Mercurial > hg > graal-compiler
comparison src/share/vm/opto/escape.cpp @ 18041:52b4284cb496
Merge with jdk8u20-b26
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 15 Oct 2014 16:02:50 +0200 |
parents | 4ca6dc0799b6 87b5e00100fe |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
17606:45d7b2c7029d | 18041:52b4284cb496 |
---|---|
708 } else if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) { | 708 } else if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) { |
709 // Stored value escapes in unsafe access. | 709 // Stored value escapes in unsafe access. |
710 Node *val = n->in(MemNode::ValueIn); | 710 Node *val = n->in(MemNode::ValueIn); |
711 PointsToNode* ptn = ptnode_adr(val->_idx); | 711 PointsToNode* ptn = ptnode_adr(val->_idx); |
712 assert(ptn != NULL, "node should be registered"); | 712 assert(ptn != NULL, "node should be registered"); |
713 ptn->set_escape_state(PointsToNode::GlobalEscape); | 713 set_escape_state(ptn, PointsToNode::GlobalEscape); |
714 // Add edge to object for unsafe access with offset. | 714 // Add edge to object for unsafe access with offset. |
715 PointsToNode* adr_ptn = ptnode_adr(adr->_idx); | 715 PointsToNode* adr_ptn = ptnode_adr(adr->_idx); |
716 assert(adr_ptn != NULL, "node should be registered"); | 716 assert(adr_ptn != NULL, "node should be registered"); |
717 if (adr_ptn->is_Field()) { | 717 if (adr_ptn->is_Field()) { |
718 assert(adr_ptn->as_Field()->is_oop(), "should be oop field"); | 718 assert(adr_ptn->as_Field()->is_oop(), "should be oop field"); |
1577 field->fields_escape_state() == PointsToNode::NoEscape, "sanity"); | 1577 field->fields_escape_state() == PointsToNode::NoEscape, "sanity"); |
1578 if (field->offset() == Type::OffsetBot) { | 1578 if (field->offset() == Type::OffsetBot) { |
1579 jobj->set_scalar_replaceable(false); | 1579 jobj->set_scalar_replaceable(false); |
1580 return; | 1580 return; |
1581 } | 1581 } |
1582 // 2. An object is not scalar replaceable if the field into which it is | |
1583 // stored has multiple bases one of which is null. | |
1584 if (field->base_count() > 1) { | |
1585 for (BaseIterator i(field); i.has_next(); i.next()) { | |
1586 PointsToNode* base = i.get(); | |
1587 if (base == null_obj) { | |
1588 jobj->set_scalar_replaceable(false); | |
1589 return; | |
1590 } | |
1591 } | |
1592 } | |
1582 } | 1593 } |
1583 assert(use->is_Field() || use->is_LocalVar(), "sanity"); | 1594 assert(use->is_Field() || use->is_LocalVar(), "sanity"); |
1584 // 2. An object is not scalar replaceable if it is merged with other objects. | 1595 // 3. An object is not scalar replaceable if it is merged with other objects. |
1585 for (EdgeIterator j(use); j.has_next(); j.next()) { | 1596 for (EdgeIterator j(use); j.has_next(); j.next()) { |
1586 PointsToNode* ptn = j.get(); | 1597 PointsToNode* ptn = j.get(); |
1587 if (ptn->is_JavaObject() && ptn != jobj) { | 1598 if (ptn->is_JavaObject() && ptn != jobj) { |
1588 // Mark all objects. | 1599 // Mark all objects. |
1589 jobj->set_scalar_replaceable(false); | 1600 jobj->set_scalar_replaceable(false); |
1598 for (EdgeIterator j(jobj); j.has_next(); j.next()) { | 1609 for (EdgeIterator j(jobj); j.has_next(); j.next()) { |
1599 // Non-escaping object node should point only to field nodes. | 1610 // Non-escaping object node should point only to field nodes. |
1600 FieldNode* field = j.get()->as_Field(); | 1611 FieldNode* field = j.get()->as_Field(); |
1601 int offset = field->as_Field()->offset(); | 1612 int offset = field->as_Field()->offset(); |
1602 | 1613 |
1603 // 3. An object is not scalar replaceable if it has a field with unknown | 1614 // 4. An object is not scalar replaceable if it has a field with unknown |
1604 // offset (array's element is accessed in loop). | 1615 // offset (array's element is accessed in loop). |
1605 if (offset == Type::OffsetBot) { | 1616 if (offset == Type::OffsetBot) { |
1606 jobj->set_scalar_replaceable(false); | 1617 jobj->set_scalar_replaceable(false); |
1607 return; | 1618 return; |
1608 } | 1619 } |
1609 // 4. Currently an object is not scalar replaceable if a LoadStore node | 1620 // 5. Currently an object is not scalar replaceable if a LoadStore node |
1610 // access its field since the field value is unknown after it. | 1621 // access its field since the field value is unknown after it. |
1611 // | 1622 // |
1612 Node* n = field->ideal_node(); | 1623 Node* n = field->ideal_node(); |
1613 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { | 1624 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
1614 if (n->fast_out(i)->is_LoadStore()) { | 1625 if (n->fast_out(i)->is_LoadStore()) { |
1615 jobj->set_scalar_replaceable(false); | 1626 jobj->set_scalar_replaceable(false); |
1616 return; | 1627 return; |
1617 } | 1628 } |
1618 } | 1629 } |
1619 | 1630 |
1620 // 5. Or the address may point to more then one object. This may produce | 1631 // 6. Or the address may point to more then one object. This may produce |
1621 // the false positive result (set not scalar replaceable) | 1632 // the false positive result (set not scalar replaceable) |
1622 // since the flow-insensitive escape analysis can't separate | 1633 // since the flow-insensitive escape analysis can't separate |
1623 // the case when stores overwrite the field's value from the case | 1634 // the case when stores overwrite the field's value from the case |
1624 // when stores happened on different control branches. | 1635 // when stores happened on different control branches. |
1625 // | 1636 // |