< prev index next >

src/hotspot/share/opto/macroArrayCopy.cpp

Print this page




  55   const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
  56   idx = transform_later( new ConvI2LNode(idx, lidxtype) );
  57 #endif
  58   Node* scale = new LShiftXNode(idx, intcon(shift));
  59   transform_later(scale);
  60   return basic_plus_adr(ary, base, scale);
  61 }
  62 
  63 Node* PhaseMacroExpand::ConvI2L(Node* offset) {
  64   return transform_later(new ConvI2LNode(offset));
  65 }
  66 
  67 Node* PhaseMacroExpand::make_leaf_call(Node* ctrl, Node* mem,
  68                                        const TypeFunc* call_type, address call_addr,
  69                                        const char* call_name,
  70                                        const TypePtr* adr_type,
  71                                        Node* parm0, Node* parm1,
  72                                        Node* parm2, Node* parm3,
  73                                        Node* parm4, Node* parm5,
  74                                        Node* parm6, Node* parm7) {
  75   int size = call_type->domain()->cnt();
  76   Node* call = new CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
  77   call->init_req(TypeFunc::Control, ctrl);
  78   call->init_req(TypeFunc::I_O    , top());
  79   call->init_req(TypeFunc::Memory , mem);
  80   call->init_req(TypeFunc::ReturnAdr, top());
  81   call->init_req(TypeFunc::FramePtr, top());
  82 
  83   // Hook each parm in order.  Stop looking at the first NULL.
  84   if (parm0 != NULL) { call->init_req(TypeFunc::Parms+0, parm0);
  85   if (parm1 != NULL) { call->init_req(TypeFunc::Parms+1, parm1);
  86   if (parm2 != NULL) { call->init_req(TypeFunc::Parms+2, parm2);
  87   if (parm3 != NULL) { call->init_req(TypeFunc::Parms+3, parm3);
  88   if (parm4 != NULL) { call->init_req(TypeFunc::Parms+4, parm4);
  89   if (parm5 != NULL) { call->init_req(TypeFunc::Parms+5, parm5);
  90   if (parm6 != NULL) { call->init_req(TypeFunc::Parms+6, parm6);
  91   if (parm7 != NULL) { call->init_req(TypeFunc::Parms+7, parm7);
  92     /* close each nested if ===> */  } } } } } } } }
  93   assert(call->in(call->req()-1) != NULL, "must initialize all parms");
  94 
  95   return call;


1066   Node* src_start  = src;
1067   Node* dest_start = dest;
1068   if (src_offset != NULL || dest_offset != NULL) {
1069     src_start =  array_element_address(src, src_offset, basic_elem_type);
1070     dest_start = array_element_address(dest, dest_offset, basic_elem_type);
1071   }
1072 
1073   // Figure out which arraycopy runtime method to call.
1074   const char* copyfunc_name = "arraycopy";
1075   address     copyfunc_addr =
1076       basictype2arraycopy(basic_elem_type, src_offset, dest_offset,
1077                           disjoint_bases, copyfunc_name, dest_uninitialized);
1078 
1079   const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1080   Node* call = make_leaf_call(*ctrl, *mem, call_type, copyfunc_addr, copyfunc_name, adr_type,
1081                               src_start, dest_start, copy_length XTOP);
1082 
1083   finish_arraycopy_call(call, ctrl, mem, adr_type);
1084 }
1085 



























