173 ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
174 assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy");
175 phase->C->dependencies()->assert_leaf_type(ik);
176 }
177
178 ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
179 assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
180
181 for (int i = 0; i < count; i++) {
182 ciField* field = ik->nonstatic_field_at(i);
183 BasicType bt = field->layout_type();
184
185 const Type *type;
186 if (bt == T_OBJECT) {
187 if (!field->type()->is_loaded()) {
188 type = TypeInstPtr::BOTTOM;
189 } else {
190 ciType* field_klass = field->type();
191 type = TypeOopPtr::make_from_klass(field_klass->as_klass());
192 }
193 if (UseLoadBarrier) {
194 if (can_reshape) {
195 PhaseIterGVN* igvn = phase->is_IterGVN();
196 igvn->_worklist.push(mem);
197 }
198 return NodeSentinel;
199 }
200 } else {
201 type = Type::get_const_basic_type(bt);
202 }
203
204 int fieldidx = phase->C->alias_type(field)->index();
205 const TypePtr* adr_type = phase->C->alias_type(field)->adr_type();
206 Node* off = phase->MakeConX(field->offset());
207 Node* next_src = phase->transform(new AddPNode(base_src,base_src,off));
208 Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off));
209
210 Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered);
211 v = phase->transform(v);
212 Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered);
213 s = phase->transform(s);
253 // We don't know if arguments are arrays
254 return false;
255 }
256
257 BasicType src_elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
258 BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
259 if (src_elem == T_ARRAY) src_elem = T_OBJECT;
260 if (dest_elem == T_ARRAY) dest_elem = T_OBJECT;
261
262 if (src_elem != dest_elem || dest_elem == T_VOID) {
263 // We don't know if arguments are arrays of the same type
264 return false;
265 }
266
267 if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() || !GraphKit::use_ReduceInitialCardMarks())) {
268 // It's an object array copy but we can't emit the card marking
269 // that is needed
270 return false;
271 }
272
273 if (dest_elem == T_OBJECT && UseLoadBarrier) {
274 return false;
275 }
276
277 value_type = ary_src->elem();
278
279 base_src = src;
280 base_dest = dest;
281
282 uint shift = exact_log2(type2aelembytes(dest_elem));
283 uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
284
285 adr_src = src;
286 adr_dest = dest;
287
288 src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
289 dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
290
291 Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
292 Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift)));
293
300 adr_src = phase->transform(adr_src);
301 adr_dest = phase->transform(adr_dest);
302
303 copy_type = dest_elem;
304 } else {
305 assert(ary_src != NULL, "should be a clone");
306 assert(is_clonebasic(), "should be");
307
308 disjoint_bases = true;
309 assert(src->is_AddP(), "should be base + off");
310 assert(dest->is_AddP(), "should be base + off");
311 adr_src = src;
312 base_src = src->in(AddPNode::Base);
313 adr_dest = dest;
314 base_dest = dest->in(AddPNode::Base);
315
316 assert(phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con() == phase->type(dest->in(AddPNode::Offset))->is_intptr_t()->get_con(), "same start offset?");
317 BasicType elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
318 if (elem == T_ARRAY) elem = T_OBJECT;
319
320 if (elem == T_OBJECT && UseLoadBarrier) {
321 return false;
322 }
323
324 int diff = arrayOopDesc::base_offset_in_bytes(elem) - phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con();
325 assert(diff >= 0, "clone should not start after 1st array element");
326 if (diff > 0) {
327 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(diff)));
328 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(diff)));
329 }
330
331 copy_type = elem;
332 value_type = ary_src->elem();
333 }
334 return true;
335 }
336
337 const TypePtr* ArrayCopyNode::get_address_type(PhaseGVN *phase, Node* n) {
338 const Type* at = phase->type(n);
339 assert(at != Type::TOP, "unexpected type");
340 const TypePtr* atp = at->isa_ptr();
359 backward_ctl = phase->transform(new IfTrueNode(iff));
360 } else {
361 forward_ctl = ctl;
362 }
363 }
364
365 Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
366 bool can_reshape,
367 Node* forward_ctl,
368 Node* start_mem_src,
369 Node* start_mem_dest,
370 const TypePtr* atp_src,
371 const TypePtr* atp_dest,
372 Node* adr_src,
373 Node* base_src,
374 Node* adr_dest,
375 Node* base_dest,
376 BasicType copy_type,
377 const Type* value_type,
378 int count) {
379 guarantee(!UseLoadBarrier || copy_type != T_OBJECT, "Must be");
380 Node* mem = phase->C->top();
381 if (!forward_ctl->is_top()) {
382 // copy forward
383 mem = start_mem_dest;
384
385 if (count > 0) {
386 Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
387 v = phase->transform(v);
388 mem = StoreNode::make(*phase, forward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
389 mem = phase->transform(mem);
390 for (int i = 1; i < count; i++) {
391 Node* off = phase->MakeConX(type2aelembytes(copy_type) * i);
392 Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
393 Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
394 v = LoadNode::make(*phase, forward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
395 v = phase->transform(v);
396 mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
397 mem = phase->transform(mem);
398 }
399 } else if(can_reshape) {
402 igvn->_worklist.push(adr_dest);
403 }
404 }
405 return mem;
406 }
407
408 Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
409 bool can_reshape,
410 Node* backward_ctl,
411 Node* start_mem_src,
412 Node* start_mem_dest,
413 const TypePtr* atp_src,
414 const TypePtr* atp_dest,
415 Node* adr_src,
416 Node* base_src,
417 Node* adr_dest,
418 Node* base_dest,
419 BasicType copy_type,
420 const Type* value_type,
421 int count) {
422 guarantee(!UseLoadBarrier || copy_type != T_OBJECT, "Must be");
423 Node* mem = phase->C->top();
424 if (!backward_ctl->is_top()) {
425 // copy backward
426 mem = start_mem_dest;
427
428 if (count > 0) {
429 for (int i = count-1; i >= 1; i--) {
430 Node* off = phase->MakeConX(type2aelembytes(copy_type) * i);
431 Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
432 Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
433 Node* v = LoadNode::make(*phase, backward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
434 v = phase->transform(v);
435 mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
436 mem = phase->transform(mem);
437 }
438 Node* v = LoadNode::make(*phase, backward_ctl, mem, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
439 v = phase->transform(v);
440 mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
441 mem = phase->transform(mem);
442 } else if(can_reshape) {
|
173 ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
174 assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy");
175 phase->C->dependencies()->assert_leaf_type(ik);
176 }
177
178 ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
179 assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
180
181 for (int i = 0; i < count; i++) {
182 ciField* field = ik->nonstatic_field_at(i);
183 BasicType bt = field->layout_type();
184
185 const Type *type;
186 if (bt == T_OBJECT) {
187 if (!field->type()->is_loaded()) {
188 type = TypeInstPtr::BOTTOM;
189 } else {
190 ciType* field_klass = field->type();
191 type = TypeOopPtr::make_from_klass(field_klass->as_klass());
192 }
193 if (UseZGC) {
194 if (can_reshape) {
195 PhaseIterGVN* igvn = phase->is_IterGVN();
196 igvn->_worklist.push(mem);
197 }
198 return NodeSentinel;
199 }
200 } else {
201 type = Type::get_const_basic_type(bt);
202 }
203
204 int fieldidx = phase->C->alias_type(field)->index();
205 const TypePtr* adr_type = phase->C->alias_type(field)->adr_type();
206 Node* off = phase->MakeConX(field->offset());
207 Node* next_src = phase->transform(new AddPNode(base_src,base_src,off));
208 Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off));
209
210 Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered);
211 v = phase->transform(v);
212 Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered);
213 s = phase->transform(s);
253 // We don't know if arguments are arrays
254 return false;
255 }
256
257 BasicType src_elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
258 BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
259 if (src_elem == T_ARRAY) src_elem = T_OBJECT;
260 if (dest_elem == T_ARRAY) dest_elem = T_OBJECT;
261
262 if (src_elem != dest_elem || dest_elem == T_VOID) {
263 // We don't know if arguments are arrays of the same type
264 return false;
265 }
266
267 if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() || !GraphKit::use_ReduceInitialCardMarks())) {
268 // It's an object array copy but we can't emit the card marking
269 // that is needed
270 return false;
271 }
272
273 if (dest_elem == T_OBJECT && UseZGC) {
274 return false;
275 }
276
277 value_type = ary_src->elem();
278
279 base_src = src;
280 base_dest = dest;
281
282 uint shift = exact_log2(type2aelembytes(dest_elem));
283 uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
284
285 adr_src = src;
286 adr_dest = dest;
287
288 src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
289 dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
290
291 Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
292 Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift)));
293
300 adr_src = phase->transform(adr_src);
301 adr_dest = phase->transform(adr_dest);
302
303 copy_type = dest_elem;
304 } else {
305 assert(ary_src != NULL, "should be a clone");
306 assert(is_clonebasic(), "should be");
307
308 disjoint_bases = true;
309 assert(src->is_AddP(), "should be base + off");
310 assert(dest->is_AddP(), "should be base + off");
311 adr_src = src;
312 base_src = src->in(AddPNode::Base);
313 adr_dest = dest;
314 base_dest = dest->in(AddPNode::Base);
315
316 assert(phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con() == phase->type(dest->in(AddPNode::Offset))->is_intptr_t()->get_con(), "same start offset?");
317 BasicType elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
318 if (elem == T_ARRAY) elem = T_OBJECT;
319
320 if (elem == T_OBJECT && UseZGC) {
321 return false;
322 }
323
324 int diff = arrayOopDesc::base_offset_in_bytes(elem) - phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con();
325 assert(diff >= 0, "clone should not start after 1st array element");
326 if (diff > 0) {
327 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(diff)));
328 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(diff)));
329 }
330
331 copy_type = elem;
332 value_type = ary_src->elem();
333 }
334 return true;
335 }
336
337 const TypePtr* ArrayCopyNode::get_address_type(PhaseGVN *phase, Node* n) {
338 const Type* at = phase->type(n);
339 assert(at != Type::TOP, "unexpected type");
340 const TypePtr* atp = at->isa_ptr();
359 backward_ctl = phase->transform(new IfTrueNode(iff));
360 } else {
361 forward_ctl = ctl;
362 }
363 }
364
365 Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
366 bool can_reshape,
367 Node* forward_ctl,
368 Node* start_mem_src,
369 Node* start_mem_dest,
370 const TypePtr* atp_src,
371 const TypePtr* atp_dest,
372 Node* adr_src,
373 Node* base_src,
374 Node* adr_dest,
375 Node* base_dest,
376 BasicType copy_type,
377 const Type* value_type,
378 int count) {
379 guarantee(!UseZGC || copy_type != T_OBJECT, "Must be");
380 Node* mem = phase->C->top();
381 if (!forward_ctl->is_top()) {
382 // copy forward
383 mem = start_mem_dest;
384
385 if (count > 0) {
386 Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
387 v = phase->transform(v);
388 mem = StoreNode::make(*phase, forward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
389 mem = phase->transform(mem);
390 for (int i = 1; i < count; i++) {
391 Node* off = phase->MakeConX(type2aelembytes(copy_type) * i);
392 Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
393 Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
394 v = LoadNode::make(*phase, forward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
395 v = phase->transform(v);
396 mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
397 mem = phase->transform(mem);
398 }
399 } else if(can_reshape) {
402 igvn->_worklist.push(adr_dest);
403 }
404 }
405 return mem;
406 }
407
408 Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
409 bool can_reshape,
410 Node* backward_ctl,
411 Node* start_mem_src,
412 Node* start_mem_dest,
413 const TypePtr* atp_src,
414 const TypePtr* atp_dest,
415 Node* adr_src,
416 Node* base_src,
417 Node* adr_dest,
418 Node* base_dest,
419 BasicType copy_type,
420 const Type* value_type,
421 int count) {
422 guarantee(!UseZGC || copy_type != T_OBJECT, "Must be");
423 Node* mem = phase->C->top();
424 if (!backward_ctl->is_top()) {
425 // copy backward
426 mem = start_mem_dest;
427
428 if (count > 0) {
429 for (int i = count-1; i >= 1; i--) {
430 Node* off = phase->MakeConX(type2aelembytes(copy_type) * i);
431 Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
432 Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
433 Node* v = LoadNode::make(*phase, backward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
434 v = phase->transform(v);
435 mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
436 mem = phase->transform(mem);
437 }
438 Node* v = LoadNode::make(*phase, backward_ctl, mem, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
439 v = phase->transform(v);
440 mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
441 mem = phase->transform(mem);
442 } else if(can_reshape) {
|