< prev index next >

test/compiler/valhalla/valuetypes/ValueTypeTestBench.java

Print this page

        

*** 28,41 **** * @library /testlibrary /test/lib /compiler/whitebox / * @build compiler.valhalla.valuetypes.ValueTypeTestBench * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller jdk.test.lib.Platform * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ! * -XX:+UnlockExperimentalVMOptions -XX:+ValueTypePassFieldsAsArgs * -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ! * -XX:+UnlockExperimentalVMOptions -XX:-ValueTypePassFieldsAsArgs * -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench */ package compiler.valhalla.valuetypes; --- 28,41 ---- * @library /testlibrary /test/lib /compiler/whitebox / * @build compiler.valhalla.valuetypes.ValueTypeTestBench * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller jdk.test.lib.Platform * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ! * -XX:+UnlockExperimentalVMOptions -XX:+ValueTypePassFieldsAsArgs -XX:+ValueArrayFlatten * -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ! * -XX:+UnlockExperimentalVMOptions -XX:-ValueTypePassFieldsAsArgs -XX:-ValueArrayFlatten * -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench */ package compiler.valhalla.valuetypes;
*** 98,107 **** --- 98,118 ---- @DontCompile public long hashInterpreted() { return s + sf + x + y + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted(); } + + @ForceInline + public void print() { + System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", v1["); + v1.print(); + System.out.print("], v2["); + v2.print(); + System.out.print("], v3["); + v3.print(); + System.out.print("], c=" + c); + } } __ByValue final class MyValue2 { final int x; final boolean b;
*** 125,134 **** --- 136,150 ---- @DontInline public long hashInterpreted() { return x + (b ? 0 : 1) + c; } + + @ForceInline + public void print() { + System.out.print("x=" + x + ", b=" + b + ", c=" + c); + } } public class ValueTypeTestBench { // Print ideal graph after execution of each test private static final boolean PRINT_GRAPH = true;
*** 281,291 **** Asserts.assertEQ(test8(true), hash()); Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1)); } // Merge value types created from two branches ! @Test(valid = ValueTypePassFieldsAsArgsOn, match = {LOAD}, matchCount = {9}, failOn = TRAP + ALLOC + STORE) @Test(valid = ValueTypePassFieldsAsArgsOff, match = {ALLOC, STORE}, matchCount = {1, 3}, failOn = LOAD + TRAP) public MyValue1 test9(boolean b) { MyValue1 v; if (b) { // Value type is not allocated --- 297,309 ---- Asserts.assertEQ(test8(true), hash()); Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1)); } // Merge value types created from two branches ! @Test(valid = ValueTypePassFieldsAsArgsOn, match = {LOAD}, matchCount = {7}, failOn = TRAP + ALLOC + STORE) ! // FIXME ! //@Test(valid = ValueTypePassFieldsAsArgsOff, match = {ALLOC, STORE}, matchCount = {1, 9}, failOn = LOAD + TRAP) @Test(valid = ValueTypePassFieldsAsArgsOff, match = {ALLOC, STORE}, matchCount = {1, 3}, failOn = LOAD + TRAP) public MyValue1 test9(boolean b) { MyValue1 v; if (b) { // Value type is not allocated
*** 393,403 **** 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 = {9}) @Test(valid = ValueTypePassFieldsAsArgsOff, failOn = (ALLOC + LOAD + STORE + TRAP)) public long test14() { MyValue1 v = MyValue1.createDontInline(rI, rL); return v.hashInterpreted(); } --- 411,421 ---- 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}) @Test(valid = ValueTypePassFieldsAsArgsOff, failOn = (ALLOC + LOAD + STORE + TRAP)) public long test14() { MyValue1 v = MyValue1.createDontInline(rI, rL); return v.hashInterpreted(); }
*** 487,518 **** public void test19_verifier(boolean warmup) { long result = test19(); Asserts.assertEQ(result, hash()); } ! // Create a value type 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); if (flag) { // uncommon trap WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test20")); } ! return v.hashInterpreted(); } @DontCompile public void test20_verifier(boolean warmup) { long result = test20(false); ! Asserts.assertEQ(result, hash()); if (!warmup) { result = test20(true); ! Asserts.assertEQ(result, hash()); } } // Value type fields in regular object MyValue1 val1; --- 505,539 ---- public void test19_verifier(boolean warmup) { long result = test19(); Asserts.assertEQ(result, hash()); } ! // 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;
*** 565,587 **** // Test OSR compilation @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) public long test23() { MyValue1 v = MyValue1.createInline(rI, rL); long result = 0; // Long loop to trigger OSR compilation for (int i = 0 ; i < 100_000 ; ++i) { // Reference local value type in interpreter state ! result = v.hash(); } return result; } @DontCompile public void test23_verifier(boolean warmup) { long result = test23(); ! Asserts.assertEQ(result, hash()); } // Test interpreter to compiled code with various signatures @Test(failOn = ALLOC + STORE + TRAP) public long test24(MyValue2 v) { --- 586,611 ---- // Test OSR compilation @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) public long test23() { MyValue1 v = MyValue1.createInline(rI, rL); + // TODO add OSR testcase for value type arrays + //MyValue1[] va = new MyValue1[10]; long result = 0; // Long loop to trigger OSR compilation for (int i = 0 ; i < 100_000 ; ++i) { // Reference local value type in interpreter state ! result = v.hash(); // + va[0].hash(); } return result; } @DontCompile public void test23_verifier(boolean warmup) { + //MyValue1[] va = new MyValue1[10]; long result = test23(); ! Asserts.assertEQ(result, hash() /* + va[0].hash() */); } // Test interpreter to compiled code with various signatures @Test(failOn = ALLOC + STORE + TRAP) public long test24(MyValue2 v) {
*** 816,826 **** lreturn(); } ); } - @Test public int test38() throws Throwable { return (int)vccUnboxLoadIntMH.invokeExact(vcc); } --- 840,849 ----
*** 910,928 **** vbox(ValueCapableClass1.class). getfield(ValueCapableClass1.class, "x", "I"). ireturn(); } ); } // ========== Test infrastructure ========== private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final int ValueTypePassFieldsAsArgsOn = 0x1; private static final int ValueTypePassFieldsAsArgsOff = 0x2; ! static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff; private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs"); 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 = 250; private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); --- 933,1118 ---- vbox(ValueCapableClass1.class). getfield(ValueCapableClass1.class, "x", "I"). ireturn(); } ); + + } + + // Test value type array creation and initialization + @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOAD)) + @Test(valid = ValueTypeArrayFlattenOn) + public MyValue1[] test41(int len) { + MyValue1[] va = new MyValue1[len]; + for (int i = 0; i < len; ++i) { + va[i] = MyValue1.createDontInline(rI, rL); + } + return va; + } + + @DontCompile + public void test41_verifier(boolean warmup) { + int len = Math.abs(rI % 10); + MyValue1[] va = test41(len); + for (int i = 0; i < len; ++i) { + 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(); + } + + @DontCompile + public void test42_verifier(boolean warmup) { + long result = test42(); + Asserts.assertEQ(result, hash()); + } + + // Test receiving a value type array from the interpreter, + // updating its elements in a loop and computing a hash. + @Test(failOn = (ALLOCA)) + public long test43(MyValue1[] va) { + long result = 0; + for (int i = 0; i < 10; ++i) { + result += va[i].hash(); + va[i] = MyValue1.createInline(rI + 1, rL + 1); + } + return result; + } + + @DontCompile + public void test43_verifier(boolean warmup) { + MyValue1[] va = new MyValue1[10]; + long expected = 0; + for (int i = 0; i < 10; ++i) { + va[i] = MyValue1.createDontInline(rI + i, rL + i); + expected += va[i].hash(); + } + long result = test43(va); + Asserts.assertEQ(expected, result); + for (int i = 0; i < 10; ++i) { + if (va[i].hash() != hash(rI + 1, rL + 1)) { + Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1)); + } + } + } + + // Test returning a value type array received from the interpreter + @Test(failOn = ALLOC + ALLOCA + LOAD + LOADP + STORE + LOOP + TRAP) + public MyValue1[] test44(MyValue1[] va) { + return va; + } + + @DontCompile + public void test44_verifier(boolean warmup) { + MyValue1[] va = new MyValue1[10]; + for (int i = 0; i < 10; ++i) { + va[i] = MyValue1.createDontInline(rI + i, rL + i); + } + va = test44(va); + 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) { + va[i] = MyValue1.createInline(rI, rL); + } + } else { + va = new MyValue1[10]; + for (int i = 0; i < 10; ++i) { + va[i] = MyValue1.createInline(rI + i, rL + i); + } + } + long sum = va[0].hashInterpreted(); + if (b) { + va[0] = MyValue1.createDontInline(rI, sum); + } else { + va[0] = MyValue1.createDontInline(rI + 1, sum + 1); + } + return va; + } + + @DontCompile + public void test45_verifier(boolean warmup) { + MyValue1[] va = test45(true); + Asserts.assertEQ(va.length, 5); + Asserts.assertEQ(va[0].hash(), hash(rI, hash())); + for (int i = 1; i < 5; ++i) { + Asserts.assertEQ(va[i].hash(), hash()); + } + va = test45(false); + Asserts.assertEQ(va.length, 10); + Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1)); + for (int i = 1; i < 10; ++i) { + 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]; + } + + @DontCompile + public void test46_verifier(boolean warmup) { + MyValue1[] va = new MyValue1[1]; + MyValue1 v = test46(); + Asserts.assertEQ(v.hash(), va[0].hash()); + } + + // Test default initialization of value type arrays + @Test(failOn = LOAD) + public MyValue1[] test47(int len) { + return new MyValue1[len]; + } + + @DontCompile + public void test47_verifier(boolean warmup) { + int len = Math.abs(rI % 10); + MyValue1[] va = new MyValue1[len]; + MyValue1[] var = test47(len); + for (int i = 0; i < len; ++i) { + Asserts.assertEQ(va[i].hash(), var[i].hash()); + } + } + + // Test creation of value type array with zero length + @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + public MyValue1[] test48() { + return new MyValue1[0]; + } + + @DontCompile + public void test48_verifier(boolean warmup) { + MyValue1[] va = test48(); + Asserts.assertEQ(va.length, 0); } // ========== 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; ! static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff; private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs"); + private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten"); 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 = 250; private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
*** 933,944 **** // Regular expressions used to match nodes in the PrintIdeal output private static final String START = "(\\d+\\t(.*"; private static final String MID = ".*)+\\t===.*"; private static final String END = ")|"; private static final String ALLOC = START + "CallStaticJava" + MID + "_new_instance_Java" + END; ! private static final String LOAD = START + "Load" + MID + "valuetype\\*" + END; ! private static final String STORE = START + "Store" + MID + "valuetype\\*" + END; private static final String LOOP = START + "Loop" + MID + "" + END; private static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap" + END; // TODO: match field values of scalar replaced object private static final String SCOBJ = "(.*# ScObj.*" + END; --- 1123,1137 ---- // Regular expressions used to match nodes in the PrintIdeal output private static final String START = "(\\d+\\t(.*"; private static final String MID = ".*)+\\t===.*"; private static final String END = ")|"; private static final String ALLOC = START + "CallStaticJava" + MID + "_new_instance_Java" + END; ! private static final String ALLOCA = START + "CallStaticJava" + MID + "_new_array_Java" + END; ! private static final String LOAD = START + "Load(B|S|I|L|F|D)" + MID + "valuetype\\*" + END; ! private static final String LOADP = START + "Load(P|N)" + MID + "valuetype\\*" + END; ! private static final String STORE = START + "Store(B|S|I|L|F|D)" + MID + "valuetype\\*" + END; ! private static final String STOREP = START + "Store(P|N)" + MID + "valuetype\\*" + END; private static final String LOOP = START + "Loop" + MID + "" + END; private static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap" + END; // TODO: match field values of scalar replaced object private static final String SCOBJ = "(.*# ScObj.*" + END;
*** 978,994 **** } public static void main(String[] args) throws Throwable { if (args.length == 0) { String field_as_args; ! if ((Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs")) { field_as_args = "-XX:+ValueTypePassFieldsAsArgs"; } else { field_as_args = "-XX:-ValueTypePassFieldsAsArgs"; } ! execute_vm("-XX:+UnlockExperimentalVMOptions", field_as_args); ! execute_vm("-XX:+AlwaysIncrementalInline", "-XX:+UnlockExperimentalVMOptions", field_as_args); } else { if (USE_COMPILER && PRINT_IDEAL && !XCOMP) { System.out.println("PrintIdeal enabled"); } // Execute tests --- 1171,1193 ---- } 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
*** 1025,1048 **** assert anno == null; anno = a; } else if ((a.valid() & ValueTypePassFieldsAsArgsOff) != 0 && !ValueTypePassFieldsAsArgs) { assert anno == null; anno = a; } } assert anno != null; String regexFail = anno.failOn(); if (!regexFail.isEmpty()) { Pattern pattern = Pattern.compile(regexFail.substring(0, regexFail.length()-1)); Matcher matcher = pattern.matcher(graph); ! boolean fail = false; ! while (matcher.find()) { ! System.out.println("Graph for '" + testName + "' contains forbidden node:"); ! System.out.println(matcher.group()); ! fail = true; ! } ! Asserts.assertFalse(fail, "Graph for '" + testName + "' contains forbidden nodes"); } String[] regexMatch = anno.match(); int[] matchCount = anno.matchCount(); for (int i = 0; i < regexMatch.length; ++i) { Pattern pattern = Pattern.compile(regexMatch[i].substring(0, regexMatch[i].length()-1)); --- 1224,1248 ---- assert anno == null; anno = a; } else if ((a.valid() & ValueTypePassFieldsAsArgsOff) != 0 && !ValueTypePassFieldsAsArgs) { assert anno == null; anno = a; + } else if ((a.valid() & ValueTypeArrayFlattenOn) != 0 && ValueTypeArrayFlatten) { + assert anno == null; + anno = a; + } else if ((a.valid() & ValueTypeArrayFlattenOff) != 0 && !ValueTypeArrayFlatten) { + assert anno == null; + anno = a; } } assert anno != null; String regexFail = anno.failOn(); if (!regexFail.isEmpty()) { Pattern pattern = Pattern.compile(regexFail.substring(0, regexFail.length()-1)); Matcher matcher = pattern.matcher(graph); ! boolean found = matcher.find(); ! Asserts.assertFalse(found, "Graph for '" + testName + "' contains forbidden node:\n" + (found ? matcher.group() : "")); } String[] regexMatch = anno.match(); int[] matchCount = anno.matchCount(); for (int i = 0; i < regexMatch.length; ++i) { Pattern pattern = Pattern.compile(regexMatch[i].substring(0, regexMatch[i].length()-1));
*** 1051,1065 **** String nodes = ""; while (matcher.find()) { count++; nodes += matcher.group() + "\n"; } ! if (matchCount[i] != count) { ! System.out.println("Graph for '" + testName + "' contains different number of match nodes:"); ! System.out.println(nodes); ! } ! Asserts.assertEQ(matchCount[i], count, "Graph for '" + testName + "' contains different number of match nodes"); } tests.remove(testName); System.out.println(testName + " passed"); } // Check if all tests were compiled --- 1251,1261 ---- String nodes = ""; while (matcher.find()) { count++; nodes += matcher.group() + "\n"; } ! 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
< prev index next >