test/compiler/valhalla/valuetypes/ValueTypeTestBench.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File valhalla Sdiff test/compiler/valhalla/valuetypes

test/compiler/valhalla/valuetypes/ValueTypeTestBench.java

Print this page




 549     // Print ideal graph after execution of each test
 550     private static final boolean PRINT_GRAPH = true;
 551 
 552     // Random test values
 553     public static final int  rI = Utils.getRandomInstance().nextInt() % 1000;
 554     public static final long rL = Utils.getRandomInstance().nextLong() % 1000;
 555 
 556     public ValueTypeTestBench() {
 557         val3 = MyValue1.createWithFieldsInline(rI, rL);
 558     }
 559 
 560     // MethodHandles and value-capable class instance needed for testing vbox/vunbox
 561     private static final MethodHandle vccUnboxLoadLongMH = generateVCCUnboxLoadLongMH();
 562     private static final MethodHandle vccUnboxLoadIntMH = generateVCCUnboxLoadIntMH();
 563     private static final MethodHandle vccUnboxBoxMH = generateVCCUnboxBoxMH();
 564     private static final MethodHandle vccUnboxBoxLoadIntMH = generateVCCUnboxBoxLoadIntMH();
 565     private static final MethodHandle nullvccUnboxLoadLongMH = generateNullVCCUnboxLoadLongMH();
 566     private static final MethodHandle objectUnboxLoadLongMH = generateObjectUnboxLoadLongMH();
 567     private static final MethodHandle objectBoxMH = generateObjectBoxMH();
 568     private static final MethodHandle checkedvccUnboxLoadLongMH = generateCheckedVCCUnboxLoadLongMH();


 569 
 570     private static final ValueCapableClass1 vcc = ValueCapableClass1.create(rL, rI, (short)rI, (short)rI);
 571     private static final ValueCapableClass2 vcc2 = ValueCapableClass2.create(rL + 1);
 572 
 573     // ========== Helper methods ==========
 574 
 575     public long hash() {
 576         return hash(rI, rL);
 577     }
 578 
 579     public long hash(int x, long y) {
 580         return MyValue1.createWithFieldsInline(x, y).hash();
 581     }
 582 
 583     // ========== Test definitions ==========
 584 
 585     // Receive value type through call to interpreter
 586     @Test(failOn = ALLOC + STORE + TRAP)
 587     public long test1() {
 588         MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL);


 752         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 753     }
 754 
 755     // Merge value types created in a loop (inlined)
 756     @Test(failOn = ALLOC + LOAD + STORE + TRAP)
 757     public long test11(int x, long y) {
 758         MyValue1 v = MyValue1.createWithFieldsInline(x, y);
 759         for (int i = 0; i < 10; ++i) {
 760             v = MyValue1.createWithFieldsInline(v.x + 1, v.y + 1);
 761         }
 762         return v.hash();
 763     }
 764 
 765     @DontCompile
 766     public void test11_verifier(boolean warmup) {
 767         long result = test11(rI, rL);
 768         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 769     }
 770 
 771     // Test loop with uncommon trap referencing a value type
 772     @Test(match = {TRAP, SCOBJ}, matchCount = {1, -1 /* at least 1 */}, failOn = LOAD)
 773     public long test12(boolean b) {
 774         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 775         MyValue1[] va = new MyValue1[Math.abs(rI) % 10];
 776         for (int i = 0; i < va.length; ++i) {
 777             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 778         }
 779         long result = rL;
 780         for (int i = 0; i < 1000; ++i) {
 781             if (b) {
 782                 result += v.x;
 783             } else {
 784                 // Uncommon trap referencing v. We delegate allocation to the
 785                 // interpreter by adding a SafePointScalarObjectNode.
 786                 result = v.hashInterpreted();
 787                 for (int j = 0; j < va.length; ++j) {
 788                     result += va[j].hash();
 789                 }
 790             }
 791         }
 792         return result;
 793     }
 794 
 795     @DontCompile
 796     public void test12_verifier(boolean warmup) {
 797         long result = test12(warmup);
 798         Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash());
 799     }
 800 
 801     // Test loop with uncommon trap referencing a value type
 802     @Test(match = {TRAP}, matchCount = {1})
 803     public long test13(boolean b) {
 804         MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL);
 805         MyValue1[] va = new MyValue1[Math.abs(rI) % 10];
 806         for (int i = 0; i < va.length; ++i) {
 807             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 808         }
 809         long result = rL;
 810         for (int i = 0; i < 1000; ++i) {
 811             if (b) {
 812                 result += v.x;
 813             } else {
 814                 // Uncommon trap referencing v. Should not allocate
 815                 // but just pass the existing oop to the uncommon trap.
 816                 result = v.hashInterpreted();
 817                 for (int j = 0; j < va.length; ++j) {
 818                     result += va[j].hashInterpreted();
 819                 }
 820             }
 821         }
 822         return result;


