< prev index next >

src/hotspot/share/opto/macro.cpp

Print this page
rev 48500 : 8194988: 8 Null pointer dereference defect groups related to MultiNode::proj_out()


 479   int offset = adr_t->offset();
 480   int instance_id = adr_t->instance_id();
 481 
 482   // Check if an appropriate value phi already exists.
 483   Node* region = mem->in(0);
 484   for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
 485     Node* phi = region->fast_out(k);
 486     if (phi->is_Phi() && phi != mem &&
 487         phi->as_Phi()->is_same_inst_field(phi_type, (int)mem->_idx, instance_id, alias_idx, offset)) {
 488       return phi;
 489     }
 490   }
 491   // Check if an appropriate new value phi already exists.
 492   Node* new_phi = value_phis->find(mem->_idx);
 493   if (new_phi != NULL)
 494     return new_phi;
 495 
 496   if (level <= 0) {
 497     return NULL; // Give up: phi tree too deep
 498   }
 499   Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
 500   Node *alloc_mem = alloc->in(TypeFunc::Memory);
 501 
 502   uint length = mem->req();
 503   GrowableArray <Node *> values(length, length, NULL, false);
 504 
 505   // create a new Phi for the value
 506   PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, mem->_idx, instance_id, alias_idx, offset);
 507   transform_later(phi);
 508   value_phis->push(phi, mem->_idx);
 509 
 510   for (uint j = 1; j < length; j++) {
 511     Node *in = mem->in(j);
 512     if (in == NULL || in->is_top()) {
 513       values.at_put(j, in);
 514     } else  {
 515       Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn);
 516       if (val == start_mem || val == alloc_mem) {
 517         // hit a sentinel, return appropriate 0 value
 518         values.at_put(j, _igvn.zerocon(ft));
 519         continue;


 559   }
 560   // Set Phi's inputs
 561   for (uint j = 1; j < length; j++) {
 562     if (values.at(j) == mem) {
 563       phi->init_req(j, phi);
 564     } else {
 565       phi->init_req(j, values.at(j));
 566     }
 567   }
 568   return phi;
 569 }
 570 
 571 // Search the last value stored into the object's field.
 572 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, Node *sfpt_ctl, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc) {
 573   assert(adr_t->is_known_instance_field(), "instance required");
 574   int instance_id = adr_t->instance_id();
 575   assert((uint)instance_id == alloc->_idx, "wrong allocation");
 576 
 577   int alias_idx = C->get_alias_index(adr_t);
 578   int offset = adr_t->offset();
 579   Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
 580   Node *alloc_ctrl = alloc->in(TypeFunc::Control);
 581   Node *alloc_mem = alloc->in(TypeFunc::Memory);
 582   Arena *a = Thread::current()->resource_area();
 583   VectorSet visited(a);
 584 
 585 
 586   bool done = sfpt_mem == alloc_mem;
 587   Node *mem = sfpt_mem;
 588   while (!done) {
 589     if (visited.test_set(mem->_idx)) {
 590       return NULL;  // found a loop, give up
 591     }
 592     mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn);
 593     if (mem == start_mem || mem == alloc_mem) {
 594       done = true;  // hit a sentinel, return appropriate 0 value
 595     } else if (mem->is_Initialize()) {
 596       mem = mem->as_Initialize()->find_captured_store(offset, type2aelembytes(ft), &_igvn);
 597       if (mem == NULL) {
 598         done = true; // Something go wrong.
 599       } else if (mem->is_Store()) {


 957         } else {
 958           field_val = transform_later(new DecodeNNode(field_val, field_val->get_ptr_type()));
 959         }
 960       }
 961       sfpt->add_req(field_val);
 962     }
 963     JVMState *jvms = sfpt->jvms();
 964     jvms->set_endoff(sfpt->req());
 965     // Now make a pass over the debug information replacing any references
 966     // to the allocated object with "sobj"
 967     int start = jvms->debug_start();
 968     int end   = jvms->debug_end();
 969     sfpt->replace_edges_in_range(res, sobj, start, end);
 970     _igvn._worklist.push(sfpt);
 971     safepoints_done.append_if_missing(sfpt); // keep it for rollback
 972   }
 973   return true;
 974 }
 975 
 976 static void disconnect_projections(MultiNode* n, PhaseIterGVN& igvn) {
 977   Node* ctl_proj = n->proj_out(TypeFunc::Control);
 978   Node* mem_proj = n->proj_out(TypeFunc::Memory);
 979   if (ctl_proj != NULL) {
 980     igvn.replace_node(ctl_proj, n->in(0));
 981   }
 982   if (mem_proj != NULL) {
 983     igvn.replace_node(mem_proj, n->in(TypeFunc::Memory));
 984   }
 985 }
 986 
 987 // Process users of eliminated allocation.
 988 void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
 989   Node* res = alloc->result_cast();
 990   if (res != NULL) {
 991     for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
 992       Node *use = res->last_out(j);
 993       uint oc1 = res->outcnt();
 994 
 995       if (use->is_AddP()) {
 996         for (DUIterator_Last kmin, k = use->last_outs(kmin); k >= kmin; ) {
 997           Node *n = use->last_out(k);
 998           uint oc2 = use->outcnt();


1069   //
1070   if (_resproj != NULL && _resproj->outcnt() != 0) {
1071     // First disconnect stores captured by Initialize node.
1072     // If Initialize node is eliminated first in the following code,
1073     // it will kill such stores and DUIterator_Last will assert.
1074     for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax);  j < jmax; j++) {
1075       Node *use = _resproj->fast_out(j);
1076       if (use->is_AddP()) {
1077         // raw memory addresses used only by the initialization
1078         _igvn.replace_node(use, C->top());
1079         --j; --jmax;
1080       }
1081     }
1082     for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) {
1083       Node *use = _resproj->last_out(j);
1084       uint oc1 = _resproj->outcnt();
1085       if (use->is_Initialize()) {
1086         // Eliminate Initialize node.
1087         InitializeNode *init = use->as_Initialize();
1088         assert(init->outcnt() <= 2, "only a control and memory projection expected");
1089         Node *ctrl_proj = init->proj_out(TypeFunc::Control);
1090         if (ctrl_proj != NULL) {
1091            assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection");
1092           _igvn.replace_node(ctrl_proj, _fallthroughcatchproj);
1093         }
1094         Node *mem_proj = init->proj_out(TypeFunc::Memory);
1095         if (mem_proj != NULL) {
1096           Node *mem = init->in(TypeFunc::Memory);
1097 #ifdef ASSERT
1098           if (mem->is_MergeMem()) {
1099             assert(mem->in(TypeFunc::Memory) == _memproj_fallthrough, "allocation memory projection");
1100           } else {
1101             assert(mem == _memproj_fallthrough, "allocation memory projection");
1102           }
1103 #endif
1104           _igvn.replace_node(mem_proj, mem);
1105         }
1106       } else  {
1107         assert(false, "only Initialize or AddP expected");
1108       }
1109       j -= (oc1 - _resproj->outcnt());
1110     }
1111   }
1112   if (_fallthroughcatchproj != NULL) {
1113     _igvn.replace_node(_fallthroughcatchproj, alloc->in(TypeFunc::Control));
1114   }


