213 |
213 |
214 void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase) { |
214 void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase) { |
215 VectorSet visited(Thread::current()->resource_area()); |
215 VectorSet visited(Thread::current()->resource_area()); |
216 GrowableArray<uint> worklist; |
216 GrowableArray<uint> worklist; |
217 |
217 |
|
218 #ifdef ASSERT |
|
219 Node *orig_n = n; |
|
220 #endif |
|
221 |
218 n = n->uncast(); |
222 n = n->uncast(); |
219 PointsToNode npt = _nodes->at_grow(n->_idx); |
223 PointsToNode npt = _nodes->at_grow(n->_idx); |
220 |
224 |
221 // If we have a JavaObject, return just that object |
225 // If we have a JavaObject, return just that object |
222 if (npt.node_type() == PointsToNode::JavaObject) { |
226 if (npt.node_type() == PointsToNode::JavaObject) { |
223 ptset.set(n->_idx); |
227 ptset.set(n->_idx); |
224 return; |
228 return; |
225 } |
229 } |
226 assert(npt._node != NULL, "unregistered node"); |
230 #ifdef ASSERT |
227 |
231 if (npt._node == NULL) { |
|
232 if (orig_n != n) |
|
233 orig_n->dump(); |
|
234 n->dump(); |
|
235 assert(npt._node != NULL, "unregistered node"); |
|
236 } |
|
237 #endif |
228 worklist.push(n->_idx); |
238 worklist.push(n->_idx); |
229 while(worklist.length() > 0) { |
239 while(worklist.length() > 0) { |
230 int ni = worklist.pop(); |
240 int ni = worklist.pop(); |
231 PointsToNode pn = _nodes->at_grow(ni); |
241 PointsToNode pn = _nodes->at_grow(ni); |
232 if (!visited.test_set(ni)) { |
242 if (!visited.test_set(ni)) { |
264 |
274 |
265 uint i = 0; |
275 uint i = 0; |
266 PointsToNode *ptn = ptnode_adr(ni); |
276 PointsToNode *ptn = ptnode_adr(ni); |
267 |
277 |
268 // Mark current edges as visited and move deferred edges to separate array. |
278 // Mark current edges as visited and move deferred edges to separate array. |
269 for (; i < ptn->edge_count(); i++) { |
279 while (i < ptn->edge_count()) { |
270 uint t = ptn->edge_target(i); |
280 uint t = ptn->edge_target(i); |
271 #ifdef ASSERT |
281 #ifdef ASSERT |
272 assert(!visited->test_set(t), "expecting no duplications"); |
282 assert(!visited->test_set(t), "expecting no duplications"); |
273 #else |
283 #else |
274 visited->set(t); |
284 visited->set(t); |
275 #endif |
285 #endif |
276 if (ptn->edge_type(i) == PointsToNode::DeferredEdge) { |
286 if (ptn->edge_type(i) == PointsToNode::DeferredEdge) { |
277 ptn->remove_edge(t, PointsToNode::DeferredEdge); |
287 ptn->remove_edge(t, PointsToNode::DeferredEdge); |
278 deferred_edges->append(t); |
288 deferred_edges->append(t); |
|
289 } else { |
|
290 i++; |
279 } |
291 } |
280 } |
292 } |
281 for (int next = 0; next < deferred_edges->length(); ++next) { |
293 for (int next = 0; next < deferred_edges->length(); ++next) { |
282 uint t = deferred_edges->at(next); |
294 uint t = deferred_edges->at(next); |
283 PointsToNode *ptt = ptnode_adr(t); |
295 PointsToNode *ptt = ptnode_adr(t); |
1714 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); |
1726 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); |
1715 break; |
1727 break; |
1716 } |
1728 } |
1717 case Op_CastPP: |
1729 case Op_CastPP: |
1718 case Op_CheckCastPP: |
1730 case Op_CheckCastPP: |
|
1731 case Op_EncodeP: |
|
1732 case Op_DecodeN: |
1719 { |
1733 { |
1720 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); |
1734 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); |
1721 int ti = n->in(1)->_idx; |
1735 int ti = n->in(1)->_idx; |
1722 PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); |
1736 PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); |
1723 if (nt == PointsToNode::UnknownType) { |
1737 if (nt == PointsToNode::UnknownType) { |
1741 es = PointsToNode::GlobalEscape; |
1755 es = PointsToNode::GlobalEscape; |
1742 |
1756 |
1743 add_node(n, PointsToNode::JavaObject, es, true); |
1757 add_node(n, PointsToNode::JavaObject, es, true); |
1744 break; |
1758 break; |
1745 } |
1759 } |
1746 case Op_CreateEx: |
|
1747 { |
|
1748 // assume that all exception objects globally escape |
|
1749 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); |
|
1750 break; |
|
1751 } |
|
1752 case Op_ConN: |
1760 case Op_ConN: |
1753 { |
1761 { |
1754 // assume all narrow oop constants globally escape except for null |
1762 // assume all narrow oop constants globally escape except for null |
1755 PointsToNode::EscapeState es; |
1763 PointsToNode::EscapeState es; |
1756 if (phase->type(n) == TypeNarrowOop::NULL_PTR) |
1764 if (phase->type(n) == TypeNarrowOop::NULL_PTR) |
1757 es = PointsToNode::NoEscape; |
1765 es = PointsToNode::NoEscape; |
1758 else |
1766 else |
1759 es = PointsToNode::GlobalEscape; |
1767 es = PointsToNode::GlobalEscape; |
1760 |
1768 |
1761 add_node(n, PointsToNode::JavaObject, es, true); |
1769 add_node(n, PointsToNode::JavaObject, es, true); |
|
1770 break; |
|
1771 } |
|
1772 case Op_CreateEx: |
|
1773 { |
|
1774 // assume that all exception objects globally escape |
|
1775 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); |
1762 break; |
1776 break; |
1763 } |
1777 } |
1764 case Op_LoadKlass: |
1778 case Op_LoadKlass: |
1765 { |
1779 { |
1766 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); |
1780 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); |
1974 { |
1988 { |
1975 assert(false, "Op_LoadKlass"); |
1989 assert(false, "Op_LoadKlass"); |
1976 break; |
1990 break; |
1977 } |
1991 } |
1978 case Op_LoadP: |
1992 case Op_LoadP: |
|
1993 case Op_LoadN: |
1979 { |
1994 { |
1980 const Type *t = phase->type(n); |
1995 const Type *t = phase->type(n); |
1981 #ifdef ASSERT |
1996 #ifdef ASSERT |
1982 if (t->isa_ptr() == NULL) |
1997 if (!t->isa_narrowoop() && t->isa_ptr() == NULL) |
1983 assert(false, "Op_LoadP"); |
1998 assert(false, "Op_LoadP"); |
1984 #endif |
1999 #endif |
1985 |
2000 |
1986 Node* adr = n->in(MemNode::Address)->uncast(); |
2001 Node* adr = n->in(MemNode::Address)->uncast(); |
1987 const Type *adr_type = phase->type(adr); |
2002 const Type *adr_type = phase->type(adr); |
2058 } |
2073 } |
2059 _processed.set(n->_idx); |
2074 _processed.set(n->_idx); |
2060 break; |
2075 break; |
2061 } |
2076 } |
2062 case Op_StoreP: |
2077 case Op_StoreP: |
|
2078 case Op_StoreN: |
2063 case Op_StorePConditional: |
2079 case Op_StorePConditional: |
2064 case Op_CompareAndSwapP: |
2080 case Op_CompareAndSwapP: |
|
2081 case Op_CompareAndSwapN: |
2065 { |
2082 { |
2066 Node *adr = n->in(MemNode::Address); |
2083 Node *adr = n->in(MemNode::Address); |
2067 const Type *adr_type = phase->type(adr); |
2084 const Type *adr_type = phase->type(adr); |
|
2085 if (adr_type->isa_narrowoop()) { |
|
2086 adr_type = adr_type->is_narrowoop()->make_oopptr(); |
|
2087 } |
2068 #ifdef ASSERT |
2088 #ifdef ASSERT |
2069 if (!adr_type->isa_oopptr()) |
2089 if (!adr_type->isa_oopptr()) |
2070 assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP"); |
2090 assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP"); |
2071 #endif |
2091 #endif |
2072 |
2092 |