1420 
1421     // Test returning a value type array received from the interpreter
1422     @Test(failOn = ALLOC + ALLOCA + LOAD + LOADP + STORE + LOOP + TRAP)
1423     public MyValue1[] test44(MyValue1[] va) {
1424         return va;
1425     }
1426 
1427     @DontCompile
1428     public void test44_verifier(boolean warmup) {
1429         MyValue1[] va = new MyValue1[10];
1430         for (int i = 0; i < 10; ++i) {
1431             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
1432         }
1433         va = test44(va);
1434         for (int i = 0; i < 10; ++i) {
1435             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
1436         }
1437     }
1438 
1439     // Merge value type arrays created from two branches
1440     @Test(failOn = (TRAP))
1441     public MyValue1[] test45(boolean b) {
1442         MyValue1[] va;
1443         if (b) {
1444             va = new MyValue1[5];
1445             for (int i = 0; i < 5; ++i) {
1446                 va[i] = MyValue1.createWithFieldsInline(rI, rL);
1447             }
1448         } else {
1449             va = new MyValue1[10];
1450             for (int i = 0; i < 10; ++i) {
1451                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
1452             }
1453         }
1454         long sum = va[0].hashInterpreted();
1455         if (b) {
1456             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
1457         } else {
1458             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
1459         }
1460         return va;


2144     }
2145 
2146     @DontCompile
2147     public void test76_verifier(boolean warmup) throws Exception {
2148         MyValue3 vt = test76();
2149         test76_vt.verify(vt);
2150     }
2151 
2152     static {
2153         try {
2154             MethodHandles.Lookup lookup = MethodHandles.lookup();
2155             MethodType mt = MethodType.fromMethodDescriptorString("()Qcompiler/valhalla/valuetypes/MyValue3;", ValueTypeTestBench.class.getClassLoader());
2156             test73_mh = lookup.findVirtual(ValueTypeTestBench.class, "test73_target", mt);
2157             test74_mh = lookup.findVirtual(ValueTypeTestBench.class, "test74_target", mt);
2158             test75_mh = lookup.findVirtual(ValueTypeTestBench.class, "test75_target", mt);
2159         } catch (NoSuchMethodException|IllegalAccessException e) {
2160             throw new RuntimeException("method handle lookup fails");
2161         }
2162     }
2163 










































































































































































































2164     // ========== Test infrastructure ==========
2165 
2166     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
2167     private static final int ValueTypePassFieldsAsArgsOn = 0x1;
2168     private static final int ValueTypePassFieldsAsArgsOff = 0x2;
2169     private static final int ValueTypeArrayFlattenOn = 0x4;
2170     private static final int ValueTypeArrayFlattenOff = 0x8;
2171     private static final int ValueTypeReturnedAsFieldsOn = 0x10;
2172     private static final int ValueTypeReturnedAsFieldsOff = 0x20;
2173     static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn;
2174     private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
2175     private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
2176     private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
2177     private static final int COMP_LEVEL_ANY = -1;
2178     private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
2179     private static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
2180     private static final int WARMUP = 251;
2181     private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
2182     private static boolean PRINT_IDEAL  = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
2183     private static boolean XCOMP = Platform.isComp();


