comparison src/share/vm/opto/escape.cpp @ 101:a6cb86dd209b

6681577: PIT: some VM tests fails with -XX:+AggressiveOpts in 6u5p b01 Summary: C2 spends > 60% in escape analysis code during test nsk/regression/b4675027. Reviewed-by: never
author kvn
date Wed, 02 Apr 2008 16:59:37 -0700
parents 99269dbf4ba8
children f96100ac3d12
comparison
equal deleted inserted replaced
100:c7c777385a15 101:a6cb86dd209b
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();