1086 void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) {
1087   Node* ctrl = ac->in(TypeFunc::Control);
1088   Node* io = ac->in(TypeFunc::I_O);
1089   Node* src = ac->in(ArrayCopyNode::Src);
1090   Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
1091   Node* dest = ac->in(ArrayCopyNode::Dest);
1092   Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
1093   Node* length = ac->in(ArrayCopyNode::Length);
1094   MergeMemNode* merge_mem = NULL;
1095 
1096   if (ac->is_clonebasic()) {
1097     assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null");
1098     Node* mem = ac->in(TypeFunc::Memory);
1099     const char* copyfunc_name = "arraycopy";
1100     address     copyfunc_addr =
1101       basictype2arraycopy(T_LONG, NULL, NULL,
1102                           true, copyfunc_name, true);
1103 
1104     const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
1105     const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1106 
1107     Node* call = make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length XTOP);
1108     transform_later(call);
1109 













1110     _igvn.replace_node(ac, call);

1111     return;
1112   } else if (ac->is_copyof() || ac->is_copyofrange() || ac->is_cloneoop()) {
1113     Node* mem = ac->in(TypeFunc::Memory);
1114     merge_mem = MergeMemNode::make(mem);
1115     transform_later(merge_mem);
1116 
1117     RegionNode* slow_region = new RegionNode(1);
1118     transform_later(slow_region);
1119 
1120     AllocateArrayNode* alloc = NULL;
1121     if (ac->is_alloc_tightly_coupled()) {
1122       alloc = AllocateArrayNode::Ideal_array_allocation(dest, &_igvn);
1123       assert(alloc != NULL, "expect alloc");
1124     }
1125 
1126     const TypePtr* adr_type = _igvn.type(dest)->is_oopptr()->add_offset(Type::OffsetBot);
1127     if (ac->_dest_type != TypeOopPtr::BOTTOM) {
1128       adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
1129     }
1130     generate_arraycopy(ac, alloc, &ctrl, merge_mem, &io,




  55   const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
  56   idx = transform_later( new ConvI2LNode(idx, lidxtype) );
  57 #endif
  58   Node* scale = new LShiftXNode(idx, intcon(shift));
  59   transform_later(scale);
  60   return basic_plus_adr(ary, base, scale);
  61 }
  62 
  63 Node* PhaseMacroExpand::ConvI2L(Node* offset) {
  64   return transform_later(new ConvI2LNode(offset));
  65 }
  66 
  67 Node* PhaseMacroExpand::make_leaf_call(Node* ctrl, Node* mem,
  68                                        const TypeFunc* call_type, address call_addr,
  69                                        const char* call_name,
  70                                        const TypePtr* adr_type,
  71                                        Node* parm0, Node* parm1,
  72                                        Node* parm2, Node* parm3,
  73                                        Node* parm4, Node* parm5,
  74                                        Node* parm6, Node* parm7) {

  75   Node* call = new CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
  76   call->init_req(TypeFunc::Control, ctrl);
  77   call->init_req(TypeFunc::I_O    , top());
  78   call->init_req(TypeFunc::Memory , mem);
  79   call->init_req(TypeFunc::ReturnAdr, top());
  80   call->init_req(TypeFunc::FramePtr, top());
  81 
  82   // Hook each parm in order.  Stop looking at the first NULL.
  83   if (parm0 != NULL) { call->init_req(TypeFunc::Parms+0, parm0);
  84   if (parm1 != NULL) { call->init_req(TypeFunc::Parms+1, parm1);
  85   if (parm2 != NULL) { call->init_req(TypeFunc::Parms+2, parm2);
  86   if (parm3 != NULL) { call->init_req(TypeFunc::Parms+3, parm3);
  87   if (parm4 != NULL) { call->init_req(TypeFunc::Parms+4, parm4);
  88   if (parm5 != NULL) { call->init_req(TypeFunc::Parms+5, parm5);
  89   if (parm6 != NULL) { call->init_req(TypeFunc::Parms+6, parm6);
  90   if (parm7 != NULL) { call->init_req(TypeFunc::Parms+7, parm7);
  91     /* close each nested if ===> */  } } } } } } } }
  92   assert(call->in(call->req()-1) != NULL, "must initialize all parms");
  93 
  94   return call;


1065   Node* src_start  = src;
1066   Node* dest_start = dest;
1067   if (src_offset != NULL || dest_offset != NULL) {
1068     src_start =  array_element_address(src, src_offset, basic_elem_type);
1069     dest_start = array_element_address(dest, dest_offset, basic_elem_type);
1070   }
1071 
1072   // Figure out which arraycopy runtime method to call.
1073   const char* copyfunc_name = "arraycopy";
1074   address     copyfunc_addr =
1075       basictype2arraycopy(basic_elem_type, src_offset, dest_offset,
1076                           disjoint_bases, copyfunc_name, dest_uninitialized);
1077 
1078   const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1079   Node* call = make_leaf_call(*ctrl, *mem, call_type, copyfunc_addr, copyfunc_name, adr_type,
1080                               src_start, dest_start, copy_length XTOP);
1081 
1082   finish_arraycopy_call(call, ctrl, mem, adr_type);
1083 }
1084 
1085 bool PhaseMacroExpand::clone_needs_postbarrier(ArrayCopyNode *ac) {
1086   Node* src = ac->in(ArrayCopyNode::Src);
1087   const TypeOopPtr* src_type = _igvn.type(src)->is_oopptr();
1088   if (src_type->isa_instptr() != NULL) {
1089     ciInstanceKlass* ik = src_type->klass()->as_instance_klass();
1090     if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) {
1091       if (ik->has_object_fields()) {
1092         return true;
1093       } else {
1094         if (!src_type->klass_is_exact()) {
1095           C->dependencies()->assert_leaf_type(ik);
1096         }
1097       }
1098     } else {
1099       return true;
1100     }
1101   } else if (src_type->isa_aryptr()) {
1102     BasicType src_elem  = src_type->klass()->as_array_klass()->element_type()->basic_type();
1103     if (src_elem == T_OBJECT || src_elem == T_ARRAY) {
1104       return true;
1105     }
1106   } else {
1107     return true;
1108   }
1109   return false;
1110 }
1111 
1112 void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) {
1113   Node* ctrl = ac->in(TypeFunc::Control);
1114   Node* io = ac->in(TypeFunc::I_O);
1115   Node* src = ac->in(ArrayCopyNode::Src);
1116   Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
1117   Node* dest = ac->in(ArrayCopyNode::Dest);
1118   Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
1119   Node* length = ac->in(ArrayCopyNode::Length);
1120   MergeMemNode* merge_mem = NULL;
1121 
1122   if (ac->is_clonebasic()) {
1123     assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null");
1124     Node* mem = ac->in(TypeFunc::Memory);
1125     const char* copyfunc_name = "arraycopy";
1126     address     copyfunc_addr =
1127       basictype2arraycopy(T_LONG, NULL, NULL,
1128                           true, copyfunc_name, true);
1129 
1130     const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
1131     const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1132 
1133     Node* call = make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length XTOP);
1134     transform_later(call);
1135 
1136     if (clone_needs_postbarrier(ac)) {
1137       const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
1138       Node* c = new ProjNode(call,TypeFunc::Control);
1139       transform_later(c);
1140       Node* m = new ProjNode(call, TypeFunc::Memory);
1141       transform_later(m);
1142       BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
1143       bs->array_copy_post_barrier_at_expansion(ac, c, m, _igvn);
1144       Node* out_c = ac->proj_out(TypeFunc::Control);
1145       Node* out_m = ac->proj_out(TypeFunc::Memory);
1146       _igvn.replace_node(out_c, c);
1147       _igvn.replace_node(out_m, m);
1148     } else {
1149     _igvn.replace_node(ac, call);
1150     }
1151     return;
1152   } else if (ac->is_copyof() || ac->is_copyofrange() || ac->is_cloneoop()) {
1153     Node* mem = ac->in(TypeFunc::Memory);
1154     merge_mem = MergeMemNode::make(mem);
1155     transform_later(merge_mem);
1156 
1157     RegionNode* slow_region = new RegionNode(1);
1158     transform_later(slow_region);
1159 
1160     AllocateArrayNode* alloc = NULL;
1161     if (ac->is_alloc_tightly_coupled()) {
1162       alloc = AllocateArrayNode::Ideal_array_allocation(dest, &_igvn);
1163       assert(alloc != NULL, "expect alloc");
1164     }
1165 
1166     const TypePtr* adr_type = _igvn.type(dest)->is_oopptr()->add_offset(Type::OffsetBot);
1167     if (ac->_dest_type != TypeOopPtr::BOTTOM) {
1168       adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
1169     }
1170     generate_arraycopy(ac, alloc, &ctrl, merge_mem, &io,


< prev index next >