hotspot/src/share/vm/opto/escape.cpp
changeset 13886 8d82c4dfa722
parent 13393 f0344cc50a90
child 13969 d2a189b83b87
equal deleted inserted replaced
13885:6b056026ecad 13886:8d82c4dfa722
   280 #endif
   280 #endif
   281   }
   281   }
   282   return has_non_escaping_obj;
   282   return has_non_escaping_obj;
   283 }
   283 }
   284 
   284 
       
   285 // Utility function for nodes that load an object
       
   286 void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
       
   287   // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
       
   288   // ThreadLocal has RawPtr type.
       
   289   const Type* t = _igvn->type(n);
       
   290   if (t->make_ptr() != NULL) {
       
   291     Node* adr = n->in(MemNode::Address);
       
   292 #ifdef ASSERT
       
   293     if (!adr->is_AddP()) {
       
   294       assert(_igvn->type(adr)->isa_rawptr(), "sanity");
       
   295     } else {
       
   296       assert((ptnode_adr(adr->_idx) == NULL ||
       
   297               ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
       
   298     }
       
   299 #endif
       
   300     add_local_var_and_edge(n, PointsToNode::NoEscape,
       
   301                            adr, delayed_worklist);
       
   302   }
       
   303 }
       
   304 
   285 // Populate Connection Graph with PointsTo nodes and create simple
   305 // Populate Connection Graph with PointsTo nodes and create simple
   286 // connection graph edges.
   306 // connection graph edges.
   287 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
   307 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
   288   assert(!_verify, "this method sould not be called for verification");
   308   assert(!_verify, "this method sould not be called for verification");
   289   PhaseGVN* igvn = _igvn;
   309   PhaseGVN* igvn = _igvn;
   385       break;
   405       break;
   386     }
   406     }
   387     case Op_LoadP:
   407     case Op_LoadP:
   388     case Op_LoadN:
   408     case Op_LoadN:
   389     case Op_LoadPLocked: {
   409     case Op_LoadPLocked: {
   390       // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
   410       add_objload_to_connection_graph(n, delayed_worklist);
   391       // ThreadLocal has RawPrt type.
       
   392       const Type* t = igvn->type(n);
       
   393       if (t->make_ptr() != NULL) {
       
   394         Node* adr = n->in(MemNode::Address);
       
   395 #ifdef ASSERT
       
   396         if (!adr->is_AddP()) {
       
   397           assert(igvn->type(adr)->isa_rawptr(), "sanity");
       
   398         } else {
       
   399           assert((ptnode_adr(adr->_idx) == NULL ||
       
   400                   ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
       
   401         }
       
   402 #endif
       
   403         add_local_var_and_edge(n, PointsToNode::NoEscape,
       
   404                                adr, delayed_worklist);
       
   405       }
       
   406       break;
   411       break;
   407     }
   412     }
   408     case Op_Parm: {
   413     case Op_Parm: {
   409       map_ideal_node(n, phantom_obj);
   414       map_ideal_node(n, phantom_obj);
   410       break;
   415       break;
   415       map_ideal_node(n, phantom_obj); // Result is unknown
   420       map_ideal_node(n, phantom_obj); // Result is unknown
   416       break;
   421       break;
   417     }
   422     }
   418     case Op_Phi: {
   423     case Op_Phi: {
   419       // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
   424       // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
   420       // ThreadLocal has RawPrt type.
   425       // ThreadLocal has RawPtr type.
   421       const Type* t = n->as_Phi()->type();
   426       const Type* t = n->as_Phi()->type();
   422       if (t->make_ptr() != NULL) {
   427       if (t->make_ptr() != NULL) {
   423         add_local_var(n, PointsToNode::NoEscape);
   428         add_local_var(n, PointsToNode::NoEscape);
   424         // Do not add edges during first iteration because some could be
   429         // Do not add edges during first iteration because some could be
   425         // not defined yet.
   430         // not defined yet.
   443         // Treat Return value as LocalVar with GlobalEscape escape state.
   448         // Treat Return value as LocalVar with GlobalEscape escape state.
   444         add_local_var_and_edge(n, PointsToNode::GlobalEscape,
   449         add_local_var_and_edge(n, PointsToNode::GlobalEscape,
   445                                n->in(TypeFunc::Parms), delayed_worklist);
   450                                n->in(TypeFunc::Parms), delayed_worklist);
   446       }
   451       }
   447       break;
   452       break;
       
   453     }
       
   454     case Op_GetAndSetP:
       
   455     case Op_GetAndSetN: {
       
   456       add_objload_to_connection_graph(n, delayed_worklist);
       
   457       // fallthrough
   448     }
   458     }
   449     case Op_StoreP:
   459     case Op_StoreP:
   450     case Op_StoreN:
   460     case Op_StoreN:
   451     case Op_StorePConditional:
   461     case Op_StorePConditional:
   452     case Op_CompareAndSwapP:
   462     case Op_CompareAndSwapP:
   583     }
   593     }
   584     case Op_LoadP:
   594     case Op_LoadP:
   585     case Op_LoadN:
   595     case Op_LoadN:
   586     case Op_LoadPLocked: {
   596     case Op_LoadPLocked: {
   587       // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
   597       // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
   588       // ThreadLocal has RawPrt type.
   598       // ThreadLocal has RawPtr type.
   589       const Type* t = _igvn->type(n);
   599       const Type* t = _igvn->type(n);
   590       if (t->make_ptr() != NULL) {
   600       if (t->make_ptr() != NULL) {
   591         Node* adr = n->in(MemNode::Address);
   601         Node* adr = n->in(MemNode::Address);
   592         add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
   602         add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
   593         break;
   603         break;
   594       }
   604       }
   595       ELSE_FAIL("Op_LoadP");
   605       ELSE_FAIL("Op_LoadP");
   596     }
   606     }
   597     case Op_Phi: {
   607     case Op_Phi: {
   598       // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
   608       // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
   599       // ThreadLocal has RawPrt type.
   609       // ThreadLocal has RawPtr type.
   600       const Type* t = n->as_Phi()->type();
   610       const Type* t = n->as_Phi()->type();
   601       if (t->make_ptr() != NULL) {
   611       if (t->make_ptr() != NULL) {
   602         for (uint i = 1; i < n->req(); i++) {
   612         for (uint i = 1; i < n->req(); i++) {
   603           Node* in = n->in(i);
   613           Node* in = n->in(i);
   604           if (in == NULL)
   614           if (in == NULL)
   636     }
   646     }
   637     case Op_StoreP:
   647     case Op_StoreP:
   638     case Op_StoreN:
   648     case Op_StoreN:
   639     case Op_StorePConditional:
   649     case Op_StorePConditional:
   640     case Op_CompareAndSwapP:
   650     case Op_CompareAndSwapP:
   641     case Op_CompareAndSwapN: {
   651     case Op_CompareAndSwapN:
       
   652     case Op_GetAndSetP:
       
   653     case Op_GetAndSetN: {
   642       Node* adr = n->in(MemNode::Address);
   654       Node* adr = n->in(MemNode::Address);
       
   655       if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
       
   656         const Type* t = _igvn->type(n);
       
   657         if (t->make_ptr() != NULL) {
       
   658           add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
       
   659         }
       
   660       }
   643       const Type *adr_type = _igvn->type(adr);
   661       const Type *adr_type = _igvn->type(adr);
   644       adr_type = adr_type->make_ptr();
   662       adr_type = adr_type->make_ptr();
   645       if (adr_type->isa_oopptr() ||
   663       if (adr_type->isa_oopptr() ||
   646           (opcode == Op_StoreP || opcode == Op_StoreN) &&
   664           (opcode == Op_StoreP || opcode == Op_StoreN) &&
   647                         (adr_type == TypeRawPtr::NOTNULL &&
   665                         (adr_type == TypeRawPtr::NOTNULL &&