< prev index next >

test/compiler/valhalla/valuetypes/ValueTypeTestBench.java

Print this page

        

*** 35,44 **** --- 35,51 ---- * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:-ValueTypePassFieldsAsArgs -XX:-ValueArrayFlatten * -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench */ + // TODO Enable this + /* + * run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+UnlockExperimentalVMOptions -XX:+ValueTypePassFieldsAsArgs -XX:+AlwaysIncrementalInline -XX:+ValueArrayFlatten + * -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench + */ + package compiler.valhalla.valuetypes; import compiler.whitebox.CompilerWhiteBoxTest; import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts;
*** 473,525 **** long result = test11(rI, rL); Asserts.assertEQ(result, hash(rI + 10, rL + 10)); } // Test loop with uncommon trap referencing a value type ! @Test(match = {TRAP, SCOBJ}, matchCount = {1, 1}, failOn = ALLOC + LOAD + STORE) public long test12(boolean b) { MyValue1 v = MyValue1.createInline(rI, rL); ! long result = 42; for (int i = 0; i < 1000; ++i) { if (b) { result += v.x; } else { // Uncommon trap referencing v. We delegate allocation to the // interpreter by adding a SafePointScalarObjectNode. result = v.hashInterpreted(); } } return result; } @DontCompile public void test12_verifier(boolean warmup) { long result = test12(warmup); ! Asserts.assertEQ(result, warmup ? 42 + (1000*rI) : hash()); } // Test loop with uncommon trap referencing a value type ! @Test(match = {TRAP, LOAD}, matchCount = {1, 1}, failOn = ALLOC + STORE + SCOBJ) public long test13(boolean b) { MyValue1 v = MyValue1.createDontInline(rI, rL); ! long result = 42; for (int i = 0; i < 1000; ++i) { if (b) { result += v.x; } else { // Uncommon trap referencing v. Should not allocate // but just pass the existing oop to the uncommon trap. result = v.hashInterpreted(); } } return result; } @DontCompile public void test13_verifier(boolean warmup) { long result = test13(warmup); ! Asserts.assertEQ(result, warmup ? 42 + (1000*rI) : hash()); } // Create a value type in a non-inlined method and then call a // non-inlined method on that value type. @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = (ALLOC + STORE + TRAP), match = {LOAD}, matchCount = {7}) --- 480,546 ---- long result = test11(rI, rL); Asserts.assertEQ(result, hash(rI + 10, rL + 10)); } // Test loop with uncommon trap referencing a value type ! @Test(match = {TRAP, SCOBJ}, matchCount = {1, -1 /* at least 1 */}, failOn = LOAD) public long test12(boolean b) { MyValue1 v = MyValue1.createInline(rI, rL); ! MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; ! for (int i = 0; i < va.length; ++i) { ! va[i] = MyValue1.createInline(rI, rL); ! } ! long result = rL; for (int i = 0; i < 1000; ++i) { if (b) { result += v.x; } else { // Uncommon trap referencing v. We delegate allocation to the // interpreter by adding a SafePointScalarObjectNode. result = v.hashInterpreted(); + for (int j = 0; j < va.length; ++j) { + result += va[j].hash(); + } } } return result; } @DontCompile public void test12_verifier(boolean warmup) { long result = test12(warmup); ! Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); } // Test loop with uncommon trap referencing a value type ! @Test(match = {TRAP}, matchCount = {1}) public long test13(boolean b) { MyValue1 v = MyValue1.createDontInline(rI, rL); ! MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; ! for (int i = 0; i < va.length; ++i) { ! va[i] = MyValue1.createDontInline(rI, rL); ! } ! long result = rL; for (int i = 0; i < 1000; ++i) { if (b) { result += v.x; } else { // Uncommon trap referencing v. Should not allocate // but just pass the existing oop to the uncommon trap. result = v.hashInterpreted(); + for (int j = 0; j < va.length; ++j) { + result += va[j].hashInterpreted(); + } } } return result; } @DontCompile public void test13_verifier(boolean warmup) { long result = test13(warmup); ! Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); } // Create a value type in a non-inlined method and then call a // non-inlined method on that value type. @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = (ALLOC + STORE + TRAP), match = {LOAD}, matchCount = {7})
*** 619,648 **** // Create a value type (array) in compiled code and pass it to the // interpreter via a call. The value type is live at the uncommon // trap: verify that deoptimization causes the value type to be // correctly allocated. @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = LOAD + ALLOC + STORE) ! @Test(valid = ValueTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD) public long test20(boolean flag) { MyValue1 v = MyValue1.createInline(rI, rL); ! // TODO add value type array testcase ! // MyValue1[] va = new MyValue1[42]; if (flag) { // uncommon trap WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test20")); } ! return v.hashInterpreted(); // + va[0].hashInterpreted(); } @DontCompile public void test20_verifier(boolean warmup) { MyValue1[] va = new MyValue1[42]; long result = test20(false); ! Asserts.assertEQ(result, hash() /* + va[0].hash() */); if (!warmup) { result = test20(true); ! Asserts.assertEQ(result, hash() /* + va[0].hash() */); } } // Value type fields in regular object MyValue1 val1; --- 640,669 ---- // Create a value type (array) in compiled code and pass it to the // interpreter via a call. The value type is live at the uncommon // trap: verify that deoptimization causes the value type to be // correctly allocated. @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = LOAD + ALLOC + STORE) ! @Test(valid = ValueTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {2}, failOn = LOAD) public long test20(boolean flag) { MyValue1 v = MyValue1.createInline(rI, rL); ! MyValue1[] va = new MyValue1[3]; if (flag) { // uncommon trap WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test20")); } ! return v.hashInterpreted() + va[0].hashInterpreted() + ! va[1].hashInterpreted() + va[2].hashInterpreted(); } @DontCompile public void test20_verifier(boolean warmup) { MyValue1[] va = new MyValue1[42]; long result = test20(false); ! Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); if (!warmup) { result = test20(true); ! Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); } } // Value type fields in regular object MyValue1 val1;
*** 893,923 **** Asserts.assertEQ(result, v1.hashInterpreted() + rL + rI + v2.hashInterpreted()); } // test that debug info at a call is correct @DontCompile ! public long test36_interp(MyValue2 v, boolean flag) { if (flag) { // uncommon trap WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test36")); } ! return v.hash(); } @Test(failOn = ALLOC + STORE + TRAP) ! public long test36(MyValue2 v, boolean flag, long l) { ! return test36_interp(v, flag) + l; } @DontCompile public void test36_verifier(boolean warmup) { MyValue2 v = MyValue2.createInline(rI, true); ! long result = test36(v, false, rL); ! Asserts.assertEQ(result, v.hashInterpreted() + rL); if (!warmup) { ! result = test36(v, true, rL); ! Asserts.assertEQ(result, v.hashInterpreted() + rL); } } // Test vbox and vunbox @Test --- 914,947 ---- Asserts.assertEQ(result, v1.hashInterpreted() + rL + rI + v2.hashInterpreted()); } // test that debug info at a call is correct @DontCompile ! public long test36_interp(MyValue2 v, MyValue1[] va, boolean flag) { if (flag) { // uncommon trap WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test36")); } ! return v.hash() + va[0].hash() + va[1].hash(); } @Test(failOn = ALLOC + STORE + TRAP) ! public long test36(MyValue2 v, MyValue1[] va, boolean flag, long l) { ! return test36_interp(v, va, flag) + l; } @DontCompile public void test36_verifier(boolean warmup) { MyValue2 v = MyValue2.createInline(rI, true); ! MyValue1[] va = new MyValue1[2]; ! va[0] = MyValue1.createDontInline(rI, rL); ! va[1] = MyValue1.createDontInline(rI, rL); ! long result = test36(v, va, false, rL); ! Asserts.assertEQ(result, v.hashInterpreted() + va[0].hash() + va[1].hash() + rL); if (!warmup) { ! result = test36(v, va, true, rL); ! Asserts.assertEQ(result, v.hashInterpreted() + va[0].hash() + va[1].hash() + rL); } } // Test vbox and vunbox @Test
*** 1066,1076 **** Asserts.assertEQ(va[i].hash(), hash()); } } // Test creation of a value type array and element access ! @Test(failOn = (LOOP + LOAD + TRAP)) public long test42() { MyValue1[] va = new MyValue1[1]; va[0] = MyValue1.createInline(rI, rL); return va[0].hash(); } --- 1090,1101 ---- Asserts.assertEQ(va[i].hash(), hash()); } } // Test creation of a value type array and element access ! @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOOP + LOAD + TRAP)) ! @Test(valid = ValueTypeArrayFlattenOn, failOn = (ALLOC + ALLOCA + LOOP + LOAD + LOADP + STORE + TRAP)) public long test42() { MyValue1[] va = new MyValue1[1]; va[0] = MyValue1.createInline(rI, rL); return va[0].hash(); }
*** 1126,1137 **** for (int i = 0; i < 10; ++i) { Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); } } ! // TODO add match rules ! @Test() public MyValue1[] test45(boolean b) { MyValue1[] va; if (b) { va = new MyValue1[5]; for (int i = 0; i < 5; ++i) { --- 1151,1161 ---- for (int i = 0; i < 10; ++i) { Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); } } ! @Test(failOn = (TRAP)) public MyValue1[] test45(boolean b) { MyValue1[] va; if (b) { va = new MyValue1[5]; for (int i = 0; i < 5; ++i) {
*** 1167,1177 **** Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); } } // Test creation of value type array with single element ! @Test(failOn = LOOP + TRAP) public MyValue1 test46() { MyValue1[] va = new MyValue1[1]; return va[0]; } --- 1191,1202 ---- Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); } } // Test creation of value type array with single element ! @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOAD + LOOP + TRAP)) ! @Test(valid = ValueTypeArrayFlattenOn, failOn = (ALLOCA + LOAD + LOOP + TRAP)) public MyValue1 test46() { MyValue1[] va = new MyValue1[1]; return va[0]; }
*** 1208,1219 **** public void test48_verifier(boolean warmup) { MyValue1[] va = test48(); Asserts.assertEQ(va.length, 0); } - // Test that value type array loaded from field has correct type static MyValue1[] test49_va; @Test(failOn = (LOOP)) public long test49() { return test49_va[0].hash(); } --- 1233,1245 ---- public void test48_verifier(boolean warmup) { MyValue1[] va = test48(); Asserts.assertEQ(va.length, 0); } static MyValue1[] test49_va; + + // Test that value type array loaded from field has correct type @Test(failOn = (LOOP)) public long test49() { return test49_va[0].hash(); }
*** 1224,1234 **** long result = test49(); Asserts.assertEQ(result, hash()); } // test vdefault ! @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) public long test50() { MyValue2 v = MyValue2.createDefaultInline(); return v.hash(); } --- 1250,1260 ---- long result = test49(); Asserts.assertEQ(result, hash()); } // test vdefault ! @Test(failOn = ALLOC + LOAD + LOADP + STORE + LOOP + TRAP) public long test50() { MyValue2 v = MyValue2.createDefaultInline(); return v.hash(); }
*** 1251,1261 **** long result = test51(); Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hash()); } // test vwithfield ! @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) public long test52() { MyValue2 v = MyValue2.createWithFieldsInline(rI, true); return v.hash(); } --- 1277,1287 ---- long result = test51(); Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hash()); } // test vwithfield ! @Test(failOn = ALLOC + LOAD + LOADP + STORE + LOOP + TRAP) public long test52() { MyValue2 v = MyValue2.createWithFieldsInline(rI, true); return v.hash(); }
*** 1278,1288 **** long result = test53(); Asserts.assertEQ(result, 2 * hash()); } // multi-dimensional arrays ! @Test() public MyValue1[][][] test54(int len1, int len2, int len3) { MyValue1[][][] arr = new MyValue1[len1][len2][len3]; for (int i = 0; i < len1; i++) { for (int j = 0; j < len2; j++) { for (int k = 0; k < len3; k++) { --- 1304,1314 ---- long result = test53(); Asserts.assertEQ(result, 2 * hash()); } // multi-dimensional arrays ! @Test public MyValue1[][][] test54(int len1, int len2, int len3) { MyValue1[][][] arr = new MyValue1[len1][len2][len3]; for (int i = 0; i < len1; i++) { for (int j = 0; j < len2; j++) { for (int k = 0; k < len3; k++) {
*** 1303,1313 **** } } } } ! @Test() public void test55(MyValue1[][][] arr, long[] res) { int l = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { for (int k = 0; k < arr[i][j].length; k++) { --- 1329,1339 ---- } } } } ! @Test public void test55(MyValue1[][][] arr, long[] res) { int l = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { for (int k = 0; k < arr[i][j].length; k++) {
*** 1381,1405 **** tests.put("ValueTypeTestBench::" + m.getName(), m); } } } ! private static void execute_vm(String... extra_args) throws Throwable { ! ArrayList<String> all_args = new ArrayList(List.of( ! "-noverify", ! "-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI", ! "-XX:-TieredCompilation", "-XX:-BackgroundCompilation", ! "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+PrintCompilation", "-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::*" ! )); ! all_args.addAll(List.of(extra_args)); // Run tests in own process and verify output all_args.add(ValueTypeTestBench.class.getName()); all_args.add("run"); ! OutputAnalyzer oa = ProcessTools.executeTestJvm(all_args.toArray(new String[0])); // If ideal graph printing is enabled/supported, verify output String output = oa.getOutput(); oa.shouldHaveExitValue(0); if (output.contains("PrintIdeal enabled")) { parseOutput(output); --- 1407,1424 ---- tests.put("ValueTypeTestBench::" + m.getName(), m); } } } ! private static void execute_vm(String... args) throws Throwable { ! Asserts.assertFalse(tests.isEmpty(), "no tests to execute"); ! ArrayList<String> all_args = new ArrayList(List.of(args)); // Run tests in own process and verify output all_args.add(ValueTypeTestBench.class.getName()); all_args.add("run"); ! // Spawn process with default JVM options from the test's run command ! OutputAnalyzer oa = ProcessTools.executeTestJvmAllArgs(all_args.toArray(new String[all_args.size()])); // If ideal graph printing is enabled/supported, verify output String output = oa.getOutput(); oa.shouldHaveExitValue(0); if (output.contains("PrintIdeal enabled")) { parseOutput(output);
*** 1408,1435 **** } } public static void main(String[] args) throws Throwable { if (args.length == 0) { ! String field_as_args; ! String array_flatten; ! if (ValueTypePassFieldsAsArgs) { ! field_as_args = "-XX:+ValueTypePassFieldsAsArgs"; ! } else { ! field_as_args = "-XX:-ValueTypePassFieldsAsArgs"; ! } ! if (ValueTypeArrayFlatten) { ! array_flatten = "-XX:+ValueArrayFlatten"; ! } else { ! array_flatten = "-XX:-ValueArrayFlatten"; ! } ! execute_vm("-XX:+UnlockExperimentalVMOptions", field_as_args, array_flatten); ! execute_vm("-XX:+AlwaysIncrementalInline", "-XX:+UnlockExperimentalVMOptions", field_as_args, array_flatten); } else { - if (USE_COMPILER && PRINT_IDEAL && !XCOMP) { - System.out.println("PrintIdeal enabled"); - } // Execute tests ValueTypeTestBench bench = new ValueTypeTestBench(); bench.run(); } } --- 1427,1442 ---- } } public static void main(String[] args) throws Throwable { if (args.length == 0) { ! execute_vm("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-BackgroundCompilation", ! "-XX:+PrintCompilation", "-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::*"); } else { // Execute tests ValueTypeTestBench bench = new ValueTypeTestBench(); bench.run(); } }
*** 1489,1500 **** --- 1496,1511 ---- String nodes = ""; while (matcher.find()) { count++; nodes += matcher.group() + "\n"; } + if (matchCount[i] < 0) { + Asserts.assertLTE(Math.abs(matchCount[i]), count, "Graph for '" + testName + "' contains different number of match nodes:\n" + nodes); + } else { Asserts.assertEQ(matchCount[i], count, "Graph for '" + testName + "' contains different number of match nodes:\n" + nodes); } + } tests.remove(testName); System.out.println(testName + " passed"); } // Check if all tests were compiled if (tests.size() != 0) {
*** 1522,1531 **** --- 1533,1545 ---- } } } public void run() throws Exception { + if (USE_COMPILER && PRINT_IDEAL && !XCOMP) { + System.out.println("PrintIdeal enabled"); + } System.out.format("rI = %d, rL = %d\n", rI, rL); setup(this.getClass().getDeclaredMethods()); setup(MyValue1.class.getDeclaredMethods()); setup(MyValue2.class.getDeclaredMethods());
< prev index next >