1.1 --- a/src/share/vm/opto/escape.cpp Wed Apr 02 12:09:59 2008 -0700 1.2 +++ b/src/share/vm/opto/escape.cpp Wed Apr 02 16:59:37 2008 -0700 1.3 @@ -256,39 +256,49 @@ 1.4 } 1.5 } 1.6 1.7 -void ConnectionGraph::remove_deferred(uint ni) { 1.8 - VectorSet visited(Thread::current()->resource_area()); 1.9 +void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) { 1.10 + // This method is most expensive during ConnectionGraph construction. 1.11 + // Reuse vectorSet and an additional growable array for deferred edges. 1.12 + deferred_edges->clear(); 1.13 + visited->Clear(); 1.14 1.15 uint i = 0; 1.16 PointsToNode *ptn = ptnode_adr(ni); 1.17 1.18 - while(i < ptn->edge_count()) { 1.19 + // Mark current edges as visited and move deferred edges to separate array. 1.20 + for (; i < ptn->edge_count(); i++) { 1.21 uint t = ptn->edge_target(i); 1.22 +#ifdef ASSERT 1.23 + assert(!visited->test_set(t), "expecting no duplications"); 1.24 +#else 1.25 + visited->set(t); 1.26 +#endif 1.27 + if (ptn->edge_type(i) == PointsToNode::DeferredEdge) { 1.28 + ptn->remove_edge(t, PointsToNode::DeferredEdge); 1.29 + deferred_edges->append(t); 1.30 + } 1.31 + } 1.32 + for (int next = 0; next < deferred_edges->length(); ++next) { 1.33 + uint t = deferred_edges->at(next); 1.34 PointsToNode *ptt = ptnode_adr(t); 1.35 - if (ptn->edge_type(i) != PointsToNode::DeferredEdge) { 1.36 - i++; 1.37 - } else { 1.38 - ptn->remove_edge(t, PointsToNode::DeferredEdge); 1.39 - if(!visited.test_set(t)) { 1.40 - for (uint j = 0; j < ptt->edge_count(); j++) { 1.41 - uint n1 = ptt->edge_target(j); 1.42 - PointsToNode *pt1 = ptnode_adr(n1); 1.43 - switch(ptt->edge_type(j)) { 1.44 - case PointsToNode::PointsToEdge: 1.45 - add_pointsto_edge(ni, n1); 1.46 - if(n1 == _phantom_object) { 1.47 - // Special case - field set outside (globally escaping). 1.48 - ptn->set_escape_state(PointsToNode::GlobalEscape); 1.49 - } 1.50 - break; 1.51 - case PointsToNode::DeferredEdge: 1.52 - add_deferred_edge(ni, n1); 1.53 - break; 1.54 - case PointsToNode::FieldEdge: 1.55 - assert(false, "invalid connection graph"); 1.56 - break; 1.57 + for (uint j = 0; j < ptt->edge_count(); j++) { 1.58 + uint n1 = ptt->edge_target(j); 1.59 + if (visited->test_set(n1)) 1.60 + continue; 1.61 + switch(ptt->edge_type(j)) { 1.62 + case PointsToNode::PointsToEdge: 1.63 + add_pointsto_edge(ni, n1); 1.64 + if(n1 == _phantom_object) { 1.65 + // Special case - field set outside (globally escaping). 1.66 + ptn->set_escape_state(PointsToNode::GlobalEscape); 1.67 } 1.68 - } 1.69 + break; 1.70 + case PointsToNode::DeferredEdge: 1.71 + deferred_edges->append(n1); 1.72 + break; 1.73 + case PointsToNode::FieldEdge: 1.74 + assert(false, "invalid connection graph"); 1.75 + break; 1.76 } 1.77 } 1.78 } 1.79 @@ -1236,8 +1246,10 @@ 1.80 } 1.81 1.82 VectorSet ptset(Thread::current()->resource_area()); 1.83 - GrowableArray<Node*> alloc_worklist; 1.84 - GrowableArray<int> worklist; 1.85 + GrowableArray<Node*> alloc_worklist; 1.86 + GrowableArray<int> worklist; 1.87 + GrowableArray<uint> deferred_edges; 1.88 + VectorSet visited(Thread::current()->resource_area()); 1.89 1.90 // remove deferred edges from the graph and collect 1.91 // information we will need for type splitting 1.92 @@ -1247,7 +1259,7 @@ 1.93 PointsToNode::NodeType nt = ptn->node_type(); 1.94 Node *n = ptn->_node; 1.95 if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { 1.96 - remove_deferred(ni); 1.97 + remove_deferred(ni, &deferred_edges, &visited); 1.98 if (n->is_AddP()) { 1.99 // If this AddP computes an address which may point to more that one 1.100 // object, nothing the address points to can be scalar replaceable.