< prev index next >

src/hotspot/share/opto/escape.cpp

Print this page




1710   for (EdgeIterator j(jobj); j.has_next(); j.next()) {
1711     if (j.get()->is_Arraycopy()) {
1712       continue;
1713     }
1714 
1715     // Non-escaping object node should point only to field nodes.
1716     FieldNode* field = j.get()->as_Field();
1717     int offset = field->as_Field()->offset();
1718 
1719     // 4. An object is not scalar replaceable if it has a field with unknown
1720     // offset (array's element is accessed in loop).
1721     if (offset == Type::OffsetBot) {
1722       jobj->set_scalar_replaceable(false);
1723       return;
1724     }
1725     // 5. Currently an object is not scalar replaceable if a LoadStore node
1726     // access its field since the field value is unknown after it.
1727     //
1728     Node* n = field->ideal_node();
1729     for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1730       if (n->fast_out(i)->is_LoadStore()) {

1731         jobj->set_scalar_replaceable(false);
1732         return;
1733       }
1734     }
1735 
1736     // 6. Or the address may point to more then one object. This may produce
1737     // the false positive result (set not scalar replaceable)
1738     // since the flow-insensitive escape analysis can't separate
1739     // the case when stores overwrite the field's value from the case
1740     // when stores happened on different control branches.
1741     //
1742     // Note: it will disable scalar replacement in some cases:
1743     //
1744     //    Point p[] = new Point[1];
1745     //    p[0] = new Point(); // Will be not scalar replaced
1746     //
1747     // but it will save us from incorrect optimizations in next cases:
1748     //
1749     //    Point p[] = new Point[1];
1750     //    if ( x ) p[0] = new Point(); // Will be not scalar replaced




1710   for (EdgeIterator j(jobj); j.has_next(); j.next()) {
1711     if (j.get()->is_Arraycopy()) {
1712       continue;
1713     }
1714 
1715     // Non-escaping object node should point only to field nodes.
1716     FieldNode* field = j.get()->as_Field();
1717     int offset = field->as_Field()->offset();
1718 
1719     // 4. An object is not scalar replaceable if it has a field with unknown
1720     // offset (array's element is accessed in loop).
1721     if (offset == Type::OffsetBot) {
1722       jobj->set_scalar_replaceable(false);
1723       return;
1724     }
1725     // 5. Currently an object is not scalar replaceable if a LoadStore node
1726     // access its field since the field value is unknown after it.
1727     //
1728     Node* n = field->ideal_node();
1729     for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1730       Node* u = n->fast_out(i);
1731       if (u->is_LoadStore() || (u->is_Mem() && u->as_Mem()->is_mismatched_access())) {
1732         jobj->set_scalar_replaceable(false);
1733         return;
1734       }
1735     }
1736 
1737     // 6. Or the address may point to more then one object. This may produce
1738     // the false positive result (set not scalar replaceable)
1739     // since the flow-insensitive escape analysis can't separate
1740     // the case when stores overwrite the field's value from the case
1741     // when stores happened on different control branches.
1742     //
1743     // Note: it will disable scalar replacement in some cases:
1744     //
1745     //    Point p[] = new Point[1];
1746     //    p[0] = new Point(); // Will be not scalar replaced
1747     //
1748     // but it will save us from incorrect optimizations in next cases:
1749     //
1750     //    Point p[] = new Point[1];
1751     //    if ( x ) p[0] = new Point(); // Will be not scalar replaced


< prev index next >