1181     }
1182     log->tail("eliminate_allocation");
1183   }
1184 
1185   process_users_of_allocation(alloc);
1186 
1187 #ifndef PRODUCT
1188   if (PrintEliminateAllocations) {
1189     if (alloc->is_AllocateArray())
1190       tty->print_cr("++++ Eliminated: %d AllocateArray", alloc->_idx);
1191     else
1192       tty->print_cr("++++ Eliminated: %d Allocate", alloc->_idx);
1193   }
1194 #endif
1195 
1196   return true;
1197 }
1198 
1199 bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
1200   // EA should remove all uses of non-escaping boxing node.
1201   if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) {
1202     return false;
1203   }
1204 
1205   assert(boxing->result_cast() == NULL, "unexpected boxing node result");
1206 
1207   extract_call_projections(boxing);
1208 
1209   const TypeTuple* r = boxing->tf()->range();
1210   assert(r->cnt() > TypeFunc::Parms, "sanity");
1211   const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr();
1212   assert(t != NULL, "sanity");
1213 
1214   CompileLog* log = C->log();
1215   if (log != NULL) {
1216     log->head("eliminate_boxing type='%d'",
1217               log->identify(t->klass()));
1218     JVMState* p = boxing->jvms();
1219     while (p != NULL) {
1220       log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
1221       p = p->caller();


1563         (init == NULL || !init->is_complete_with_arraycopy())) {
1564       if (init == NULL || init->req() < InitializeNode::RawStores) {
1565         // No InitializeNode or no stores captured by zeroing
1566         // elimination. Simply add the MemBarStoreStore after object
1567         // initialization.
1568         MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1569         transform_later(mb);
1570 
1571         mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
1572         mb->init_req(TypeFunc::Control, fast_oop_ctrl);
1573         fast_oop_ctrl = new ProjNode(mb,TypeFunc::Control);
1574         transform_later(fast_oop_ctrl);
1575         fast_oop_rawmem = new ProjNode(mb,TypeFunc::Memory);
1576         transform_later(fast_oop_rawmem);
1577       } else {
1578         // Add the MemBarStoreStore after the InitializeNode so that
1579         // all stores performing the initialization that were moved
1580         // before the InitializeNode happen before the storestore
1581         // barrier.
1582 
1583         Node* init_ctrl = init->proj_out(TypeFunc::Control);
1584         Node* init_mem = init->proj_out(TypeFunc::Memory);
1585 
1586         MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1587         transform_later(mb);
1588 
1589         Node* ctrl = new ProjNode(init,TypeFunc::Control);
1590         transform_later(ctrl);
1591         Node* mem = new ProjNode(init,TypeFunc::Memory);
1592         transform_later(mem);
1593 
1594         // The MemBarStoreStore depends on control and memory coming
1595         // from the InitializeNode
1596         mb->init_req(TypeFunc::Memory, mem);
1597         mb->init_req(TypeFunc::Control, ctrl);
1598 
1599         ctrl = new ProjNode(mb,TypeFunc::Control);
1600         transform_later(ctrl);
1601         mem = new ProjNode(mb,TypeFunc::Memory);
1602         transform_later(mem);
1603 
1604         // All nodes that depended on the InitializeNode for control




 479   int offset = adr_t->offset();
 480   int instance_id = adr_t->instance_id();
 481 
 482   // Check if an appropriate value phi already exists.
 483   Node* region = mem->in(0);
 484   for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
 485     Node* phi = region->fast_out(k);
 486     if (phi->is_Phi() && phi != mem &&
 487         phi->as_Phi()->is_same_inst_field(phi_type, (int)mem->_idx, instance_id, alias_idx, offset)) {
 488       return phi;
 489     }
 490   }
 491   // Check if an appropriate new value phi already exists.
 492   Node* new_phi = value_phis->find(mem->_idx);
 493   if (new_phi != NULL)
 494     return new_phi;
 495 
 496   if (level <= 0) {
 497     return NULL; // Give up: phi tree too deep
 498   }
 499   Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
 500   Node *alloc_mem = alloc->in(TypeFunc::Memory);
 501 
 502   uint length = mem->req();
 503   GrowableArray <Node *> values(length, length, NULL, false);
 504 
 505   // create a new Phi for the value
 506   PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, mem->_idx, instance_id, alias_idx, offset);
 507   transform_later(phi);
 508   value_phis->push(phi, mem->_idx);
 509 
 510   for (uint j = 1; j < length; j++) {
 511     Node *in = mem->in(j);
 512     if (in == NULL || in->is_top()) {
 513       values.at_put(j, in);
 514     } else  {
 515       Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn);
 516       if (val == start_mem || val == alloc_mem) {
 517         // hit a sentinel, return appropriate 0 value
 518         values.at_put(j, _igvn.zerocon(ft));
 519         continue;


 559   }
 560   // Set Phi's inputs
 561   for (uint j = 1; j < length; j++) {
 562     if (values.at(j) == mem) {
 563       phi->init_req(j, phi);
 564     } else {
 565       phi->init_req(j, values.at(j));
 566     }
 567   }
 568   return phi;
 569 }
 570 
 571 // Search the last value stored into the object's field.
 572 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, Node *sfpt_ctl, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc) {
 573   assert(adr_t->is_known_instance_field(), "instance required");
 574   int instance_id = adr_t->instance_id();
 575   assert((uint)instance_id == alloc->_idx, "wrong allocation");
 576 
 577   int alias_idx = C->get_alias_index(adr_t);
 578   int offset = adr_t->offset();
 579   Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
 580   Node *alloc_ctrl = alloc->in(TypeFunc::Control);
 581   Node *alloc_mem = alloc->in(TypeFunc::Memory);
 582   Arena *a = Thread::current()->resource_area();
 583   VectorSet visited(a);
 584 
 585 
 586   bool done = sfpt_mem == alloc_mem;
 587   Node *mem = sfpt_mem;
 588   while (!done) {
 589     if (visited.test_set(mem->_idx)) {
 590       return NULL;  // found a loop, give up
 591     }
 592     mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn);
 593     if (mem == start_mem || mem == alloc_mem) {
 594       done = true;  // hit a sentinel, return appropriate 0 value
 595     } else if (mem->is_Initialize()) {
 596       mem = mem->as_Initialize()->find_captured_store(offset, type2aelembytes(ft), &_igvn);
 597       if (mem == NULL) {
 598         done = true; // Something go wrong.
 599       } else if (mem->is_Store()) {


 957         } else {
 958           field_val = transform_later(new DecodeNNode(field_val, field_val->get_ptr_type()));
 959         }
 960       }
 961       sfpt->add_req(field_val);
 962     }
 963     JVMState *jvms = sfpt->jvms();
 964     jvms->set_endoff(sfpt->req());
 965     // Now make a pass over the debug information replacing any references
 966     // to the allocated object with "sobj"
 967     int start = jvms->debug_start();
 968     int end   = jvms->debug_end();
 969     sfpt->replace_edges_in_range(res, sobj, start, end);
 970     _igvn._worklist.push(sfpt);
 971     safepoints_done.append_if_missing(sfpt); // keep it for rollback
 972   }
 973   return true;
 974 }
 975 
 976 static void disconnect_projections(MultiNode* n, PhaseIterGVN& igvn) {
 977   Node* ctl_proj = n->proj_out_or_null(TypeFunc::Control);
 978   Node* mem_proj = n->proj_out_or_null(TypeFunc::Memory);
 979   if (ctl_proj != NULL) {
 980     igvn.replace_node(ctl_proj, n->in(0));
 981   }
 982   if (mem_proj != NULL) {
 983     igvn.replace_node(mem_proj, n->in(TypeFunc::Memory));
 984   }
 985 }
 986 
 987 // Process users of eliminated allocation.
 988 void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
 989   Node* res = alloc->result_cast();
 990   if (res != NULL) {
 991     for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
 992       Node *use = res->last_out(j);
 993       uint oc1 = res->outcnt();
 994 
 995       if (use->is_AddP()) {
 996         for (DUIterator_Last kmin, k = use->last_outs(kmin); k >= kmin; ) {
 997           Node *n = use->last_out(k);
 998           uint oc2 = use->outcnt();


1069   //
1070   if (_resproj != NULL && _resproj->outcnt() != 0) {
1071     // First disconnect stores captured by Initialize node.
1072     // If Initialize node is eliminated first in the following code,
1073     // it will kill such stores and DUIterator_Last will assert.
1074     for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax);  j < jmax; j++) {
1075       Node *use = _resproj->fast_out(j);
1076       if (use->is_AddP()) {
1077         // raw memory addresses used only by the initialization
1078         _igvn.replace_node(use, C->top());
1079         --j; --jmax;
1080       }
1081     }
1082     for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) {
1083       Node *use = _resproj->last_out(j);
1084       uint oc1 = _resproj->outcnt();
1085       if (use->is_Initialize()) {
1086         // Eliminate Initialize node.
1087         InitializeNode *init = use->as_Initialize();
1088         assert(init->outcnt() <= 2, "only a control and memory projection expected");
1089         Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
1090         if (ctrl_proj != NULL) {
1091            assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection");
1092           _igvn.replace_node(ctrl_proj, _fallthroughcatchproj);
1093         }
1094         Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
1095         if (mem_proj != NULL) {
1096           Node *mem = init->in(TypeFunc::Memory);
1097 #ifdef ASSERT
1098           if (mem->is_MergeMem()) {
1099             assert(mem->in(TypeFunc::Memory) == _memproj_fallthrough, "allocation memory projection");
1100           } else {
1101             assert(mem == _memproj_fallthrough, "allocation memory projection");
1102           }
1103 #endif
1104           _igvn.replace_node(mem_proj, mem);
1105         }
1106       } else  {
1107         assert(false, "only Initialize or AddP expected");
1108       }
1109       j -= (oc1 - _resproj->outcnt());
1110     }
1111   }
1112   if (_fallthroughcatchproj != NULL) {
1113     _igvn.replace_node(_fallthroughcatchproj, alloc->in(TypeFunc::Control));
1114   }


