diff --git a/runtime/vm/BytecodeInterpreter.hpp b/runtime/vm/BytecodeInterpreter.hpp index d2ee898b3df..77bce73df93 100644 --- a/runtime/vm/BytecodeInterpreter.hpp +++ b/runtime/vm/BytecodeInterpreter.hpp @@ -1225,7 +1225,10 @@ class INTERPRETER_CLASS J9Class *destComponentClass = ((J9ArrayClass *)destClazz)->componentType; if (J9_IS_J9CLASS_FLATTENED(srcClazz) && J9_IS_J9CLASS_FLATTENED(destClazz) && J9_ARE_NO_BITS_SET(srcComponentClass->classFlags, J9ClassHasReferences) && J9_ARE_NO_BITS_SET(destComponentClass->classFlags, J9ClassHasReferences)) { - if (srcClazz == destClazz) { + if (srcClazz == destClazz + || (J9_IS_J9ARRAYCLASS_NULL_RESTRICTED(srcClazz) && (((J9ArrayClass *)srcClazz)->companionArray == destClazz)) + || (J9_IS_J9ARRAYCLASS_NULL_RESTRICTED(destClazz) && (srcClazz == ((J9ArrayClass *)destClazz)->companionArray)) + ) { UDATA elementSize = J9ARRAYCLASS_GET_STRIDE(srcClazz); /* This only works for contiguous flattened arrays, since discontiguous flattened arrays are not supported by GC */ VM_ArrayCopyHelpers::primitiveArrayCopy(_currentThread, srcObject, srcStart * elementSize, destObject, destStart * elementSize, elementSize * elementCount, 0); diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java index 9e31a1a8bd7..f705219b8a7 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java @@ -26,7 +26,6 @@ import org.testng.annotations.Test; import org.testng.annotations.BeforeClass; -import jdk.internal.value.NullRestrictedCheckedType; import jdk.internal.value.ValueClass; import jdk.internal.vm.annotation.ImplicitlyConstructible; import jdk.internal.vm.annotation.NullRestricted; @@ -60,6 +59,7 @@ public static class SomeIdentityClass2 implements SomeInterface { } } + @ImplicitlyConstructible public value static class SomeValueClass implements SomeInterface { double val1; long val2; @@ -117,12 +117,14 @@ public static value class SomePrimitiveValueClass2 implements SomeInterface { public static SomeValueClass[] vtArrayDst = new SomeValueClass[ARRAY_SIZE]; public static SomeValueClass[] vtArraySrc = new SomeValueClass[ARRAY_SIZE]; public static SomePrimitiveValueClass[] primitiveVtArrayDst = - (SomePrimitiveValueClass[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveValueClass.class), ARRAY_SIZE); + (SomePrimitiveValueClass[])ValueClass.newNullRestrictedArray(SomePrimitiveValueClass.class, ARRAY_SIZE); public static SomePrimitiveValueClass[] primitiveVtArraySrc = - (SomePrimitiveValueClass[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveValueClass.class), ARRAY_SIZE); - + (SomePrimitiveValueClass[])ValueClass.newNullRestrictedArray(SomePrimitiveValueClass.class, ARRAY_SIZE); + /* These arrays should replace primitiveVTArrayDst/Src once javac supports null-restricted classes. */ + public static SomeValueClass[] nullRestrictedVtArraySrc = + (SomeValueClass[])ValueClass.newNullRestrictedArray(SomeValueClass.class, ARRAY_SIZE); + public static SomeValueClass[] nullRestrictedVtArrayDst = + (SomeValueClass[])ValueClass.newNullRestrictedArray(SomeValueClass.class, ARRAY_SIZE); public static SomeInterface[] ifIdArrayDst = new SomeIdentityClass[ARRAY_SIZE]; public static SomeInterface[] ifIdArraySrc = new SomeIdentityClass[ARRAY_SIZE]; public static SomeInterface[] ifVtArrayDst = new SomeValueClass[ARRAY_SIZE]; @@ -135,8 +137,7 @@ public static value class SomePrimitiveValueClass2 implements SomeInterface { public static SomeIdentityClass[] idArrayDstCheckForException = new SomeIdentityClass[ARRAY_SIZE]; public static SomePrimitiveValueClass[] primitiveVtArrayDstCheckForException = - (SomePrimitiveValueClass[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveValueClass.class), ARRAY_SIZE); + (SomePrimitiveValueClass[])ValueClass.newNullRestrictedArray(SomePrimitiveValueClass.class, ARRAY_SIZE); static private void initArrays() { for (int i=0; i < ARRAY_SIZE; i++) { @@ -162,6 +163,9 @@ static private void initArrays() { ifArray1[i] = new SomeIdentityClass(i*13); ifArray2[i] = new SomeValueClass(i*14); ifArray3[i] = new SomePrimitiveValueClass(i*15); + + nullRestrictedVtArrayDst[i] = new SomeValueClass(i*16); + nullRestrictedVtArraySrc[i] = new SomeValueClass(i*17); } } @@ -465,7 +469,7 @@ static public void testSystemArrayCopy8() throws Throwable { checkResults(primitiveVtArraySrc, ifPrimitiveVtArrayDst); } - @Test(priority=1) + @Test(priority=1) // TODO is this the same test? static public void testSystemArrayCopy9() throws Throwable { initArrays(); @@ -821,4 +825,16 @@ static public void testSystemArrayCopy26() throws Throwable { Assert.fail("Expect a ArrayStoreException. No exception or wrong kind of exception thrown"); } + + @Test(priority=1) + static public void testSystemArrayCopy27() throws Throwable { + initArrays(); + testVTVT(vtArraySrc, nullRestrictedVtArrayDst); + } + + @Test(priority=1) + static public void testSystemArrayCopy28() throws Throwable { + initArrays(); + testVTVT(nullRestrictedVtArraySrc, vtArrayDst); + } }