2218         all_args.add(ValueTypeTestBench.class.getName());
2219         all_args.add("run");
2220         // Spawn process with default JVM options from the test's run command
2221         String[] vmInputArgs = InputArguments.getVmInputArgs();
2222         String[] cmds = Arrays.copyOf(vmInputArgs, vmInputArgs.length + all_args.size());
2223         System.arraycopy(all_args.toArray(), 0, cmds, vmInputArgs.length, all_args.size());
2224         OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds);
2225         // If ideal graph printing is enabled/supported, verify output
2226         String output = oa.getOutput();
2227         oa.shouldHaveExitValue(0);
2228         boolean verifyIR = output.contains("PrintIdeal enabled") &&
2229                 !output.contains("ValueTypePassFieldsAsArgs is not supported on this platform");
2230         if (verifyIR) {
2231             parseOutput(output);
2232         } else {
2233             System.out.println("WARNING: IR verification disabled! Running with -Xint, -Xcomp or release build?");
2234         }
2235     }
2236 
2237     public static void main(String[] args) throws Throwable {
2238         //tests.values().removeIf(p -> !p.getName().equals("test74")); // Run single test
2239         if (args.length == 0) {
2240             execute_vm("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-BackgroundCompilation",
2241                     "-XX:+PrintCompilation", "-XX:+PrintInlining", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly",
2242                     "-XX:CICompilerCount=1",
2243                     "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*",
2244                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue1::*",
2245                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2::*",
2246                     "-XX:CompileCommand=compileonly,java.lang.Object::<init>",
2247                     "-XX:CompileCommand=inline,java.lang.__Value::hashCode",
2248                     "-XX:CompileCommand=compileonly,java.lang.invoke.*::*");
2249         } else {
2250             // Execute tests
2251             ValueTypeTestBench bench = new ValueTypeTestBench();
2252             bench.run();
2253         }
2254     }
2255 
2256     public static void parseOutput(String output) throws Exception {
2257         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");
2258         Matcher m = comp_re.matcher(output);




 549     // Print ideal graph after execution of each test
 550     private static final boolean PRINT_GRAPH = true;
 551 
 552     // Random test values
 553     public static final int  rI = Utils.getRandomInstance().nextInt() % 1000;
 554     public static final long rL = Utils.getRandomInstance().nextLong() % 1000;
 555 
 556     public ValueTypeTestBench() {
 557         val3 = MyValue1.createWithFieldsInline(rI, rL);
 558     }
 559 
 560     // MethodHandles and value-capable class instance needed for testing vbox/vunbox
 561     private static final MethodHandle vccUnboxLoadLongMH = generateVCCUnboxLoadLongMH();
 562     private static final MethodHandle vccUnboxLoadIntMH = generateVCCUnboxLoadIntMH();
 563     private static final MethodHandle vccUnboxBoxMH = generateVCCUnboxBoxMH();
 564     private static final MethodHandle vccUnboxBoxLoadIntMH = generateVCCUnboxBoxLoadIntMH();
 565     private static final MethodHandle nullvccUnboxLoadLongMH = generateNullVCCUnboxLoadLongMH();
 566     private static final MethodHandle objectUnboxLoadLongMH = generateObjectUnboxLoadLongMH();
 567     private static final MethodHandle objectBoxMH = generateObjectBoxMH();
 568     private static final MethodHandle checkedvccUnboxLoadLongMH = generateCheckedVCCUnboxLoadLongMH();
 569     private static final MethodHandle vastoreMH = generateVastore();
 570     private static final MethodHandle invalidVastoreMH = generateInvalidVastore();
 571 
 572     private static final ValueCapableClass1 vcc = ValueCapableClass1.create(rL, rI, (short)rI, (short)rI);
 573     private static final ValueCapableClass2 vcc2 = ValueCapableClass2.create(rL + 1);
 574 
 575     // ========== Helper methods ==========
 576 
 577     public long hash() {
 578         return hash(rI, rL);
 579     }
 580 
 581     public long hash(int x, long y) {
 582         return MyValue1.createWithFieldsInline(x, y).hash();
 583     }
 584 
 585     // ========== Test definitions ==========
 586 
 587     // Receive value type through call to interpreter
 588     @Test(failOn = ALLOC + STORE + TRAP)
 589     public long test1() {
 590         MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL);


 754         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 755     }
 756 
 757     // Merge value types created in a loop (inlined)
 758     @Test(failOn = ALLOC + LOAD + STORE + TRAP)
 759     public long test11(int x, long y) {
 760         MyValue1 v = MyValue1.createWithFieldsInline(x, y);
 761         for (int i = 0; i < 10; ++i) {
 762             v = MyValue1.createWithFieldsInline(v.x + 1, v.y + 1);
 763         }
 764         return v.hash();
 765     }
 766 
 767     @DontCompile
 768     public void test11_verifier(boolean warmup) {
 769         long result = test11(rI, rL);
 770         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 771     }
 772 
 773     // Test loop with uncommon trap referencing a value type
 774     @Test(match = {SCOBJ}, matchCount = {-1 /* at least 1 */}, failOn = LOAD)
 775     public long test12(boolean b) {
 776         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 777         MyValue1[] va = new MyValue1[Math.abs(rI) % 10];
 778         for (int i = 0; i < va.length; ++i) {
 779             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 780         }
 781         long result = rL;
 782         for (int i = 0; i < 1000; ++i) {
 783             if (b) {
 784                 result += v.x;
 785             } else {
 786                 // Uncommon trap referencing v. We delegate allocation to the
 787                 // interpreter by adding a SafePointScalarObjectNode.
 788                 result = v.hashInterpreted();
 789                 for (int j = 0; j < va.length; ++j) {
 790                     result += va[j].hash();
 791                 }
 792             }
 793         }
 794         return result;
 795     }
 796 
 797     @DontCompile
 798     public void test12_verifier(boolean warmup) {
 799         long result = test12(warmup);
 800         Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash());
 801     }
 802 
 803     // Test loop with uncommon trap referencing a value type
 804     @Test
 805     public long test13(boolean b) {
 806         MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL);
 807         MyValue1[] va = new MyValue1[Math.abs(rI) % 10];
 808         for (int i = 0; i < va.length; ++i) {
 809             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 810         }
 811         long result = rL;
 812         for (int i = 0; i < 1000; ++i) {
 813             if (b) {
 814                 result += v.x;
 815             } else {
 816                 // Uncommon trap referencing v. Should not allocate
 817                 // but just pass the existing oop to the uncommon trap.
 818                 result = v.hashInterpreted();
 819                 for (int j = 0; j < va.length; ++j) {
 820                     result += va[j].hashInterpreted();
 821                 }
 822             }
 823         }
 824         return result;


