Mercurial > hg > truffle
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(); |