Mercurial > hg > truffle
comparison src/share/vm/opto/chaitin.cpp @ 729:04fa5affa478
6709742: find_base_for_derived's use of Ideal NULL is unsafe causing crashes during register allocation
Summary: Create a mach node corresponding to ideal node ConP #NULL specifically for derived pointers.
Reviewed-by: never
author | kvn |
---|---|
date | Wed, 22 Apr 2009 17:03:18 -0700 |
parents | fbc12e71c476 |
children | e90521d61f9a |
comparison
equal
deleted
inserted
replaced
728:85656c8fa13f | 729:04fa5affa478 |
---|---|
1421 // See if this happens to be a base. | 1421 // See if this happens to be a base. |
1422 // NOTE: we use TypePtr instead of TypeOopPtr because we can have | 1422 // NOTE: we use TypePtr instead of TypeOopPtr because we can have |
1423 // pointers derived from NULL! These are always along paths that | 1423 // pointers derived from NULL! These are always along paths that |
1424 // can't happen at run-time but the optimizer cannot deduce it so | 1424 // can't happen at run-time but the optimizer cannot deduce it so |
1425 // we have to handle it gracefully. | 1425 // we have to handle it gracefully. |
1426 assert(!derived->bottom_type()->isa_narrowoop() || | |
1427 derived->bottom_type()->make_ptr()->is_ptr()->_offset == 0, "sanity"); | |
1426 const TypePtr *tj = derived->bottom_type()->isa_ptr(); | 1428 const TypePtr *tj = derived->bottom_type()->isa_ptr(); |
1427 // If its an OOP with a non-zero offset, then it is derived. | 1429 // If its an OOP with a non-zero offset, then it is derived. |
1428 if( tj->_offset == 0 ) { | 1430 if( tj == NULL || tj->_offset == 0 ) { |
1429 derived_base_map[derived->_idx] = derived; | 1431 derived_base_map[derived->_idx] = derived; |
1430 return derived; | 1432 return derived; |
1431 } | 1433 } |
1432 // Derived is NULL+offset? Base is NULL! | 1434 // Derived is NULL+offset? Base is NULL! |
1433 if( derived->is_Con() ) { | 1435 if( derived->is_Con() ) { |
1434 Node *base = new (C, 1) ConPNode( TypePtr::NULL_PTR ); | 1436 Node *base = _matcher.mach_null(); |
1435 uint no_lidx = 0; // an unmatched constant in debug info has no LRG | 1437 assert(base != NULL, "sanity"); |
1436 _names.extend(base->_idx, no_lidx); | 1438 if (base->in(0) == NULL) { |
1439 // Initialize it once and make it shared: | |
1440 // set control to _root and place it into Start block | |
1441 // (where top() node is placed). | |
1442 base->init_req(0, _cfg._root); | |
1443 Block *startb = _cfg._bbs[C->top()->_idx]; | |
1444 startb->_nodes.insert(startb->find_node(C->top()), base ); | |
1445 _cfg._bbs.map( base->_idx, startb ); | |
1446 assert (n2lidx(base) == 0, "should not have LRG yet"); | |
1447 } | |
1448 if (n2lidx(base) == 0) { | |
1449 new_lrg(base, maxlrg++); | |
1450 } | |
1451 assert(base->in(0) == _cfg._root && | |
1452 _cfg._bbs[base->_idx] == _cfg._bbs[C->top()->_idx], "base NULL should be shared"); | |
1437 derived_base_map[derived->_idx] = base; | 1453 derived_base_map[derived->_idx] = base; |
1438 return base; | 1454 return base; |
1439 } | 1455 } |
1440 | 1456 |
1441 // Check for AddP-related opcodes | 1457 // Check for AddP-related opcodes |
1458 derived_base_map[derived->_idx] = base; | 1474 derived_base_map[derived->_idx] = base; |
1459 return base; | 1475 return base; |
1460 } | 1476 } |
1461 | 1477 |
1462 // Now we see we need a base-Phi here to merge the bases | 1478 // Now we see we need a base-Phi here to merge the bases |
1463 base = new (C, derived->req()) PhiNode( derived->in(0), base->bottom_type() ); | 1479 const Type *t = base->bottom_type(); |
1464 for( i = 1; i < derived->req(); i++ ) | 1480 base = new (C, derived->req()) PhiNode( derived->in(0), t ); |
1481 for( i = 1; i < derived->req(); i++ ) { | |
1465 base->init_req(i, find_base_for_derived(derived_base_map, derived->in(i), maxlrg)); | 1482 base->init_req(i, find_base_for_derived(derived_base_map, derived->in(i), maxlrg)); |
1483 t = t->meet(base->in(i)->bottom_type()); | |
1484 } | |
1485 base->as_Phi()->set_type(t); | |
1466 | 1486 |
1467 // Search the current block for an existing base-Phi | 1487 // Search the current block for an existing base-Phi |
1468 Block *b = _cfg._bbs[derived->_idx]; | 1488 Block *b = _cfg._bbs[derived->_idx]; |
1469 for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi | 1489 for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi |
1470 Node *phi = b->_nodes[i]; | 1490 Node *phi = b->_nodes[i]; |
1558 while ((neighbor = elements.next()) != 0) { | 1578 while ((neighbor = elements.next()) != 0) { |
1559 // Find reaching DEF for base and derived values | 1579 // Find reaching DEF for base and derived values |
1560 // This works because we are still in SSA during this call. | 1580 // This works because we are still in SSA during this call. |
1561 Node *derived = lrgs(neighbor)._def; | 1581 Node *derived = lrgs(neighbor)._def; |
1562 const TypePtr *tj = derived->bottom_type()->isa_ptr(); | 1582 const TypePtr *tj = derived->bottom_type()->isa_ptr(); |
1583 assert(!derived->bottom_type()->isa_narrowoop() || | |
1584 derived->bottom_type()->make_ptr()->is_ptr()->_offset == 0, "sanity"); | |
1563 // If its an OOP with a non-zero offset, then it is derived. | 1585 // If its an OOP with a non-zero offset, then it is derived. |
1564 if( tj && tj->_offset != 0 && tj->isa_oop_ptr() ) { | 1586 if( tj && tj->_offset != 0 && tj->isa_oop_ptr() ) { |
1565 Node *base = find_base_for_derived( derived_base_map, derived, maxlrg ); | 1587 Node *base = find_base_for_derived( derived_base_map, derived, maxlrg ); |
1566 assert( base->_idx < _names.Size(), "" ); | 1588 assert( base->_idx < _names.Size(), "" ); |
1567 // Add reaching DEFs of derived pointer and base pointer as a | 1589 // Add reaching DEFs of derived pointer and base pointer as a |