1 /* 2 * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 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 "ci/ciFlatArrayKlass.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 "opto/inlinetypenode.hpp" 33 #include "runtime/sharedRuntime.hpp" 34 #include "utilities/macros.hpp" 35 #include "utilities/powerOfTwo.hpp" 36 37 const TypeFunc* ArrayCopyNode::_arraycopy_type_Type = nullptr; 38 39 ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard) 40 : CallNode(arraycopy_type(), nullptr, TypePtr::BOTTOM), 41 _kind(None), 42 _alloc_tightly_coupled(alloc_tightly_coupled), 43 _has_negative_length_guard(has_negative_length_guard), 44 _arguments_validated(false), 45 _src_type(TypeOopPtr::BOTTOM), 46 _dest_type(TypeOopPtr::BOTTOM) { 47 init_class_id(Class_ArrayCopy); 48 init_flags(Flag_is_macro); 49 C->add_macro_node(this); 50 } 51 52 uint ArrayCopyNode::size_of() const { return sizeof(*this); } 53 54 ArrayCopyNode* ArrayCopyNode::make(GraphKit* kit, bool may_throw, 55 Node* src, Node* src_offset, 56 Node* dest, Node* dest_offset, 57 Node* length, 58 bool alloc_tightly_coupled, 59 bool has_negative_length_guard, 60 Node* src_klass, Node* dest_klass, 61 Node* src_length, Node* dest_length) { 62 63 ArrayCopyNode* ac = new ArrayCopyNode(kit->C, alloc_tightly_coupled, has_negative_length_guard); 64 kit->set_predefined_input_for_runtime_call(ac); 65 66 ac->init_req(ArrayCopyNode::Src, src); 67 ac->init_req(ArrayCopyNode::SrcPos, src_offset); 68 ac->init_req(ArrayCopyNode::Dest, dest); 69 ac->init_req(ArrayCopyNode::DestPos, dest_offset); 70 ac->init_req(ArrayCopyNode::Length, length); 71 ac->init_req(ArrayCopyNode::SrcLen, src_length); 72 ac->init_req(ArrayCopyNode::DestLen, dest_length); 73 ac->init_req(ArrayCopyNode::SrcKlass, src_klass); 74 ac->init_req(ArrayCopyNode::DestKlass, dest_klass); 75 76 if (may_throw) { 77 ac->set_req(TypeFunc::I_O , kit->i_o()); 78 kit->add_safepoint_edges(ac, false); 79 } 80 81 return ac; 82 } 83 84 void ArrayCopyNode::connect_outputs(GraphKit* kit, bool deoptimize_on_exception) { 85 kit->set_all_memory_call(this, true); 86 kit->set_control(kit->gvn().transform(new ProjNode(this,TypeFunc::Control))); 87 kit->set_i_o(kit->gvn().transform(new ProjNode(this, TypeFunc::I_O))); 88 kit->make_slow_call_ex(this, kit->env()->Throwable_klass(), true, deoptimize_on_exception); 89 kit->set_all_memory_call(this); 90 } 91 92 #ifndef PRODUCT 93 const char* ArrayCopyNode::_kind_names[] = {"arraycopy", "arraycopy, validated arguments", "clone", "oop array clone", "CopyOf", "CopyOfRange"}; 94 95 void ArrayCopyNode::dump_spec(outputStream *st) const { 96 CallNode::dump_spec(st); 97 st->print(" (%s%s)", _kind_names[_kind], _alloc_tightly_coupled ? ", tightly coupled allocation" : ""); 98 } 99 100 void ArrayCopyNode::dump_compact_spec(outputStream* st) const { 101 st->print("%s%s", _kind_names[_kind], _alloc_tightly_coupled ? ",tight" : ""); 102 } 103 #endif 104 105 intptr_t ArrayCopyNode::get_length_if_constant(PhaseGVN *phase) const { 106 // check that length is constant 107 Node* length = in(ArrayCopyNode::Length); 108 const Type* length_type = phase->type(length); 109 110 if (length_type == Type::TOP) { 111 return -1; 112 } 113 114 assert(is_clonebasic() || is_arraycopy() || is_copyof() || is_copyofrange(), "unexpected array copy type"); 115 116 return is_clonebasic() ? length->find_intptr_t_con(-1) : length->find_int_con(-1); 117 } 118 119 int ArrayCopyNode::get_count(PhaseGVN *phase) const { 120 if (is_clonebasic()) { 121 Node* src = in(ArrayCopyNode::Src); 122 const Type* src_type = phase->type(src); 123 124 if (src_type == Type::TOP) { 125 return -1; 126 } 127 128 if (src_type->isa_instptr()) { 129 const TypeInstPtr* inst_src = src_type->is_instptr(); 130 ciInstanceKlass* ik = inst_src->instance_klass(); 131 // ciInstanceKlass::nof_nonstatic_fields() doesn't take injected 132 // fields into account. They are rare anyway so easier to simply 133 // skip instances with injected fields. 134 if ((!inst_src->klass_is_exact() && (ik->is_interface() || ik->has_subklass())) || ik->has_injected_fields()) { 135 return -1; 136 } 137 int nb_fields = ik->nof_nonstatic_fields(); 138 return nb_fields; 139 } else { 140 const TypeAryPtr* ary_src = src_type->isa_aryptr(); 141 assert (ary_src != nullptr, "not an array or instance?"); 142 // clone passes a length as a rounded number of longs. If we're 143 // cloning an array we'll do it element by element. If the 144 // length of the input array is constant, ArrayCopyNode::Length 145 // must be too. Note that the opposite does not need to hold, 146 // because different input array lengths (e.g. int arrays with 147 // 3 or 4 elements) might lead to the same length input 148 // (e.g. 2 double-words). 149 assert(!ary_src->size()->is_con() || (get_length_if_constant(phase) >= 0) || 150 (UseArrayFlattening && ary_src->elem()->make_oopptr() != nullptr && ary_src->elem()->make_oopptr()->can_be_inline_type()) || 151 phase->is_IterGVN() || phase->C->inlining_incrementally() || StressReflectiveCode, "inconsistent"); 152 if (ary_src->size()->is_con()) { 153 return ary_src->size()->get_con(); 154 } 155 return -1; 156 } 157 } 158 159 return get_length_if_constant(phase); 160 } 161 162 Node* ArrayCopyNode::load(BarrierSetC2* bs, PhaseGVN *phase, Node*& ctl, MergeMemNode* mem, Node* adr, const TypePtr* adr_type, const Type *type, BasicType bt) { 163 // Pin the load: if this is an array load, it's going to be dependent on a condition that's not a range check for that 164 // access. If that condition is replaced by an identical dominating one, then an unpinned load would risk floating 165 // above runtime checks that guarantee it is within bounds. 166 DecoratorSet decorators = C2_READ_ACCESS | C2_CONTROL_DEPENDENT_LOAD | IN_HEAP | C2_ARRAY_COPY | C2_UNKNOWN_CONTROL_LOAD; 167 C2AccessValuePtr addr(adr, adr_type); 168 C2OptAccess access(*phase, ctl, mem, decorators, bt, adr->in(AddPNode::Base), addr); 169 Node* res = bs->load_at(access, type); 170 ctl = access.ctl(); 171 return res; 172 } 173 174 void ArrayCopyNode::store(BarrierSetC2* bs, PhaseGVN *phase, Node*& ctl, MergeMemNode* mem, Node* adr, const TypePtr* adr_type, Node* val, const Type *type, BasicType bt) { 175 DecoratorSet decorators = C2_WRITE_ACCESS | IN_HEAP | C2_ARRAY_COPY; 176 if (is_alloc_tightly_coupled()) { 177 decorators |= C2_TIGHTLY_COUPLED_ALLOC; 178 } 179 C2AccessValuePtr addr(adr, adr_type); 180 C2AccessValue value(val, type); 181 C2OptAccess access(*phase, ctl, mem, decorators, bt, adr->in(AddPNode::Base), addr); 182 bs->store_at(access, value); 183 ctl = access.ctl(); 184 } 185 186 187 Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int count) { 188 if (!is_clonebasic()) { 189 return nullptr; 190 } 191 192 Node* base_src = in(ArrayCopyNode::Src); 193 Node* base_dest = in(ArrayCopyNode::Dest); 194 Node* ctl = in(TypeFunc::Control); 195 Node* in_mem = in(TypeFunc::Memory); 196 197 const Type* src_type = phase->type(base_src); 198 const TypeInstPtr* inst_src = src_type->isa_instptr(); 199 if (inst_src == nullptr) { 200 return nullptr; 201 } 202 203 MergeMemNode* mem = phase->transform(MergeMemNode::make(in_mem))->as_MergeMem(); 204 phase->record_for_igvn(mem); 205 if (can_reshape) { 206 phase->is_IterGVN()->_worklist.push(mem); 207 } 208 209 210 ciInstanceKlass* ik = inst_src->instance_klass(); 211 212 if (!inst_src->klass_is_exact()) { 213 assert(!ik->is_interface(), "inconsistent klass hierarchy"); 214 if (ik->has_subklass()) { 215 // Concurrent class loading. 216 // Fail fast and return NodeSentinel to indicate that the transform failed. 217 return NodeSentinel; 218 } else { 219 phase->C->dependencies()->assert_leaf_type(ik); 220 } 221 } 222 223 assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields"); 224 225 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 226 for (int i = 0; i < count; i++) { 227 ciField* field = ik->nonstatic_field_at(i); 228 const TypePtr* adr_type = phase->C->alias_type(field)->adr_type(); 229 Node* off = phase->MakeConX(field->offset_in_bytes()); 230 Node* next_src = phase->transform(new AddPNode(base_src,base_src,off)); 231 Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off)); 232 assert(phase->C->get_alias_index(adr_type) == phase->C->get_alias_index(phase->type(next_src)->isa_ptr()), 233 "slice of address and input slice don't match"); 234 assert(phase->C->get_alias_index(adr_type) == phase->C->get_alias_index(phase->type(next_dest)->isa_ptr()), 235 "slice of address and input slice don't match"); 236 BasicType bt = field->layout_type(); 237 238 const Type *type; 239 if (bt == T_OBJECT) { 240 if (!field->type()->is_loaded()) { 241 type = TypeInstPtr::BOTTOM; 242 } else { 243 ciType* field_klass = field->type(); 244 type = TypeOopPtr::make_from_klass(field_klass->as_klass()); 245 } 246 } else { 247 type = Type::get_const_basic_type(bt); 248 } 249 250 Node* v = load(bs, phase, ctl, mem, next_src, adr_type, type, bt); 251 store(bs, phase, ctl, mem, next_dest, adr_type, v, type, bt); 252 } 253 254 if (!finish_transform(phase, can_reshape, ctl, mem)) { 255 // Return NodeSentinel to indicate that the transform failed 256 return NodeSentinel; 257 } 258 259 return mem; 260 } 261 262 bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape, 263 Node*& adr_src, 264 Node*& base_src, 265 Node*& adr_dest, 266 Node*& base_dest, 267 BasicType& copy_type, 268 const Type*& value_type, 269 bool& disjoint_bases) { 270 base_src = in(ArrayCopyNode::Src); 271 base_dest = in(ArrayCopyNode::Dest); 272 const Type* src_type = phase->type(base_src); 273 const TypeAryPtr* ary_src = src_type->isa_aryptr(); 274 275 Node* src_offset = in(ArrayCopyNode::SrcPos); 276 Node* dest_offset = in(ArrayCopyNode::DestPos); 277 278 if (is_arraycopy() || is_copyofrange() || is_copyof()) { 279 const Type* dest_type = phase->type(base_dest); 280 const TypeAryPtr* ary_dest = dest_type->isa_aryptr(); 281 282 // newly allocated object is guaranteed to not overlap with source object 283 disjoint_bases = is_alloc_tightly_coupled(); 284 if (ary_src == nullptr || ary_src->elem() == Type::BOTTOM || 285 ary_dest == nullptr || ary_dest->elem() == Type::BOTTOM) { 286 // We don't know if arguments are arrays 287 return false; 288 } 289 290 BasicType src_elem = ary_src->elem()->array_element_basic_type(); 291 BasicType dest_elem = ary_dest->elem()->array_element_basic_type(); 292 if (is_reference_type(src_elem, true)) src_elem = T_OBJECT; 293 if (is_reference_type(dest_elem, true)) dest_elem = T_OBJECT; 294 295 // TODO 8350865 What about atomicity? 296 if (src_elem != dest_elem || ary_src->is_null_free() != ary_dest->is_null_free() || ary_src->is_flat() != ary_dest->is_flat() || dest_elem == T_VOID) { 297 // We don't know if arguments are arrays of the same type 298 return false; 299 } 300 301 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 302 if ((!ary_dest->is_flat() && bs->array_copy_requires_gc_barriers(is_alloc_tightly_coupled(), dest_elem, false, false, BarrierSetC2::Optimization)) || 303 (ary_dest->is_flat() && ary_src->elem()->inline_klass()->contains_oops() && 304 bs->array_copy_requires_gc_barriers(is_alloc_tightly_coupled(), T_OBJECT, false, false, BarrierSetC2::Optimization))) { 305 // It's an object array copy but we can't emit the card marking that is needed 306 return false; 307 } 308 309 value_type = ary_src->elem(); 310 311 uint shift = exact_log2(type2aelembytes(dest_elem)); 312 if (ary_dest->is_flat()) { 313 shift = ary_src->flat_log_elem_size(); 314 } 315 uint header = arrayOopDesc::base_offset_in_bytes(dest_elem); 316 317 src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size()); 318 if (src_offset->is_top()) { 319 // Offset is out of bounds (the ArrayCopyNode will be removed) 320 return false; 321 } 322 dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size()); 323 if (dest_offset->is_top()) { 324 // Offset is out of bounds (the ArrayCopyNode will be removed) 325 if (can_reshape) { 326 // record src_offset, so it can be deleted later (if it is dead) 327 phase->is_IterGVN()->_worklist.push(src_offset); 328 } 329 return false; 330 } 331 332 Node* hook = new Node(1); 333 hook->init_req(0, dest_offset); 334 335 Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift))); 336 337 hook->destruct(phase); 338 339 Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift))); 340 341 adr_src = phase->transform(new AddPNode(base_src, base_src, src_scale)); 342 adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_scale)); 343 344 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(header))); 345 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(header))); 346 347 copy_type = dest_elem; 348 } else { 349 assert(ary_src != nullptr, "should be a clone"); 350 assert(is_clonebasic(), "should be"); 351 352 disjoint_bases = true; 353 354 if (ary_src->elem()->make_oopptr() != nullptr && 355 ary_src->elem()->make_oopptr()->can_be_inline_type()) { 356 return false; 357 } 358 359 BasicType elem = ary_src->isa_aryptr()->elem()->array_element_basic_type(); 360 if (is_reference_type(elem, true)) { 361 elem = T_OBJECT; 362 } 363 364 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 365 if ((!ary_src->is_flat() && bs->array_copy_requires_gc_barriers(true, elem, true, is_clone_inst(), BarrierSetC2::Optimization)) || 366 (ary_src->is_flat() && ary_src->elem()->inline_klass()->contains_oops() && 367 bs->array_copy_requires_gc_barriers(true, T_OBJECT, true, is_clone_inst(), BarrierSetC2::Optimization))) { 368 // It's an object array copy but we can't emit the card marking that is needed 369 return false; 370 } 371 372 adr_src = phase->transform(new AddPNode(base_src, base_src, src_offset)); 373 adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_offset)); 374 375 // The address is offsetted to an aligned address where a raw copy would start. 376 // If the clone copy is decomposed into load-stores - the address is adjusted to 377 // point at where the array starts. 378 const Type* toff = phase->type(src_offset); 379 int offset = toff->isa_long() ? (int) toff->is_long()->get_con() : (int) toff->is_int()->get_con(); 380 int diff = arrayOopDesc::base_offset_in_bytes(elem) - offset; 381 assert(diff >= 0, "clone should not start after 1st array element"); 382 if (diff > 0) { 383 adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(diff))); 384 adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(diff))); 385 } 386 copy_type = elem; 387 value_type = ary_src->elem(); 388 } 389 return true; 390 } 391 392 const TypeAryPtr* ArrayCopyNode::get_address_type(PhaseGVN* phase, const TypePtr* atp, Node* n) { 393 if (atp == TypeOopPtr::BOTTOM) { 394 atp = phase->type(n)->isa_ptr(); 395 } 396 // adjust atp to be the correct array element address type 397 return atp->add_offset(Type::OffsetBot)->is_aryptr(); 398 } 399 400 void ArrayCopyNode::array_copy_test_overlap(GraphKit& kit, bool disjoint_bases, int count, Node*& backward_ctl) { 401 Node* ctl = kit.control(); 402 if (!disjoint_bases && count > 1) { 403 PhaseGVN& gvn = kit.gvn(); 404 Node* src_offset = in(ArrayCopyNode::SrcPos); 405 Node* dest_offset = in(ArrayCopyNode::DestPos); 406 assert(src_offset != nullptr && dest_offset != nullptr, "should be"); 407 Node* cmp = gvn.transform(new CmpINode(src_offset, dest_offset)); 408 Node *bol = gvn.transform(new BoolNode(cmp, BoolTest::lt)); 409 IfNode *iff = new IfNode(ctl, bol, PROB_FAIR, COUNT_UNKNOWN); 410 411 gvn.transform(iff); 412 413 kit.set_control(gvn.transform(new IfFalseNode(iff))); 414 backward_ctl = gvn.transform(new IfTrueNode(iff)); 415 } 416 } 417 418 void ArrayCopyNode::copy(GraphKit& kit, 419 const TypeAryPtr* atp_src, 420 const TypeAryPtr* atp_dest, 421 int i, 422 Node* base_src, 423 Node* base_dest, 424 Node* adr_src, 425 Node* adr_dest, 426 BasicType copy_type, 427 const Type* value_type) { 428 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 429 Node* ctl = kit.control(); 430 if (atp_dest->is_flat()) { 431 ciInlineKlass* vk = atp_src->elem()->inline_klass(); 432 for (int j = 0; j < vk->nof_nonstatic_fields(); j++) { 433 ciField* field = vk->nonstatic_field_at(j); 434 int off_in_vt = field->offset_in_bytes() - vk->payload_offset(); 435 Node* off = kit.MakeConX(off_in_vt + i * atp_src->flat_elem_size()); 436 ciType* ft = field->type(); 437 BasicType bt = type2field[ft->basic_type()]; 438 assert(!field->is_flat(), "flat field encountered"); 439 const Type* rt = Type::get_const_type(ft); 440 const TypePtr* adr_type = atp_src->with_field_offset(off_in_vt)->add_offset(Type::OffsetBot); 441 assert(!bs->array_copy_requires_gc_barriers(is_alloc_tightly_coupled(), bt, false, false, BarrierSetC2::Optimization), "GC barriers required"); 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, adr_type, rt, bt); 445 store(bs, &kit.gvn(), ctl, kit.merged_memory(), next_dest, adr_type, v, rt, bt); 446 } 447 } else { 448 Node* off = kit.MakeConX(type2aelembytes(copy_type) * i); 449 Node* next_src = kit.gvn().transform(new AddPNode(base_src, adr_src, off)); 450 Node* next_dest = kit.gvn().transform(new AddPNode(base_dest, adr_dest, off)); 451 Node* v = load(bs, &kit.gvn(), ctl, kit.merged_memory(), next_src, atp_src, value_type, copy_type); 452 store(bs, &kit.gvn(), ctl, kit.merged_memory(), next_dest, atp_dest, v, value_type, copy_type); 453 } 454 kit.set_control(ctl); 455 } 456 457 458 void ArrayCopyNode::array_copy_forward(GraphKit& kit, 459 bool can_reshape, 460 const TypeAryPtr* atp_src, 461 const TypeAryPtr* atp_dest, 462 Node* adr_src, 463 Node* base_src, 464 Node* adr_dest, 465 Node* base_dest, 466 BasicType copy_type, 467 const Type* value_type, 468 int count) { 469 if (!kit.stopped()) { 470 // copy forward 471 if (count > 0) { 472 for (int i = 0; i < count; i++) { 473 copy(kit, atp_src, atp_dest, i, base_src, base_dest, adr_src, adr_dest, copy_type, value_type); 474 } 475 } else if (can_reshape) { 476 PhaseGVN& gvn = kit.gvn(); 477 assert(gvn.is_IterGVN(), ""); 478 gvn.record_for_igvn(adr_src); 479 gvn.record_for_igvn(adr_dest); 480 } 481 } 482 } 483 484 void ArrayCopyNode::array_copy_backward(GraphKit& kit, 485 bool can_reshape, 486 const TypeAryPtr* atp_src, 487 const TypeAryPtr* atp_dest, 488 Node* adr_src, 489 Node* base_src, 490 Node* adr_dest, 491 Node* base_dest, 492 BasicType copy_type, 493 const Type* value_type, 494 int count) { 495 if (!kit.stopped()) { 496 // copy backward 497 PhaseGVN& gvn = kit.gvn(); 498 499 if (count > 0) { 500 for (int i = count-1; i >= 0; i--) { 501 copy(kit, atp_src, atp_dest, i, base_src, base_dest, adr_src, adr_dest, copy_type, value_type); 502 } 503 } else if(can_reshape) { 504 PhaseGVN& gvn = kit.gvn(); 505 assert(gvn.is_IterGVN(), ""); 506 gvn.record_for_igvn(adr_src); 507 gvn.record_for_igvn(adr_dest); 508 } 509 } 510 } 511 512 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape, 513 Node* ctl, Node *mem) { 514 if (can_reshape) { 515 PhaseIterGVN* igvn = phase->is_IterGVN(); 516 igvn->set_delay_transform(false); 517 if (is_clonebasic()) { 518 Node* out_mem = proj_out(TypeFunc::Memory); 519 520 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 521 if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() || 522 out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) { 523 assert(bs->array_copy_requires_gc_barriers(true, T_OBJECT, true, is_clone_inst(), BarrierSetC2::Optimization), "can only happen with card marking"); 524 return false; 525 } 526 527 igvn->replace_node(out_mem->raw_out(0), mem); 528 529 Node* out_ctl = proj_out(TypeFunc::Control); 530 igvn->replace_node(out_ctl, ctl); 531 } else { 532 // replace fallthrough projections of the ArrayCopyNode by the 533 // new memory, control and the input IO. 534 CallProjections* callprojs = extract_projections(true, false); 535 536 if (callprojs->fallthrough_ioproj != nullptr) { 537 igvn->replace_node(callprojs->fallthrough_ioproj, in(TypeFunc::I_O)); 538 } 539 if (callprojs->fallthrough_memproj != nullptr) { 540 igvn->replace_node(callprojs->fallthrough_memproj, mem); 541 } 542 if (callprojs->fallthrough_catchproj != nullptr) { 543 igvn->replace_node(callprojs->fallthrough_catchproj, ctl); 544 } 545 546 // The ArrayCopyNode is not disconnected. It still has the 547 // projections for the exception case. Replace current 548 // ArrayCopyNode with a dummy new one with a top() control so 549 // that this part of the graph stays consistent but is 550 // eventually removed. 551 552 set_req(0, phase->C->top()); 553 remove_dead_region(phase, can_reshape); 554 } 555 } else { 556 if (in(TypeFunc::Control) != ctl) { 557 // we can't return new memory and control from Ideal at parse time 558 assert(!is_clonebasic() || UseShenandoahGC, "added control for clone?"); 559 phase->record_for_igvn(this); 560 return false; 561 } 562 } 563 return true; 564 } 565 566 567 Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) { 568 // Perform any generic optimizations first 569 Node* result = SafePointNode::Ideal(phase, can_reshape); 570 if (result != nullptr) { 571 return result; 572 } 573 574 if (StressArrayCopyMacroNode && !can_reshape) { 575 phase->record_for_igvn(this); 576 return nullptr; 577 } 578 579 // See if it's a small array copy and we can inline it as 580 // loads/stores 581 // Here we can only do: 582 // - arraycopy if all arguments were validated before and we don't 583 // need card marking 584 // - clone for which we don't need to do card marking 585 586 if (!is_clonebasic() && !is_arraycopy_validated() && 587 !is_copyofrange_validated() && !is_copyof_validated()) { 588 return nullptr; 589 } 590 591 assert(in(TypeFunc::Control) != nullptr && 592 in(TypeFunc::Memory) != nullptr && 593 in(ArrayCopyNode::Src) != nullptr && 594 in(ArrayCopyNode::Dest) != nullptr && 595 in(ArrayCopyNode::Length) != nullptr && 596 in(ArrayCopyNode::SrcPos) != nullptr && 597 in(ArrayCopyNode::DestPos) != nullptr, "broken inputs"); 598 599 if (in(TypeFunc::Control)->is_top() || 600 in(TypeFunc::Memory)->is_top() || 601 phase->type(in(ArrayCopyNode::Src)) == Type::TOP || 602 phase->type(in(ArrayCopyNode::Dest)) == Type::TOP || 603 (in(ArrayCopyNode::SrcPos) != nullptr && in(ArrayCopyNode::SrcPos)->is_top()) || 604 (in(ArrayCopyNode::DestPos) != nullptr && in(ArrayCopyNode::DestPos)->is_top())) { 605 return nullptr; 606 } 607 608 int count = get_count(phase); 609 610 if (count < 0 || count > ArrayCopyLoadStoreMaxElem) { 611 return nullptr; 612 } 613 614 Node* src = in(ArrayCopyNode::Src); 615 Node* dest = in(ArrayCopyNode::Dest); 616 const Type* src_type = phase->type(src); 617 const Type* dest_type = phase->type(dest); 618 619 if (src_type->isa_aryptr() && dest_type->isa_instptr()) { 620 // clone used for load of unknown inline type can't be optimized at 621 // this point 622 return nullptr; 623 } 624 625 Node* mem = try_clone_instance(phase, can_reshape, count); 626 if (mem != nullptr) { 627 return (mem == NodeSentinel) ? nullptr : mem; 628 } 629 630 Node* adr_src = nullptr; 631 Node* base_src = nullptr; 632 Node* adr_dest = nullptr; 633 Node* base_dest = nullptr; 634 BasicType copy_type = T_ILLEGAL; 635 const Type* value_type = nullptr; 636 bool disjoint_bases = false; 637 638 if (!prepare_array_copy(phase, can_reshape, 639 adr_src, base_src, adr_dest, base_dest, 640 copy_type, value_type, disjoint_bases)) { 641 assert(adr_src == nullptr, "no node can be left behind"); 642 assert(adr_dest == nullptr, "no node can be left behind"); 643 return nullptr; 644 } 645 646 JVMState* new_jvms = nullptr; 647 SafePointNode* new_map = nullptr; 648 if (!is_clonebasic()) { 649 new_jvms = jvms()->clone_shallow(phase->C); 650 new_map = new SafePointNode(req(), new_jvms); 651 for (uint i = TypeFunc::FramePtr; i < req(); i++) { 652 new_map->init_req(i, in(i)); 653 } 654 new_jvms->set_map(new_map); 655 } else { 656 new_jvms = new (phase->C) JVMState(0); 657 new_map = new SafePointNode(TypeFunc::Parms, new_jvms); 658 new_jvms->set_map(new_map); 659 } 660 new_map->set_control(in(TypeFunc::Control)); 661 new_map->set_memory(MergeMemNode::make(in(TypeFunc::Memory))); 662 new_map->set_i_o(in(TypeFunc::I_O)); 663 phase->record_for_igvn(new_map); 664 665 const TypeAryPtr* atp_src = get_address_type(phase, _src_type, src); 666 const TypeAryPtr* atp_dest = get_address_type(phase, _dest_type, dest); 667 668 if (can_reshape) { 669 assert(!phase->is_IterGVN()->delay_transform(), "cannot delay transforms"); 670 phase->is_IterGVN()->set_delay_transform(true); 671 } 672 673 GraphKit kit(new_jvms, phase); 674 675 SafePointNode* backward_map = nullptr; 676 SafePointNode* forward_map = nullptr; 677 Node* backward_ctl = phase->C->top(); 678 679 array_copy_test_overlap(kit, disjoint_bases, count, backward_ctl); 680 681 { 682 PreserveJVMState pjvms(&kit); 683 684 array_copy_forward(kit, can_reshape, 685 atp_src, atp_dest, 686 adr_src, base_src, adr_dest, base_dest, 687 copy_type, value_type, count); 688 689 forward_map = kit.stop(); 690 } 691 692 kit.set_control(backward_ctl); 693 array_copy_backward(kit, can_reshape, 694 atp_src, atp_dest, 695 adr_src, base_src, adr_dest, base_dest, 696 copy_type, value_type, count); 697 698 backward_map = kit.stop(); 699 700 if (!forward_map->control()->is_top() && !backward_map->control()->is_top()) { 701 assert(forward_map->i_o() == backward_map->i_o(), "need a phi on IO?"); 702 Node* ctl = new RegionNode(3); 703 Node* mem = new PhiNode(ctl, Type::MEMORY, TypePtr::BOTTOM); 704 kit.set_map(forward_map); 705 ctl->init_req(1, kit.control()); 706 mem->init_req(1, kit.reset_memory()); 707 kit.set_map(backward_map); 708 ctl->init_req(2, kit.control()); 709 mem->init_req(2, kit.reset_memory()); 710 kit.set_control(phase->transform(ctl)); 711 kit.set_all_memory(phase->transform(mem)); 712 } else if (!forward_map->control()->is_top()) { 713 kit.set_map(forward_map); 714 } else { 715 assert(!backward_map->control()->is_top(), "no copy?"); 716 kit.set_map(backward_map); 717 } 718 719 if (can_reshape) { 720 assert(phase->is_IterGVN()->delay_transform(), "should be delaying transforms"); 721 phase->is_IterGVN()->set_delay_transform(false); 722 } 723 724 mem = kit.map()->memory(); 725 if (!finish_transform(phase, can_reshape, kit.control(), mem)) { 726 if (!can_reshape) { 727 phase->record_for_igvn(this); 728 } else { 729 // put in worklist, so that if it happens to be dead it is removed 730 phase->is_IterGVN()->_worklist.push(mem); 731 } 732 return nullptr; 733 } 734 735 return mem; 736 } 737 738 bool ArrayCopyNode::may_modify(const TypeOopPtr* t_oop, PhaseValues* phase) { 739 Node* dest = in(ArrayCopyNode::Dest); 740 if (dest->is_top()) { 741 return false; 742 } 743 const TypeOopPtr* dest_t = phase->type(dest)->is_oopptr(); 744 assert(!dest_t->is_known_instance() || _dest_type->is_known_instance(), "result of EA not recorded"); 745 assert(in(ArrayCopyNode::Src)->is_top() || !phase->type(in(ArrayCopyNode::Src))->is_oopptr()->is_known_instance() || 746 _src_type->is_known_instance(), "result of EA not recorded"); 747 748 if (_dest_type != TypeOopPtr::BOTTOM || t_oop->is_known_instance()) { 749 assert(_dest_type == TypeOopPtr::BOTTOM || _dest_type->is_known_instance(), "result of EA is known instance"); 750 return t_oop->instance_id() == _dest_type->instance_id(); 751 } 752 753 return CallNode::may_modify_arraycopy_helper(dest_t, t_oop, phase); 754 } 755 756 bool ArrayCopyNode::may_modify_helper(const TypeOopPtr* t_oop, Node* n, PhaseValues* phase, CallNode*& call) { 757 if (n != nullptr && 758 n->is_Call() && 759 n->as_Call()->may_modify(t_oop, phase) && 760 (n->as_Call()->is_ArrayCopy() || n->as_Call()->is_call_to_arraycopystub())) { 761 call = n->as_Call(); 762 return true; 763 } 764 return false; 765 } 766 767 bool ArrayCopyNode::may_modify(const TypeOopPtr* t_oop, MemBarNode* mb, PhaseValues* phase, ArrayCopyNode*& ac) { 768 Node* c = mb->in(0); 769 770 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 771 // step over g1 gc barrier if we're at e.g. a clone with ReduceInitialCardMarks off 772 c = bs->step_over_gc_barrier(c); 773 774 CallNode* call = nullptr; 775 guarantee(c != nullptr, "step_over_gc_barrier failed, there must be something to step to."); 776 if (c->is_Region()) { 777 for (uint i = 1; i < c->req(); i++) { 778 if (c->in(i) != nullptr) { 779 Node* n = c->in(i)->in(0); 780 if (may_modify_helper(t_oop, n, phase, call)) { 781 ac = call->isa_ArrayCopy(); 782 assert(c == mb->in(0), "only for clone"); 783 return true; 784 } 785 } 786 } 787 } else if (may_modify_helper(t_oop, c->in(0), phase, call)) { 788 ac = call->isa_ArrayCopy(); 789 #ifdef ASSERT 790 bool use_ReduceInitialCardMarks = BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 791 static_cast<CardTableBarrierSetC2*>(bs)->use_ReduceInitialCardMarks(); 792 assert(c == mb->in(0) || (ac != nullptr && ac->is_clonebasic() && !use_ReduceInitialCardMarks), "only for clone"); 793 #endif 794 return true; 795 } else if (mb->trailing_partial_array_copy()) { 796 return true; 797 } 798 799 return false; 800 } 801 802 // Does this array copy modify offsets between offset_lo and offset_hi 803 // in the destination array 804 // if must_modify is false, return true if the copy could write 805 // between offset_lo and offset_hi 806 // if must_modify is true, return true if the copy is guaranteed to 807 // write between offset_lo and offset_hi 808 bool ArrayCopyNode::modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseValues* phase, bool must_modify) const { 809 assert(_kind == ArrayCopy || _kind == CopyOf || _kind == CopyOfRange, "only for real array copies"); 810 811 Node* dest = in(Dest); 812 Node* dest_pos = in(DestPos); 813 Node* len = in(Length); 814 815 const TypeInt *dest_pos_t = phase->type(dest_pos)->isa_int(); 816 const TypeInt *len_t = phase->type(len)->isa_int(); 817 const TypeAryPtr* ary_t = phase->type(dest)->isa_aryptr(); 818 819 if (dest_pos_t == nullptr || len_t == nullptr || ary_t == nullptr) { 820 return !must_modify; 821 } 822 823 BasicType ary_elem = ary_t->isa_aryptr()->elem()->array_element_basic_type(); 824 if (is_reference_type(ary_elem, true)) ary_elem = T_OBJECT; 825 826 uint header = arrayOopDesc::base_offset_in_bytes(ary_elem); 827 uint elemsize = ary_t->is_flat() ? ary_t->flat_elem_size() : type2aelembytes(ary_elem); 828 829 jlong dest_pos_plus_len_lo = (((jlong)dest_pos_t->_lo) + len_t->_lo) * elemsize + header; 830 jlong dest_pos_plus_len_hi = (((jlong)dest_pos_t->_hi) + len_t->_hi) * elemsize + header; 831 jlong dest_pos_lo = ((jlong)dest_pos_t->_lo) * elemsize + header; 832 jlong dest_pos_hi = ((jlong)dest_pos_t->_hi) * elemsize + header; 833 834 if (must_modify) { 835 if (offset_lo >= dest_pos_hi && offset_hi < dest_pos_plus_len_lo) { 836 return true; 837 } 838 } else { 839 if (offset_hi >= dest_pos_lo && offset_lo < dest_pos_plus_len_hi) { 840 return true; 841 } 842 } 843 return false; 844 } 845 846 // As an optimization, choose optimum vector size for copy length known at compile time. 847 int ArrayCopyNode::get_partial_inline_vector_lane_count(BasicType type, int const_len) { 848 int lane_count = ArrayOperationPartialInlineSize/type2aelembytes(type); 849 if (const_len > 0) { 850 int size_in_bytes = const_len * type2aelembytes(type); 851 if (size_in_bytes <= 16) 852 lane_count = 16/type2aelembytes(type); 853 else if (size_in_bytes > 16 && size_in_bytes <= 32) 854 lane_count = 32/type2aelembytes(type); 855 } 856 return lane_count; 857 }