234
235 // newly allocated object is guaranteed to not overlap with source object
236 disjoint_bases = is_alloc_tightly_coupled();
237
238 if (ary_src == NULL || ary_src->klass() == NULL ||
239 ary_dest == NULL || ary_dest->klass() == NULL) {
240 // We don't know if arguments are arrays
241 return false;
242 }
243
244 BasicType src_elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
245 BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
246 if (src_elem == T_ARRAY) src_elem = T_OBJECT;
247 if (dest_elem == T_ARRAY) dest_elem = T_OBJECT;
248
249 if (src_elem != dest_elem || dest_elem == T_VOID) {
250 // We don't know if arguments are arrays of the same type
251 return false;
252 }
253
254 if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() || !GraphKit::use_ReduceInitialCardMarks())) {
255 // It's an object array copy but we can't emit the card marking
256 // that is needed
257 return false;
258 }
259
260 value_type = ary_src->elem();
261
262 base_src = src;
263 base_dest = dest;
264
265 uint shift = exact_log2(type2aelembytes(dest_elem));
266 uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
267
268 adr_src = src;
269 adr_dest = dest;
270
271 src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
272 dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
273
274 Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
416 v = phase->transform(v);
417 mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
418 mem = phase->transform(mem);
419 } else if(can_reshape) {
420 PhaseIterGVN* igvn = phase->is_IterGVN();
421 igvn->_worklist.push(adr_src);
422 igvn->_worklist.push(adr_dest);
423 }
424 }
425 return mem;
426 }
427
428 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
429 Node* ctl, Node *mem) {
430 if (can_reshape) {
431 PhaseIterGVN* igvn = phase->is_IterGVN();
432 igvn->set_delay_transform(false);
433 if (is_clonebasic()) {
434 Node* out_mem = proj_out(TypeFunc::Memory);
435
436 if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
437 out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
438 assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking");
439 return false;
440 }
441
442 igvn->replace_node(out_mem->raw_out(0), mem);
443
444 Node* out_ctl = proj_out(TypeFunc::Control);
445 igvn->replace_node(out_ctl, ctl);
446 } else {
447 // replace fallthrough projections of the ArrayCopyNode by the
448 // new memory, control and the input IO.
449 CallProjections callprojs;
450 extract_projections(&callprojs, true, false);
451
452 if (callprojs.fallthrough_ioproj != NULL) {
453 igvn->replace_node(callprojs.fallthrough_ioproj, in(TypeFunc::I_O));
454 }
455 if (callprojs.fallthrough_memproj != NULL) {
456 igvn->replace_node(callprojs.fallthrough_memproj, mem);
457 }
458 if (callprojs.fallthrough_catchproj != NULL) {
|
234
235 // newly allocated object is guaranteed to not overlap with source object
236 disjoint_bases = is_alloc_tightly_coupled();
237
238 if (ary_src == NULL || ary_src->klass() == NULL ||
239 ary_dest == NULL || ary_dest->klass() == NULL) {
240 // We don't know if arguments are arrays
241 return false;
242 }
243
244 BasicType src_elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
245 BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
246 if (src_elem == T_ARRAY) src_elem = T_OBJECT;
247 if (dest_elem == T_ARRAY) dest_elem = T_OBJECT;
248
249 if (src_elem != dest_elem || dest_elem == T_VOID) {
250 // We don't know if arguments are arrays of the same type
251 return false;
252 }
253
254 C2BarrierSetCodeGen* code_gen = Universe::heap()->barrier_set()->c2_code_gen();
255 if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() ||
256 code_gen->array_copy_requires_gc_barriers(T_OBJECT))) {
257 // It's an object array copy but we can't emit the card marking
258 // that is needed
259 return false;
260 }
261
262 value_type = ary_src->elem();
263
264 base_src = src;
265 base_dest = dest;
266
267 uint shift = exact_log2(type2aelembytes(dest_elem));
268 uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
269
270 adr_src = src;
271 adr_dest = dest;
272
273 src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
274 dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
275
276 Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
418 v = phase->transform(v);
419 mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
420 mem = phase->transform(mem);
421 } else if(can_reshape) {
422 PhaseIterGVN* igvn = phase->is_IterGVN();
423 igvn->_worklist.push(adr_src);
424 igvn->_worklist.push(adr_dest);
425 }
426 }
427 return mem;
428 }
429
430 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
431 Node* ctl, Node *mem) {
432 if (can_reshape) {
433 PhaseIterGVN* igvn = phase->is_IterGVN();
434 igvn->set_delay_transform(false);
435 if (is_clonebasic()) {
436 Node* out_mem = proj_out(TypeFunc::Memory);
437
438 C2BarrierSetCodeGen* code_gen = Universe::heap()->barrier_set()->c2_code_gen();
439 if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
440 out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
441 assert(code_gen->array_copy_requires_gc_barriers(T_OBJECT), "can only happen with card marking");
442 return false;
443 }
444
445 igvn->replace_node(out_mem->raw_out(0), mem);
446
447 Node* out_ctl = proj_out(TypeFunc::Control);
448 igvn->replace_node(out_ctl, ctl);
449 } else {
450 // replace fallthrough projections of the ArrayCopyNode by the
451 // new memory, control and the input IO.
452 CallProjections callprojs;
453 extract_projections(&callprojs, true, false);
454
455 if (callprojs.fallthrough_ioproj != NULL) {
456 igvn->replace_node(callprojs.fallthrough_ioproj, in(TypeFunc::I_O));
457 }
458 if (callprojs.fallthrough_memproj != NULL) {
459 igvn->replace_node(callprojs.fallthrough_memproj, mem);
460 }
461 if (callprojs.fallthrough_catchproj != NULL) {
|