diff --git a/src/hotspot/share/opto/arraycopynode.cpp b/src/hotspot/share/opto/arraycopynode.cpp index 11560f6419b..b0f30703f91 100644 --- a/src/hotspot/share/opto/arraycopynode.cpp +++ b/src/hotspot/share/opto/arraycopynode.cpp @@ -189,9 +189,8 @@ Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int c } MergeMemNode* mem = phase->transform(MergeMemNode::make(in_mem))->as_MergeMem(); - PhaseIterGVN* igvn = phase->is_IterGVN(); - if (igvn != NULL) { - igvn->_worklist.push(mem); + if (can_reshape) { + phase->is_IterGVN()->_worklist.push(mem); } if (!inst_src->klass_is_exact()) { @@ -294,9 +293,17 @@ bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape, uint header = arrayOopDesc::base_offset_in_bytes(dest_elem); src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size()); + if (src_offset->is_top()) { + // Offset is out of bounds (the ArrayCopyNode will be removed) + return false; + } dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size()); - if (src_offset->is_top() || dest_offset->is_top()) { + if (dest_offset->is_top()) { // Offset is out of bounds (the ArrayCopyNode will be removed) + if (can_reshape) { + // record src_offset, so it can be deleted later (if it is dead) + phase->is_IterGVN()->_worklist.push(src_offset); + } return false; } @@ -316,9 +323,6 @@ bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape, disjoint_bases = true; - adr_src = phase->transform(new AddPNode(base_src, base_src, src_offset)); - adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_offset)); - BasicType elem = ary_src->klass()->as_array_klass()->element_type()->basic_type(); if (is_reference_type(elem)) { elem = T_OBJECT; @@ -329,6 +333,9 @@ bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape, return false; } + adr_src = phase->transform(new AddPNode(base_src, base_src, src_offset)); + adr_dest = phase->transform(new AddPNode(base_dest, base_dest, dest_offset)); + // The address is offseted to an aligned address where a raw copy would start. // If the clone copy is decomposed into load-stores - the address is adjusted to // point at where the array starts. @@ -566,6 +573,8 @@ Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (!prepare_array_copy(phase, can_reshape, adr_src, base_src, adr_dest, base_dest, copy_type, value_type, disjoint_bases)) { + assert(adr_src == NULL, "no node can be left behind"); + assert(adr_dest == NULL, "no node can be left behind"); return NULL; } @@ -629,6 +638,10 @@ Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) { } if (!finish_transform(phase, can_reshape, ctl, mem)) { + if (can_reshape) { + // put in worklist, so that if it happens to be dead it is removed + phase->is_IterGVN()->_worklist.push(mem); + } return NULL; } diff --git a/src/hotspot/share/opto/subtypenode.cpp b/src/hotspot/share/opto/subtypenode.cpp index 508d62fd04c..7aed5e65ef3 100644 --- a/src/hotspot/share/opto/subtypenode.cpp +++ b/src/hotspot/share/opto/subtypenode.cpp @@ -135,7 +135,7 @@ Node *SubTypeCheckNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* obj = AddPNode::Ideal_base_and_offset(addr, phase, con); if (con == oopDesc::klass_offset_in_bytes() && obj != NULL) { assert(is_oop(phase, obj), "only for oop input"); - set_req(ObjOrSubKlass, obj); + set_req_X(ObjOrSubKlass, obj, phase); return this; } } @@ -144,7 +144,7 @@ Node *SubTypeCheckNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* allocated_klass = AllocateNode::Ideal_klass(obj_or_subklass, phase); if (allocated_klass != NULL) { assert(is_oop(phase, obj_or_subklass), "only for oop input"); - set_req(ObjOrSubKlass, allocated_klass); + set_req_X(ObjOrSubKlass, allocated_klass, phase); return this; } diff --git a/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyAsLoadsStores.java b/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyAsLoadsStores.java index 4c4c38848d8..103e99fefef 100644 --- a/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyAsLoadsStores.java +++ b/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyAsLoadsStores.java @@ -38,6 +38,19 @@ * compiler.arraycopy.TestArrayCopyAsLoadsStores */ +/* + * @test + * @bug 8282590 + * @library / + * + * @run main/othervm -ea -XX:-BackgroundCompilation -XX:-UseOnStackReplacement + * -XX:CompileCommand=dontinline,compiler.arraycopy.TestArrayCopyAsLoadsStores::m* + * -XX:TypeProfileLevel=200 + * -XX:+IgnoreUnrecognizedVMOptions -XX:+StressArrayCopyMacroNode + * -XX:-TieredCompilation -XX:+StressReflectiveCode -XX:-ReduceInitialCardMarks + * compiler.arraycopy.TestArrayCopyAsLoadsStores + */ + package compiler.arraycopy; import java.util.Arrays;