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++ ) { |