1422 
1423     // Test returning a value type array received from the interpreter
1424     @Test(failOn = ALLOC + ALLOCA + LOAD + LOADP + STORE + LOOP + TRAP)
1425     public MyValue1[] test44(MyValue1[] va) {
1426         return va;
1427     }
1428 
1429     @DontCompile
1430     public void test44_verifier(boolean warmup) {
1431         MyValue1[] va = new MyValue1[10];
1432         for (int i = 0; i < 10; ++i) {
1433             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
1434         }
1435         va = test44(va);
1436         for (int i = 0; i < 10; ++i) {
1437             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
1438         }
1439     }
1440 
1441     // Merge value type arrays created from two branches
1442     @Test
1443     public MyValue1[] test45(boolean b) {
1444         MyValue1[] va;
1445         if (b) {
1446             va = new MyValue1[5];
1447             for (int i = 0; i < 5; ++i) {
1448                 va[i] = MyValue1.createWithFieldsInline(rI, rL);
1449             }
1450         } else {
1451             va = new MyValue1[10];
1452             for (int i = 0; i < 10; ++i) {
1453                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
1454             }
1455         }
1456         long sum = va[0].hashInterpreted();
1457         if (b) {
1458             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
1459         } else {
1460             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
1461         }
1462         return va;


2146     }
2147 
2148     @DontCompile
2149     public void test76_verifier(boolean warmup) throws Exception {
2150         MyValue3 vt = test76();
2151         test76_vt.verify(vt);
2152     }
2153 
2154     static {
2155         try {
2156             MethodHandles.Lookup lookup = MethodHandles.lookup();
2157             MethodType mt = MethodType.fromMethodDescriptorString("()Qcompiler/valhalla/valuetypes/MyValue3;", ValueTypeTestBench.class.getClassLoader());
2158             test73_mh = lookup.findVirtual(ValueTypeTestBench.class, "test73_target", mt);
2159             test74_mh = lookup.findVirtual(ValueTypeTestBench.class, "test74_target", mt);
2160             test75_mh = lookup.findVirtual(ValueTypeTestBench.class, "test75_target", mt);
2161         } catch (NoSuchMethodException|IllegalAccessException e) {
2162             throw new RuntimeException("method handle lookup fails");
2163         }
2164     }
2165 
2166     /* Array load out of bounds (upper bound) at compile time.*/
2167     @Test
2168     public int test77() {
2169         int arraySize = Math.abs(rI) % 10;;
2170         MyValue1[] va = new MyValue1[arraySize];
2171 
2172         for (int i = 0; i < arraySize; i++) {
2173             va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
2174         }
2175         
2176         try {
2177             return va[arraySize + 1].x;
2178         } catch (ArrayIndexOutOfBoundsException e) {
2179             return rI;
2180         }
2181     }
2182 
2183     public void test77_verifier(boolean warmup) {
2184         Asserts.assertEQ(test77(), rI);
2185     }
2186 
2187     /* Array load  out of bounds (lower bound) at compile time.*/
2188     @Test
2189     public int test78() {
2190         int arraySize = Math.abs(rI) % 10;;
2191         MyValue1[] va = new MyValue1[arraySize];
2192 
2193         for (int i = 0; i < arraySize; i++) {
2194             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL);
2195         }
2196         
2197         try {
2198             return va[-arraySize].x;
2199         } catch (ArrayIndexOutOfBoundsException e) {
2200             return rI;
2201         }
2202     }
2203 
2204     public void test78_verifier(boolean warmup) {
2205         Asserts.assertEQ(test78(), rI);
2206     }
2207 
2208     /* Array load out of bound not known to compiler (both lower and upper bound). */
2209     @Test
2210     public int test79(MyValue1[] va, int index)  {
2211         return va[index].x;
2212     }
2213 
2214     public void test79_verifier(boolean warmup) {
2215         int arraySize = Math.abs(rI) % 10;
2216         MyValue1[] va = new MyValue1[arraySize];
2217 
2218         for (int i = 0; i < arraySize; i++) {
2219             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
2220         }
2221 
2222         int result;
2223         for (int i = -20; i < 20; i++) {
2224             try {
2225                 result = test79(va, i);
2226             } catch (ArrayIndexOutOfBoundsException e) {
2227                 result = rI;
2228             }
2229             Asserts.assertEQ(result, rI);
2230         }
2231     }
2232 
2233       /* Array store out of bounds (upper bound) at compile time.*/
2234     @Test
2235     public int test80() {
2236         int arraySize = Math.abs(rI) % 10;;
2237         MyValue1[] va = new MyValue1[arraySize];
2238 
2239         try {
2240             for (int i = 0; i <= arraySize; i++) {
2241                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
2242             }
2243             return rI - 1;
2244         } catch (ArrayIndexOutOfBoundsException e) {
2245             return rI;
2246         }
2247    }
2248 
2249    public void test80_verifier(boolean warmup) {
2250         Asserts.assertEQ(test80(), rI);
2251    }
2252 
2253     /* Array store out of bounds (lower bound) at compile time.*/
2254     @Test
2255     public int test81() {
2256         int arraySize = Math.abs(rI) % 10;;
2257         MyValue1[] va = new MyValue1[arraySize];
2258 
2259         try {
2260             for (int i = -1; i <= arraySize; i++) {
2261                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
2262             }
2263             return rI - 1;
2264         } catch (ArrayIndexOutOfBoundsException e) {
2265             return rI;
2266         }
2267     }
2268 
2269     public void test81_verifier(boolean warmup) {
2270         Asserts.assertEQ(test81(), rI);
2271     }
2272 
2273     /* Array store out of bound not known to compiler (both lower and upper bound). */
2274     @Test
2275     public int test82(MyValue1[] va, int index, MyValue1 vt)  {
2276         va[index] = vt;
2277         return va[index].x;
2278     }
2279 
2280     @DontCompile
2281     public void test82_verifier(boolean warmup) {
2282         int arraySize = Math.abs(rI) % 10;
2283         MyValue1[] va = new MyValue1[arraySize];
2284 
2285         for (int i = 0; i < arraySize; i++) {
2286             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
2287         }
2288 
2289         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL);
2290         int result;
2291         for (int i = -20; i < 20; i++) {
2292             try {
2293                 result = test82(va, i, vt);
2294             } catch (ArrayIndexOutOfBoundsException e) {
2295                 result = rI + 1;
2296             }
2297             Asserts.assertEQ(result, rI + 1);
2298         }
2299 
2300         for (int i = 0; i < arraySize; i++) {
2301             Asserts.assertEQ(va[i].x, rI + 1);
2302         }
2303     }
2304 
2305     /* Create a new value type array and store a value type into
2306      * it. The test should pass without throwing an exception. */
2307     @Test
2308     public void test83() throws Throwable {
2309         vastoreMH.invokeExact(vcc);
2310     }
2311     
2312     public void test83_verifier(boolean warmup) throws Throwable {
2313         test83();
2314     }
2315 
2316     private static MethodHandle generateVastore() {
2317         return MethodHandleBuilder.loadCode(MethodHandles.lookup(),
2318                 "Vastore",
2319                 MethodType.methodType(void.class, ValueCapableClass1.class),
2320                 CODE -> {
2321                     CODE.
2322                         iconst_1().
2323                         anewarray(ValueType.forClass(ValueCapableClass1.class).valueClass()).
2324                         iconst_0().
2325                         aload_0().
2326                         vunbox(ValueType.forClass(ValueCapableClass1.class).valueClass()).
2327                         vastore().
2328                         return_();
2329                }
2330                );
2331     }
2332 
2333     /* Create a new value type array with element type
2334      * ValueCapableClass1 and attempt to store a value type of type
2335      * ValueCapableClass2 into it. */
2336     @Test
2337     public void test84() throws Throwable {
2338         invalidVastoreMH.invokeExact(vcc2);
2339     }
2340     
2341     public void test84_verifier(boolean warmup) throws Throwable {
2342         boolean exceptionThrown = false;
2343         try {
2344             test84();
2345         } catch (ArrayStoreException e) {
2346             exceptionThrown = true;
2347         }
2348         Asserts.assertTrue(exceptionThrown, "ArrayStoreException must be thrown");
2349     }
2350 
2351     private static MethodHandle generateInvalidVastore() {
2352         return MethodHandleBuilder.loadCode(MethodHandles.lookup(),
2353                 "Vastore",
2354                 MethodType.methodType(void.class, ValueCapableClass2.class),
2355                 CODE -> {
2356                     CODE.
2357                         iconst_1().
2358                         anewarray(ValueType.forClass(ValueCapableClass1.class).valueClass()).
2359                         iconst_0().
2360                         aload_0().
2361                         vunbox(ValueType.forClass(ValueCapableClass2.class).valueClass()).
2362                         vastore().
2363                         return_();
2364                }
2365                 );
2366     }
2367 
2368     // ========== Test infrastructure ==========
2369 
2370     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
2371     private static final int ValueTypePassFieldsAsArgsOn = 0x1;
2372     private static final int ValueTypePassFieldsAsArgsOff = 0x2;
2373     private static final int ValueTypeArrayFlattenOn = 0x4;
2374     private static final int ValueTypeArrayFlattenOff = 0x8;
2375     private static final int ValueTypeReturnedAsFieldsOn = 0x10;
2376     private static final int ValueTypeReturnedAsFieldsOff = 0x20;
2377     static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn;
2378     private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
2379     private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
2380     private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
2381     private static final int COMP_LEVEL_ANY = -1;
2382     private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
2383     private static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
2384     private static final int WARMUP = 251;
2385     private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
2386     private static boolean PRINT_IDEAL  = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
2387     private static boolean XCOMP = Platform.isComp();