1181     }
1182     log->tail("eliminate_allocation");
1183   }
1184 
1185   process_users_of_allocation(alloc);
1186 
1187 #ifndef PRODUCT
1188   if (PrintEliminateAllocations) {
1189     if (alloc->is_AllocateArray())
1190       tty->print_cr("++++ Eliminated: %d AllocateArray", alloc->_idx);
1191     else
1192       tty->print_cr("++++ Eliminated: %d Allocate", alloc->_idx);
1193   }
1194 #endif
1195 
1196   return true;
1197 }
1198 
1199 bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
1200   // EA should remove all uses of non-escaping boxing node.
1201   if (!C->eliminate_boxing() || boxing->proj_out_or_null(TypeFunc::Parms) != NULL) {
1202     return false;
1203   }
1204 
1205   assert(boxing->result_cast() == NULL, "unexpected boxing node result");
1206 
1207   extract_call_projections(boxing);
1208 
1209   const TypeTuple* r = boxing->tf()->range();
1210   assert(r->cnt() > TypeFunc::Parms, "sanity");
1211   const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr();
1212   assert(t != NULL, "sanity");
1213 
1214   CompileLog* log = C->log();
1215   if (log != NULL) {
1216     log->head("eliminate_boxing type='%d'",
1217               log->identify(t->klass()));
1218     JVMState* p = boxing->jvms();
1219     while (p != NULL) {
1220       log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
1221       p = p->caller();


1563         (init == NULL || !init->is_complete_with_arraycopy())) {
1564       if (init == NULL || init->req() < InitializeNode::RawStores) {
1565         // No InitializeNode or no stores captured by zeroing
1566         // elimination. Simply add the MemBarStoreStore after object
1567         // initialization.
1568         MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1569         transform_later(mb);
1570 
1571         mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
1572         mb->init_req(TypeFunc::Control, fast_oop_ctrl);
1573         fast_oop_ctrl = new ProjNode(mb,TypeFunc::Control);
1574         transform_later(fast_oop_ctrl);
1575         fast_oop_rawmem = new ProjNode(mb,TypeFunc::Memory);
1576         transform_later(fast_oop_rawmem);
1577       } else {
1578         // Add the MemBarStoreStore after the InitializeNode so that
1579         // all stores performing the initialization that were moved
1580         // before the InitializeNode happen before the storestore
1581         // barrier.
1582 
1583         Node* init_ctrl = init->proj_out_or_null(TypeFunc::Control);
1584         Node* init_mem = init->proj_out_or_null(TypeFunc::Memory);
1585 
1586         MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1587         transform_later(mb);
1588 
1589         Node* ctrl = new ProjNode(init,TypeFunc::Control);
1590         transform_later(ctrl);
1591         Node* mem = new ProjNode(init,TypeFunc::Memory);
1592         transform_later(mem);
1593 
1594         // The MemBarStoreStore depends on control and memory coming
1595         // from the InitializeNode
1596         mb->init_req(TypeFunc::Memory, mem);
1597         mb->init_req(TypeFunc::Control, ctrl);
1598 
1599         ctrl = new ProjNode(mb,TypeFunc::Control);
1600         transform_later(ctrl);
1601         mem = new ProjNode(mb,TypeFunc::Memory);
1602         transform_later(mem);
1603 
1604         // All nodes that depended on the InitializeNode for control


< prev index next >