hotspot/src/share/vm/opto/escape.cpp
changeset 348 905c4cbf5d6a
parent 238 803c80713999
child 349 94856a2bae83
equal deleted inserted replaced
347:df859fcca515 348:905c4cbf5d6a
   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();