< prev index next >

src/hotspot/share/opto/arraycopynode.cpp

Print this page

  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) {
< prev index next >