2422         all_args.add(ValueTypeTestBench.class.getName());
2423         all_args.add("run");
2424         // Spawn process with default JVM options from the test's run command
2425         String[] vmInputArgs = InputArguments.getVmInputArgs();
2426         String[] cmds = Arrays.copyOf(vmInputArgs, vmInputArgs.length + all_args.size());
2427         System.arraycopy(all_args.toArray(), 0, cmds, vmInputArgs.length, all_args.size());
2428         OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds);
2429         // If ideal graph printing is enabled/supported, verify output
2430         String output = oa.getOutput();
2431         oa.shouldHaveExitValue(0);
2432         boolean verifyIR = output.contains("PrintIdeal enabled") &&
2433                 !output.contains("ValueTypePassFieldsAsArgs is not supported on this platform");
2434         if (verifyIR) {
2435             parseOutput(output);
2436         } else {
2437             System.out.println("WARNING: IR verification disabled! Running with -Xint, -Xcomp or release build?");
2438         }
2439     }
2440 
2441     public static void main(String[] args) throws Throwable {
2442         //tests.values().removeIf(p -> !p.getName().equals("test85")); // Run single test
2443         if (args.length == 0) {
2444             execute_vm("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-BackgroundCompilation",
2445                     "-XX:+PrintCompilation", "-XX:+PrintInlining", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly",
2446                     "-XX:CICompilerCount=1",
2447                     "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*",
2448                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue1::*",
2449                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2::*",
2450                     "-XX:CompileCommand=compileonly,java.lang.Object::<init>",
2451                     "-XX:CompileCommand=inline,java.lang.__Value::hashCode",
2452                     "-XX:CompileCommand=compileonly,java.lang.invoke.*::*");
2453         } else {
2454             // Execute tests
2455             ValueTypeTestBench bench = new ValueTypeTestBench();
2456             bench.run();
2457         }
2458     }
2459 
2460     public static void parseOutput(String output) throws Exception {
2461         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");
2462         Matcher m = comp_re.matcher(output);


test/compiler/valhalla/valuetypes/ValueTypeTestBench.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File