diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index 073e2788ba2..77054bafbbc 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -600,7 +600,6 @@ void ciTypeFlow::StateVector::do_aload(ciBytecodeStream* str) { return; } ciKlass* element_klass = array_klass->element_klass(); - // TODO 8350865 Can we check that array_klass is null_free and use mark_as_null_free on the result here? if (!element_klass->is_loaded() && element_klass->is_instance_klass()) { Untested("unloaded array element class in ciTypeFlow"); trap(str, element_klass, @@ -608,7 +607,11 @@ void ciTypeFlow::StateVector::do_aload(ciBytecodeStream* str) { (Deoptimization::Reason_unloaded, Deoptimization::Action_reinterpret)); } else { - push_object(element_klass); + ciType* maybe_null_free_element_klass = element_klass; + if (array_klass->is_refined() && array_klass->is_elem_null_free()) { + maybe_null_free_element_klass = outer()->mark_as_null_free(element_klass); + } + push(maybe_null_free_element_klass); } } diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 3aeef8e552c..65c03e89463 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -3984,7 +3984,6 @@ Node* GraphKit::null_free_array_test(Node* array, bool null_free) { Node* GraphKit::null_free_atomic_array_test(Node* array, ciInlineKlass* vk) { assert(vk->has_null_free_atomic_layout() || vk->has_null_free_non_atomic_layout(), "Can't be null-free and flat"); - // TODO 8350865 Add a stress flag to always access atomic if layout exists? if (!vk->has_null_free_non_atomic_layout()) { return intcon(1); // Always atomic } else if (!vk->has_null_free_atomic_layout()) { diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index ad0a720c211..ec407fee384 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -2740,7 +2740,7 @@ bool LibraryCallKit::inline_unsafe_flat_access(bool is_store, AccessKind kind) { if (layout == LayoutKind::REFERENCE) { if (!base_type->is_aryptr()->is_not_flat()) { const TypeAryPtr* array_type = base_type->is_aryptr()->cast_to_not_flat(); - // TODO 8350865 This should be a CheckCastPP, can we add a test? + // TODO 8388444 This should be a CheckCastPP, can we add a test? Node* new_base = _gvn.transform(new CastPPNode(control(), base, array_type, ConstraintCastNode::DependencyType::NonFloatingNarrowing)); replace_in_map(base, new_base); base = new_base; @@ -2757,7 +2757,7 @@ bool LibraryCallKit::inline_unsafe_flat_access(bool is_store, AccessKind kind) { ptr = basic_plus_adr(base, ConvL2X(offset)); const TypeAryPtr* ptr_type = _gvn.type(ptr)->is_aryptr(); if (ptr_type->field_offset().get() != 0) { - // TODO 8350865 This should be a CheckCastPP, can we add a test? + // TODO 8388444 This should be a CheckCastPP, can we add a test? ptr = _gvn.transform(new CastPPNode(control(), ptr, ptr_type->with_field_offset(0), ConstraintCastNode::DependencyType::NonFloatingNarrowing)); } } else { diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp index aef867fc70c..40db50d4d05 100644 --- a/src/hotspot/share/opto/phaseX.cpp +++ b/src/hotspot/share/opto/phaseX.cpp @@ -2816,7 +2816,6 @@ void PhaseIterGVN::add_users_of_use_to_worklist(Node* n, Node* use, Unique_Node_ if (use_op == Op_CastP2X) { for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { Node* u = use->fast_out(i2); - // TODO 8350865 Still needed? Yes, I think this is from PhaseMacroExpand::expand_mh_intrinsic_return if (u->Opcode() == Op_AndX) { worklist.push(u); } @@ -3233,7 +3232,6 @@ void PhaseCCP::push_counted_loop_phi(Unique_Node_List& worklist, Node* parent, c } } -// TODO 8350865 Still needed? Yes, I think this is from PhaseMacroExpand::expand_mh_intrinsic_return void PhaseCCP::push_cast(Unique_Node_List& worklist, const Node* use) { uint use_op = use->Opcode(); if (use_op == Op_CastP2X) { diff --git a/src/hotspot/share/opto/subtypenode.cpp b/src/hotspot/share/opto/subtypenode.cpp index c759b948299..91076d0cef7 100644 --- a/src/hotspot/share/opto/subtypenode.cpp +++ b/src/hotspot/share/opto/subtypenode.cpp @@ -47,7 +47,6 @@ const Type* SubTypeCheckNode::sub(const Type* sub_t, const Type* super_t) const } } - // TODO 8350865 Shouldn't this be encoded in helper methods of the type system (maybe_java_subtype_of() etc.?) // Similar to logic in CmpPNode::sub() bool unrelated_classes = false; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index ebab0a1052b..6519a4191bd 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -573,12 +573,11 @@ static MyValue1 tmp = null; // correctly allocated. @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - counts = {ALLOC_OF_MYVALUE_KLASS, "<= 1"}, // 1 MyValue2 allocation (if not the all-zero value) + counts = {ALLOC_OF_MYVALUE_KLASS, "<= 1"}, // 1 MyValue2 allocation (if not the all-zero value): MyValue1.createWithFieldsInline -> setV4 failOn = {LOAD_OF_ANY_KLASS}) - // TODO 8350865 - //@IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - // counts = {ALLOC_OF_MYVALUE_KLASS, "<= 2"}, // 1 MyValue1 and 1 MyValue2 allocation (if not the all-zero value) - // failOn = LOAD_OF_ANY_KLASS) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC_OF_MYVALUE_KLASS, "<= 3"}, // 1 MyValue1 and 2 MyValue2 allocation (if not the all-zero value): same as above + the local v (MyValue1) + MyValue2.DEFAULT for the calls to MyValue2.hashInterpreted() + failOn = LOAD_OF_ANY_KLASS) public long test20(boolean deopt, Method m) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue2[] va = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 3, MyValue2.DEFAULT); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatInArraysFolding.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatInArraysFolding.java index d6716ba5f50..1cad6bec219 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatInArraysFolding.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatInArraysFolding.java @@ -78,9 +78,8 @@ public class TestFlatInArraysFolding { static int iFld; public static void main(String[] args) { - // TODO 8350865 Scenarios are equivalent, FlatArrayElementMaxSize does not exist anymore - Scenario flatArrayElementMaxSize1Scenario = new Scenario(1, "-XX:-UseArrayFlattening"); - Scenario flatArrayElementMaxSize4Scenario = new Scenario(2, "-XX:-UseArrayFlattening"); + Scenario flatArrayElementMaxSize1Scenario = new Scenario(1, "-XX:FlatArrayElementMaxOops=0"); + Scenario flatArrayElementMaxSize4Scenario = new Scenario(2, "-XX:FlatArrayElementMaxOops=4"); Scenario noFlagsScenario = new Scenario(3); TestFramework testFramework = new TestFramework(); testFramework.setDefaultWarmup(0) @@ -165,8 +164,7 @@ public class TestFlatInArraysFolding { } } - // TODO 8350865 FlatArrayElementMaxSize does not exist anymore - // PUnique is the unique concrete sub class of AUnique and is not flat in array (with FlatArrayElementMaxSize=4). + // PUnique is the unique concrete sub class of AUnique and is not flat in array (with FlatArrayElementMaxOops=0). // The CheckCastPP output of the sub type check uses PUnique while the sub type check itself uses AUnique. This leads // to a bad graph because the type system determines that the flat in array super klass cannot be met with the // not flat in array sub klass. But the sub type check does not fold away because AUnique *could* be flat in array. @@ -253,10 +251,10 @@ public class TestFlatInArraysFolding { @LooselyConsistentValue static value class PUnique extends AUnique { int x; - int y; + String y; PUnique(int x) { this.x = x; - this.y = 34; + this.y = "abc"; } public void foo() {} @@ -282,14 +280,15 @@ public class TestFlatInArraysFolding { public void bar() {} } - // TODO 8350865 FlatArrayElementMaxSize does not exist anymore - // Not flat in array with -XX:FlatArrayElementMaxSize=4 + // Not flat in array with -XX:FlatArrayElementMaxOops=0 static value class NotFlatInArray extends A implements I { int x; int y; + String z; NotFlatInArray(int x) { this.x = x; this.y = 34; + this.z = "abc"; } public void foo() {} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index 299230f0b98..7a311143ece 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -43,7 +43,6 @@ import static compiler.valhalla.inlinetypes.InlineTypes.rL; import static compiler.lib.ir_framework.IRNode.LOAD; import static compiler.lib.ir_framework.IRNode.LOAD_KLASS; -import static compiler.valhalla.inlinetypes.InlineTypes.*; /* * @test @@ -2035,9 +2034,8 @@ public class TestIntrinsics { // Test correctness of the ValueClass::isAtomicArray intrinsic @Test - // TODO 8350865 Implemented intrinsic - // @IR(failOn = {STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray", - // STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray0"}) + @IR(failOn = {STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray", + STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray0"}) public boolean test87(Object[] array) { return ValueClass.isAtomicArray(array); } @@ -2053,9 +2051,8 @@ public class TestIntrinsics { // Verify that ValueClass::isAtomicArray checks with statically known classes are folded @Test - // TODO 8350865 Implemented intrinsic - // @IR(failOn = {LOAD_KLASS, STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray", - // STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray0"}) + @IR(failOn = {LOAD_KLASS, STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray", + STATIC_CALL_OF_METHOD, "jdk.internal.value.ValueClass::isAtomicArray0"}) public boolean test88() { boolean check1 = ValueClass.isAtomicArray(TEST_ARRAY1); if (!TEST_ARRAY1_IS_ATOMIC) { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index ef64dc12e78..bea5884be24 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -25,6 +25,7 @@ package compiler.valhalla.inlinetypes; import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; +import jdk.test.whitebox.WhiteBox; import test.java.lang.invoke.lib.InstructionHelper; import java.lang.invoke.MethodHandle; @@ -53,7 +54,6 @@ import static compiler.lib.ir_framework.IRNode.COUNTED_LOOP_MAIN; import static compiler.lib.ir_framework.IRNode.DYNAMIC_CALL_OF_METHOD; import static compiler.lib.ir_framework.IRNode.FIELD_ACCESS; import static compiler.lib.ir_framework.IRNode.LOAD; -import static compiler.lib.ir_framework.IRNode.STORE; import static compiler.lib.ir_framework.IRNode.LOAD_P; import static compiler.lib.ir_framework.IRNode.LOOP; import static compiler.lib.ir_framework.IRNode.MEMBAR; @@ -4606,11 +4606,11 @@ public class TestLWorld { } @LooselyConsistentValue - static value class ValueClassWithDouble { - double d; + static value class ValueClassWithFloat { + float f; - ValueClassWithDouble(double d) { - this.d = d; + ValueClassWithFloat(float f) { + this.f = f; } } @@ -4634,36 +4634,70 @@ public class TestLWorld { } @LooselyConsistentValue - static value class SubValueClassWithDouble extends AbstractValueClassWithByte { - double d; + static value class SubValueClassWithFloat extends AbstractValueClassWithByte { + float f; - SubValueClassWithDouble(double d) { - this.d = d; - super((byte)(d + 1)); + SubValueClassWithFloat(float f) { + this.f = f; + super((byte)(f + 1)); } } - // TODO 8350865 We need more copies of these tests for all ValueClass array factories - static final ValueClassWithInt[] VALUE_CLASS_WITH_INT_ARRAY = (ValueClassWithInt[]) ValueClass.newNullRestrictedNonAtomicArray(ValueClassWithInt.class, 2, new ValueClassWithInt(0)); - static final ValueClassWithDouble[] VALUE_CLASS_WITH_DOUBLE_ARRAY = (ValueClassWithDouble[]) ValueClass.newNullRestrictedNonAtomicArray(ValueClassWithDouble.class, 2, new ValueClassWithDouble(0)); - static final SubValueClassWithInt[] SUB_VALUE_CLASS_WITH_INT_ARRAY = (SubValueClassWithInt[]) ValueClass.newNullRestrictedNonAtomicArray(SubValueClassWithInt.class, 2, new SubValueClassWithInt(0)); - static final SubValueClassWithDouble[] SUB_VALUE_CLASS_WITH_DOUBLE_ARRAY = (SubValueClassWithDouble[]) ValueClass.newNullRestrictedNonAtomicArray(SubValueClassWithDouble.class, 2, new SubValueClassWithDouble(0)); + static final ValueClassWithInt[] VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC = (ValueClassWithInt[]) ValueClass.newNullRestrictedNonAtomicArray(ValueClassWithInt.class, 2, new ValueClassWithInt(0)); + static final ValueClassWithFloat[] VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC = (ValueClassWithFloat[]) ValueClass.newNullRestrictedNonAtomicArray(ValueClassWithFloat.class, 2, new ValueClassWithFloat(0)); + static final SubValueClassWithInt[] SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC = (SubValueClassWithInt[]) ValueClass.newNullRestrictedNonAtomicArray(SubValueClassWithInt.class, 2, new SubValueClassWithInt(0)); + static final SubValueClassWithFloat[] SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC = (SubValueClassWithFloat[]) ValueClass.newNullRestrictedNonAtomicArray(SubValueClassWithFloat.class, 2, new SubValueClassWithFloat(0)); + static final ValueClassWithInt[] VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC = (ValueClassWithInt[]) ValueClass.newNullRestrictedAtomicArray(ValueClassWithInt.class, 2, new ValueClassWithInt(0)); + static final ValueClassWithFloat[] VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC = (ValueClassWithFloat[]) ValueClass.newNullRestrictedAtomicArray(ValueClassWithFloat.class, 2, new ValueClassWithFloat(0)); + static final SubValueClassWithInt[] SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC = (SubValueClassWithInt[]) ValueClass.newNullRestrictedAtomicArray(SubValueClassWithInt.class, 2, new SubValueClassWithInt(0)); + static final SubValueClassWithFloat[] SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC = (SubValueClassWithFloat[]) ValueClass.newNullRestrictedAtomicArray(SubValueClassWithFloat.class, 2, new SubValueClassWithFloat(0)); + + static final ValueClassWithInt[] VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC = (ValueClassWithInt[]) ValueClass.newNullableAtomicArray(ValueClassWithInt.class, 2); + static final ValueClassWithFloat[] VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC = (ValueClassWithFloat[]) ValueClass.newNullableAtomicArray(ValueClassWithFloat.class, 2); + static final SubValueClassWithInt[] SUB_VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC = (SubValueClassWithInt[]) ValueClass.newNullableAtomicArray(SubValueClassWithInt.class, 2); + static final SubValueClassWithFloat[] SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC = (SubValueClassWithFloat[]) ValueClass.newNullableAtomicArray(SubValueClassWithFloat.class, 2); + + static final ValueClassWithInt[] VALUE_CLASS_WITH_INT_ARRAY_REF = (ValueClassWithInt[]) ValueClass.newReferenceArray(ValueClassWithInt.class, 2); + static final ValueClassWithFloat[] VALUE_CLASS_WITH_FLOAT_ARRAY_REF = (ValueClassWithFloat[]) ValueClass.newReferenceArray(ValueClassWithFloat.class, 2); + static final SubValueClassWithInt[] SUB_VALUE_CLASS_WITH_INT_ARRAY_REF = (SubValueClassWithInt[]) ValueClass.newReferenceArray(SubValueClassWithInt.class, 2); + static final SubValueClassWithFloat[] SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_REF = (SubValueClassWithFloat[]) ValueClass.newReferenceArray(SubValueClassWithFloat.class, 2); static { - VALUE_CLASS_WITH_INT_ARRAY[0] = new ValueClassWithInt(5); - VALUE_CLASS_WITH_DOUBLE_ARRAY[0] = new ValueClassWithDouble(6); - SUB_VALUE_CLASS_WITH_INT_ARRAY[0] = new SubValueClassWithInt(7); - SUB_VALUE_CLASS_WITH_DOUBLE_ARRAY[0] = new SubValueClassWithDouble(8); + VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0] = new ValueClassWithInt(5); + VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0] = new ValueClassWithFloat(6); + SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0] = new SubValueClassWithInt(7); + SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0] = new SubValueClassWithFloat(8); + + VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC[0] = new ValueClassWithInt(5); + VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC[0] = new ValueClassWithFloat(6); + SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC[0] = new SubValueClassWithInt(7); + SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC[0] = new SubValueClassWithFloat(8); + + VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC[0] = new ValueClassWithInt(5); + VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC[0] = new ValueClassWithFloat(6); + SUB_VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC[0] = new SubValueClassWithInt(7); + SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC[0] = new SubValueClassWithFloat(8); + + VALUE_CLASS_WITH_INT_ARRAY_REF[0] = new ValueClassWithInt(5); + VALUE_CLASS_WITH_FLOAT_ARRAY_REF[0] = new ValueClassWithFloat(6); + SUB_VALUE_CLASS_WITH_INT_ARRAY_REF[0] = new SubValueClassWithInt(7); + SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_REF[0] = new SubValueClassWithFloat(8); + } + + // Make sure the WhiteBox API is only loaded in the Test VM such that we can run this test in driver mode + static class Flags { + private static final WhiteBox WHITEBOX = WhiteBox.getWhiteBox(); + private static final boolean UseArrayFlattening = WHITEBOX.getBooleanVMFlag("UseArrayFlattening"); } @Test - static void testFlatArrayInexactObjectStore(Object o, boolean flag) { + static void testFlatArrayInexactObjectStore_NullRestricted_NonAtomic(Object o, boolean flag) { Object[] oArr; if (flag) { - oArr = VALUE_CLASS_WITH_INT_ARRAY; // VALUE_CLASS_WITH_INT_ARRAY is statically known to be flat. + oArr = VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; // VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC is statically known to be flat. } else { - oArr = VALUE_CLASS_WITH_DOUBLE_ARRAY; // VALUE_CLASS_WITH_DOUBLE_ARRAY is statically known to be flat. + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; // VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC is statically known to be flat. } // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] @@ -4673,12 +4707,12 @@ public class TestLWorld { } @Test - static Object testFlatArrayInexactObjectLoad(boolean flag) { + static Object testFlatArrayInexactObjectLoad_NullRestricted_NonAtomic(boolean flag) { Object[] oArr; if (flag) { - oArr = VALUE_CLASS_WITH_INT_ARRAY; // VALUE_CLASS_WITH_INT_ARRAY is statically known to be flat. + oArr = VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; // VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC is statically known to be flat. } else { - oArr = VALUE_CLASS_WITH_DOUBLE_ARRAY; // VALUE_CLASS_WITH_DOUBLE_ARRAY is statically known to be flat. + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; // VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC is statically known to be flat. } // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] @@ -4688,59 +4722,330 @@ public class TestLWorld { } @Test - static void testFlatArrayInexactAbstractValueClassStore(AbstractValueClassWithByte abstractValueClassWithByte, + static void testFlatArrayInexactAbstractValueClassStore_NullRestricted_NonAtomic(AbstractValueClassWithByte abstractValueClassWithByte, boolean flag) { AbstractValueClassWithByte[] avArr; if (flag) { - avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY; + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; } else { - avArr = SUB_VALUE_CLASS_WITH_DOUBLE_ARRAY; + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; } - // Same as testFlatArrayInexactObjectStore() but the inexact type is with an abstract value class: + // Same as testFlatArrayInexactObjectStore_NullRestricted_NonAtomic() but the inexact type is with an abstract value class: // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] avArr[0] = abstractValueClassWithByte; } @Test - static AbstractValueClassWithByte testFlatArrayInexactAbstractValueClassLoad(boolean flag) { + static AbstractValueClassWithByte testFlatArrayInexactAbstractValueClassLoad_NullRestricted_NonAtomic(boolean flag) { AbstractValueClassWithByte[] avArr; if (flag) { - avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY; + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; } else { - avArr = SUB_VALUE_CLASS_WITH_DOUBLE_ARRAY; + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC; } - // Same as testFlatArrayInexactObjectLoad() but the inexact type is with an abstract value class: + // Same as testFlatArrayInexactObjectLoad_NullRestricted_NonAtomic() but the inexact type is with an abstract value class: // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] return avArr[0]; } - @Run(test = {"testFlatArrayInexactObjectStore", - "testFlatArrayInexactObjectLoad", - "testFlatArrayInexactAbstractValueClassStore", - "testFlatArrayInexactAbstractValueClassLoad"}) - static void runFlatArrayInexactLoadAndStore() { - boolean flag = true; + @Run(test = {"testFlatArrayInexactObjectStore_NullRestricted_NonAtomic", + "testFlatArrayInexactObjectLoad_NullRestricted_NonAtomic", + "testFlatArrayInexactAbstractValueClassStore_NullRestricted_NonAtomic", + "testFlatArrayInexactAbstractValueClassLoad_NullRestricted_NonAtomic"}) + static void runFlatArrayInexactLoadAndStore_NullRestricted_NonAtomic() { + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC)); + ValueClassWithInt valueClassWithInt = new ValueClassWithInt(15); - ValueClassWithDouble valueClassWithDouble = new ValueClassWithDouble(16); + ValueClassWithFloat ValueClassWithFloat = new ValueClassWithFloat(16); - testFlatArrayInexactObjectStore(valueClassWithInt, true); - Asserts.assertEQ(valueClassWithInt, VALUE_CLASS_WITH_INT_ARRAY[0]); - testFlatArrayInexactObjectStore(valueClassWithDouble, false); - Asserts.assertEQ(valueClassWithDouble, VALUE_CLASS_WITH_DOUBLE_ARRAY[0]); + testFlatArrayInexactObjectStore_NullRestricted_NonAtomic(valueClassWithInt, true); + Asserts.assertEQ(valueClassWithInt, VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0]); + testFlatArrayInexactObjectStore_NullRestricted_NonAtomic(ValueClassWithFloat, false); + Asserts.assertEQ(ValueClassWithFloat, VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0]); - Asserts.assertEQ(valueClassWithInt, testFlatArrayInexactObjectLoad(true)); - Asserts.assertEQ(valueClassWithDouble, testFlatArrayInexactObjectLoad(false)); + Asserts.assertEQ(valueClassWithInt, testFlatArrayInexactObjectLoad_NullRestricted_NonAtomic(true)); + Asserts.assertEQ(ValueClassWithFloat, testFlatArrayInexactObjectLoad_NullRestricted_NonAtomic(false)); SubValueClassWithInt subValueClassWithInt = new SubValueClassWithInt(17); - SubValueClassWithDouble subValueClassWithDouble = new SubValueClassWithDouble(18); + SubValueClassWithFloat subValueClassWithFloat = new SubValueClassWithFloat(18); - testFlatArrayInexactAbstractValueClassStore(subValueClassWithInt, true); - Asserts.assertEQ(subValueClassWithInt, SUB_VALUE_CLASS_WITH_INT_ARRAY[0]); - testFlatArrayInexactAbstractValueClassStore(subValueClassWithDouble, false); - Asserts.assertEQ(subValueClassWithDouble, SUB_VALUE_CLASS_WITH_DOUBLE_ARRAY[0]); + testFlatArrayInexactAbstractValueClassStore_NullRestricted_NonAtomic(subValueClassWithInt, true); + Asserts.assertEQ(subValueClassWithInt, SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0]); + testFlatArrayInexactAbstractValueClassStore_NullRestricted_NonAtomic(subValueClassWithFloat, false); + Asserts.assertEQ(subValueClassWithFloat, SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_NON_ATOMIC[0]); - Asserts.assertEQ(subValueClassWithInt, testFlatArrayInexactAbstractValueClassLoad(true)); - Asserts.assertEQ(subValueClassWithDouble, testFlatArrayInexactAbstractValueClassLoad(false)); + Asserts.assertEQ(subValueClassWithInt, testFlatArrayInexactAbstractValueClassLoad_NullRestricted_NonAtomic(true)); + Asserts.assertEQ(subValueClassWithFloat, testFlatArrayInexactAbstractValueClassLoad_NullRestricted_NonAtomic(false)); + } + + @Test + static void testFlatArrayInexactObjectStore_NullRestricted_Atomic(Object o, boolean flag) { + Object[] oArr; + if (flag) { + oArr = VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC; // VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC is statically known to be flat. + } else { + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC; // VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC is statically known to be flat. + } + // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: + // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] + // Since the type is inexact, we do not know the exact flat array layout statically and thus need to fall back + // to call "store_unknown_inline_Type()" at runtime where we know the flat array layout + oArr[0] = o; + } + + @Test + static Object testFlatArrayInexactObjectLoad_NullRestricted_Atomic(boolean flag) { + Object[] oArr; + if (flag) { + oArr = VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC; // VALUE_CLASS_WITH_INT_ARRAY is statically known to be flat. + } else { + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC; // VALUE_CLASS_WITH_FLOAT_ARRAY is statically known to be flat. + } + // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: + // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] + // Since the type is inexact, we do not know the exact flat array layout statically and thus need to fall back + // to call "load_unknown_inline_Type()" at runtime where we know the flat array layout + return oArr[0]; + } + + @Test + static void testFlatArrayInexactAbstractValueClassStore_NullRestricted_Atomic(AbstractValueClassWithByte abstractValueClassWithByte, boolean flag) { + AbstractValueClassWithByte[] avArr; + if (flag) { + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC; + } else { + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC; + } + // Same as testFlatArrayInexactObjectStore_NullRestricted_Atomic() but the inexact type is with an abstract value class: + // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] + avArr[0] = abstractValueClassWithByte; + } + + @Test + static AbstractValueClassWithByte testFlatArrayInexactAbstractValueClassLoad_NullRestricted_Atomic(boolean flag) { + AbstractValueClassWithByte[] avArr; + if (flag) { + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC; + } else { + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC; + } + // Same as testFlatArrayInexactObjectLoad_NullRestricted_Atomic() but the inexact type is with an abstract value class: + // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] + return avArr[0]; + } + + @Run(test = {"testFlatArrayInexactObjectStore_NullRestricted_Atomic", + "testFlatArrayInexactObjectLoad_NullRestricted_Atomic", + "testFlatArrayInexactAbstractValueClassStore_NullRestricted_Atomic", + "testFlatArrayInexactAbstractValueClassLoad_NullRestricted_Atomic"}) + static void runFlatArrayInexactLoadAndStore_NullRestricted_Atomic() { + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC)); + + ValueClassWithInt valueClassWithInt = new ValueClassWithInt(15); + ValueClassWithFloat ValueClassWithFloat = new ValueClassWithFloat(16); + + testFlatArrayInexactObjectStore_NullRestricted_Atomic(valueClassWithInt, true); + Asserts.assertEQ(valueClassWithInt, VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC[0]); + testFlatArrayInexactObjectStore_NullRestricted_Atomic(ValueClassWithFloat, false); + Asserts.assertEQ(ValueClassWithFloat, VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC[0]); + + Asserts.assertEQ(valueClassWithInt, testFlatArrayInexactObjectLoad_NullRestricted_Atomic(true)); + Asserts.assertEQ(ValueClassWithFloat, testFlatArrayInexactObjectLoad_NullRestricted_Atomic(false)); + + SubValueClassWithInt subValueClassWithInt = new SubValueClassWithInt(17); + SubValueClassWithFloat subValueClassWithFloat = new SubValueClassWithFloat(18); + + testFlatArrayInexactAbstractValueClassStore_NullRestricted_Atomic(subValueClassWithInt, true); + Asserts.assertEQ(subValueClassWithInt, SUB_VALUE_CLASS_WITH_INT_ARRAY_NULL_RESTRICTED_ATOMIC[0]); + testFlatArrayInexactAbstractValueClassStore_NullRestricted_Atomic(subValueClassWithFloat, false); + Asserts.assertEQ(subValueClassWithFloat, SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULL_RESTRICTED_ATOMIC[0]); + + Asserts.assertEQ(subValueClassWithInt, testFlatArrayInexactAbstractValueClassLoad_NullRestricted_Atomic(true)); + Asserts.assertEQ(subValueClassWithFloat, testFlatArrayInexactAbstractValueClassLoad_NullRestricted_Atomic(false)); + } + + @Test + static void testFlatArrayInexactObjectStore_Nullable_Atomic(Object o, boolean flag) { + Object[] oArr; + if (flag) { + oArr = VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC; // VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC is statically known to be flat. + } else { + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC; // VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC is statically known to be flat. + } + // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: + // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] + // Since the type is inexact, we do not know the exact flat array layout statically and thus need to fall back + // to call "store_unknown_inline_Type()" at runtime where we know the flat array layout + oArr[0] = o; + } + + @Test + static Object testFlatArrayInexactObjectLoad_Nullable_Atomic(boolean flag) { + Object[] oArr; + if (flag) { + oArr = VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC; // VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC is statically known to be flat. + } else { + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC; // VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC is statically known to be flat. + } + // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: + // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] + // Since the type is inexact, we do not know the exact flat array layout statically and thus need to fall back + // to call "load_unknown_inline_Type()" at runtime where we know the flat array layout + return oArr[0]; + } + + @Test + static void testFlatArrayInexactAbstractValueClassStore_Nullable_Atomic(AbstractValueClassWithByte abstractValueClassWithByte, boolean flag) { + AbstractValueClassWithByte[] avArr; + if (flag) { + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC; + } else { + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC; + } + // Same as testFlatArrayInexactObjectStore_Nullable_Atomic() but the inexact type is with an abstract value class: + // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] + avArr[0] = abstractValueClassWithByte; + } + + @Test + static AbstractValueClassWithByte testFlatArrayInexactAbstractValueClassLoad_Nullable_Atomic(boolean flag) { + AbstractValueClassWithByte[] avArr; + if (flag) { + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC; + } else { + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC; + } + // Same as testFlatArrayInexactObjectLoad_Nullable_Atomic() but the inexact type is with an abstract value class: + // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] + return avArr[0]; + } + + @Run(test = {"testFlatArrayInexactObjectStore_Nullable_Atomic", + "testFlatArrayInexactObjectLoad_Nullable_Atomic", + "testFlatArrayInexactAbstractValueClassStore_Nullable_Atomic", + "testFlatArrayInexactAbstractValueClassLoad_Nullable_Atomic"}) + static void runFlatArrayInexactLoadAndStore_Nullable_Atomic() { + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC)); + Asserts.assertEQ(Flags.UseArrayFlattening, ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC)); + + ValueClassWithInt valueClassWithInt = new ValueClassWithInt(15); + ValueClassWithFloat ValueClassWithFloat = new ValueClassWithFloat(16); + + testFlatArrayInexactObjectStore_Nullable_Atomic(valueClassWithInt, true); + Asserts.assertEQ(valueClassWithInt, VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC[0]); + testFlatArrayInexactObjectStore_Nullable_Atomic(ValueClassWithFloat, false); + Asserts.assertEQ(ValueClassWithFloat, VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC[0]); + + Asserts.assertEQ(valueClassWithInt, testFlatArrayInexactObjectLoad_Nullable_Atomic(true)); + Asserts.assertEQ(ValueClassWithFloat, testFlatArrayInexactObjectLoad_Nullable_Atomic(false)); + + SubValueClassWithInt subValueClassWithInt = new SubValueClassWithInt(17); + SubValueClassWithFloat subValueClassWithFloat = new SubValueClassWithFloat(18); + + testFlatArrayInexactAbstractValueClassStore_Nullable_Atomic(subValueClassWithInt, true); + Asserts.assertEQ(subValueClassWithInt, SUB_VALUE_CLASS_WITH_INT_ARRAY_NULLABLE_ATOMIC[0]); + testFlatArrayInexactAbstractValueClassStore_Nullable_Atomic(subValueClassWithFloat, false); + Asserts.assertEQ(subValueClassWithFloat, SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_NULLABLE_ATOMIC[0]); + + Asserts.assertEQ(subValueClassWithInt, testFlatArrayInexactAbstractValueClassLoad_Nullable_Atomic(true)); + Asserts.assertEQ(subValueClassWithFloat, testFlatArrayInexactAbstractValueClassLoad_Nullable_Atomic(false)); + } + + @Test + static void testFlatArrayInexactObjectStore_Ref(Object o, boolean flag) { + Object[] oArr; + if (flag) { + oArr = VALUE_CLASS_WITH_INT_ARRAY_REF; // VALUE_CLASS_WITH_INT_ARRAY_REF is statically known not to be flat. + } else { + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_REF; // VALUE_CLASS_WITH_FLOAT_ARRAY_REF is statically known not to be flat. + } + // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: + // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] + // Since the type is inexact, we do not know the exact flat array layout statically and thus need to fall back + // to call "store_unknown_inline_Type()" at runtime where we know the flat array layout + oArr[0] = o; + } + + @Test + static Object testFlatArrayInexactObjectLoad_Ref(boolean flag) { + Object[] oArr; + if (flag) { + oArr = VALUE_CLASS_WITH_INT_ARRAY_REF; // VALUE_CLASS_WITH_INT_ARRAY_REF is statically known not to be flat. + } else { + oArr = VALUE_CLASS_WITH_FLOAT_ARRAY_REF; // VALUE_CLASS_WITH_FLOAT_ARRAY_REF is statically known not to be flat. + } + // The type of 'oArr' is inexact here because we merge two arrays. Since both arrays are flat, 'oArr' is also flat: + // Type: flat:narrowoop: java/lang/Object:NotNull * (flat in array)[int:2] + // Since the type is inexact, we do not know the exact flat array layout statically and thus need to fall back + // to call "load_unknown_inline_Type()" at runtime where we know the flat array layout + return oArr[0]; + } + + @Test + static void testFlatArrayInexactAbstractValueClassStore_Ref(AbstractValueClassWithByte abstractValueClassWithByte, boolean flag) { + AbstractValueClassWithByte[] avArr; + if (flag) { + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_REF; + } else { + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_REF; + } + // Same as testFlatArrayInexactObjectStore_Ref() but the inexact type is with an abstract value class: + // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] + avArr[0] = abstractValueClassWithByte; + } + + @Test + static AbstractValueClassWithByte testFlatArrayInexactAbstractValueClassLoad_Ref(boolean flag) { + AbstractValueClassWithByte[] avArr; + if (flag) { + avArr = SUB_VALUE_CLASS_WITH_INT_ARRAY_REF; + } else { + avArr = SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_REF; + } + // Same as testFlatArrayInexactObjectLoad_Ref() but the inexact type is with an abstract value class: + // flat:narrowoop: compiler/valhalla/inlinetypes/TestLWorld$AbstractValueClassWithByte:NotNull * (flat in array)[int:2] + return avArr[0]; + } + + @Run(test = {"testFlatArrayInexactObjectStore_Ref", + "testFlatArrayInexactObjectLoad_Ref", + "testFlatArrayInexactAbstractValueClassStore_Ref", + "testFlatArrayInexactAbstractValueClassLoad_Ref"}) + static void runFlatArrayInexactLoadAndStore_Ref() { + Asserts.assertFalse(ValueClass.isFlatArray(VALUE_CLASS_WITH_INT_ARRAY_REF)); + Asserts.assertFalse(ValueClass.isFlatArray(VALUE_CLASS_WITH_FLOAT_ARRAY_REF)); + Asserts.assertFalse(ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_INT_ARRAY_REF)); + Asserts.assertFalse(ValueClass.isFlatArray(SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_REF)); + + ValueClassWithInt valueClassWithInt = new ValueClassWithInt(15); + ValueClassWithFloat ValueClassWithFloat = new ValueClassWithFloat(16); + + testFlatArrayInexactObjectStore_Ref(valueClassWithInt, true); + Asserts.assertEQ(valueClassWithInt, VALUE_CLASS_WITH_INT_ARRAY_REF[0]); + testFlatArrayInexactObjectStore_Ref(ValueClassWithFloat, false); + Asserts.assertEQ(ValueClassWithFloat, VALUE_CLASS_WITH_FLOAT_ARRAY_REF[0]); + + Asserts.assertEQ(valueClassWithInt, testFlatArrayInexactObjectLoad_Ref(true)); + Asserts.assertEQ(ValueClassWithFloat, testFlatArrayInexactObjectLoad_Ref(false)); + + SubValueClassWithInt subValueClassWithInt = new SubValueClassWithInt(17); + SubValueClassWithFloat subValueClassWithFloat = new SubValueClassWithFloat(18); + + testFlatArrayInexactAbstractValueClassStore_Ref(subValueClassWithInt, true); + Asserts.assertEQ(subValueClassWithInt, SUB_VALUE_CLASS_WITH_INT_ARRAY_REF[0]); + testFlatArrayInexactAbstractValueClassStore_Ref(subValueClassWithFloat, false); + Asserts.assertEQ(subValueClassWithFloat, SUB_VALUE_CLASS_WITH_FLOAT_ARRAY_REF[0]); + + Asserts.assertEQ(subValueClassWithInt, testFlatArrayInexactAbstractValueClassLoad_Ref(true)); + Asserts.assertEQ(subValueClassWithFloat, testFlatArrayInexactAbstractValueClassLoad_Ref(false)); } // Check that comparisons between Java mirrors are optimized to comparisons of the klass