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) { |