254 } |
254 } |
255 } |
255 } |
256 } |
256 } |
257 } |
257 } |
258 |
258 |
259 void ConnectionGraph::remove_deferred(uint ni) { |
259 void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) { |
260 VectorSet visited(Thread::current()->resource_area()); |
260 // This method is most expensive during ConnectionGraph construction. |
|
261 // Reuse vectorSet and an additional growable array for deferred edges. |
|
262 deferred_edges->clear(); |
|
263 visited->Clear(); |
261 |
264 |
262 uint i = 0; |
265 uint i = 0; |
263 PointsToNode *ptn = ptnode_adr(ni); |
266 PointsToNode *ptn = ptnode_adr(ni); |
264 |
267 |
265 while(i < ptn->edge_count()) { |
268 // Mark current edges as visited and move deferred edges to separate array. |
|
269 for (; i < ptn->edge_count(); i++) { |
266 uint t = ptn->edge_target(i); |
270 uint t = ptn->edge_target(i); |
|
271 #ifdef ASSERT |
|
272 assert(!visited->test_set(t), "expecting no duplications"); |
|
273 #else |
|
274 visited->set(t); |
|
275 #endif |
|
276 if (ptn->edge_type(i) == PointsToNode::DeferredEdge) { |
|
277 ptn->remove_edge(t, PointsToNode::DeferredEdge); |
|
278 deferred_edges->append(t); |
|
279 } |
|
280 } |
|
281 for (int next = 0; next < deferred_edges->length(); ++next) { |
|
282 uint t = deferred_edges->at(next); |
267 PointsToNode *ptt = ptnode_adr(t); |
283 PointsToNode *ptt = ptnode_adr(t); |
268 if (ptn->edge_type(i) != PointsToNode::DeferredEdge) { |
284 for (uint j = 0; j < ptt->edge_count(); j++) { |
269 i++; |
285 uint n1 = ptt->edge_target(j); |
270 } else { |
286 if (visited->test_set(n1)) |
271 ptn->remove_edge(t, PointsToNode::DeferredEdge); |
287 continue; |
272 if(!visited.test_set(t)) { |
288 switch(ptt->edge_type(j)) { |
273 for (uint j = 0; j < ptt->edge_count(); j++) { |
289 case PointsToNode::PointsToEdge: |
274 uint n1 = ptt->edge_target(j); |
290 add_pointsto_edge(ni, n1); |
275 PointsToNode *pt1 = ptnode_adr(n1); |
291 if(n1 == _phantom_object) { |
276 switch(ptt->edge_type(j)) { |
292 // Special case - field set outside (globally escaping). |
277 case PointsToNode::PointsToEdge: |
293 ptn->set_escape_state(PointsToNode::GlobalEscape); |
278 add_pointsto_edge(ni, n1); |
|
279 if(n1 == _phantom_object) { |
|
280 // Special case - field set outside (globally escaping). |
|
281 ptn->set_escape_state(PointsToNode::GlobalEscape); |
|
282 } |
|
283 break; |
|
284 case PointsToNode::DeferredEdge: |
|
285 add_deferred_edge(ni, n1); |
|
286 break; |
|
287 case PointsToNode::FieldEdge: |
|
288 assert(false, "invalid connection graph"); |
|
289 break; |
|
290 } |
294 } |
291 } |
295 break; |
|
296 case PointsToNode::DeferredEdge: |
|
297 deferred_edges->append(n1); |
|
298 break; |
|
299 case PointsToNode::FieldEdge: |
|
300 assert(false, "invalid connection graph"); |
|
301 break; |
292 } |
302 } |
293 } |
303 } |
294 } |
304 } |
295 } |
305 } |
296 |
306 |
1234 cg_worklist.append(n->_idx); // Collect CG nodes |
1244 cg_worklist.append(n->_idx); // Collect CG nodes |
1235 } |
1245 } |
1236 } |
1246 } |
1237 |
1247 |
1238 VectorSet ptset(Thread::current()->resource_area()); |
1248 VectorSet ptset(Thread::current()->resource_area()); |
1239 GrowableArray<Node*> alloc_worklist; |
1249 GrowableArray<Node*> alloc_worklist; |
1240 GrowableArray<int> worklist; |
1250 GrowableArray<int> worklist; |
|
1251 GrowableArray<uint> deferred_edges; |
|
1252 VectorSet visited(Thread::current()->resource_area()); |
1241 |
1253 |
1242 // remove deferred edges from the graph and collect |
1254 // remove deferred edges from the graph and collect |
1243 // information we will need for type splitting |
1255 // information we will need for type splitting |
1244 for( int next = 0; next < cg_worklist.length(); ++next ) { |
1256 for( int next = 0; next < cg_worklist.length(); ++next ) { |
1245 int ni = cg_worklist.at(next); |
1257 int ni = cg_worklist.at(next); |
1246 PointsToNode* ptn = _nodes->adr_at(ni); |
1258 PointsToNode* ptn = _nodes->adr_at(ni); |
1247 PointsToNode::NodeType nt = ptn->node_type(); |
1259 PointsToNode::NodeType nt = ptn->node_type(); |
1248 Node *n = ptn->_node; |
1260 Node *n = ptn->_node; |
1249 if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { |
1261 if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { |
1250 remove_deferred(ni); |
1262 remove_deferred(ni, &deferred_edges, &visited); |
1251 if (n->is_AddP()) { |
1263 if (n->is_AddP()) { |
1252 // If this AddP computes an address which may point to more that one |
1264 // If this AddP computes an address which may point to more that one |
1253 // object, nothing the address points to can be scalar replaceable. |
1265 // object, nothing the address points to can be scalar replaceable. |
1254 Node *base = get_addp_base(n); |
1266 Node *base = get_addp_base(n); |
1255 ptset.Clear(); |
1267 ptset.Clear(); |