< prev index next >

test/compiler/valhalla/valuetypes/ValueTypeTestBench.java

Print this page

        

*** 31,50 **** * @compile -XDenableValueTypes ValueCapableClass1.java ValueCapableClass2.java ValueTypeTestBench.java * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller jdk.test.lib.Platform * @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+VerifyAdapterSharing ! * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueArrayFlatten * -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 -XX:+FullGCALotWithValueTypes * compiler.valhalla.valuetypes.ValueTypeTestBench * @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation ! * -XX:+EnableValhalla -XX:+EnableMVT -XX:-ValueTypePassFieldsAsArgs -XX:-ValueArrayFlatten * compiler.valhalla.valuetypes.ValueTypeTestBench * @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+AlwaysIncrementalInline ! * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueArrayFlatten * -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 * compiler.valhalla.valuetypes.ValueTypeTestBench */ package compiler.valhalla.valuetypes; --- 31,50 ---- * @compile -XDenableValueTypes ValueCapableClass1.java ValueCapableClass2.java ValueTypeTestBench.java * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller jdk.test.lib.Platform * @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+VerifyAdapterSharing ! * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten * -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 -XX:+FullGCALotWithValueTypes * compiler.valhalla.valuetypes.ValueTypeTestBench * @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation ! * -XX:+EnableValhalla -XX:+EnableMVT -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:-ValueArrayFlatten * compiler.valhalla.valuetypes.ValueTypeTestBench * @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+AlwaysIncrementalInline ! * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten * -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 * compiler.valhalla.valuetypes.ValueTypeTestBench */ package compiler.valhalla.valuetypes;
*** 65,75 **** --- 65,77 ---- import java.lang.invoke.*; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Hashtable; + import java.util.LinkedHashMap; import java.util.List; + import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import jdk.experimental.value.*; // Test value types
*** 299,308 **** --- 301,552 ---- v.b = b; return v; } } + // Value type definition to stress test return of a value in registers + // (uses all registers of calling convention on x86_64) + __ByValue final class MyValue3 { + final boolean b; + final char c; + final byte bb; + final short s; + final int i1; + final long l; + final float f1; + final double f2; + final float f3; + final double f4; + final float f5; + final double f6; + final float f7; + final double f8; + + private MyValue3(boolean b, + char c, + byte bb, + short s, + int i1, + long l, + float f1, + double f2, + float f3, + double f4, + float f5, + double f6, + float f7, + double f8) { + this.b = b; + this.c = c; + this.bb = bb; + this.s = s; + this.i1 = i1; + this.l = l; + this.f1 = f1; + this.f2 = f2; + this.f3 = f3; + this.f4 = f4; + this.f5 = f5; + this.f6 = f6; + this.f7 = f7; + this.f8 = f8; + } + + private MyValue3() { + this.b = false; + this.c = 0; + this.bb = 0; + this.s = 0; + this.i1 = 0; + this.l = 0; + this.f1 = 0; + this.f2 = 0; + this.f3 = 0; + this.f4 = 0; + this.f5 = 0; + this.f6 = 0; + this.f7 = 0; + this.f8 = 0; + } + + @ForceInline + __ValueFactory static MyValue3 setB(MyValue3 v, boolean b) { + v.b = b; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setC(MyValue3 v, char c) { + v.c = c; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setBB(MyValue3 v, byte bb) { + v.bb = bb; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setS(MyValue3 v, short s) { + v.s = s; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setI1(MyValue3 v, int i1) { + v.i1 = i1; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setL(MyValue3 v, long l) { + v.l = l; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF1(MyValue3 v, float f1) { + v.f1 = f1; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF2(MyValue3 v, double f2) { + v.f2 = f2; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF3(MyValue3 v, float f3) { + v.f3 = f3; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF4(MyValue3 v, double f4) { + v.f4 = f4; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF5(MyValue3 v, float f5) { + v.f5 = f5; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF6(MyValue3 v, double f6) { + v.f6 = f6; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF7(MyValue3 v, float f7) { + v.f7 = f7; + return v; + } + + @ForceInline + __ValueFactory static MyValue3 setF8(MyValue3 v, double f8) { + v.f8 = f8; + return v; + } + + @ForceInline + __ValueFactory public static MyValue3 createDefault() { + return __MakeDefault MyValue3(); + } + + @ForceInline + public static MyValue3 create() { + java.util.Random r = Utils.getRandomInstance(); + MyValue3 v = createDefault(); + v = setB(v, r.nextBoolean()); + v = setC(v, (char)r.nextInt()); + v = setBB(v, (byte)r.nextInt()); + v = setS(v, (short)r.nextInt()); + v = setI1(v, r.nextInt()); + v = setL(v, r.nextLong()); + v = setF1(v, r.nextFloat()); + v = setF2(v, r.nextDouble()); + v = setF3(v, r.nextFloat()); + v = setF4(v, r.nextDouble()); + v = setF5(v, r.nextFloat()); + v = setF6(v, r.nextDouble()); + v = setF7(v, r.nextFloat()); + v = setF8(v, r.nextDouble()); + return v; + } + + public void verify(MyValue3 other) { + Asserts.assertEQ(b, other.b); + Asserts.assertEQ(c, other.c); + Asserts.assertEQ(bb, other.bb); + Asserts.assertEQ(s, other.s); + Asserts.assertEQ(i1, other.i1); + Asserts.assertEQ(l, other.l); + Asserts.assertEQ(f1, other.f1); + Asserts.assertEQ(f2, other.f2); + Asserts.assertEQ(f3, other.f3); + Asserts.assertEQ(f4, other.f4); + Asserts.assertEQ(f5, other.f5); + Asserts.assertEQ(f6, other.f6); + Asserts.assertEQ(f7, other.f7); + Asserts.assertEQ(f8, other.f8); + } + } + + // Value type definition with too many fields to return in registers + __ByValue final class MyValue4 { + final MyValue3 v1; + final MyValue3 v2; + + private MyValue4(MyValue3 v1, MyValue3 v2) { + this.v1 = v1; + this.v2 = v2; + } + + private MyValue4() { + this.v1 = MyValue3.createDefault(); + this.v2 = MyValue3.createDefault(); + } + + @ForceInline + __ValueFactory static MyValue4 setV1(MyValue4 v, MyValue3 v1) { + v.v1 = v1; + return v; + } + + @ForceInline + __ValueFactory static MyValue4 setV2(MyValue4 v, MyValue3 v2) { + v.v2 = v2; + return v; + } + + @ForceInline + __ValueFactory public static MyValue4 createDefault() { + return __MakeDefault MyValue4(); + } + + @ForceInline + public static MyValue4 create() { + MyValue4 v = createDefault(); + MyValue3 v1 = MyValue3.create(); + v = setV1(v, v1); + MyValue3 v2 = MyValue3.create(); + v = setV2(v, v2); + return v; + } + + public void verify(MyValue4 other) { + v1.verify(other.v1); + v2.verify(other.v2); + } + } + + public class ValueTypeTestBench { // Print ideal graph after execution of each test private static final boolean PRINT_GRAPH = true; // Random test values
*** 1503,1514 **** /* The compiler is supposed to determine that the value to be * unboxed in nullcvvUnboxLoadLong is always null. Therefore, the * compiler generates only the path leading to the corresponding * uncommon trap. */ ! @Test(valid = AlwaysIncrementalInlineOff, failOn = RETURN) ! @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1}) public long test61() throws Throwable { return (long)nullvccUnboxLoadLongMH.invokeExact(); } @DontCompile --- 1747,1757 ---- /* The compiler is supposed to determine that the value to be * unboxed in nullcvvUnboxLoadLong is always null. Therefore, the * compiler generates only the path leading to the corresponding * uncommon trap. */ ! @Test(failOn = RETURN) public long test61() throws Throwable { return (long)nullvccUnboxLoadLongMH.invokeExact(); } @DontCompile
*** 1536,1547 **** /* The compiler is supposed to determine that the allocated * ValueCapableClass1 instance is never null (and therefore not * generate a null check). Also, the source and target type match * (known at compile time), so no type check is needed either.*/ ! @Test(valid = AlwaysIncrementalInlineOff, failOn = NPE) ! @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1}) public long test62() throws Throwable { return (long)checkedvccUnboxLoadLongMH.invokeExact(); } @DontCompile --- 1779,1789 ---- /* The compiler is supposed to determine that the allocated * ValueCapableClass1 instance is never null (and therefore not * generate a null check). Also, the source and target type match * (known at compile time), so no type check is needed either.*/ ! @Test(failOn = NPE) public long test62() throws Throwable { return (long)checkedvccUnboxLoadLongMH.invokeExact(); } @DontCompile
*** 1566,1577 **** /* The compiler is supposed to emit a runtime null check because * it does not have enough information to determine that the value * to be unboxed is not null (and either that it is null). The * declared type of the */ ! @Test(valid = AlwaysIncrementalInlineOff, match = {NPE}, matchCount = {1}) ! @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1}) public long test63(ValueCapableClass1 vcc) throws Throwable { return (long)vccUnboxLoadLongMH.invokeExact(vcc); } @DontCompile --- 1808,1818 ---- /* The compiler is supposed to emit a runtime null check because * it does not have enough information to determine that the value * to be unboxed is not null (and either that it is null). The * declared type of the */ ! @Test(match = {NPE}, matchCount = {1}) public long test63(ValueCapableClass1 vcc) throws Throwable { return (long)vccUnboxLoadLongMH.invokeExact(vcc); } @DontCompile
*** 1584,1595 **** } /* Attempt to unbox an object that is not a subclass of the * value-capable class derived from the value type specified in * the vunbox bytecode. */ ! @Test(valid = AlwaysIncrementalInlineOff, match = {NPE,CCE}, matchCount = {1,1}) ! @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1}) public long test64(Object vcc) throws Throwable { return (long)objectUnboxLoadLongMH.invokeExact(vcc); } @DontCompile --- 1825,1835 ---- } /* Attempt to unbox an object that is not a subclass of the * value-capable class derived from the value type specified in * the vunbox bytecode. */ ! @Test(match = {NPE,CCE}, matchCount = {1,1}) public long test64(Object vcc) throws Throwable { return (long)objectUnboxLoadLongMH.invokeExact(vcc); } @DontCompile
*** 1624,1635 **** } /* Generate an if-then-else construct with one path that contains * an invalid boxing operation (boxing of a value-type to a * non-matching value-capable class).*/ ! @Test(valid = AlwaysIncrementalInlineOff, match = {NPE,CCE}, matchCount = {2,3}) ! @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1}) public long test65(Object obj, boolean warmup) throws Throwable { return (long)objectBoxMH.invokeExact(obj, warmup); } @DontCompile --- 1864,1874 ---- } /* Generate an if-then-else construct with one path that contains * an invalid boxing operation (boxing of a value-type to a * non-matching value-capable class).*/ ! @Test(match = {NPE,CCE}, matchCount = {2,3}) public long test65(Object obj, boolean warmup) throws Throwable { return (long)objectBoxMH.invokeExact(obj, warmup); } @DontCompile
*** 1676,1698 **** lreturn(); } ); } // ========== Test infrastructure ========== private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final int ValueTypePassFieldsAsArgsOn = 0x1; private static final int ValueTypePassFieldsAsArgsOff = 0x2; private static final int ValueTypeArrayFlattenOn = 0x4; private static final int ValueTypeArrayFlattenOff = 0x8; private static final int AlwaysIncrementalInlineOff = 0x10; private static final int AlwaysIncrementalInlineOn = 0x20; ! static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | AlwaysIncrementalInlineOff | AlwaysIncrementalInlineOn; private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs"); private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten"); private static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline"); private static final int COMP_LEVEL_ANY = -1; private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; private static final Hashtable<String, Method> tests = new Hashtable<String, Method>(); private static final int WARMUP = 251; private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); --- 1915,2163 ---- lreturn(); } ); } + // Test deoptimization at call return with return value in registers + @DontCompile + public MyValue2 test66_interp(boolean deopt) { + if (deopt) { + // uncommon trap + WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test66")); + } + return MyValue2.createWithFieldsInline(rI, true); + } + + @Test() + public MyValue2 test66(boolean flag) { + return test66_interp(flag); + } + + @DontCompile + public void test66_verifier(boolean warmup) { + MyValue2 result = test66(!warmup); + MyValue2 v = MyValue2.createWithFieldsInline(rI, true); + Asserts.assertEQ(result.hash(), v.hash()); + } + + // Return value types in registers from interpreter -> compiled + final MyValue3 test67_vt = MyValue3.create(); + @DontCompile + public MyValue3 test67_interp() { + return test67_vt; + } + + MyValue3 test67_vt2; + @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP) + @Test(valid = ValueTypeReturnedAsFieldsOff) + public void test67() { + test67_vt2 = test67_interp(); + } + + @DontCompile + public void test67_verifier(boolean warmup) { + test67(); + test67_vt.verify(test67_vt2); + } + + // Return value types in registers from compiled -> interpreter + final MyValue3 test68_vt = MyValue3.create(); + @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + STORE + TRAP) + @Test(valid = ValueTypeReturnedAsFieldsOff) + public MyValue3 test68() { + return test68_vt; + } + + @DontCompile + public void test68_verifier(boolean warmup) { + MyValue3 vt = test68(); + test68_vt.verify(vt); + } + + // Return value types in registers from compiled -> compiled + final MyValue3 test69_vt = MyValue3.create(); + @DontInline + public MyValue3 test69_comp() { + return test69_vt; + } + + MyValue3 test69_vt2; + @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP) + @Test(valid = ValueTypeReturnedAsFieldsOff) + public void test69() { + test69_vt2 = test69_comp(); + } + + @DontCompile + public void test69_verifier(boolean warmup) throws Exception { + Method helper_m = getClass().getDeclaredMethod("test69_comp"); + if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { + WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); + Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test69_comp not compiled"); + } + test69(); + test69_vt.verify(test69_vt2); + } + + // Same tests as above but with a value type that cannot be returned in registers + + // Return value types in registers from interpreter -> compiled + final MyValue4 test70_vt = MyValue4.create(); + @DontCompile + public MyValue4 test70_interp() { + return test70_vt; + } + + MyValue4 test70_vt2; + @Test + public void test70() { + test70_vt2 = test70_interp(); + } + + @DontCompile + public void test70_verifier(boolean warmup) { + test70(); + test70_vt.verify(test70_vt2); + } + + // Return value types in registers from compiled -> interpreter + final MyValue4 test71_vt = MyValue4.create(); + @Test + public MyValue4 test71() { + return test71_vt; + } + + @DontCompile + public void test71_verifier(boolean warmup) { + MyValue4 vt = test71(); + test71_vt.verify(vt); + } + + // Return value types in registers from compiled -> compiled + final MyValue4 test72_vt = MyValue4.create(); + @DontInline + public MyValue4 test72_comp() { + return test72_vt; + } + + MyValue4 test72_vt2; + @Test + public void test72() { + test72_vt2 = test72_comp(); + } + + @DontCompile + public void test72_verifier(boolean warmup) throws Exception { + Method helper_m = getClass().getDeclaredMethod("test72_comp"); + if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { + WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); + Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test72_comp not compiled"); + } + test72(); + test72_vt.verify(test72_vt2); + } + + // Return values and method handles tests + + // Everything inlined + final MyValue3 test73_vt = MyValue3.create(); + @ForceInline + MyValue3 test73_target() { + return test73_vt; + } + + static final MethodHandle test73_mh; + + @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + STORE + CALL) + @Test(valid = ValueTypeReturnedAsFieldsOff, match = { ALLOC, STORE }, matchCount = { 1, 12 }) + MyValue3 test73() throws Throwable { + return (MyValue3)test73_mh.invokeExact(this); + } + + @DontCompile + public void test73_verifier(boolean warmup) throws Throwable { + MyValue3 vt = test73(); + test73_vt.verify(vt); + } + + // Leaf method not inlined but returned type is known + final MyValue3 test74_vt = MyValue3.create(); + @DontInline + MyValue3 test74_target() { + return test74_vt; + } + + static final MethodHandle test74_mh; + + @Test + MyValue3 test74() throws Throwable { + return (MyValue3)test74_mh.invokeExact(this); + } + + @DontCompile + public void test74_verifier(boolean warmup) throws Throwable { + Method helper_m = getClass().getDeclaredMethod("test74_target"); + if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { + WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); + Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test74_target not compiled"); + } + MyValue3 vt = test74(); + test74_vt.verify(vt); + } + + // Leaf method not inlined and returned type not known + final MyValue3 test75_vt = MyValue3.create(); + @DontInline + MyValue3 test75_target() { + return test75_vt; + } + + static final MethodHandle test75_mh; + + @Test + MyValue3 test75() throws Throwable { + return (MyValue3)test75_mh.invokeExact(this); + } + + @DontCompile + public void test75_verifier(boolean warmup) throws Throwable { + // hack so C2 doesn't know the target of the invoke call + Class c = Class.forName("java.lang.invoke.DirectMethodHandle"); + Method m = c.getDeclaredMethod("internalMemberName", Object.class); + WHITE_BOX.testSetDontInlineMethod(m, warmup); + MyValue3 vt = test75(); + test75_vt.verify(vt); + } + + static { + try { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.fromMethodDescriptorString("()Qcompiler/valhalla/valuetypes/MyValue3;", ValueTypeTestBench.class.getClassLoader()); + test73_mh = lookup.findVirtual(ValueTypeTestBench.class, "test73_target", mt); + test74_mh = lookup.findVirtual(ValueTypeTestBench.class, "test74_target", mt); + test75_mh = lookup.findVirtual(ValueTypeTestBench.class, "test75_target", mt); + } catch (NoSuchMethodException|IllegalAccessException e) { + throw new RuntimeException("method handle lookup fails"); + } + } + // ========== Test infrastructure ========== private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final int ValueTypePassFieldsAsArgsOn = 0x1; private static final int ValueTypePassFieldsAsArgsOff = 0x2; private static final int ValueTypeArrayFlattenOn = 0x4; private static final int ValueTypeArrayFlattenOff = 0x8; private static final int AlwaysIncrementalInlineOff = 0x10; private static final int AlwaysIncrementalInlineOn = 0x20; ! private static final int ValueTypeReturnedAsFieldsOn = 0x40; ! private static final int ValueTypeReturnedAsFieldsOff = 0x80; ! static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | AlwaysIncrementalInlineOff | AlwaysIncrementalInlineOn | ValueTypeReturnedAsFieldsOn; private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs"); private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten"); private static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline"); + private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields"); private static final int COMP_LEVEL_ANY = -1; private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; private static final Hashtable<String, Method> tests = new Hashtable<String, Method>(); private static final int WARMUP = 251; private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
*** 1713,1722 **** --- 2178,2188 ---- private static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END; private static final String RETURN = START + "Return" + MID + "returns" + END; private static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END; private static final String NPE = START + "CallStaticJava" + MID + "null_check" + END; private static final String CCE = START + "CallStaticJava" + MID + "class_check" + END; + private static final String CALL = START + "CallStaticJava" + MID + END; private static final String SCOBJ = "(.*# ScObj.*" + END; static { // Gather all test methods and put them in Hashtable for (Method m : ValueTypeTestBench.class.getDeclaredMethods()) {
*** 1753,1793 **** public static void main(String[] args) throws Throwable { //tests.values().removeIf(p -> !p.getName().equals("test64")); // Run single test if (args.length == 0) { execute_vm("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-BackgroundCompilation", "-XX:+PrintCompilation", "-XX:+PrintInlining", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue1::*", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2::*", "-XX:CompileCommand=compileonly,java.lang.Object::<init>", ! "-XX:CompileCommand=inline,java.lang.__Value::hashCode"); } else { // Execute tests ValueTypeTestBench bench = new ValueTypeTestBench(); bench.run(); } } public static void parseOutput(String output) throws Exception { ! String split = "b compiler.valhalla.valuetypes."; ! String[] compilations = output.split(split); // Print header ! System.out.println(compilations[0]); ! // Iterate over compilation output ! for (String graph : compilations) { ! String[] lines = graph.split("\\n"); ! if (lines[0].contains("@")) { ! continue; // Ignore OSR compilations } ! String testName = lines[0].split(" ")[0]; Method test = tests.get(testName); if (test == null) { // Skip helper methods continue; } if (PRINT_GRAPH) { ! System.out.println("\nGraph for " + graph); } // Parse graph using regular expressions to determine if it contains forbidden nodes Test[] annos = test.getAnnotationsByType(Test.class); Test anno = null; for (Test a : annos) { --- 2219,2278 ---- public static void main(String[] args) throws Throwable { //tests.values().removeIf(p -> !p.getName().equals("test64")); // Run single test if (args.length == 0) { execute_vm("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-BackgroundCompilation", "-XX:+PrintCompilation", "-XX:+PrintInlining", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly", + "-XX:CICompilerCount=1", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue1::*", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2::*", "-XX:CompileCommand=compileonly,java.lang.Object::<init>", ! "-XX:CompileCommand=inline,java.lang.__Value::hashCode", ! "-XX:CompileCommand=compileonly,java.lang.invoke.*::*"); } else { // Execute tests ValueTypeTestBench bench = new ValueTypeTestBench(); bench.run(); } } public static void parseOutput(String output) throws Exception { ! Pattern comp_re = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+(%| )(s| )(!| )b(n| )\\s+\\S+\\.(?<name>[^.]+::\\S+)\\s+(?<osr>@ \\d+\\s+)?[(]\\d+ bytes[)]\\n"); ! Matcher m = comp_re.matcher(output); ! Map<String,String> compilations = new LinkedHashMap<>(); ! int prev = 0; ! String methodName = null; ! while (m.find()) { ! if (prev == 0) { // Print header ! System.out.print(output.substring(0, m.start()+1)); ! } else if (methodName != null) { ! compilations.put(methodName, output.substring(prev, m.start()+1)); } ! if (m.group("osr") != null) { ! methodName = null; ! } else { ! methodName = m.group("name"); ! } ! prev = m.end(); ! } ! if (prev == 0) { ! // Print header ! System.out.print(output); ! } else if (methodName != null) { ! compilations.put(methodName, output.substring(prev)); ! } ! // Iterate over compilation output ! for (String testName : compilations.keySet()) { Method test = tests.get(testName); if (test == null) { // Skip helper methods continue; } + String graph = compilations.get(testName); if (PRINT_GRAPH) { ! System.out.println("\nGraph for " + testName + "\n" + graph); } // Parse graph using regular expressions to determine if it contains forbidden nodes Test[] annos = test.getAnnotationsByType(Test.class); Test anno = null; for (Test a : annos) {
*** 1807,1816 **** --- 2292,2307 ---- assert anno == null; anno = a; } else if ((a.valid() & AlwaysIncrementalInlineOn) != 0 && AlwaysIncrementalInline) { assert anno == null; anno = a; + } else if ((a.valid() & ValueTypeReturnedAsFieldsOn) != 0 && ValueTypeReturnedAsFields) { + assert anno == null; + anno = a; + } else if ((a.valid() & ValueTypeReturnedAsFieldsOff) != 0 && !ValueTypeReturnedAsFields) { + assert anno == null; + anno = a; } } assert anno != null; String regexFail = anno.failOn(); if (!regexFail.isEmpty()) {
< prev index next >