< prev index next >

src/hotspot/share/opto/macroArrayCopy.cpp

Print this page
rev 53542 : Move Shenandoah clone-expansion from shared code to ShBSC2


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




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

















1090 void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) {
1091   Node* ctrl = ac->in(TypeFunc::Control);
1092   Node* io = ac->in(TypeFunc::I_O);
1093   Node* src = ac->in(ArrayCopyNode::Src);
1094   Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
1095   Node* dest = ac->in(ArrayCopyNode::Dest);
1096   Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
1097   Node* length = ac->in(ArrayCopyNode::Length);
1098   MergeMemNode* merge_mem = NULL;
1099 
1100   if (ac->is_clonebasic()) {











































1101     BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
1102     bs->clone_at_expansion(this, ac);

1103     return;
1104   } else if (ac->is_copyof() || ac->is_copyofrange() || ac->is_cloneoop()) {
1105     Node* mem = ac->in(TypeFunc::Memory);
1106     merge_mem = MergeMemNode::make(mem);
1107     transform_later(merge_mem);
1108 
1109     RegionNode* slow_region = new RegionNode(1);
1110     transform_later(slow_region);
1111 
1112     AllocateArrayNode* alloc = NULL;
1113     if (ac->is_alloc_tightly_coupled()) {
1114       alloc = AllocateArrayNode::Ideal_array_allocation(dest, &_igvn);
1115       assert(alloc != NULL, "expect alloc");
1116     }
1117 
1118     const TypePtr* adr_type = _igvn.type(dest)->is_oopptr()->add_offset(Type::OffsetBot);
1119     if (ac->_dest_type != TypeOopPtr::BOTTOM) {
1120       adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
1121     }
1122     if (ac->_src_type != ac->_dest_type) {


< prev index next >