< prev index next >

src/hotspot/share/opto/macro.cpp

Print this page




 844 bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <SafePointNode *>& safepoints) {
 845   GrowableArray <SafePointNode *> safepoints_done;
 846 
 847   ciKlass* klass = NULL;
 848   ciInstanceKlass* iklass = NULL;
 849   int nfields = 0;
 850   int array_base = 0;
 851   int element_size = 0;
 852   BasicType basic_elem_type = T_ILLEGAL;
 853   ciType* elem_type = NULL;
 854 
 855   Node* res = alloc->result_cast();
 856   assert(res == NULL || res->is_CheckCastPP(), "unexpected AllocateNode result");
 857   const TypeOopPtr* res_type = NULL;
 858   if (res != NULL) { // Could be NULL when there are no users
 859     res_type = _igvn.type(res)->isa_oopptr();
 860   }
 861 
 862   if (res != NULL) {
 863     klass = res_type->klass();
 864     // Value types are only allocated on demand
 865     if (res_type->isa_instptr() || res_type->isa_valuetypeptr()) {
 866       // find the fields of the class which will be needed for safepoint debug information
 867       assert(klass->is_instance_klass(), "must be an instance klass.");
 868       iklass = klass->as_instance_klass();
 869       nfields = iklass->nof_nonstatic_fields();
 870     } else {
 871       // find the array's elements which will be needed for safepoint debug information
 872       nfields = alloc->in(AllocateNode::ALength)->find_int_con(-1);
 873       assert(klass->is_array_klass() && nfields >= 0, "must be an array klass.");
 874       elem_type = klass->as_array_klass()->element_type();
 875       basic_elem_type = elem_type->basic_type();
 876       array_base = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
 877       element_size = type2aelembytes(basic_elem_type);
 878       if (klass->is_value_array_klass()) {
 879         // Flattened value type array
 880         element_size = klass->as_value_array_klass()->element_byte_size();
 881       }
 882     }
 883   }
 884   //
 885   // Process the safepoint uses


2665 
2666   Node *memproj = transform_later(new ProjNode(call, TypeFunc::Memory) );
2667   mem_phi->init_req(1, memproj );
2668   mem_phi->init_req(2, mem);
2669   transform_later(mem_phi);
2670   _igvn.replace_node(_memproj_fallthrough, mem_phi);
2671 }
2672 
2673 // A value type is returned from the call but we don't know its
2674 // type. Either we get a buffered value (and nothing needs to be done)
2675 // or one of the values being returned is the klass of the value type
2676 // and we need to allocate a value type instance of that type and
2677 // initialize it with other values being returned. In that case, we
2678 // first try a fast path allocation and initialize the value with the
2679 // value klass's pack handler or we fall back to a runtime call.
2680 void PhaseMacroExpand::expand_mh_intrinsic_return(CallStaticJavaNode* call) {
2681   Node* ret = call->proj_out(TypeFunc::Parms);
2682   if (ret == NULL) {
2683     return;
2684   }
2685   assert(ret->bottom_type()->is_valuetypeptr()->is__Value(), "unexpected return type from MH intrinsic");

2686   const TypeFunc* tf = call->_tf;
2687   const TypeTuple* domain = OptoRuntime::store_value_type_fields_Type()->domain_cc();
2688   const TypeFunc* new_tf = TypeFunc::make(tf->domain_sig(), tf->domain_cc(), tf->range_sig(), domain);
2689   call->_tf = new_tf;
2690   // Make sure the change of type is applied before projections are
2691   // processed by igvn
2692   _igvn.set_type(call, call->Value(&_igvn));
2693   _igvn.set_type(ret, ret->Value(&_igvn));
2694 
2695   // Before any new projection is added:
2696   CallProjections* projs = call->extract_projections(true, true);
2697 
2698   Node* ctl = new Node(1);
2699   Node* mem = new Node(1);
2700   Node* io = new Node(1);
2701   Node* ex_ctl = new Node(1);
2702   Node* ex_mem = new Node(1);
2703   Node* ex_io = new Node(1);
2704   Node* res = new Node(1);
2705 
2706   Node* cast = transform_later(new CastP2XNode(ctl, res));
2707   Node* mask = MakeConX(0x1);
2708   Node* masked = transform_later(new AndXNode(cast, mask));
2709   Node* cmp = transform_later(new CmpXNode(masked, mask));
2710   Node* bol = transform_later(new BoolNode(cmp, BoolTest::eq));
2711   IfNode* allocation_iff = new IfNode(ctl, bol, PROB_MAX, COUNT_UNKNOWN);
2712   transform_later(allocation_iff);
2713   Node* allocation_ctl = transform_later(new IfTrueNode(allocation_iff));
2714   Node* no_allocation_ctl = transform_later(new IfFalseNode(allocation_iff));
2715 
2716   Node* no_allocation_res = transform_later(new CheckCastPPNode(no_allocation_ctl, res, TypeValueTypePtr::NOTNULL));
2717 
2718   Node* mask2 = MakeConX(-2);
2719   Node* masked2 = transform_later(new AndXNode(cast, mask2));
2720   Node* rawklassptr = transform_later(new CastX2PNode(masked2));
2721   Node* klass_node = transform_later(new CheckCastPPNode(allocation_ctl, rawklassptr, TypeKlassPtr::OBJECT_OR_NULL));
2722 
2723   Node* slowpath_bol = NULL;
2724   Node* top_adr = NULL;
2725   Node* old_top = NULL;
2726   Node* new_top = NULL;
2727   if (UseTLAB) {
2728     Node* end_adr = NULL;
2729     set_eden_pointers(top_adr, end_adr);
2730     Node* end = make_load(ctl, mem, end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS);
2731     old_top = new LoadPNode(ctl, mem, top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered);
2732     transform_later(old_top);
2733     Node* layout_val = make_load(NULL, mem, klass_node, in_bytes(Klass::layout_helper_offset()), TypeInt::INT, T_INT);
2734     Node* size_in_bytes = ConvI2X(layout_val);
2735     new_top = new AddPNode(top(), old_top, size_in_bytes);
2736     transform_later(new_top);




 844 bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <SafePointNode *>& safepoints) {
 845   GrowableArray <SafePointNode *> safepoints_done;
 846 
 847   ciKlass* klass = NULL;
 848   ciInstanceKlass* iklass = NULL;
 849   int nfields = 0;
 850   int array_base = 0;
 851   int element_size = 0;
 852   BasicType basic_elem_type = T_ILLEGAL;
 853   ciType* elem_type = NULL;
 854 
 855   Node* res = alloc->result_cast();
 856   assert(res == NULL || res->is_CheckCastPP(), "unexpected AllocateNode result");
 857   const TypeOopPtr* res_type = NULL;
 858   if (res != NULL) { // Could be NULL when there are no users
 859     res_type = _igvn.type(res)->isa_oopptr();
 860   }
 861 
 862   if (res != NULL) {
 863     klass = res_type->klass();
 864     if (res_type->isa_instptr()) {

 865       // find the fields of the class which will be needed for safepoint debug information
 866       assert(klass->is_instance_klass(), "must be an instance klass.");
 867       iklass = klass->as_instance_klass();
 868       nfields = iklass->nof_nonstatic_fields();
 869     } else {
 870       // find the array's elements which will be needed for safepoint debug information
 871       nfields = alloc->in(AllocateNode::ALength)->find_int_con(-1);
 872       assert(klass->is_array_klass() && nfields >= 0, "must be an array klass.");
 873       elem_type = klass->as_array_klass()->element_type();
 874       basic_elem_type = elem_type->basic_type();
 875       array_base = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
 876       element_size = type2aelembytes(basic_elem_type);
 877       if (klass->is_value_array_klass()) {
 878         // Flattened value type array
 879         element_size = klass->as_value_array_klass()->element_byte_size();
 880       }
 881     }
 882   }
 883   //
 884   // Process the safepoint uses


2664 
2665   Node *memproj = transform_later(new ProjNode(call, TypeFunc::Memory) );
2666   mem_phi->init_req(1, memproj );
2667   mem_phi->init_req(2, mem);
2668   transform_later(mem_phi);
2669   _igvn.replace_node(_memproj_fallthrough, mem_phi);
2670 }
2671 
2672 // A value type is returned from the call but we don't know its
2673 // type. Either we get a buffered value (and nothing needs to be done)
2674 // or one of the values being returned is the klass of the value type
2675 // and we need to allocate a value type instance of that type and
2676 // initialize it with other values being returned. In that case, we
2677 // first try a fast path allocation and initialize the value with the
2678 // value klass's pack handler or we fall back to a runtime call.
2679 void PhaseMacroExpand::expand_mh_intrinsic_return(CallStaticJavaNode* call) {
2680   Node* ret = call->proj_out(TypeFunc::Parms);
2681   if (ret == NULL) {
2682     return;
2683   }
2684   // TODO fix this with the calling convention changes
2685   //assert(ret->bottom_type()->is_valuetypeptr()->is__Value(), "unexpected return type from MH intrinsic");
2686   const TypeFunc* tf = call->_tf;
2687   const TypeTuple* domain = OptoRuntime::store_value_type_fields_Type()->domain_cc();
2688   const TypeFunc* new_tf = TypeFunc::make(tf->domain_sig(), tf->domain_cc(), tf->range_sig(), domain);
2689   call->_tf = new_tf;
2690   // Make sure the change of type is applied before projections are
2691   // processed by igvn
2692   _igvn.set_type(call, call->Value(&_igvn));
2693   _igvn.set_type(ret, ret->Value(&_igvn));
2694 
2695   // Before any new projection is added:
2696   CallProjections* projs = call->extract_projections(true, true);
2697 
2698   Node* ctl = new Node(1);
2699   Node* mem = new Node(1);
2700   Node* io = new Node(1);
2701   Node* ex_ctl = new Node(1);
2702   Node* ex_mem = new Node(1);
2703   Node* ex_io = new Node(1);
2704   Node* res = new Node(1);
2705 
2706   Node* cast = transform_later(new CastP2XNode(ctl, res));
2707   Node* mask = MakeConX(0x1);
2708   Node* masked = transform_later(new AndXNode(cast, mask));
2709   Node* cmp = transform_later(new CmpXNode(masked, mask));
2710   Node* bol = transform_later(new BoolNode(cmp, BoolTest::eq));
2711   IfNode* allocation_iff = new IfNode(ctl, bol, PROB_MAX, COUNT_UNKNOWN);
2712   transform_later(allocation_iff);
2713   Node* allocation_ctl = transform_later(new IfTrueNode(allocation_iff));
2714   Node* no_allocation_ctl = transform_later(new IfFalseNode(allocation_iff));
2715 
2716   Node* no_allocation_res = transform_later(new CheckCastPPNode(no_allocation_ctl, res, TypeInstPtr::NOTNULL));
2717 
2718   Node* mask2 = MakeConX(-2);
2719   Node* masked2 = transform_later(new AndXNode(cast, mask2));
2720   Node* rawklassptr = transform_later(new CastX2PNode(masked2));
2721   Node* klass_node = transform_later(new CheckCastPPNode(allocation_ctl, rawklassptr, TypeKlassPtr::OBJECT_OR_NULL));
2722 
2723   Node* slowpath_bol = NULL;
2724   Node* top_adr = NULL;
2725   Node* old_top = NULL;
2726   Node* new_top = NULL;
2727   if (UseTLAB) {
2728     Node* end_adr = NULL;
2729     set_eden_pointers(top_adr, end_adr);
2730     Node* end = make_load(ctl, mem, end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS);
2731     old_top = new LoadPNode(ctl, mem, top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered);
2732     transform_later(old_top);
2733     Node* layout_val = make_load(NULL, mem, klass_node, in_bytes(Klass::layout_helper_offset()), TypeInt::INT, T_INT);
2734     Node* size_in_bytes = ConvI2X(layout_val);
2735     new_top = new AddPNode(top(), old_top, size_in_bytes);
2736     transform_later(new_top);


< prev index next >