6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/barrierSet.hpp"
27 #include "gc/shared/c2/barrierSetC2.hpp"
28 #include "gc/shared/c2/cardTableBarrierSetC2.hpp"
29 #include "gc/shared/gc_globals.hpp"
30 #include "opto/arraycopynode.hpp"
31 #include "opto/graphKit.hpp"
32 #include "runtime/sharedRuntime.hpp"
33 #include "utilities/macros.hpp"
34 #include "utilities/powerOfTwo.hpp"
35
36 ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard)
37 : CallNode(arraycopy_type(), nullptr, TypePtr::BOTTOM),
38 _kind(None),
39 _alloc_tightly_coupled(alloc_tightly_coupled),
40 _has_negative_length_guard(has_negative_length_guard),
41 _arguments_validated(false),
42 _src_type(TypeOopPtr::BOTTOM),
43 _dest_type(TypeOopPtr::BOTTOM) {
44 init_class_id(Class_ArrayCopy);
45 init_flags(Flag_is_macro);
46 C->add_macro_node(this);
47 }
48
49 uint ArrayCopyNode::size_of() const { return sizeof(*this); }
50
51 ArrayCopyNode* ArrayCopyNode::make(GraphKit* kit, bool may_throw,
97 void ArrayCopyNode::dump_compact_spec(outputStream* st) const {
98 st->print("%s%s", _kind_names[_kind], _alloc_tightly_coupled ? ",tight" : "");
99 }
100 #endif
101
102 intptr_t ArrayCopyNode::get_length_if_constant(PhaseGVN *phase) const {
103 // check that length is constant
104 Node* length = in(ArrayCopyNode::Length);
105 const Type* length_type = phase->type(length);
106
107 if (length_type == Type::TOP) {
108 return -1;
109 }
110
111 assert(is_clonebasic() || is_arraycopy() || is_copyof() || is_copyofrange(), "unexpected array copy type");
112
113 return is_clonebasic() ? length->find_intptr_t_con(-1) : length->find_int_con(-1);
114 }
115
116 int ArrayCopyNode::get_count(PhaseGVN *phase) const {
117 Node* src = in(ArrayCopyNode::Src);
118 const Type* src_type = phase->type(src);
119
120 if (is_clonebasic()) {
121 if (src_type->isa_instptr()) {
122 const TypeInstPtr* inst_src = src_type->is_instptr();
123 ciInstanceKlass* ik = inst_src->instance_klass();
124 // ciInstanceKlass::nof_nonstatic_fields() doesn't take injected
125 // fields into account. They are rare anyway so easier to simply
126 // skip instances with injected fields.
127 if ((!inst_src->klass_is_exact() && (ik->is_interface() || ik->has_subklass())) || ik->has_injected_fields()) {
128 return -1;
129 }
130 int nb_fields = ik->nof_nonstatic_fields();
131 return nb_fields;
132 } else {
133 const TypeAryPtr* ary_src = src_type->isa_aryptr();
134 assert (ary_src != nullptr, "not an array or instance?");
135 // clone passes a length as a rounded number of longs. If we're
136 // cloning an array we'll do it element by element. If the
137 // length input to ArrayCopyNode is constant, length of input
138 // array must be too.
139
140 assert((get_length_if_constant(phase) == -1) != ary_src->size()->is_con() ||
141 phase->is_IterGVN() || phase->C->inlining_incrementally() || StressReflectiveCode, "inconsistent");
142
143 if (ary_src->size()->is_con()) {
144 return ary_src->size()->get_con();
145 }
146 return -1;
147 }
148 }
149
150 return get_length_if_constant(phase);
151 }
152
153 Node* ArrayCopyNode::load(BarrierSetC2* bs, PhaseGVN *phase, Node*& ctl, MergeMemNode* mem, Node* adr, const TypePtr* adr_type, const Type *type, BasicType bt) {
154 DecoratorSet decorators = C2_READ_ACCESS | C2_CONTROL_DEPENDENT_LOAD | IN_HEAP | C2_ARRAY_COPY;
155 C2AccessValuePtr addr(adr, adr_type);
156 C2OptAccess access(*phase, ctl, mem, decorators, bt, adr->in(AddPNode::Base), addr);
157 Node* res = bs->load_at(access, type);
158 ctl = access.ctl();
159 return res;
160 }
172 }
173
174
175 Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int count) {
176 if (!is_clonebasic()) {
177 return nullptr;
178 }
179
180 Node* base_src = in(ArrayCopyNode::Src);
181 Node* base_dest = in(ArrayCopyNode::Dest);
182 Node* ctl = in(TypeFunc::Control);
183 Node* in_mem = in(TypeFunc::Memory);
184
185 const Type* src_type = phase->type(base_src);
186 const TypeInstPtr* inst_src = src_type->isa_instptr();
187 if (inst_src == nullptr) {
188 return nullptr;
189 }
190
191 MergeMemNode* mem = phase->transform(MergeMemNode::make(in_mem))->as_MergeMem();
192 if (can_reshape) {
193 phase->is_IterGVN()->_worklist.push(mem);
194 }
195
196
197 ciInstanceKlass* ik = inst_src->instance_klass();
198
199 if (!inst_src->klass_is_exact()) {
200 assert(!ik->is_interface(), "inconsistent klass hierarchy");
201 if (ik->has_subklass()) {
202 // Concurrent class loading.
203 // Fail fast and return NodeSentinel to indicate that the transform failed.
204 return NodeSentinel;
205 } else {
206 phase->C->dependencies()->assert_leaf_type(ik);
207 }
208 }
209
210 assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
211
258 Node* src_offset = in(ArrayCopyNode::SrcPos);
259 Node* dest_offset = in(ArrayCopyNode::DestPos);
260
261 if (is_arraycopy() || is_copyofrange() || is_copyof()) {
262 const Type* dest_type = phase->type(base_dest);
263 const TypeAryPtr* ary_dest = dest_type->isa_aryptr();
264
265 // newly allocated object is guaranteed to not overlap with source object
266 disjoint_bases = is_alloc_tightly_coupled();
267 if (ary_src == nullptr || ary_src->elem() == Type::BOTTOM ||
268 ary_dest == nullptr || ary_dest->elem() == Type::BOTTOM) {
269 // We don't know if arguments are arrays
270 return false;
271 }
272
273 BasicType src_elem = ary_src->elem()->array_element_basic_type();
274 BasicType dest_elem = ary_dest->elem()->array_element_basic_type();
275 if (is_reference_type(src_elem, true)) src_elem = T_OBJECT;
276 if (is_reference_type(dest_elem, true)) dest_elem = T_OBJECT;
277
278 if (src_elem != dest_elem || dest_elem == T_VOID) {
279 // We don't know if arguments are arrays of the same type
280 return false;
281 }
282
283 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
284 if (bs->array_copy_requires_gc_barriers(is_alloc_tightly_coupled(), dest_elem, false, false, BarrierSetC2::Optimization)) {
285 // It's an object array copy but we can't emit the card marking
286 // that is needed
287 return false;
288 }
289
290 value_type = ary_src->elem();
291
292 uint shift = exact_log2(type2aelembytes(dest_elem));
293 uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
294
295 src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
296 if (src_offset->is_top()) {
297 // Offset is out of bounds (the ArrayCopyNode will be removed)
298 return false;
299 }
300 dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
301 if (dest_offset->is_top()) {
302 // Offset is out of bounds (the ArrayCopyNode will be removed)
303 if (can_reshape) {
304 // record src_offset, so it can be deleted later (if it is dead)
305 phase->is_IterGVN()->_worklist.push(src_offset);
306 }
307 return false;
308 }
309
310 Node* hook = new Node(1);
311 hook->init_req(0, dest_offset);
312
313 Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
314
315 hook->destruct(phase);
316
317 Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift)));
318
319 adr_src = phase->transform(new AddPNode(base_src, base_src, src_scale));
320 adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_scale));
321
322 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(header)));
323 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(header)));
324
325 copy_type = dest_elem;
326 } else {
327 assert(ary_src != nullptr, "should be a clone");
328 assert(is_clonebasic(), "should be");
329
330 disjoint_bases = true;
331
332 BasicType elem = ary_src->isa_aryptr()->elem()->array_element_basic_type();
333 if (is_reference_type(elem, true)) {
334 elem = T_OBJECT;
335 }
336
337 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
338 if (bs->array_copy_requires_gc_barriers(true, elem, true, is_clone_inst(), BarrierSetC2::Optimization)) {
339 return false;
340 }
341
342 adr_src = phase->transform(new AddPNode(base_src, base_src, src_offset));
343 adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_offset));
344
345 // The address is offsetted to an aligned address where a raw copy would start.
346 // If the clone copy is decomposed into load-stores - the address is adjusted to
347 // point at where the array starts.
348 const Type* toff = phase->type(src_offset);
349 int offset = toff->isa_long() ? (int) toff->is_long()->get_con() : (int) toff->is_int()->get_con();
350 int diff = arrayOopDesc::base_offset_in_bytes(elem) - offset;
351 assert(diff >= 0, "clone should not start after 1st array element");
352 if (diff > 0) {
353 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(diff)));
354 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(diff)));
355 }
356 copy_type = elem;
357 value_type = ary_src->elem();
358 }
359 return true;
360 }
361
362 const TypePtr* ArrayCopyNode::get_address_type(PhaseGVN* phase, const TypePtr* atp, Node* n) {
363 if (atp == TypeOopPtr::BOTTOM) {
364 atp = phase->type(n)->isa_ptr();
365 }
366 // adjust atp to be the correct array element address type
367 return atp->add_offset(Type::OffsetBot);
368 }
369
370 void ArrayCopyNode::array_copy_test_overlap(PhaseGVN *phase, bool can_reshape, bool disjoint_bases, int count, Node*& forward_ctl, Node*& backward_ctl) {
371 Node* ctl = in(TypeFunc::Control);
372 if (!disjoint_bases && count > 1) {
373 Node* src_offset = in(ArrayCopyNode::SrcPos);
374 Node* dest_offset = in(ArrayCopyNode::DestPos);
375 assert(src_offset != nullptr && dest_offset != nullptr, "should be");
376 Node* cmp = phase->transform(new CmpINode(src_offset, dest_offset));
377 Node *bol = phase->transform(new BoolNode(cmp, BoolTest::lt));
378 IfNode *iff = new IfNode(ctl, bol, PROB_FAIR, COUNT_UNKNOWN);
379
380 phase->transform(iff);
381
382 forward_ctl = phase->transform(new IfFalseNode(iff));
383 backward_ctl = phase->transform(new IfTrueNode(iff));
384 } else {
385 forward_ctl = ctl;
386 }
387 }
388
389 Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
390 bool can_reshape,
391 Node*& forward_ctl,
392 Node* mem,
393 const TypePtr* atp_src,
394 const TypePtr* atp_dest,
395 Node* adr_src,
396 Node* base_src,
397 Node* adr_dest,
398 Node* base_dest,
399 BasicType copy_type,
400 const Type* value_type,
401 int count) {
402 if (!forward_ctl->is_top()) {
403 // copy forward
404 MergeMemNode* mm = MergeMemNode::make(mem);
405
406 if (count > 0) {
407 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
408 Node* v = load(bs, phase, forward_ctl, mm, adr_src, atp_src, value_type, copy_type);
409 store(bs, phase, forward_ctl, mm, adr_dest, atp_dest, v, value_type, copy_type);
410 for (int i = 1; i < count; i++) {
411 Node* off = phase->MakeConX(type2aelembytes(copy_type) * i);
412 Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
413 Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
414 v = load(bs, phase, forward_ctl, mm, next_src, atp_src, value_type, copy_type);
415 store(bs, phase, forward_ctl, mm, next_dest, atp_dest, v, value_type, copy_type);
416 }
417 } else if (can_reshape) {
418 PhaseIterGVN* igvn = phase->is_IterGVN();
419 igvn->_worklist.push(adr_src);
420 igvn->_worklist.push(adr_dest);
421 }
422 return mm;
423 }
424 return phase->C->top();
425 }
426
427 Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
428 bool can_reshape,
429 Node*& backward_ctl,
430 Node* mem,
431 const TypePtr* atp_src,
432 const TypePtr* atp_dest,
433 Node* adr_src,
434 Node* base_src,
435 Node* adr_dest,
436 Node* base_dest,
437 BasicType copy_type,
438 const Type* value_type,
439 int count) {
440 if (!backward_ctl->is_top()) {
441 // copy backward
442 MergeMemNode* mm = MergeMemNode::make(mem);
443
444 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
445 assert(copy_type != T_OBJECT || !bs->array_copy_requires_gc_barriers(false, T_OBJECT, false, false, BarrierSetC2::Optimization), "only tightly coupled allocations for object arrays");
446
447 if (count > 0) {
448 for (int i = count-1; i >= 1; i--) {
449 Node* off = phase->MakeConX(type2aelembytes(copy_type) * i);
450 Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
451 Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
452 Node* v = load(bs, phase, backward_ctl, mm, next_src, atp_src, value_type, copy_type);
453 store(bs, phase, backward_ctl, mm, next_dest, atp_dest, v, value_type, copy_type);
454 }
455 Node* v = load(bs, phase, backward_ctl, mm, adr_src, atp_src, value_type, copy_type);
456 store(bs, phase, backward_ctl, mm, adr_dest, atp_dest, v, value_type, copy_type);
457 } else if (can_reshape) {
458 PhaseIterGVN* igvn = phase->is_IterGVN();
459 igvn->_worklist.push(adr_src);
460 igvn->_worklist.push(adr_dest);
461 }
462 return phase->transform(mm);
463 }
464 return phase->C->top();
465 }
466
467 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
468 Node* ctl, Node *mem) {
469 if (can_reshape) {
470 PhaseIterGVN* igvn = phase->is_IterGVN();
471 igvn->set_delay_transform(false);
472 if (is_clonebasic()) {
473 Node* out_mem = proj_out(TypeFunc::Memory);
474
475 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
476 if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
477 out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
478 assert(bs->array_copy_requires_gc_barriers(true, T_OBJECT, true, is_clone_inst(), BarrierSetC2::Optimization), "can only happen with card marking");
479 return false;
480 }
481
482 igvn->replace_node(out_mem->raw_out(0), mem);
483
484 Node* out_ctl = proj_out(TypeFunc::Control);
485 igvn->replace_node(out_ctl, ctl);
486 } else {
487 // replace fallthrough projections of the ArrayCopyNode by the
488 // new memory, control and the input IO.
489 CallProjections callprojs;
490 extract_projections(&callprojs, true, false);
491
492 if (callprojs.fallthrough_ioproj != nullptr) {
493 igvn->replace_node(callprojs.fallthrough_ioproj, in(TypeFunc::I_O));
494 }
495 if (callprojs.fallthrough_memproj != nullptr) {
496 igvn->replace_node(callprojs.fallthrough_memproj, mem);
497 }
498 if (callprojs.fallthrough_catchproj != nullptr) {
499 igvn->replace_node(callprojs.fallthrough_catchproj, ctl);
500 }
501
502 // The ArrayCopyNode is not disconnected. It still has the
503 // projections for the exception case. Replace current
504 // ArrayCopyNode with a dummy new one with a top() control so
505 // that this part of the graph stays consistent but is
506 // eventually removed.
507
508 set_req(0, phase->C->top());
509 remove_dead_region(phase, can_reshape);
510 }
511 } else {
512 if (in(TypeFunc::Control) != ctl) {
513 // we can't return new memory and control from Ideal at parse time
514 assert(!is_clonebasic() || UseShenandoahGC, "added control for clone?");
515 phase->record_for_igvn(this);
516 return false;
517 }
518 }
519 return true;
520 }
521
522
523 Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) {
524 if (remove_dead_region(phase, can_reshape)) return this;
525
526 if (StressArrayCopyMacroNode && !can_reshape) {
527 phase->record_for_igvn(this);
528 return nullptr;
529 }
530
531 // See if it's a small array copy and we can inline it as
532 // loads/stores
533 // Here we can only do:
534 // - arraycopy if all arguments were validated before and we don't
535 // need card marking
536 // - clone for which we don't need to do card marking
537
538 if (!is_clonebasic() && !is_arraycopy_validated() &&
539 !is_copyofrange_validated() && !is_copyof_validated()) {
540 return nullptr;
541 }
542
543 assert(in(TypeFunc::Control) != nullptr &&
544 in(TypeFunc::Memory) != nullptr &&
546 in(ArrayCopyNode::Dest) != nullptr &&
547 in(ArrayCopyNode::Length) != nullptr &&
548 in(ArrayCopyNode::SrcPos) != nullptr &&
549 in(ArrayCopyNode::DestPos) != nullptr, "broken inputs");
550
551 if (in(TypeFunc::Control)->is_top() ||
552 in(TypeFunc::Memory)->is_top() ||
553 phase->type(in(ArrayCopyNode::Src)) == Type::TOP ||
554 phase->type(in(ArrayCopyNode::Dest)) == Type::TOP ||
555 (in(ArrayCopyNode::SrcPos) != nullptr && in(ArrayCopyNode::SrcPos)->is_top()) ||
556 (in(ArrayCopyNode::DestPos) != nullptr && in(ArrayCopyNode::DestPos)->is_top())) {
557 return nullptr;
558 }
559
560 int count = get_count(phase);
561
562 if (count < 0 || count > ArrayCopyLoadStoreMaxElem) {
563 return nullptr;
564 }
565
566 Node* mem = try_clone_instance(phase, can_reshape, count);
567 if (mem != nullptr) {
568 return (mem == NodeSentinel) ? nullptr : mem;
569 }
570
571 Node* adr_src = nullptr;
572 Node* base_src = nullptr;
573 Node* adr_dest = nullptr;
574 Node* base_dest = nullptr;
575 BasicType copy_type = T_ILLEGAL;
576 const Type* value_type = nullptr;
577 bool disjoint_bases = false;
578
579 if (!prepare_array_copy(phase, can_reshape,
580 adr_src, base_src, adr_dest, base_dest,
581 copy_type, value_type, disjoint_bases)) {
582 assert(adr_src == nullptr, "no node can be left behind");
583 assert(adr_dest == nullptr, "no node can be left behind");
584 return nullptr;
585 }
586
587 Node* src = in(ArrayCopyNode::Src);
588 Node* dest = in(ArrayCopyNode::Dest);
589 const TypePtr* atp_src = get_address_type(phase, _src_type, src);
590 const TypePtr* atp_dest = get_address_type(phase, _dest_type, dest);
591 Node* in_mem = in(TypeFunc::Memory);
592
593 if (can_reshape) {
594 assert(!phase->is_IterGVN()->delay_transform(), "cannot delay transforms");
595 phase->is_IterGVN()->set_delay_transform(true);
596 }
597
598 Node* backward_ctl = phase->C->top();
599 Node* forward_ctl = phase->C->top();
600 array_copy_test_overlap(phase, can_reshape, disjoint_bases, count, forward_ctl, backward_ctl);
601
602 Node* forward_mem = array_copy_forward(phase, can_reshape, forward_ctl,
603 in_mem,
604 atp_src, atp_dest,
605 adr_src, base_src, adr_dest, base_dest,
606 copy_type, value_type, count);
607
608 Node* backward_mem = array_copy_backward(phase, can_reshape, backward_ctl,
609 in_mem,
610 atp_src, atp_dest,
611 adr_src, base_src, adr_dest, base_dest,
612 copy_type, value_type, count);
613
614 Node* ctl = nullptr;
615 if (!forward_ctl->is_top() && !backward_ctl->is_top()) {
616 ctl = new RegionNode(3);
617 ctl->init_req(1, forward_ctl);
618 ctl->init_req(2, backward_ctl);
619 ctl = phase->transform(ctl);
620 MergeMemNode* forward_mm = forward_mem->as_MergeMem();
621 MergeMemNode* backward_mm = backward_mem->as_MergeMem();
622 for (MergeMemStream mms(forward_mm, backward_mm); mms.next_non_empty2(); ) {
623 if (mms.memory() != mms.memory2()) {
624 Node* phi = new PhiNode(ctl, Type::MEMORY, phase->C->get_adr_type(mms.alias_idx()));
625 phi->init_req(1, mms.memory());
626 phi->init_req(2, mms.memory2());
627 phi = phase->transform(phi);
628 mms.set_memory(phi);
629 }
630 }
631 mem = forward_mem;
632 } else if (!forward_ctl->is_top()) {
633 ctl = forward_ctl;
634 mem = forward_mem;
635 } else {
636 assert(!backward_ctl->is_top(), "no copy?");
637 ctl = backward_ctl;
638 mem = backward_mem;
639 }
640
641 if (can_reshape) {
642 assert(phase->is_IterGVN()->delay_transform(), "should be delaying transforms");
643 phase->is_IterGVN()->set_delay_transform(false);
644 }
645
646 if (!finish_transform(phase, can_reshape, ctl, mem)) {
647 if (can_reshape) {
648 // put in worklist, so that if it happens to be dead it is removed
649 phase->is_IterGVN()->_worklist.push(mem);
650 }
651 return nullptr;
652 }
653
654 return mem;
655 }
656
657 bool ArrayCopyNode::may_modify(const TypeOopPtr* t_oop, PhaseValues* phase) {
658 Node* dest = in(ArrayCopyNode::Dest);
659 if (dest->is_top()) {
660 return false;
661 }
662 const TypeOopPtr* dest_t = phase->type(dest)->is_oopptr();
663 assert(!dest_t->is_known_instance() || _dest_type->is_known_instance(), "result of EA not recorded");
664 assert(in(ArrayCopyNode::Src)->is_top() || !phase->type(in(ArrayCopyNode::Src))->is_oopptr()->is_known_instance() ||
665 _src_type->is_known_instance(), "result of EA not recorded");
666
667 if (_dest_type != TypeOopPtr::BOTTOM || t_oop->is_known_instance()) {
726 // write between offset_lo and offset_hi
727 bool ArrayCopyNode::modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseValues* phase, bool must_modify) const {
728 assert(_kind == ArrayCopy || _kind == CopyOf || _kind == CopyOfRange, "only for real array copies");
729
730 Node* dest = in(Dest);
731 Node* dest_pos = in(DestPos);
732 Node* len = in(Length);
733
734 const TypeInt *dest_pos_t = phase->type(dest_pos)->isa_int();
735 const TypeInt *len_t = phase->type(len)->isa_int();
736 const TypeAryPtr* ary_t = phase->type(dest)->isa_aryptr();
737
738 if (dest_pos_t == nullptr || len_t == nullptr || ary_t == nullptr) {
739 return !must_modify;
740 }
741
742 BasicType ary_elem = ary_t->isa_aryptr()->elem()->array_element_basic_type();
743 if (is_reference_type(ary_elem, true)) ary_elem = T_OBJECT;
744
745 uint header = arrayOopDesc::base_offset_in_bytes(ary_elem);
746 uint elemsize = type2aelembytes(ary_elem);
747
748 jlong dest_pos_plus_len_lo = (((jlong)dest_pos_t->_lo) + len_t->_lo) * elemsize + header;
749 jlong dest_pos_plus_len_hi = (((jlong)dest_pos_t->_hi) + len_t->_hi) * elemsize + header;
750 jlong dest_pos_lo = ((jlong)dest_pos_t->_lo) * elemsize + header;
751 jlong dest_pos_hi = ((jlong)dest_pos_t->_hi) * elemsize + header;
752
753 if (must_modify) {
754 if (offset_lo >= dest_pos_hi && offset_hi < dest_pos_plus_len_lo) {
755 return true;
756 }
757 } else {
758 if (offset_hi >= dest_pos_lo && offset_lo < dest_pos_plus_len_hi) {
759 return true;
760 }
761 }
762 return false;
763 }
764
765 // As an optimization, choose optimum vector size for copy length known at compile time.
766 int ArrayCopyNode::get_partial_inline_vector_lane_count(BasicType type, int const_len) {
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciFlatArrayKlass.hpp"
27 #include "gc/shared/barrierSet.hpp"
28 #include "gc/shared/c2/barrierSetC2.hpp"
29 #include "gc/shared/c2/cardTableBarrierSetC2.hpp"
30 #include "gc/shared/gc_globals.hpp"
31 #include "opto/arraycopynode.hpp"
32 #include "opto/graphKit.hpp"
33 #include "opto/inlinetypenode.hpp"
34 #include "runtime/sharedRuntime.hpp"
35 #include "utilities/macros.hpp"
36 #include "utilities/powerOfTwo.hpp"
37
38 ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard)
39 : CallNode(arraycopy_type(), nullptr, TypePtr::BOTTOM),
40 _kind(None),
41 _alloc_tightly_coupled(alloc_tightly_coupled),
42 _has_negative_length_guard(has_negative_length_guard),
43 _arguments_validated(false),
44 _src_type(TypeOopPtr::BOTTOM),
45 _dest_type(TypeOopPtr::BOTTOM) {
46 init_class_id(Class_ArrayCopy);
47 init_flags(Flag_is_macro);
48 C->add_macro_node(this);
49 }
50
51 uint ArrayCopyNode::size_of() const { return sizeof(*this); }
52
53 ArrayCopyNode* ArrayCopyNode::make(GraphKit* kit, bool may_throw,
99 void ArrayCopyNode::dump_compact_spec(outputStream* st) const {
100 st->print("%s%s", _kind_names[_kind], _alloc_tightly_coupled ? ",tight" : "");
101 }
102 #endif
103
104 intptr_t ArrayCopyNode::get_length_if_constant(PhaseGVN *phase) const {
105 // check that length is constant
106 Node* length = in(ArrayCopyNode::Length);
107 const Type* length_type = phase->type(length);
108
109 if (length_type == Type::TOP) {
110 return -1;
111 }
112
113 assert(is_clonebasic() || is_arraycopy() || is_copyof() || is_copyofrange(), "unexpected array copy type");
114
115 return is_clonebasic() ? length->find_intptr_t_con(-1) : length->find_int_con(-1);
116 }
117
118 int ArrayCopyNode::get_count(PhaseGVN *phase) const {
119 if (is_clonebasic()) {
120 Node* src = in(ArrayCopyNode::Src);
121 const Type* src_type = phase->type(src);
122
123 if (src_type == Type::TOP) {
124 return -1;
125 }
126
127 if (src_type->isa_instptr()) {
128 const TypeInstPtr* inst_src = src_type->is_instptr();
129 ciInstanceKlass* ik = inst_src->instance_klass();
130 // ciInstanceKlass::nof_nonstatic_fields() doesn't take injected
131 // fields into account. They are rare anyway so easier to simply
132 // skip instances with injected fields.
133 if ((!inst_src->klass_is_exact() && (ik->is_interface() || ik->has_subklass())) || ik->has_injected_fields()) {
134 return -1;
135 }
136 int nb_fields = ik->nof_nonstatic_fields();
137 return nb_fields;
138 } else {
139 const TypeAryPtr* ary_src = src_type->isa_aryptr();
140 assert (ary_src != nullptr, "not an array or instance?");
141 // clone passes a length as a rounded number of longs. If we're
142 // cloning an array we'll do it element by element. If the
143 // length input to ArrayCopyNode is constant, length of input
144 // array must be too.
145
146 assert((get_length_if_constant(phase) == -1) != ary_src->size()->is_con() ||
147 (UseFlatArray && ary_src->elem()->make_oopptr() != nullptr && ary_src->elem()->make_oopptr()->can_be_inline_type()) ||
148 phase->is_IterGVN() || phase->C->inlining_incrementally() || StressReflectiveCode, "inconsistent");
149
150 if (ary_src->size()->is_con()) {
151 return ary_src->size()->get_con();
152 }
153 return -1;
154 }
155 }
156
157 return get_length_if_constant(phase);
158 }
159
160 Node* ArrayCopyNode::load(BarrierSetC2* bs, PhaseGVN *phase, Node*& ctl, MergeMemNode* mem, Node* adr, const TypePtr* adr_type, const Type *type, BasicType bt) {
161 DecoratorSet decorators = C2_READ_ACCESS | C2_CONTROL_DEPENDENT_LOAD | IN_HEAP | C2_ARRAY_COPY;
162 C2AccessValuePtr addr(adr, adr_type);
163 C2OptAccess access(*phase, ctl, mem, decorators, bt, adr->in(AddPNode::Base), addr);
164 Node* res = bs->load_at(access, type);
165 ctl = access.ctl();
166 return res;
167 }
179 }
180
181
182 Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int count) {
183 if (!is_clonebasic()) {
184 return nullptr;
185 }
186
187 Node* base_src = in(ArrayCopyNode::Src);
188 Node* base_dest = in(ArrayCopyNode::Dest);
189 Node* ctl = in(TypeFunc::Control);
190 Node* in_mem = in(TypeFunc::Memory);
191
192 const Type* src_type = phase->type(base_src);
193 const TypeInstPtr* inst_src = src_type->isa_instptr();
194 if (inst_src == nullptr) {
195 return nullptr;
196 }
197
198 MergeMemNode* mem = phase->transform(MergeMemNode::make(in_mem))->as_MergeMem();
199 phase->record_for_igvn(mem);
200 if (can_reshape) {
201 phase->is_IterGVN()->_worklist.push(mem);
202 }
203
204
205 ciInstanceKlass* ik = inst_src->instance_klass();
206
207 if (!inst_src->klass_is_exact()) {
208 assert(!ik->is_interface(), "inconsistent klass hierarchy");
209 if (ik->has_subklass()) {
210 // Concurrent class loading.
211 // Fail fast and return NodeSentinel to indicate that the transform failed.
212 return NodeSentinel;
213 } else {
214 phase->C->dependencies()->assert_leaf_type(ik);
215 }
216 }
217
218 assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
219
266 Node* src_offset = in(ArrayCopyNode::SrcPos);
267 Node* dest_offset = in(ArrayCopyNode::DestPos);
268
269 if (is_arraycopy() || is_copyofrange() || is_copyof()) {
270 const Type* dest_type = phase->type(base_dest);
271 const TypeAryPtr* ary_dest = dest_type->isa_aryptr();
272
273 // newly allocated object is guaranteed to not overlap with source object
274 disjoint_bases = is_alloc_tightly_coupled();
275 if (ary_src == nullptr || ary_src->elem() == Type::BOTTOM ||
276 ary_dest == nullptr || ary_dest->elem() == Type::BOTTOM) {
277 // We don't know if arguments are arrays
278 return false;
279 }
280
281 BasicType src_elem = ary_src->elem()->array_element_basic_type();
282 BasicType dest_elem = ary_dest->elem()->array_element_basic_type();
283 if (is_reference_type(src_elem, true)) src_elem = T_OBJECT;
284 if (is_reference_type(dest_elem, true)) dest_elem = T_OBJECT;
285
286 if (src_elem != dest_elem || ary_src->is_flat() != ary_dest->is_flat() || dest_elem == T_VOID) {
287 // We don't know if arguments are arrays of the same type
288 return false;
289 }
290
291 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
292 if ((!ary_dest->is_flat() && bs->array_copy_requires_gc_barriers(is_alloc_tightly_coupled(), dest_elem, false, false, BarrierSetC2::Optimization)) ||
293 (ary_dest->is_flat() && ary_src->elem()->inline_klass()->contains_oops() &&
294 bs->array_copy_requires_gc_barriers(is_alloc_tightly_coupled(), T_OBJECT, false, false, BarrierSetC2::Optimization))) {
295 // It's an object array copy but we can't emit the card marking that is needed
296 return false;
297 }
298
299 value_type = ary_src->elem();
300
301 uint shift = exact_log2(type2aelembytes(dest_elem));
302 if (ary_dest->is_flat()) {
303 shift = ary_src->flat_log_elem_size();
304 }
305 uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
306
307 src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
308 if (src_offset->is_top()) {
309 // Offset is out of bounds (the ArrayCopyNode will be removed)
310 return false;
311 }
312 dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
313 if (dest_offset->is_top()) {
314 // Offset is out of bounds (the ArrayCopyNode will be removed)
315 if (can_reshape) {
316 // record src_offset, so it can be deleted later (if it is dead)
317 phase->is_IterGVN()->_worklist.push(src_offset);
318 }
319 return false;
320 }
321
322 Node* hook = new Node(1);
323 hook->init_req(0, dest_offset);
324
325 Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
326
327 hook->destruct(phase);
328
329 Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift)));
330
331 adr_src = phase->transform(new AddPNode(base_src, base_src, src_scale));
332 adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_scale));
333
334 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(header)));
335 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(header)));
336
337 copy_type = dest_elem;
338 } else {
339 assert(ary_src != nullptr, "should be a clone");
340 assert(is_clonebasic(), "should be");
341
342 disjoint_bases = true;
343
344 if (ary_src->elem()->make_oopptr() != nullptr &&
345 ary_src->elem()->make_oopptr()->can_be_inline_type()) {
346 return false;
347 }
348
349 BasicType elem = ary_src->isa_aryptr()->elem()->array_element_basic_type();
350 if (is_reference_type(elem, true)) {
351 elem = T_OBJECT;
352 }
353
354 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
355 if ((!ary_src->is_flat() && bs->array_copy_requires_gc_barriers(true, elem, true, is_clone_inst(), BarrierSetC2::Optimization)) ||
356 (ary_src->is_flat() && ary_src->elem()->inline_klass()->contains_oops() &&
357 bs->array_copy_requires_gc_barriers(true, T_OBJECT, true, is_clone_inst(), BarrierSetC2::Optimization))) {
358 // It's an object array copy but we can't emit the card marking that is needed
359 return false;
360 }
361
362 adr_src = phase->transform(new AddPNode(base_src, base_src, src_offset));
363 adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_offset));
364
365 // The address is offsetted to an aligned address where a raw copy would start.
366 // If the clone copy is decomposed into load-stores - the address is adjusted to
367 // point at where the array starts.
368 const Type* toff = phase->type(src_offset);
369 int offset = toff->isa_long() ? (int) toff->is_long()->get_con() : (int) toff->is_int()->get_con();
370 int diff = arrayOopDesc::base_offset_in_bytes(elem) - offset;
371 assert(diff >= 0, "clone should not start after 1st array element");
372 if (diff > 0) {
373 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(diff)));
374 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(diff)));
375 }
376 copy_type = elem;
377 value_type = ary_src->elem();
378 }
379 return true;
380 }
381
382 const TypeAryPtr* ArrayCopyNode::get_address_type(PhaseGVN* phase, const TypePtr* atp, Node* n) {
383 if (atp == TypeOopPtr::BOTTOM) {
384 atp = phase->type(n)->isa_ptr();
385 }
386 // adjust atp to be the correct array element address type
387 return atp->add_offset(Type::OffsetBot)->is_aryptr();
388 }
389
390 void ArrayCopyNode::array_copy_test_overlap(GraphKit& kit, bool disjoint_bases, int count, Node*& backward_ctl) {
391 Node* ctl = kit.control();
392 if (!disjoint_bases && count > 1) {
393 PhaseGVN& gvn = kit.gvn();
394 Node* src_offset = in(ArrayCopyNode::SrcPos);
395 Node* dest_offset = in(ArrayCopyNode::DestPos);
396 assert(src_offset != nullptr && dest_offset != nullptr, "should be");
397 Node* cmp = gvn.transform(new CmpINode(src_offset, dest_offset));
398 Node *bol = gvn.transform(new BoolNode(cmp, BoolTest::lt));
399 IfNode *iff = new IfNode(ctl, bol, PROB_FAIR, COUNT_UNKNOWN);
400
401 gvn.transform(iff);
402
403 kit.set_control(gvn.transform(new IfFalseNode(iff)));
404 backward_ctl = gvn.transform(new IfTrueNode(iff));
405 }
406 }
407
408 void ArrayCopyNode::copy(GraphKit& kit,
409 const TypeAryPtr* atp_src,
410 const TypeAryPtr* atp_dest,
411 int i,
412 Node* base_src,
413 Node* base_dest,
414 Node* adr_src,
415 Node* adr_dest,
416 BasicType copy_type,
417 const Type* value_type) {
418 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
419 Node* ctl = kit.control();
420 if (atp_dest->is_flat()) {
421 ciInlineKlass* vk = atp_src->elem()->inline_klass();
422 for (int j = 0; j < vk->nof_nonstatic_fields(); j++) {
423 ciField* field = vk->nonstatic_field_at(j);
424 int off_in_vt = field->offset_in_bytes() - vk->first_field_offset();
425 Node* off = kit.MakeConX(off_in_vt + i * atp_src->flat_elem_size());
426 ciType* ft = field->type();
427 BasicType bt = type2field[ft->basic_type()];
428 assert(!field->is_flat(), "flat field encountered");
429 if (bt == T_PRIMITIVE_OBJECT) {
430 bt = T_OBJECT;
431 }
432 const Type* rt = Type::get_const_type(ft);
433 const TypePtr* adr_type = atp_src->with_field_offset(off_in_vt)->add_offset(Type::OffsetBot);
434 assert(!bs->array_copy_requires_gc_barriers(is_alloc_tightly_coupled(), bt, false, false, BarrierSetC2::Optimization), "GC barriers required");
435 Node* next_src = kit.gvn().transform(new AddPNode(base_src, adr_src, off));
436 Node* next_dest = kit.gvn().transform(new AddPNode(base_dest, adr_dest, off));
437 Node* v = load(bs, &kit.gvn(), ctl, kit.merged_memory(), next_src, adr_type, rt, bt);
438 store(bs, &kit.gvn(), ctl, kit.merged_memory(), next_dest, adr_type, v, rt, bt);
439 }
440 } else {
441 Node* off = kit.MakeConX(type2aelembytes(copy_type) * i);
442 Node* next_src = kit.gvn().transform(new AddPNode(base_src, adr_src, off));
443 Node* next_dest = kit.gvn().transform(new AddPNode(base_dest, adr_dest, off));
444 Node* v = load(bs, &kit.gvn(), ctl, kit.merged_memory(), next_src, atp_src, value_type, copy_type);
445 store(bs, &kit.gvn(), ctl, kit.merged_memory(), next_dest, atp_dest, v, value_type, copy_type);
446 }
447 kit.set_control(ctl);
448 }
449
450
451 void ArrayCopyNode::array_copy_forward(GraphKit& kit,
452 bool can_reshape,
453 const TypeAryPtr* atp_src,
454 const TypeAryPtr* atp_dest,
455 Node* adr_src,
456 Node* base_src,
457 Node* adr_dest,
458 Node* base_dest,
459 BasicType copy_type,
460 const Type* value_type,
461 int count) {
462 if (!kit.stopped()) {
463 // copy forward
464 if (count > 0) {
465 for (int i = 0; i < count; i++) {
466 copy(kit, atp_src, atp_dest, i, base_src, base_dest, adr_src, adr_dest, copy_type, value_type);
467 }
468 } else if (can_reshape) {
469 PhaseGVN& gvn = kit.gvn();
470 assert(gvn.is_IterGVN(), "");
471 gvn.record_for_igvn(adr_src);
472 gvn.record_for_igvn(adr_dest);
473 }
474 }
475 }
476
477 void ArrayCopyNode::array_copy_backward(GraphKit& kit,
478 bool can_reshape,
479 const TypeAryPtr* atp_src,
480 const TypeAryPtr* atp_dest,
481 Node* adr_src,
482 Node* base_src,
483 Node* adr_dest,
484 Node* base_dest,
485 BasicType copy_type,
486 const Type* value_type,
487 int count) {
488 if (!kit.stopped()) {
489 // copy backward
490 PhaseGVN& gvn = kit.gvn();
491
492 if (count > 0) {
493 for (int i = count-1; i >= 0; i--) {
494 copy(kit, atp_src, atp_dest, i, base_src, base_dest, adr_src, adr_dest, copy_type, value_type);
495 }
496 } else if(can_reshape) {
497 PhaseGVN& gvn = kit.gvn();
498 assert(gvn.is_IterGVN(), "");
499 gvn.record_for_igvn(adr_src);
500 gvn.record_for_igvn(adr_dest);
501 }
502 }
503 }
504
505 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
506 Node* ctl, Node *mem) {
507 if (can_reshape) {
508 PhaseIterGVN* igvn = phase->is_IterGVN();
509 igvn->set_delay_transform(false);
510 if (is_clonebasic()) {
511 Node* out_mem = proj_out(TypeFunc::Memory);
512
513 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
514 if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
515 out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
516 assert(bs->array_copy_requires_gc_barriers(true, T_OBJECT, true, is_clone_inst(), BarrierSetC2::Optimization), "can only happen with card marking");
517 return false;
518 }
519
520 igvn->replace_node(out_mem->raw_out(0), mem);
521
522 Node* out_ctl = proj_out(TypeFunc::Control);
523 igvn->replace_node(out_ctl, ctl);
524 } else {
525 // replace fallthrough projections of the ArrayCopyNode by the
526 // new memory, control and the input IO.
527 CallProjections* callprojs = extract_projections(true, false);
528
529 if (callprojs->fallthrough_ioproj != nullptr) {
530 igvn->replace_node(callprojs->fallthrough_ioproj, in(TypeFunc::I_O));
531 }
532 if (callprojs->fallthrough_memproj != nullptr) {
533 igvn->replace_node(callprojs->fallthrough_memproj, mem);
534 }
535 if (callprojs->fallthrough_catchproj != nullptr) {
536 igvn->replace_node(callprojs->fallthrough_catchproj, ctl);
537 }
538
539 // The ArrayCopyNode is not disconnected. It still has the
540 // projections for the exception case. Replace current
541 // ArrayCopyNode with a dummy new one with a top() control so
542 // that this part of the graph stays consistent but is
543 // eventually removed.
544
545 set_req(0, phase->C->top());
546 remove_dead_region(phase, can_reshape);
547 }
548 } else {
549 if (in(TypeFunc::Control) != ctl) {
550 // we can't return new memory and control from Ideal at parse time
551 assert(!is_clonebasic() || UseShenandoahGC, "added control for clone?");
552 phase->record_for_igvn(this);
553 return false;
554 }
555 }
556 return true;
557 }
558
559
560 Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) {
561 // Perform any generic optimizations first
562 Node* result = SafePointNode::Ideal(phase, can_reshape);
563 if (result != nullptr) {
564 return result;
565 }
566
567 if (StressArrayCopyMacroNode && !can_reshape) {
568 phase->record_for_igvn(this);
569 return nullptr;
570 }
571
572 // See if it's a small array copy and we can inline it as
573 // loads/stores
574 // Here we can only do:
575 // - arraycopy if all arguments were validated before and we don't
576 // need card marking
577 // - clone for which we don't need to do card marking
578
579 if (!is_clonebasic() && !is_arraycopy_validated() &&
580 !is_copyofrange_validated() && !is_copyof_validated()) {
581 return nullptr;
582 }
583
584 assert(in(TypeFunc::Control) != nullptr &&
585 in(TypeFunc::Memory) != nullptr &&
587 in(ArrayCopyNode::Dest) != nullptr &&
588 in(ArrayCopyNode::Length) != nullptr &&
589 in(ArrayCopyNode::SrcPos) != nullptr &&
590 in(ArrayCopyNode::DestPos) != nullptr, "broken inputs");
591
592 if (in(TypeFunc::Control)->is_top() ||
593 in(TypeFunc::Memory)->is_top() ||
594 phase->type(in(ArrayCopyNode::Src)) == Type::TOP ||
595 phase->type(in(ArrayCopyNode::Dest)) == Type::TOP ||
596 (in(ArrayCopyNode::SrcPos) != nullptr && in(ArrayCopyNode::SrcPos)->is_top()) ||
597 (in(ArrayCopyNode::DestPos) != nullptr && in(ArrayCopyNode::DestPos)->is_top())) {
598 return nullptr;
599 }
600
601 int count = get_count(phase);
602
603 if (count < 0 || count > ArrayCopyLoadStoreMaxElem) {
604 return nullptr;
605 }
606
607 Node* src = in(ArrayCopyNode::Src);
608 Node* dest = in(ArrayCopyNode::Dest);
609 const Type* src_type = phase->type(src);
610 const Type* dest_type = phase->type(dest);
611
612 if (src_type->isa_aryptr() && dest_type->isa_instptr()) {
613 // clone used for load of unknown inline type can't be optimized at
614 // this point
615 return nullptr;
616 }
617
618 Node* mem = try_clone_instance(phase, can_reshape, count);
619 if (mem != nullptr) {
620 return (mem == NodeSentinel) ? nullptr : mem;
621 }
622
623 Node* adr_src = nullptr;
624 Node* base_src = nullptr;
625 Node* adr_dest = nullptr;
626 Node* base_dest = nullptr;
627 BasicType copy_type = T_ILLEGAL;
628 const Type* value_type = nullptr;
629 bool disjoint_bases = false;
630
631 if (!prepare_array_copy(phase, can_reshape,
632 adr_src, base_src, adr_dest, base_dest,
633 copy_type, value_type, disjoint_bases)) {
634 assert(adr_src == nullptr, "no node can be left behind");
635 assert(adr_dest == nullptr, "no node can be left behind");
636 return nullptr;
637 }
638
639 JVMState* new_jvms = nullptr;
640 SafePointNode* new_map = nullptr;
641 if (!is_clonebasic()) {
642 new_jvms = jvms()->clone_shallow(phase->C);
643 new_map = new SafePointNode(req(), new_jvms);
644 for (uint i = TypeFunc::FramePtr; i < req(); i++) {
645 new_map->init_req(i, in(i));
646 }
647 new_jvms->set_map(new_map);
648 } else {
649 new_jvms = new (phase->C) JVMState(0);
650 new_map = new SafePointNode(TypeFunc::Parms, new_jvms);
651 new_jvms->set_map(new_map);
652 }
653 new_map->set_control(in(TypeFunc::Control));
654 new_map->set_memory(MergeMemNode::make(in(TypeFunc::Memory)));
655 new_map->set_i_o(in(TypeFunc::I_O));
656 phase->record_for_igvn(new_map);
657
658 const TypeAryPtr* atp_src = get_address_type(phase, _src_type, src);
659 const TypeAryPtr* atp_dest = get_address_type(phase, _dest_type, dest);
660
661 if (can_reshape) {
662 assert(!phase->is_IterGVN()->delay_transform(), "cannot delay transforms");
663 phase->is_IterGVN()->set_delay_transform(true);
664 }
665
666 GraphKit kit(new_jvms, phase);
667
668 SafePointNode* backward_map = nullptr;
669 SafePointNode* forward_map = nullptr;
670 Node* backward_ctl = phase->C->top();
671
672 array_copy_test_overlap(kit, disjoint_bases, count, backward_ctl);
673
674 {
675 PreserveJVMState pjvms(&kit);
676
677 array_copy_forward(kit, can_reshape,
678 atp_src, atp_dest,
679 adr_src, base_src, adr_dest, base_dest,
680 copy_type, value_type, count);
681
682 forward_map = kit.stop();
683 }
684
685 kit.set_control(backward_ctl);
686 array_copy_backward(kit, can_reshape,
687 atp_src, atp_dest,
688 adr_src, base_src, adr_dest, base_dest,
689 copy_type, value_type, count);
690
691 backward_map = kit.stop();
692
693 if (!forward_map->control()->is_top() && !backward_map->control()->is_top()) {
694 assert(forward_map->i_o() == backward_map->i_o(), "need a phi on IO?");
695 Node* ctl = new RegionNode(3);
696 Node* mem = new PhiNode(ctl, Type::MEMORY, TypePtr::BOTTOM);
697 kit.set_map(forward_map);
698 ctl->init_req(1, kit.control());
699 mem->init_req(1, kit.reset_memory());
700 kit.set_map(backward_map);
701 ctl->init_req(2, kit.control());
702 mem->init_req(2, kit.reset_memory());
703 kit.set_control(phase->transform(ctl));
704 kit.set_all_memory(phase->transform(mem));
705 } else if (!forward_map->control()->is_top()) {
706 kit.set_map(forward_map);
707 } else {
708 assert(!backward_map->control()->is_top(), "no copy?");
709 kit.set_map(backward_map);
710 }
711
712 if (can_reshape) {
713 assert(phase->is_IterGVN()->delay_transform(), "should be delaying transforms");
714 phase->is_IterGVN()->set_delay_transform(false);
715 }
716
717 mem = kit.map()->memory();
718 if (!finish_transform(phase, can_reshape, kit.control(), mem)) {
719 if (!can_reshape) {
720 phase->record_for_igvn(this);
721 } else {
722 // put in worklist, so that if it happens to be dead it is removed
723 phase->is_IterGVN()->_worklist.push(mem);
724 }
725 return nullptr;
726 }
727
728 return mem;
729 }
730
731 bool ArrayCopyNode::may_modify(const TypeOopPtr* t_oop, PhaseValues* phase) {
732 Node* dest = in(ArrayCopyNode::Dest);
733 if (dest->is_top()) {
734 return false;
735 }
736 const TypeOopPtr* dest_t = phase->type(dest)->is_oopptr();
737 assert(!dest_t->is_known_instance() || _dest_type->is_known_instance(), "result of EA not recorded");
738 assert(in(ArrayCopyNode::Src)->is_top() || !phase->type(in(ArrayCopyNode::Src))->is_oopptr()->is_known_instance() ||
739 _src_type->is_known_instance(), "result of EA not recorded");
740
741 if (_dest_type != TypeOopPtr::BOTTOM || t_oop->is_known_instance()) {
800 // write between offset_lo and offset_hi
801 bool ArrayCopyNode::modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseValues* phase, bool must_modify) const {
802 assert(_kind == ArrayCopy || _kind == CopyOf || _kind == CopyOfRange, "only for real array copies");
803
804 Node* dest = in(Dest);
805 Node* dest_pos = in(DestPos);
806 Node* len = in(Length);
807
808 const TypeInt *dest_pos_t = phase->type(dest_pos)->isa_int();
809 const TypeInt *len_t = phase->type(len)->isa_int();
810 const TypeAryPtr* ary_t = phase->type(dest)->isa_aryptr();
811
812 if (dest_pos_t == nullptr || len_t == nullptr || ary_t == nullptr) {
813 return !must_modify;
814 }
815
816 BasicType ary_elem = ary_t->isa_aryptr()->elem()->array_element_basic_type();
817 if (is_reference_type(ary_elem, true)) ary_elem = T_OBJECT;
818
819 uint header = arrayOopDesc::base_offset_in_bytes(ary_elem);
820 uint elemsize = ary_t->is_flat() ? ary_t->flat_elem_size() : type2aelembytes(ary_elem);
821
822 jlong dest_pos_plus_len_lo = (((jlong)dest_pos_t->_lo) + len_t->_lo) * elemsize + header;
823 jlong dest_pos_plus_len_hi = (((jlong)dest_pos_t->_hi) + len_t->_hi) * elemsize + header;
824 jlong dest_pos_lo = ((jlong)dest_pos_t->_lo) * elemsize + header;
825 jlong dest_pos_hi = ((jlong)dest_pos_t->_hi) * elemsize + header;
826
827 if (must_modify) {
828 if (offset_lo >= dest_pos_hi && offset_hi < dest_pos_plus_len_lo) {
829 return true;
830 }
831 } else {
832 if (offset_hi >= dest_pos_lo && offset_lo < dest_pos_plus_len_hi) {
833 return true;
834 }
835 }
836 return false;
837 }
838
839 // As an optimization, choose optimum vector size for copy length known at compile time.
840 int ArrayCopyNode::get_partial_inline_vector_lane_count(BasicType type, int const_len) {
|