src/share/vm/opto/escape.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6695810 Sdiff src/share/vm/opto

src/share/vm/opto/escape.cpp

Print this page




 871       }
 872       set_escape_state(n->_idx, es);
 873       // in order for an object to be stackallocatable, it must be:
 874       //   - a direct allocation (not a call returning an object)
 875       //   - non-escaping
 876       //   - eligible to be a unique type
 877       //   - not determined to be ineligible by escape analysis
 878       set_map(alloc->_idx, n);
 879       set_map(n->_idx, alloc);
 880       const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
 881       if (t == NULL)
 882         continue;  // not a TypeInstPtr
 883       tinst = t->cast_to_instance(ni);
 884       igvn->hash_delete(n);
 885       igvn->set_type(n,  tinst);
 886       n->raise_bottom_type(tinst);
 887       igvn->hash_insert(n);
 888       record_for_optimizer(n);
 889       if (alloc->is_Allocate() && ptn->_scalar_replaceable &&
 890           (t->isa_instptr() || t->isa_aryptr())) {

















 891         // An allocation may have an Initialize which has raw stores. Scan
 892         // the users of the raw allocation result and push AddP users
 893         // on alloc_worklist.
 894         Node *raw_result = alloc->proj_out(TypeFunc::Parms);
 895         assert (raw_result != NULL, "must have an allocation result");
 896         for (DUIterator_Fast imax, i = raw_result->fast_outs(imax); i < imax; i++) {
 897           Node *use = raw_result->fast_out(i);
 898           if (use->is_AddP() && use->outcnt() > 0) { // Don't process dead nodes
 899             Node* addp2 = find_second_addp(use, raw_result);
 900             if (addp2 != NULL) {
 901               assert(alloc->is_AllocateArray(),"array allocation was expected");
 902               alloc_worklist.append_if_missing(addp2);
 903             }
 904             alloc_worklist.append_if_missing(use);
 905           } else if (use->is_Initialize()) {
 906             memnode_worklist.append_if_missing(use);
 907           }
 908         }
 909       }
 910     } else if (n->is_AddP()) {
 911       ptset.Clear();
 912       PointsTo(ptset, get_addp_base(n), igvn);
 913       assert(ptset.Size() == 1, "AddP address is unique");
 914       uint elem = ptset.getelem(); // Allocation node's index
 915       if (elem == _phantom_object)
 916         continue; // Assume the value was set outside this method.
 917       Node *base = get_map(elem);  // CheckCastPP node
 918       split_AddP(n, base, igvn);
 919       tinst = igvn->type(base)->isa_oopptr();
 920     } else if (n->is_Phi() ||
 921                n->is_CheckCastPP() ||


 922                (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) {
 923       if (visited.test_set(n->_idx)) {
 924         assert(n->is_Phi(), "loops only through Phi's");
 925         continue;  // already processed
 926       }
 927       ptset.Clear();
 928       PointsTo(ptset, n, igvn);
 929       if (ptset.Size() == 1) {
 930         uint elem = ptset.getelem(); // Allocation node's index
 931         if (elem == _phantom_object)
 932           continue; // Assume the value was set outside this method.
 933         Node *val = get_map(elem);   // CheckCastPP node
 934         TypeNode *tn = n->as_Type();
 935         tinst = igvn->type(val)->isa_oopptr();
 936         assert(tinst != NULL && tinst->is_instance() &&
 937                tinst->instance_id() == elem , "instance type expected.");
 938         const TypeOopPtr *tn_t = igvn->type(tn)->isa_oopptr();
 939 








 940         if (tn_t != NULL &&
 941  tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) {





 942           igvn->hash_delete(tn);
 943           igvn->set_type(tn, tinst);
 944           tn->set_type(tinst);
 945           igvn->hash_insert(tn);
 946           record_for_optimizer(n);
 947         }
 948       }
 949     } else {
 950       continue;
 951     }
 952     // push users on appropriate worklist
 953     for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
 954       Node *use = n->fast_out(i);
 955       if(use->is_Mem() && use->in(MemNode::Address) == n) {
 956         memnode_worklist.append_if_missing(use);
 957       } else if (use->is_Initialize()) {
 958         memnode_worklist.append_if_missing(use);
 959       } else if (use->is_MergeMem()) {
 960         mergemem_worklist.append_if_missing(use);
 961       } else if (use->is_Call() && tinst != NULL) {
 962         // Look for MergeMem nodes for calls which reference unique allocation
 963         // (through CheckCastPP nodes) even for debug info.
 964         Node* m = use->in(TypeFunc::Memory);
 965         uint iid = tinst->instance_id();
 966         while (m->is_Proj() && m->in(0)->is_Call() &&
 967                m->in(0) != use && !m->in(0)->_idx != iid) {
 968           m = m->in(0)->in(TypeFunc::Memory);
 969         }
 970         if (m->is_MergeMem()) {
 971           mergemem_worklist.append_if_missing(m);
 972         }
 973       } else if (use->is_AddP() && use->outcnt() > 0) { // No dead nodes
 974         Node* addp2 = find_second_addp(use, n);
 975         if (addp2 != NULL) {
 976           alloc_worklist.append_if_missing(addp2);
 977         }
 978         alloc_worklist.append_if_missing(use);
 979       } else if (use->is_Phi() ||
 980                  use->is_CheckCastPP() ||


 981                  (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) {
 982         alloc_worklist.append_if_missing(use);
 983       }
 984     }
 985 
 986   }
 987   // New alias types were created in split_AddP().
 988   uint new_index_end = (uint) _compile->num_alias_types();
 989 
 990   //  Phase 2:  Process MemNode's from memnode_worklist. compute new address type and
 991   //            compute new values for Memory inputs  (the Memory inputs are not
 992   //            actually updated until phase 4.)
 993   if (memnode_worklist.length() == 0)
 994     return;  // nothing to do
 995 
 996   while (memnode_worklist.length() != 0) {
 997     Node *n = memnode_worklist.pop();
 998     if (visited.test_set(n->_idx))
 999       continue;
1000     if (n->is_Phi()) {


1182   }
1183 
1184   // Update the memory inputs of MemNodes with the value we computed
1185   // in Phase 2.
1186   for (int i = 0; i < _nodes->length(); i++) {
1187     Node *nmem = get_map(i);
1188     if (nmem != NULL) {
1189       Node *n = _nodes->adr_at(i)->_node;
1190       if (n != NULL && n->is_Mem()) {
1191         igvn->hash_delete(n);
1192         n->set_req(MemNode::Memory, nmem);
1193         igvn->hash_insert(n);
1194         record_for_optimizer(n);
1195       }
1196     }
1197   }
1198 }
1199 
1200 void ConnectionGraph::compute_escape() {
1201 
1202   // 1. Populate Connection Graph with Ideal nodes.
1203 
1204   Unique_Node_List worklist_init;
1205   worklist_init.map(_compile->unique(), NULL);  // preallocate space
1206 
1207   // Initialize worklist
1208   if (_compile->root() != NULL) {
1209     worklist_init.push(_compile->root());
1210   }
1211 
1212   GrowableArray<int> cg_worklist;
1213   PhaseGVN* igvn = _compile->initial_gvn();
1214   bool has_allocations = false;
1215 
1216   // Push all useful nodes onto CG list and set their type.
1217   for( uint next = 0; next < worklist_init.size(); ++next ) {
1218     Node* n = worklist_init.at(next);
1219     record_for_escape_analysis(n, igvn);
1220     if (n->is_Call() &&
1221         _nodes->adr_at(n->_idx)->node_type() == PointsToNode::JavaObject) {
1222       has_allocations = true;


1264     }
1265   }
1266 
1267   VectorSet ptset(Thread::current()->resource_area());
1268   GrowableArray<Node*> alloc_worklist;
1269   GrowableArray<int>   worklist;
1270   GrowableArray<uint>  deferred_edges;
1271   VectorSet visited(Thread::current()->resource_area());
1272 
1273   // remove deferred edges from the graph and collect
1274   // information we will need for type splitting
1275   for( int next = 0; next < cg_worklist.length(); ++next ) {
1276     int ni = cg_worklist.at(next);
1277     PointsToNode* ptn = _nodes->adr_at(ni);
1278     PointsToNode::NodeType nt = ptn->node_type();
1279     Node *n = ptn->_node;
1280     if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
1281       remove_deferred(ni, &deferred_edges, &visited);
1282       if (n->is_AddP()) {
1283         // If this AddP computes an address which may point to more that one
1284         // object, nothing the address points to can be scalar replaceable.

1285         Node *base = get_addp_base(n);
1286         ptset.Clear();
1287         PointsTo(ptset, base, igvn);
1288         if (ptset.Size() > 1) {

1289           for( VectorSetI j(&ptset); j.test(); ++j ) {
1290             uint pt = j.elem;
1291             ptnode_adr(pt)->_scalar_replaceable = false;
1292           }
1293         }
1294       }
1295     } else if (nt == PointsToNode::JavaObject && n->is_Call()) {
1296       // Push call on alloc_worlist (alocations are calls)
1297       // for processing by split_unique_types().
1298       alloc_worklist.append(n);
1299     }
1300   }
1301 
1302   // push all GlobalEscape nodes on the worklist
1303   for( int next = 0; next < cg_worklist.length(); ++next ) {
1304     int nk = cg_worklist.at(next);
1305     if (_nodes->adr_at(nk)->escape_state() == PointsToNode::GlobalEscape)
1306       worklist.append(nk);
1307   }
1308   // mark all node reachable from GlobalEscape nodes


