From 4561302f86dc68ecf881d508f82b48d4f72157a0 Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Tue, 24 Mar 2026 14:29:20 +0100 Subject: [PATCH 1/4] reworked InlineTypeDensity --- .../inlinetypes/InlineTypeDensity.java | 95 ++++++------------- 1 file changed, 27 insertions(+), 68 deletions(-) diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java index 2806b739c4e..4a5517dd13d 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java @@ -24,10 +24,6 @@ package runtime.valhalla.inlinetypes; -import java.lang.management.MemoryPoolMXBean; - -import com.sun.jdi.NativeMethodException; - import jdk.internal.value.ValueClass; import jdk.internal.vm.annotation.LooselyConsistentValue; import jdk.internal.vm.annotation.NullRestricted; @@ -39,7 +35,6 @@ * @test id=compressed-oops * @summary Heap density test for InlineTypes * @library /test/lib - * @requires vm.flagless * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value * @enablePreview @@ -54,7 +49,6 @@ * @test id=no-compressed-oops * @summary Heap density test for InlineTypes * @library /test/lib - * @requires vm.flagless * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value * @enablePreview @@ -69,7 +63,6 @@ * @test id=no-explicit-compression * @summary Heap density test for InlineTypes * @library /test/lib - * @requires vm.flagless * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value * @enablePreview @@ -84,7 +77,6 @@ * @test id=force-non-tearable * @summary Heap density test for InlineTypes * @library /test/lib - * @requires vm.flagless * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value * @enablePreview @@ -273,82 +265,49 @@ static value class MyInt { int v = 0; } @LooselyConsistentValue static value class MyLong { long v = 0; } - void assertArraySameSize(Object a, Object b, int nofElements) { - long aSize = WHITE_BOX.getObjectSize(a); - long bSize = WHITE_BOX.getObjectSize(b); - Asserts.assertEquals(aSize, bSize, - a + "(" + aSize + " bytes) not equivalent size " + - b + "(" + bSize + " bytes)" + - (nofElements >= 0 ? " (array of " + nofElements + " elements)" : "")); - } - - void testByteArraySizesSame(int[] testSizes) { + public void testPrimitiveLikeArraysAreFlattened() { + int[] testSizes = new int[] { 0, 1, 2, 3, 4, 7, 10, 257 }; for (int testSize : testSizes) { - byte[] ba = new byte[testSize]; MyByte[] mba = (MyByte[])ValueClass.newNullRestrictedNonAtomicArray(MyByte.class, testSize, new MyByte()); - assertArraySameSize(ba, mba, testSize); - } - } - - void testShortArraySizesSame(int[] testSizes) { - for (int testSize : testSizes) { - short[] sa = new short[testSize]; MyShort[] msa = (MyShort[])ValueClass.newNullRestrictedNonAtomicArray(MyShort.class, testSize, new MyShort()); - assertArraySameSize(sa, msa, testSize); - } - } - - void testIntArraySizesSame(int[] testSizes) { - for (int testSize : testSizes) { - int[] ia = new int[testSize]; MyInt[] mia = (MyInt[])ValueClass.newNullRestrictedNonAtomicArray(MyInt.class, testSize, new MyInt()); - assertArraySameSize(ia, mia, testSize); - } - } - - void testLongArraySizesSame(int[] testSizes) { - for (int testSize : testSizes) { - long[] la = new long[testSize]; MyLong[] mla = (MyLong[])ValueClass.newNullRestrictedNonAtomicArray(MyLong.class, testSize, new MyLong()); - assertArraySameSize(la, mla, testSize); - } - } - public void testPrimitiveArraySizesSame() { - int[] testSizes = new int[] { 0, 1, 2, 3, 4, 7, 10, 257 }; - testByteArraySizesSame(testSizes); - testShortArraySizesSame(testSizes); - testIntArraySizesSame(testSizes); - testLongArraySizesSame(testSizes); + Asserts.assertTrue(ValueClass.isFlatArray(mba), "MyByte array should be flat"); + Asserts.assertTrue(ValueClass.isFlatArray(msa), "MyShort array should be flat"); + Asserts.assertTrue(ValueClass.isFlatArray(mia), "MyInt array should be flat"); + Asserts.assertTrue(ValueClass.isFlatArray(mla), "MyLong array should be flat"); + } } @LooselyConsistentValue - static value class bbValue { byte b = 0; byte b2 = 0;} + static value class MyBB { byte b = 0; byte b2 = 0;} @LooselyConsistentValue - static value class bsValue { byte b = 0; short s = 0;} + static value class MyBS { byte b = 0; short s = 0;} @LooselyConsistentValue - static value class siValue { short s = 0; int i = 0;} + static value class MySI { short s = 0; int i = 0;} @LooselyConsistentValue - static value class ssiValue { short s = 0; short s2 = 0; int i = 0;} - @LooselyConsistentValue - static value class blValue { byte b = 0; long l = 0; } - - // Expect aligned array addressing to nearest pow2 - void testAlignedSize() { - int testSize = 10; - assertArraySameSize(new short[testSize], ValueClass.newNullRestrictedNonAtomicArray(bbValue.class, testSize, new bbValue()), testSize); - assertArraySameSize(new long[testSize], ValueClass.newNullRestrictedNonAtomicArray(siValue.class, testSize, new siValue()), testSize); - assertArraySameSize(new long[testSize], ValueClass.newNullRestrictedNonAtomicArray(ssiValue.class, testSize, new ssiValue()), testSize); - assertArraySameSize(new long[testSize*2], ValueClass.newNullRestrictedNonAtomicArray(blValue.class, testSize, new blValue()), testSize); - assertArraySameSize(new int[testSize], ValueClass.newNullRestrictedNonAtomicArray(bsValue.class, testSize, new bsValue()), testSize); + static value class MySSI { short s = 0; short s2 = 0; int i = 0;} + + public void testTupleArraysAreFlattened() { + int[] testSizes = new int[] { 0, 1, 2, 3, 4, 7, 10, 257 }; + for (int testSize : testSizes) { + MyBB[] mbb = (MyBB[])ValueClass.newNullRestrictedNonAtomicArray(MyBB.class, testSize, new MyBB()); + MyBS[] mbs = (MyBS[])ValueClass.newNullRestrictedNonAtomicArray(MyBS.class, testSize, new MyBS()); + MySI[] msi = (MySI[])ValueClass.newNullRestrictedNonAtomicArray(MySI.class, testSize, new MySI()); + MySSI[] mssi = (MySSI[])ValueClass.newNullRestrictedNonAtomicArray(MySSI.class, testSize, new MySSI()); + + Asserts.assertTrue(ValueClass.isFlatArray(mbb), "MyBB array should be flat"); + Asserts.assertTrue(ValueClass.isFlatArray(mbs), "MyBS array should be flat"); + Asserts.assertTrue(ValueClass.isFlatArray(msi), "MySI array should be flat"); + Asserts.assertTrue(ValueClass.isFlatArray(mssi), "MySSI array should be flat"); + } } public void test() { ensureArraySizeWin(); - testPrimitiveArraySizesSame(); - if (!VM_FLAG_FORCENONTEARABLE) { - testAlignedSize(); - } + testPrimitiveLikeArraysAreFlattened(); + testTupleArraysAreFlattened(); } public static void main(String[] args) { From bdf1d2b06c71711fcae9c962ddb4695e9af67cea Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Fri, 27 Mar 2026 15:58:00 +0100 Subject: [PATCH 2/4] test for array flattening and alignment --- .../inlinetypes/InlineTypeDensity.java | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java index 4a5517dd13d..094b229a6ab 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java @@ -29,6 +29,7 @@ import jdk.internal.vm.annotation.NullRestricted; import jdk.test.lib.Asserts; import jdk.test.whitebox.WhiteBox; +import jdk.internal.misc.Unsafe; /** @@ -37,6 +38,7 @@ * @library /test/lib * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value + * java.base/jdk.internal.misc * @enablePreview * @compile InlineTypeDensity.java * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox @@ -51,6 +53,7 @@ * @library /test/lib * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value + * java.base/jdk.internal.misc * @enablePreview * @compile InlineTypeDensity.java * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox @@ -65,6 +68,7 @@ * @library /test/lib * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value + * java.base/jdk.internal.misc * @enablePreview * @compile InlineTypeDensity.java * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox @@ -79,6 +83,7 @@ * @library /test/lib * @modules java.base/jdk.internal.vm.annotation * java.base/jdk.internal.value + * java.base/jdk.internal.misc * @enablePreview * @compile InlineTypeDensity.java * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox @@ -89,14 +94,10 @@ public class InlineTypeDensity { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final boolean VM_FLAG_FORCENONTEARABLE = WHITE_BOX.getStringVMFlag("ForceNonTearable").equals("*"); - - public InlineTypeDensity() { - if (WHITE_BOX.getBooleanVMFlag("UseArrayFlattening") != true) { - throw new IllegalStateException("UseArrayFlattening should be true"); - } - } + private static final boolean ARRAY_FLATTENING_ON = WHITE_BOX.getBooleanVMFlag("UseArrayFlattening"); interface LocalDate { public int getYear(); @@ -273,10 +274,15 @@ public void testPrimitiveLikeArraysAreFlattened() { MyInt[] mia = (MyInt[])ValueClass.newNullRestrictedNonAtomicArray(MyInt.class, testSize, new MyInt()); MyLong[] mla = (MyLong[])ValueClass.newNullRestrictedNonAtomicArray(MyLong.class, testSize, new MyLong()); - Asserts.assertTrue(ValueClass.isFlatArray(mba), "MyByte array should be flat"); - Asserts.assertTrue(ValueClass.isFlatArray(msa), "MyShort array should be flat"); - Asserts.assertTrue(ValueClass.isFlatArray(mia), "MyInt array should be flat"); - Asserts.assertTrue(ValueClass.isFlatArray(mla), "MyLong array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(mba), ARRAY_FLATTENING_ON, "MyByte array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(msa), ARRAY_FLATTENING_ON, "MyShort array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(mia), ARRAY_FLATTENING_ON, "MyInt array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(mla), ARRAY_FLATTENING_ON, "MyLong array should be flat"); + + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mba) % 8 == 0); + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(msa) % 8 == 0); + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mia) % 8 == 0); + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mla) % 8 == 0); } } @@ -297,10 +303,15 @@ public void testTupleArraysAreFlattened() { MySI[] msi = (MySI[])ValueClass.newNullRestrictedNonAtomicArray(MySI.class, testSize, new MySI()); MySSI[] mssi = (MySSI[])ValueClass.newNullRestrictedNonAtomicArray(MySSI.class, testSize, new MySSI()); - Asserts.assertTrue(ValueClass.isFlatArray(mbb), "MyBB array should be flat"); - Asserts.assertTrue(ValueClass.isFlatArray(mbs), "MyBS array should be flat"); - Asserts.assertTrue(ValueClass.isFlatArray(msi), "MySI array should be flat"); - Asserts.assertTrue(ValueClass.isFlatArray(mssi), "MySSI array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(mbb), ARRAY_FLATTENING_ON, "MyBB array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(mbs), ARRAY_FLATTENING_ON, "MyBS array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(msi), ARRAY_FLATTENING_ON, "MySI array should be flat"); + Asserts.assertEquals(ValueClass.isFlatArray(mssi), ARRAY_FLATTENING_ON, "MySSI array should be flat"); + + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mbb) % 8 == 0); + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mbs) % 8 == 0); + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(msi) % 8 == 0); + Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mssi) % 8 == 0); } } From 4447566e3db587ef9f3f551f7251000b9e98502d Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Thu, 2 Apr 2026 14:37:29 +0200 Subject: [PATCH 3/4] test improvements --- .../inlinetypes/InlineTypeDensity.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java index 28505b3c0d9..eb3b9798e31 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java @@ -24,12 +24,12 @@ package runtime.valhalla.inlinetypes; +import jdk.internal.misc.Unsafe; import jdk.internal.value.ValueClass; import jdk.internal.vm.annotation.LooselyConsistentValue; import jdk.internal.vm.annotation.NullRestricted; import jdk.test.lib.Asserts; import jdk.test.whitebox.WhiteBox; -import jdk.internal.misc.Unsafe; /** @@ -257,6 +257,12 @@ public void ensureArraySizeWin() { Asserts.assertLessThan(flatArraySize, objectArraySize, "Flat array accounts for more heap than object array + elements !"); } + private static void assertFlat(String name, Object[] value, boolean shouldBeFlat) { + String expectation = shouldBeFlat ? "be flat" : "not be flat"; + Asserts.assertEquals(ValueClass.isFlatArray(value), shouldBeFlat, + "%s array should %s".formatted(name, expectation)); + } + @LooselyConsistentValue static value class MyByte { byte v = 0; } @LooselyConsistentValue @@ -274,10 +280,10 @@ public void testPrimitiveLikeArraysAreFlattened() { MyInt[] mia = (MyInt[])ValueClass.newNullRestrictedNonAtomicArray(MyInt.class, testSize, new MyInt()); MyLong[] mla = (MyLong[])ValueClass.newNullRestrictedNonAtomicArray(MyLong.class, testSize, new MyLong()); - Asserts.assertEquals(ValueClass.isFlatArray(mba), ARRAY_FLATTENING_ON, "MyByte array should be flat"); - Asserts.assertEquals(ValueClass.isFlatArray(msa), ARRAY_FLATTENING_ON, "MyShort array should be flat"); - Asserts.assertEquals(ValueClass.isFlatArray(mia), ARRAY_FLATTENING_ON, "MyInt array should be flat"); - Asserts.assertEquals(ValueClass.isFlatArray(mla), ARRAY_FLATTENING_ON, "MyLong array should be flat"); + assertFlat("MyByte", mba, ARRAY_FLATTENING_ON); + assertFlat("MyShort", msa, ARRAY_FLATTENING_ON); + assertFlat("MyInt", mia, ARRAY_FLATTENING_ON); + assertFlat("MyLong", mla, ARRAY_FLATTENING_ON); Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mba) % 8 == 0); Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(msa) % 8 == 0); @@ -303,10 +309,10 @@ public void testTupleArraysAreFlattened() { MySI[] msi = (MySI[])ValueClass.newNullRestrictedNonAtomicArray(MySI.class, testSize, new MySI()); MySSI[] mssi = (MySSI[])ValueClass.newNullRestrictedNonAtomicArray(MySSI.class, testSize, new MySSI()); - Asserts.assertEquals(ValueClass.isFlatArray(mbb), ARRAY_FLATTENING_ON, "MyBB array should be flat"); - Asserts.assertEquals(ValueClass.isFlatArray(mbs), ARRAY_FLATTENING_ON, "MyBS array should be flat"); - Asserts.assertEquals(ValueClass.isFlatArray(msi), ARRAY_FLATTENING_ON, "MySI array should be flat"); - Asserts.assertEquals(ValueClass.isFlatArray(mssi), ARRAY_FLATTENING_ON, "MySSI array should be flat"); + assertFlat("MyBB", mbb, ARRAY_FLATTENING_ON); + assertFlat("MyBS", mbs, ARRAY_FLATTENING_ON); + assertFlat("MySI", msi, ARRAY_FLATTENING_ON); + assertFlat("MySSI", mssi, ARRAY_FLATTENING_ON); Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mbb) % 8 == 0); Asserts.assertTrue(UNSAFE.arrayInstanceBaseOffset(mbs) % 8 == 0); From ace6c15132a3c8c115d56861ff22627fa43311d5 Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Wed, 8 Apr 2026 17:35:33 +0200 Subject: [PATCH 4/4] changed test functions to private --- .../runtime/valhalla/inlinetypes/InlineTypeDensity.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java index eb3b9798e31..092fdef67e1 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypeDensity.java @@ -233,7 +233,7 @@ static final class LocalDateTimeClass implements LocalDateTime { public int getNano() { return time.nano; } } - public void ensureArraySizeWin() { + private void ensureArraySizeWin() { int arrayLength = 1000; System.out.println("ensureArraySizeWin for length " + arrayLength); LocalDateTimeClass[] objectArray = new LocalDateTimeClass[arrayLength]; @@ -272,7 +272,7 @@ static value class MyInt { int v = 0; } @LooselyConsistentValue static value class MyLong { long v = 0; } - public void testPrimitiveLikeArraysAreFlattened() { + private void testPrimitiveLikeArraysAreFlattened() { int[] testSizes = new int[] { 0, 1, 2, 3, 4, 7, 10, 257 }; for (int testSize : testSizes) { MyByte[] mba = (MyByte[])ValueClass.newNullRestrictedNonAtomicArray(MyByte.class, testSize, new MyByte()); @@ -301,7 +301,7 @@ static value class MySI { short s = 0; int i = 0;} @LooselyConsistentValue static value class MySSI { short s = 0; short s2 = 0; int i = 0;} - public void testTupleArraysAreFlattened() { + private void testTupleArraysAreFlattened() { int[] testSizes = new int[] { 0, 1, 2, 3, 4, 7, 10, 257 }; for (int testSize : testSizes) { MyBB[] mbb = (MyBB[])ValueClass.newNullRestrictedNonAtomicArray(MyBB.class, testSize, new MyBB()); @@ -321,7 +321,7 @@ public void testTupleArraysAreFlattened() { } } - public void test() { + private void test() { ensureArraySizeWin(); testPrimitiveLikeArraysAreFlattened(); testTupleArraysAreFlattened();