Merge branches 'JDK-8386769.array-store', 'JDK-8386769.basic-functionality', 'JDK-8386769.do_aload', 'JDK-8386769.inline_unsafe_flat_access', 'JDK-8386769.intrinsics', 'JDK-8386769.null_free_atomic_array_test', 'JDK-8386769.phaseX', 'JDK-8386769.replay', 'JDK-8386769.subtypenode', 'JDK-8386769.test-flat-in-arrays-folding' and 'JDK-8386769.test-lworld' into JDK-8386769

This commit is contained in:
Marc Chevalier 2026-07-31 13:20:16 +02:00
9 changed files with 381 additions and 82 deletions

View File

@ -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);
}
}

View File

@ -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()) {

View File

@ -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 {

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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() {}

View File

@ -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) {

View File

@ -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