1962     }
1963     case Op_CastPP:
1964     case Op_CheckCastPP:
1965     case Op_EncodeP:
1966     case Op_DecodeN:
1967     {
1968       int ti = n->in(1)->_idx;
1969       if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) {
1970         add_pointsto_edge(n->_idx, ti);
1971       } else {
1972         add_deferred_edge(n->_idx, ti);
1973       }
1974       _processed.set(n->_idx);
1975       break;
1976     }
1977     case Op_ConP:
1978     {
1979       assert(false, "Op_ConP");
1980       break;
1981     }





1982     case Op_CreateEx:
1983     {
1984       assert(false, "Op_CreateEx");
1985       break;
1986     }
1987     case Op_LoadKlass:
1988     {
1989       assert(false, "Op_LoadKlass");
1990       break;
1991     }
1992     case Op_LoadP:
1993     case Op_LoadN:
1994     {
1995       const Type *t = phase->type(n);
1996 #ifdef ASSERT
1997       if (!t->isa_narrowoop() && t->isa_ptr() == NULL)
1998         assert(false, "Op_LoadP");
1999 #endif
2000 
2001       Node* adr = n->in(MemNode::Address)->uncast();




 871       }
 872       set_escape_state(n->_idx, es);
 873       // in order for an object to be stackallocatable, it must be:
 874       //   - a direct allocation (not a call returning an object)
 875       //   - non-escaping
 876       //   - eligible to be a unique type
 877       //   - not determined to be ineligible by escape analysis
 878       set_map(alloc->_idx, n);
 879       set_map(n->_idx, alloc);
 880       const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
 881       if (t == NULL)
 882         continue;  // not a TypeInstPtr
 883       tinst = t->cast_to_instance(ni);
 884       igvn->hash_delete(n);
 885       igvn->set_type(n,  tinst);
 886       n->raise_bottom_type(tinst);
 887       igvn->hash_insert(n);
 888       record_for_optimizer(n);
 889       if (alloc->is_Allocate() && ptn->_scalar_replaceable &&
 890           (t->isa_instptr() || t->isa_aryptr())) {
 891 
 892         // First, put on the worklist all Field edges from Connection Graph
 893         // which is more accurate then putting immediate users from Ideal Graph.
 894         for (uint e = 0; e < ptn->edge_count(); e++) {
 895           Node *use = _nodes->adr_at(ptn->edge_target(e))->_node;
 896           assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(),
 897                  "only AddP nodes are Field edges in CG");
 898           if (use->outcnt() > 0) { // Don't process dead nodes
 899             Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
 900             if (addp2 != NULL) {
 901               assert(alloc->is_AllocateArray(),"array allocation was expected");
 902               alloc_worklist.append_if_missing(addp2);
 903             }
 904             alloc_worklist.append_if_missing(use);
 905           }
 906         }
 907 
 908         // An allocation may have an Initialize which has raw stores. Scan
 909         // the users of the raw allocation result and push AddP users
 910         // on alloc_worklist.
 911         Node *raw_result = alloc->proj_out(TypeFunc::Parms);
 912         assert (raw_result != NULL, "must have an allocation result");
 913         for (DUIterator_Fast imax, i = raw_result->fast_outs(imax); i < imax; i++) {
 914           Node *use = raw_result->fast_out(i);
 915           if (use->is_AddP() && use->outcnt() > 0) { // Don't process dead nodes
 916             Node* addp2 = find_second_addp(use, raw_result);
 917             if (addp2 != NULL) {
 918               assert(alloc->is_AllocateArray(),"array allocation was expected");
 919               alloc_worklist.append_if_missing(addp2);
 920             }
 921             alloc_worklist.append_if_missing(use);
 922           } else if (use->is_Initialize()) {
 923             memnode_worklist.append_if_missing(use);
 924           }
 925         }
 926       }
 927     } else if (n->is_AddP()) {
 928       ptset.Clear();
 929       PointsTo(ptset, get_addp_base(n), igvn);
 930       assert(ptset.Size() == 1, "AddP address is unique");
 931       uint elem = ptset.getelem(); // Allocation node's index
 932       if (elem == _phantom_object)
 933         continue; // Assume the value was set outside this method.
 934       Node *base = get_map(elem);  // CheckCastPP node
 935       split_AddP(n, base, igvn);
 936       tinst = igvn->type(base)->isa_oopptr();
 937     } else if (n->is_Phi() ||
 938                n->is_CheckCastPP() ||
 939                n->Opcode() == Op_EncodeP ||
 940                n->Opcode() == Op_DecodeN ||
 941                (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) {
 942       if (visited.test_set(n->_idx)) {
 943         assert(n->is_Phi(), "loops only through Phi's");
 944         continue;  // already processed
 945       }
 946       ptset.Clear();
 947       PointsTo(ptset, n, igvn);
 948       if (ptset.Size() == 1) {
 949         uint elem = ptset.getelem(); // Allocation node's index
 950         if (elem == _phantom_object)
 951           continue; // Assume the value was set outside this method.
 952         Node *val = get_map(elem);   // CheckCastPP node
 953         TypeNode *tn = n->as_Type();
 954         tinst = igvn->type(val)->isa_oopptr();
 955         assert(tinst != NULL && tinst->is_instance() &&
 956                tinst->instance_id() == elem , "instance type expected.");

 957 
 958         const TypeOopPtr *tn_t = NULL;
 959         const Type *tn_type = igvn->type(tn);
 960         if (tn_type->isa_narrowoop()) {
 961           tn_t = tn_type->is_narrowoop()->make_oopptr()->isa_oopptr();
 962         } else {
 963           tn_t = tn_type->isa_oopptr();
 964         }
 965 
 966         if (tn_t != NULL &&
 967  tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) {
 968           if (tn_type->isa_narrowoop()) {
 969             tn_type = tinst->make_narrowoop();
 970           } else {
 971             tn_type = tinst;
 972           }
 973           igvn->hash_delete(tn);
 974           igvn->set_type(tn, tn_type);
 975           tn->set_type(tn_type);
 976           igvn->hash_insert(tn);
 977           record_for_optimizer(n);
 978         }
 979       }
 980     } else {
 981       continue;
 982     }
 983     // push users on appropriate worklist
 984     for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
 985       Node *use = n->fast_out(i);
 986       if(use->is_Mem() && use->in(MemNode::Address) == n) {
 987         memnode_worklist.append_if_missing(use);
 988       } else if (use->is_Initialize()) {
 989         memnode_worklist.append_if_missing(use);
 990       } else if (use->is_MergeMem()) {
 991         mergemem_worklist.append_if_missing(use);
 992       } else if (use->is_Call() && tinst != NULL) {
 993         // Look for MergeMem nodes for calls which reference unique allocation
 994         // (through CheckCastPP nodes) even for debug info.
 995         Node* m = use->in(TypeFunc::Memory);
 996         uint iid = tinst->instance_id();
 997         while (m->is_Proj() && m->in(0)->is_Call() &&
 998                m->in(0) != use && !m->in(0)->_idx != iid) {
 999           m = m->in(0)->in(TypeFunc::Memory);
1000         }
1001         if (m->is_MergeMem()) {
1002           mergemem_worklist.append_if_missing(m);
1003         }
1004       } else if (use->is_AddP() && use->outcnt() > 0) { // No dead nodes
1005         Node* addp2 = find_second_addp(use, n);
1006         if (addp2 != NULL) {
1007           alloc_worklist.append_if_missing(addp2);
1008         }
1009         alloc_worklist.append_if_missing(use);
1010       } else if (use->is_Phi() ||
1011                  use->is_CheckCastPP() ||
1012                  use->Opcode() == Op_EncodeP ||
1013                  use->Opcode() == Op_DecodeN ||
1014                  (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) {
1015         alloc_worklist.append_if_missing(use);
1016       }
1017     }
1018 
1019   }
1020   // New alias types were created in split_AddP().
1021   uint new_index_end = (uint) _compile->num_alias_types();
1022 
1023   //  Phase 2:  Process MemNode's from memnode_worklist. compute new address type and
1024   //            compute new values for Memory inputs  (the Memory inputs are not
1025   //            actually updated until phase 4.)
1026   if (memnode_worklist.length() == 0)
1027     return;  // nothing to do
1028 
1029   while (memnode_worklist.length() != 0) {
1030     Node *n = memnode_worklist.pop();
1031     if (visited.test_set(n->_idx))
1032       continue;
1033     if (n->is_Phi()) {


1215   }
1216 
1217   // Update the memory inputs of MemNodes with the value we computed
1218   // in Phase 2.
1219   for (int i = 0; i < _nodes->length(); i++) {
1220     Node *nmem = get_map(i);
1221     if (nmem != NULL) {
1222       Node *n = _nodes->adr_at(i)->_node;
1223       if (n != NULL && n->is_Mem()) {
1224         igvn->hash_delete(n);
1225         n->set_req(MemNode::Memory, nmem);
1226         igvn->hash_insert(n);
1227         record_for_optimizer(n);
1228       }
1229     }
1230   }
1231 }
1232 
1233 void ConnectionGraph::compute_escape() {
1234 
1235   // 1. Populate Connection Graph (CG) with Ideal nodes.
1236 
1237   Unique_Node_List worklist_init;
1238   worklist_init.map(_compile->unique(), NULL);  // preallocate space
1239 
1240   // Initialize worklist
1241   if (_compile->root() != NULL) {
1242     worklist_init.push(_compile->root());
1243   }
1244 
1245   GrowableArray<int> cg_worklist;
1246   PhaseGVN* igvn = _compile->initial_gvn();
1247   bool has_allocations = false;
1248 
1249   // Push all useful nodes onto CG list and set their type.
1250   for( uint next = 0; next < worklist_init.size(); ++next ) {
1251     Node* n = worklist_init.at(next);
1252     record_for_escape_analysis(n, igvn);
1253     if (n->is_Call() &&
1254         _nodes->adr_at(n->_idx)->node_type() == PointsToNode::JavaObject) {
1255       has_allocations = true;


1297     }
1298   }
1299 
1300   VectorSet ptset(Thread::current()->resource_area());
1301   GrowableArray<Node*> alloc_worklist;
1302   GrowableArray<int>   worklist;
1303   GrowableArray<uint>  deferred_edges;
1304   VectorSet visited(Thread::current()->resource_area());
1305 
1306   // remove deferred edges from the graph and collect
1307   // information we will need for type splitting
1308   for( int next = 0; next < cg_worklist.length(); ++next ) {
1309     int ni = cg_worklist.at(next);
1310     PointsToNode* ptn = _nodes->adr_at(ni);
1311     PointsToNode::NodeType nt = ptn->node_type();
1312     Node *n = ptn->_node;
1313     if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
1314       remove_deferred(ni, &deferred_edges, &visited);
1315       if (n->is_AddP()) {
1316         // If this AddP computes an address which may point to more that one
1317         // object or more then one field (array's element), nothing the address
1318         // points to can be scalar replaceable.
1319         Node *base = get_addp_base(n);
1320         ptset.Clear();
1321         PointsTo(ptset, base, igvn);
1322         if (ptset.Size() > 1 ||
1323             (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) {
1324           for( VectorSetI j(&ptset); j.test(); ++j ) {
1325             uint pt = j.elem;
1326             ptnode_adr(pt)->_scalar_replaceable = false;
1327           }
1328         }
1329       }
1330     } else if (nt == PointsToNode::JavaObject && n->is_Call()) {
1331       // Push call on alloc_worlist (alocations are calls)
1332       // for processing by split_unique_types().
1333       alloc_worklist.append(n);
1334     }
1335   }
1336 
1337   // push all GlobalEscape nodes on the worklist
1338   for( int next = 0; next < cg_worklist.length(); ++next ) {
1339     int nk = cg_worklist.at(next);
1340     if (_nodes->adr_at(nk)->escape_state() == PointsToNode::GlobalEscape)
1341       worklist.append(nk);
1342   }
1343   // mark all node reachable from GlobalEscape nodes


1997     }
1998     case Op_CastPP:
1999     case Op_CheckCastPP:
2000     case Op_EncodeP:
2001     case Op_DecodeN:
2002     {
2003       int ti = n->in(1)->_idx;
2004       if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) {
2005         add_pointsto_edge(n->_idx, ti);
2006       } else {
2007         add_deferred_edge(n->_idx, ti);
2008       }
2009       _processed.set(n->_idx);
2010       break;
2011     }
2012     case Op_ConP:
2013     {
2014       assert(false, "Op_ConP");
2015       break;
2016     }
2017     case Op_ConN:
2018     {
2019       assert(false, "Op_ConN");
2020       break;
2021     }
2022     case Op_CreateEx:
2023     {
2024       assert(false, "Op_CreateEx");
2025       break;
2026     }
2027     case Op_LoadKlass:
2028     {
2029       assert(false, "Op_LoadKlass");
2030       break;
2031     }
2032     case Op_LoadP:
2033     case Op_LoadN:
2034     {
2035       const Type *t = phase->type(n);
2036 #ifdef ASSERT
2037       if (!t->isa_narrowoop() && t->isa_ptr() == NULL)
2038         assert(false, "Op_LoadP");
2039 #endif
2040 
2041       Node* adr = n->in(MemNode::Address)->uncast();


src/share/vm/opto/escape.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File