src/share/vm/opto/escape.cpp

changeset 3242
e69a66a1457b
parent 2951
642c68c75db9
child 3254
59e515ee9354
equal deleted inserted replaced
3241:a6eef545f1a2 3242:e69a66a1457b
106 add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true); 106 add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true);
107 107
108 // Add ConP(#NULL) and ConN(#NULL) nodes. 108 // Add ConP(#NULL) and ConN(#NULL) nodes.
109 Node* oop_null = igvn->zerocon(T_OBJECT); 109 Node* oop_null = igvn->zerocon(T_OBJECT);
110 _oop_null = oop_null->_idx; 110 _oop_null = oop_null->_idx;
111 assert(_oop_null < C->unique(), "should be created already"); 111 assert(_oop_null < nodes_size(), "should be created already");
112 add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true); 112 add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
113 113
114 if (UseCompressedOops) { 114 if (UseCompressedOops) {
115 Node* noop_null = igvn->zerocon(T_NARROWOOP); 115 Node* noop_null = igvn->zerocon(T_NARROWOOP);
116 _noop_null = noop_null->_idx; 116 _noop_null = noop_null->_idx;
117 assert(_noop_null < C->unique(), "should be created already"); 117 assert(_noop_null < nodes_size(), "should be created already");
118 add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true); 118 add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
119 } else {
120 _noop_null = _oop_null; // Should be initialized
119 } 121 }
120 } 122 }
121 123
122 void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) { 124 void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) {
123 PointsToNode *f = ptnode_adr(from_i); 125 PointsToNode *f = ptnode_adr(from_i);
172 174
173 add_edge(f, to_i, PointsToNode::FieldEdge); 175 add_edge(f, to_i, PointsToNode::FieldEdge);
174 } 176 }
175 177
176 void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) { 178 void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) {
179 // Don't change non-escaping state of NULL pointer.
180 if (ni == _noop_null || ni == _oop_null)
181 return;
177 PointsToNode *npt = ptnode_adr(ni); 182 PointsToNode *npt = ptnode_adr(ni);
178 PointsToNode::EscapeState old_es = npt->escape_state(); 183 PointsToNode::EscapeState old_es = npt->escape_state();
179 if (es > old_es) 184 if (es > old_es)
180 npt->set_escape_state(es); 185 npt->set_escape_state(es);
181 } 186 }
229 if (pes > es) 234 if (pes > es)
230 es = pes; 235 es = pes;
231 } 236 }
232 if (orig_es != es) { 237 if (orig_es != es) {
233 // cache the computed escape state 238 // cache the computed escape state
234 assert(es != PointsToNode::UnknownEscape, "should have computed an escape state"); 239 assert(es > orig_es, "should have computed an escape state");
235 ptnode_adr(idx)->set_escape_state(es); 240 set_escape_state(idx, es);
236 } // orig_es could be PointsToNode::UnknownEscape 241 } // orig_es could be PointsToNode::UnknownEscape
237 return es; 242 return es;
238 } 243 }
239 244
240 VectorSet* ConnectionGraph::PointsTo(Node * n) { 245 VectorSet* ConnectionGraph::PointsTo(Node * n) {
332 PointsToNode::EdgeType et = ptt->edge_type(e); 337 PointsToNode::EdgeType et = ptt->edge_type(e);
333 if (et == PointsToNode::PointsToEdge) { 338 if (et == PointsToNode::PointsToEdge) {
334 add_pointsto_edge(ni, etgt); 339 add_pointsto_edge(ni, etgt);
335 if(etgt == _phantom_object) { 340 if(etgt == _phantom_object) {
336 // Special case - field set outside (globally escaping). 341 // Special case - field set outside (globally escaping).
337 ptn->set_escape_state(PointsToNode::GlobalEscape); 342 set_escape_state(ni, PointsToNode::GlobalEscape);
338 } 343 }
339 } else if (et == PointsToNode::DeferredEdge) { 344 } else if (et == PointsToNode::DeferredEdge) {
340 deferred_edges->append(etgt); 345 deferred_edges->append(etgt);
341 } else { 346 } else {
342 assert(false,"invalid connection graph"); 347 assert(false,"invalid connection graph");
1684 uint e_cnt = ptn->edge_count(); 1689 uint e_cnt = ptn->edge_count();
1685 for (uint ei = 0; ei < e_cnt; ei++) { 1690 for (uint ei = 0; ei < e_cnt; ei++) {
1686 uint npi = ptn->edge_target(ei); 1691 uint npi = ptn->edge_target(ei);
1687 PointsToNode *np = ptnode_adr(npi); 1692 PointsToNode *np = ptnode_adr(npi);
1688 if (np->escape_state() < PointsToNode::GlobalEscape) { 1693 if (np->escape_state() < PointsToNode::GlobalEscape) {
1689 np->set_escape_state(PointsToNode::GlobalEscape); 1694 set_escape_state(npi, PointsToNode::GlobalEscape);
1690 worklist.push(npi); 1695 worklist.push(npi);
1691 } 1696 }
1692 } 1697 }
1693 } 1698 }
1694 1699
1706 uint e_cnt = ptn->edge_count(); 1711 uint e_cnt = ptn->edge_count();
1707 for (uint ei = 0; ei < e_cnt; ei++) { 1712 for (uint ei = 0; ei < e_cnt; ei++) {
1708 uint npi = ptn->edge_target(ei); 1713 uint npi = ptn->edge_target(ei);
1709 PointsToNode *np = ptnode_adr(npi); 1714 PointsToNode *np = ptnode_adr(npi);
1710 if (np->escape_state() < PointsToNode::ArgEscape) { 1715 if (np->escape_state() < PointsToNode::ArgEscape) {
1711 np->set_escape_state(PointsToNode::ArgEscape); 1716 set_escape_state(npi, PointsToNode::ArgEscape);
1712 worklist.push(npi); 1717 worklist.push(npi);
1713 } 1718 }
1714 } 1719 }
1715 } 1720 }
1716 1721
1722 if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape) 1727 if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape)
1723 worklist.push(nk); 1728 worklist.push(nk);
1724 } 1729 }
1725 // mark all nodes reachable from NoEscape nodes 1730 // mark all nodes reachable from NoEscape nodes
1726 while(worklist.length() > 0) { 1731 while(worklist.length() > 0) {
1727 PointsToNode* ptn = ptnode_adr(worklist.pop()); 1732 uint nk = worklist.pop();
1728 if (ptn->node_type() == PointsToNode::JavaObject) 1733 PointsToNode* ptn = ptnode_adr(nk);
1729 has_non_escaping_obj = true; // Non GlobalEscape 1734 if (ptn->node_type() == PointsToNode::JavaObject &&
1735 !(nk == _noop_null || nk == _oop_null))
1736 has_non_escaping_obj = true; // Non Escape
1730 Node* n = ptn->_node; 1737 Node* n = ptn->_node;
1731 if (n->is_Allocate() && ptn->_scalar_replaceable ) { 1738 if (n->is_Allocate() && ptn->_scalar_replaceable ) {
1732 // Push scalar replaceable allocations on alloc_worklist 1739 // Push scalar replaceable allocations on alloc_worklist
1733 // for processing in split_unique_types(). 1740 // for processing in split_unique_types().
1734 alloc_worklist.append(n); 1741 alloc_worklist.append(n);
1736 uint e_cnt = ptn->edge_count(); 1743 uint e_cnt = ptn->edge_count();
1737 for (uint ei = 0; ei < e_cnt; ei++) { 1744 for (uint ei = 0; ei < e_cnt; ei++) {
1738 uint npi = ptn->edge_target(ei); 1745 uint npi = ptn->edge_target(ei);
1739 PointsToNode *np = ptnode_adr(npi); 1746 PointsToNode *np = ptnode_adr(npi);
1740 if (np->escape_state() < PointsToNode::NoEscape) { 1747 if (np->escape_state() < PointsToNode::NoEscape) {
1741 np->set_escape_state(PointsToNode::NoEscape); 1748 set_escape_state(npi, PointsToNode::NoEscape);
1742 worklist.push(npi); 1749 worklist.push(npi);
1743 } 1750 }
1744 } 1751 }
1745 } 1752 }
1746 1753
1747 _collecting = false; 1754 _collecting = false;
1748 assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build"); 1755 assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
1756
1757 assert(ptnode_adr(_oop_null)->escape_state() == PointsToNode::NoEscape, "sanity");
1758 if (UseCompressedOops) {
1759 assert(ptnode_adr(_noop_null)->escape_state() == PointsToNode::NoEscape, "sanity");
1760 }
1749 1761
1750 if (EliminateLocks) { 1762 if (EliminateLocks) {
1751 // Mark locks before changing ideal graph. 1763 // Mark locks before changing ideal graph.
1752 int cnt = C->macro_count(); 1764 int cnt = C->macro_count();
1753 for( int i=0; i < cnt; i++ ) { 1765 for( int i=0; i < cnt; i++ ) {

mercurial