257 domain_fields[TypeFunc::Parms + 1] = TypeInstPtr::NOTNULL; // dst
258 domain_fields[TypeFunc::Parms + 2] = TypeLong::LONG; // size lower
259 domain_fields[TypeFunc::Parms + 3] = Type::HALF; // size upper
260 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + 4, domain_fields);
261
262 // Create result type (range)
263 const Type** range_fields = TypeTuple::fields(0);
264 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 0, range_fields);
265
266 return TypeFunc::make(domain, range);
267 }
268
269 #define XTOP LP64_ONLY(COMMA phase->top())
270
271 void XBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const {
272 Node* const src = ac->in(ArrayCopyNode::Src);
273 const TypeAryPtr* ary_ptr = src->get_ptr_type()->isa_aryptr();
274
275 if (ac->is_clone_array() && ary_ptr != nullptr) {
276 BasicType bt = ary_ptr->elem()->array_element_basic_type();
277 if (is_reference_type(bt)) {
278 // Clone object array
279 bt = T_OBJECT;
280 } else {
281 // Clone primitive array
282 bt = T_LONG;
283 }
284
285 Node* ctrl = ac->in(TypeFunc::Control);
286 Node* mem = ac->in(TypeFunc::Memory);
287 Node* src = ac->in(ArrayCopyNode::Src);
288 Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
289 Node* dest = ac->in(ArrayCopyNode::Dest);
290 Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
291 Node* length = ac->in(ArrayCopyNode::Length);
292
293 if (bt == T_OBJECT) {
294 // BarrierSetC2::clone sets the offsets via BarrierSetC2::arraycopy_payload_base_offset
295 // which 8-byte aligns them to allow for word size copies. Make sure the offsets point
296 // to the first element in the array when cloning object arrays. Otherwise, load
297 // barriers are applied to parts of the header. Also adjust the length accordingly.
|
257 domain_fields[TypeFunc::Parms + 1] = TypeInstPtr::NOTNULL; // dst
258 domain_fields[TypeFunc::Parms + 2] = TypeLong::LONG; // size lower
259 domain_fields[TypeFunc::Parms + 3] = Type::HALF; // size upper
260 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + 4, domain_fields);
261
262 // Create result type (range)
263 const Type** range_fields = TypeTuple::fields(0);
264 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 0, range_fields);
265
266 return TypeFunc::make(domain, range);
267 }
268
269 #define XTOP LP64_ONLY(COMMA phase->top())
270
271 void XBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const {
272 Node* const src = ac->in(ArrayCopyNode::Src);
273 const TypeAryPtr* ary_ptr = src->get_ptr_type()->isa_aryptr();
274
275 if (ac->is_clone_array() && ary_ptr != nullptr) {
276 BasicType bt = ary_ptr->elem()->array_element_basic_type();
277 if (is_reference_type(bt) && !ary_ptr->is_flat()) {
278 // Clone object array
279 bt = T_OBJECT;
280 } else {
281 // Clone primitive array
282 bt = T_LONG;
283 }
284
285 Node* ctrl = ac->in(TypeFunc::Control);
286 Node* mem = ac->in(TypeFunc::Memory);
287 Node* src = ac->in(ArrayCopyNode::Src);
288 Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
289 Node* dest = ac->in(ArrayCopyNode::Dest);
290 Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
291 Node* length = ac->in(ArrayCopyNode::Length);
292
293 if (bt == T_OBJECT) {
294 // BarrierSetC2::clone sets the offsets via BarrierSetC2::arraycopy_payload_base_offset
295 // which 8-byte aligns them to allow for word size copies. Make sure the offsets point
296 // to the first element in the array when cloning object arrays. Otherwise, load
297 // barriers are applied to parts of the header. Also adjust the length accordingly.
|