< prev index next >

test/compiler/valhalla/valuetypes/ValueTypeTestBench.java

Print this page

        

@@ -50,419 +50,468 @@
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-// Test value type
-__ByValue final class MyValue {
+// Test value types
+__ByValue final class MyValue1 {
     final int x;
     final long y;
-    final double z;
+    final MyValue2 v1;
+    final MyValue2 v2;
+    final int c;
 
-    private MyValue(int x, long y, double z) {
+    private MyValue1(int x, long y, MyValue2 v1, MyValue2 v2, int c) {
         this.x = x;
         this.y = y;
-        this.z = z;
+        this.v1 = v1;
+        this.v2 = v2;
+        this.c = c;
     }
 
     @DontInline
-    public static MyValue createDontInline(int x, long y, double z) {
-        return __Make MyValue(x, y, z);
+    public static MyValue1 createDontInline(int x, long y) {
+        return __Make MyValue1(x, y, MyValue2.createInline(x, x < y), MyValue2.createInline(x, x > y), ValueTypeTestBench.rI);
     }
 
     @ForceInline
-    public static MyValue createInline(int x, long y, double z) {
-        return __Make MyValue(x, y, z);
+    public static MyValue1 createInline(int x, long y) {
+        return __Make MyValue1(x, y, MyValue2.createInline(x, x < y), MyValue2.createInline(x, x > y), ValueTypeTestBench.rI);
     }
 
-    @DontInline
-    public String toStringDontInline() {
-        return "MyValue: x=" + x + " y=" + y + " z=" + z;
+    @ForceInline
+    public long hash() {
+        return x + y + c + v1.hash() + v2.hash();
+    }
+
+    @DontCompile
+    public long hashInterpreted() {
+        return x + y + c + v1.hash() + v2.hash();
+    }
+}
+
+__ByValue final class MyValue2 {
+    final int x;
+    final boolean b;
+    final long c;
+
+    private MyValue2(int x, boolean b, long c) {
+        this.x = x;
+        this.b = b;
+        this.c = c;
     }
 
     @ForceInline
-    public String toStringInline() {
-        return "MyValue: x=" + x + " y=" + y + " z=" + z;
+    public static MyValue2 createInline(int x, boolean b) {
+        return __Make MyValue2(x, b, ValueTypeTestBench.rL);
+    }
+
+    @ForceInline
+    public long hash() {
+        return x + (b ? 0 : 1) + c;
     }
 }
 
 public class ValueTypeTestBench {
     // Print ideal graph after execution of each test
     private static final boolean PRINT_GRAPH = true;
 
+    // ========== Helper methods ==========
+
+    public long hash() {
+        return hash(rI, rL);
+    }
+
+    public long hash(int x, long y) {
+        return MyValue1.createInline(x, y).hash();
+    }
+
     // ========== Test definitions ==========
 
     // Receive value type through call to interpreter
-    @Test(failOn = ALLOC + STORE)
-    public double test1() {
-        MyValue v = MyValue.createDontInline(rI, rL, rD);
-        return v.x + v.y + v.z;
+    @Test(failOn = ALLOC + STORE + TRAP)
+    public long test1() {
+        MyValue1 v = MyValue1.createDontInline(rI, rL);
+        return v.hash();
     }
 
     @DontCompile
     public void test1_verifier(boolean warmup) {
-        double result = test1();
-        Asserts.assertEQ(result, rI + rL + rD);
+        long result = test1();
+        Asserts.assertEQ(result, hash());
     }
 
     // Receive value type from interpreter via parameter
-    @Test(failOn = ALLOC + STORE)
-    public double test2(MyValue v) {
-        return v.x + v.y + v.z;
+    @Test(failOn = ALLOC + STORE + TRAP)
+    public long test2(MyValue1 v) {
+        return v.hash();
     }
 
     @DontCompile
     public void test2_verifier(boolean warmup) {
-        MyValue v = MyValue.createDontInline(rI, rL, rD);
-        double result = test2(v);
-        Asserts.assertEQ(result, rI + rL + rD);
+        MyValue1 v = MyValue1.createDontInline(rI, rL);
+        long result = test2(v);
+        Asserts.assertEQ(result, hash());
     }
 
     // Return incoming value type without accessing fields
-    @Test(failOn = ALLOC + LOAD + STORE)
-    public MyValue test3(MyValue v) {
+    @Test(failOn = ALLOC + LOAD + STORE + TRAP)
+    public MyValue1 test3(MyValue1 v) {
         return v;
     }
 
     @DontCompile
     public void test3_verifier(boolean warmup) {
-        MyValue v1 = MyValue.createDontInline(rI, rL, rD);
-        MyValue v2 = test3(v1);
+        MyValue1 v1 = MyValue1.createDontInline(rI, rL);
+        MyValue1 v2 = test3(v1);
         Asserts.assertEQ(v1.x, v2.x);
         Asserts.assertEQ(v1.y, v2.y);
-        Asserts.assertEQ(v1.z, v2.z);
     }
 
     // Create a value type in compiled code and only use fields.
     // Allocation should go away because value type does not escape.
-    @Test(failOn = ALLOC + LOAD + STORE)
-    public double test4() {
-        MyValue v = MyValue.createInline(rI, rL, rD);
-        return v.x + v.y + v.z;
+    @Test(failOn = ALLOC + LOAD + STORE + TRAP)
+    public long test4() {
+        MyValue1 v = MyValue1.createInline(rI, rL);
+        return v.hash();
     }
 
     @DontCompile
     public void test4_verifier(boolean warmup) {
-        double result = test4();
-        Asserts.assertEQ(result, rI + rL + rD);
+        long result = test4();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in compiled code and pass it to
     // an inlined compiled method via a call.
-    @Test(failOn = ALLOC + LOAD + STORE)
-    public double test5() {
-        MyValue v = MyValue.createInline(rI, rL, rD);
+    @Test(failOn = ALLOC + LOAD + STORE + TRAP)
+    public long test5() {
+        MyValue1 v = MyValue1.createInline(rI, rL);
         return test5Inline(v);
     }
 
     @ForceInline
-    public double test5Inline(MyValue v) {
-        return v.x + v.y + v.z;
+    public long test5Inline(MyValue1 v) {
+        return v.hash();
     }
 
     @DontCompile
     public void test5_verifier(boolean warmup) {
-        double result = test5();
-        Asserts.assertEQ(result, rI + rL + rD);
+        long result = test5();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in compiled code and pass it to
     // the interpreter via a call.
-    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD)
-    public double test6() {
-        MyValue v = MyValue.createInline(rI, rL, rD);
+    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP)
+    public long test6() {
+        MyValue1 v = MyValue1.createInline(rI, rL);
         // Pass to interpreter
-        return sumValue(v);
+        return v.hashInterpreted();
     }
 
     @DontCompile
     public void test6_verifier(boolean warmup) {
-        double result = test6();
-        Asserts.assertEQ(result, rI + rL + rD);
+        long result = test6();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in compiled code and pass it to
     // the interpreter by returning.
-    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD)
-    public MyValue test7(int x, long y, double z) {
-        return MyValue.createInline(x, y, z);
+    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP)
+    public MyValue1 test7(int x, long y) {
+        return MyValue1.createInline(x, y);
     }
 
     @DontCompile
     public void test7_verifier(boolean warmup) {
-        MyValue v = test7(rI, rL, rD);
-        double result = v.x + v.y + v.z;
-        Asserts.assertEQ(result, rI + rL + rD);
+        MyValue1 v = test7(rI, rL);
+        Asserts.assertEQ(v.hash(), hash());
     }
 
     // Merge value types created from two branches
-    @Test(failOn = ALLOC + STORE)
-    public double test8(boolean b) {
-        MyValue v;
+    @Test(failOn = ALLOC + STORE + TRAP)
+    public long test8(boolean b) {
+        MyValue1 v;
         if (b) {
-            v = MyValue.createInline(rI, rL, rD);
+            v = MyValue1.createInline(rI, rL);
         } else {
-            v = MyValue.createDontInline(rI + 1, rL + 1, rD + 1);
+            v = MyValue1.createDontInline(rI + 1, rL + 1);
         }
-        return v.x + v.y + v.z;
+        return v.hash();
     }
 
     @DontCompile
     public void test8_verifier(boolean warmup) {
-        Asserts.assertEQ(test8(true), rI + rL + rD);
-        Asserts.assertEQ(test8(false), rI + 1 + rL + 1 + ((double)rD + 1));
+        Asserts.assertEQ(test8(true), hash());
+        Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1));
     }
 
     // Merge value types created from two branches
-    @Test(match = {ALLOC, STORE}, matchCount = {1, 3}, failOn = LOAD)
-    public MyValue test9(boolean b) {
-        MyValue v;
+    @Test(match = {ALLOC, STORE}, matchCount = {1, 9}, failOn = LOAD + TRAP)
+    public MyValue1 test9(boolean b) {
+        MyValue1 v;
         if (b) {
             // Value type is not allocated
-            v = MyValue.createInline(rI, rL, rD);
+            v = MyValue1.createInline(rI, rL);
         } else {
             // Value type is allocated by the callee
-            v = MyValue.createDontInline(rI + 1, rL + 1, rD + 1);
+            v = MyValue1.createDontInline(rI + 1, rL + 1);
         }
         // Need to allocate value type if 'b' is true
-        double sum = sumValue(v);
+        long sum = v.hashInterpreted();
         if (b) {
-            v = MyValue.createDontInline(rI, rL, sum);
+            v = MyValue1.createDontInline(rI, sum);
         } else {
-            v = MyValue.createDontInline(rI, rL, sum + 1);
+            v = MyValue1.createDontInline(rI, sum + 1);
         }
         // Don't need to allocate value type because both branches allocate
         return v;
     }
 
     @DontCompile
     public void test9_verifier(boolean warmup) {
-        MyValue v = test9(true);
+        MyValue1 v = test9(true);
         Asserts.assertEQ(v.x, rI);
-        Asserts.assertEQ(v.y, rL);
-        Asserts.assertEQ(v.z, rI + rL + rD);
-
+        Asserts.assertEQ(v.y, hash());
         v = test9(false);
         Asserts.assertEQ(v.x, rI);
-        Asserts.assertEQ(v.y, rL);
-        Asserts.assertEQ(v.z, rI + rL + ((double)rD + 1));
+        Asserts.assertEQ(v.y, hash(rI + 1, rL + 1) + 1);
     }
 
     // Merge value types created in a loop (not inlined)
-    @Test(failOn = ALLOC + STORE)
-    public double test10(int x, long y, double z) {
-        MyValue v = MyValue.createDontInline(x, y, z);
+    @Test(failOn = ALLOC + STORE + TRAP)
+    public long test10(int x, long y) {
+        MyValue1 v = MyValue1.createDontInline(x, y);
         for (int i = 0; i < 10; ++i) {
-            v = MyValue.createDontInline(v.x + 1, v.y + 1, v.z + 1);
+            v = MyValue1.createDontInline(v.x + 1, v.y + 1);
         }
-        return v.x + v.y + v.z;
+        return v.hash();
     }
 
     @DontCompile
     public void test10_verifier(boolean warmup) {
-        double result = test10(rI, rL, rD);
-        Asserts.assertEQ(result, rI + rL + 20 + ((double)rD + 10));
+        long result = test10(rI, rL);
+        Asserts.assertEQ(result, hash(rI + 10, rL + 10));
     }
 
     // Merge value types created in a loop (inlined)
-    @Test(failOn = ALLOC + LOAD + STORE + LOOP)
-    public double test11(int x, long y, double z) {
-        MyValue v = MyValue.createInline(x, y, z);
+    @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
+    public long test11(int x, long y) {
+        MyValue1 v = MyValue1.createInline(x, y);
         for (int i = 0; i < 10; ++i) {
-            v = MyValue.createInline(v.x + 1, v.y + 1, v.z + 1);
+            v = MyValue1.createInline(v.x + 1, v.y + 1);
         }
-        return v.x + v.y + v.z;
+        return v.hash();
     }
 
     @DontCompile
     public void test11_verifier(boolean warmup) {
-        double result = test11(rI, rL, rD);
-        Asserts.assertEQ(result, rI + rL + 20 + ((double)rD + 10));
+        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 double test12(boolean b) {
-        MyValue v = MyValue.createInline(rI, rL, rD);
-        double result = 42;
+    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 = sumValue(v);
+                result = v.hashInterpreted();
             }
         }
         return result;
     }
 
     @DontCompile
     public void test12_verifier(boolean warmup) {
-        double result = test12(warmup);
-        Asserts.assertEQ(result, warmup ? 42 + (1000*(double)rI) : (rI + rL + rD));
+        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 double test13(boolean b) {
-        MyValue v = MyValue.createDontInline(rI, rL, rD);
-        double result = 42;
+    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 = sumValue(v);
+                result = v.hashInterpreted();
             }
         }
         return result;
     }
 
     @DontCompile
     public void test13_verifier(boolean warmup) {
-        double result = test13(warmup);
-        Asserts.assertEQ(result, warmup ? 42 + (1000*(double)rI) : (rI + rL + rD));
+        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(failOn = (ALLOC + STORE))
-    public String test14() {
-        MyValue v = MyValue.createDontInline(32, 64L, 128.0);
-        String s = v.toStringDontInline();
-        return s;
+    @Test(failOn = (ALLOC + LOAD + STORE + TRAP))
+    public long test14() {
+        MyValue1 v = MyValue1.createDontInline(rI, rL);
+        return v.hashInterpreted();
     }
 
     @DontCompile
     public void test14_verifier(boolean b) {
-        String s = test14();
-        System.out.println("Result is: " + s);
+        long result = test14();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in an inlined method and then call a
     // non-inlined method on that value type.
-    @Test(match = {ALLOC}, matchCount = {1})
-    public String test15() {
-        MyValue v = MyValue.createInline(65, 129L, 257.0);
-        String s = v.toStringDontInline();
-        return s;
+    @Test(failOn = (LOAD + TRAP), match = {ALLOC}, matchCount = {1})
+    public long test15() {
+        MyValue1 v = MyValue1.createInline(rI, rL);
+        return v.hashInterpreted();
     }
 
     @DontCompile
     public void test15_verifier(boolean b) {
-        String s = test15();
-        System.out.println("Result is: " + s);
+        long result = test15();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in a non-inlined method and then call an
-    // inlined method on that value type. Allocations are due to building
-    // String objects and not due to allocating value types.
-    @Test(match = {ALLOC}, matchCount = {2})
-    public String test16() {
-        MyValue v = MyValue.createDontInline(130, 258L, 514.0);
-        String s = v.toStringInline();
-        return s;
+    // inlined method on that value type.
+    @Test(failOn = (ALLOC + STORE + TRAP))
+    public long test16() {
+        MyValue1 v = MyValue1.createDontInline(rI, rL);
+        return v.hash();
     }
 
     @DontCompile
     public void test16_verifier(boolean b) {
-        String s = test16();
-        System.out.println("Result is: " + s);
+        long result = test16();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in an inlined method and then call an
-    // inlined method on that value type. Allocations are due to
-    // building String objects and not due to allocating value types.
-    @Test(match = {ALLOC}, matchCount = {2})
-    public String test17() {
-        MyValue v = MyValue.createInline(259, 515L, 1027.0);
-        String s = v.toStringInline();
-        return s;
+    // inlined method on that value type.
+    @Test(failOn = (ALLOC + LOAD + STORE + TRAP))
+    public long test17() {
+        MyValue1 v = MyValue1.createInline(rI, rL);
+        return v.hash();
     }
 
     @DontCompile
     public void test17_verifier(boolean b) {
-        String s = test17();
-        System.out.println("Result is: " + s);
+        long result = test17();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in compiled code and pass it to the
     // interpreter via a call. The value is live at the first call so
     // debug info should include a reference to all its fields.
-    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD)
-    public double test18() {
-        MyValue v = MyValue.createInline(rI, rL, rD);
-        sumValue(v);
-        return sumValue(v);
+    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP)
+    public long test18() {
+        MyValue1 v = MyValue1.createInline(rI, rL);
+        v.hashInterpreted();
+        return v.hashInterpreted();
     }
 
     @DontCompile
     public void test18_verifier(boolean warmup) {
-        double result = test18();
-        Asserts.assertEQ(result, rI + rL + rD);
+        long result = test18();
+        Asserts.assertEQ(result, hash());
     }
 
     // Create a value type in compiled code and pass it to the
     // interpreter via a call. The value type is passed twice but
     // should only be allocated once.
-    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD)
-    public double test19() {
-        MyValue v = MyValue.createInline(rI, rL, rD);
+    @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP)
+    public long test19() {
+        MyValue1 v = MyValue1.createInline(rI, rL);
         return sumValue(v, v);
     }
 
     @DontCompile
+    public long sumValue(MyValue1 v, MyValue1 dummy) {
+        return v.hash();
+    }
+
+    @DontCompile
     public void test19_verifier(boolean warmup) {
-        double result = test19();
-        Asserts.assertEQ(result, rI + rL + rD);
+        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(match = {ALLOC}, matchCount = {1}, failOn = LOAD)
-    public double test20(boolean flag) {
-        MyValue v = MyValue.createInline(rI, rL, rD);
+    public long test20(boolean flag) {
+        MyValue1 v = MyValue1.createInline(rI, rL);
         if (flag) { 
             // uncommon trap
             WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test16"));
         }
-        return sumValue(v);
+        return v.hashInterpreted();
     }
 
     @DontCompile
     public void test20_verifier(boolean warmup) {
-        double result = test20(false);
-        Asserts.assertEQ(result, rI + rL + rD);
+        long result = test20(false);
+        Asserts.assertEQ(result, hash());
         if (!warmup) {
             result = test20(true);
-            Asserts.assertEQ(result, rI + rL + rD);
+            Asserts.assertEQ(result, hash());
         }
     }
 
-    // ========== Helper methods ==========
-
-    @DontCompile
-    public double sumValue(MyValue v) {
-        return v.x + v.y + v.z;
+    // Value type fields in regular object
+    MyValue1 val1;
+    MyValue2 val2;
+
+    // Test value type fields in objects
+    @Test(failOn = (ALLOC + TRAP))
+    public long test21(int x, long y) {
+        // Compute hash of value type fields
+        long result = val1.hash() + val2.hash();
+        // Update fields
+        val1 = MyValue1.createInline(x, y);
+        val2 = MyValue2.createInline(x, true);
+        return result;
     }    
 
     @DontCompile
-    public double sumValue(MyValue v, MyValue dummy) {
-        return v.x + v.y + v.z;
+    public void test21_verifier(boolean warmup) {
+        // Check if hash computed by test18 is correct
+        val1 = MyValue1.createInline(rI, rL);
+        val2 = val1.v2;
+        long hash = val1.hash() + val2.hash();
+        long result = test21(rI + 1, rL + 1);
+        Asserts.assertEQ(result, hash);
+        // Check if value type fields were updated
+        Asserts.assertEQ(val1.hash(), hash(rI + 1, rL + 1));
+        Asserts.assertEQ(val2.hash(), MyValue2.createInline(rI + 1, true).hash());
     }
 
+
     // ========== Test infrastructure ==========
 
     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
     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 = 10;
+    private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
+    private static boolean PRINT_IDEAL  = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
 
     // 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 = ")|";

@@ -472,15 +521,13 @@
     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;
 
-
     // Random test values
-    private static final int    rI = Utils.getRandomInstance().nextInt();
-    private static final long   rL = Utils.getRandomInstance().nextLong();
-    private static final double rD = Utils.getRandomInstance().nextDouble();
+    public static final int  rI = Utils.getRandomInstance().nextInt() % 1000;
+    public static final long rL = Utils.getRandomInstance().nextLong() % 1000;
 
     static {
         // Gather all test methods and put them in Hashtable
         for (Method m : ValueTypeTestBench.class.getDeclaredMethods()) {
             if (m.isAnnotationPresent(Test.class)) {

@@ -493,18 +540,27 @@
         if (args.length == 0) {
             // Run tests in own process and verify output
             OutputAnalyzer oa = ProcessTools.executeTestJvm("-noverify",
                                                             "-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI",
                                                             "-XX:-TieredCompilation", "-XX:-BackgroundCompilation", "-XX:-UseOnStackReplacement",
-                                                            "-XX:CompileCommand=quiet", "-XX:+PrintCompilation", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly",
-                                                            "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*",
-                                                            "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue::*",
+                    "-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::*",
                                                             ValueTypeTestBench.class.getName(), "run");
+            // If ideal graph printing is enabled/supported, verify output
             String output = oa.getOutput();
             oa.shouldHaveExitValue(0);
+            if (output.contains("PrintIdeal enabled")) {
             parseOutput(output);
         } else {
+                System.out.println("WARNING: test methods not compiled or PrintIdeal disabled! Running with -Xint or release build?");
+            }
+        } else {
+            if (USE_COMPILER && PRINT_IDEAL) {
+                System.out.println("PrintIdeal enabled");
+            }
             // Execute tests
             ValueTypeTestBench bench = new ValueTypeTestBench();
             bench.run();
         }
     }

@@ -586,24 +642,25 @@
             }
         }
     }
 
     public void run() throws Exception {
-        System.out.format("rI = %d, rL = %d, rD = %f\n", rI, rL, rD);
+        System.out.format("rI = %d, rL = %d\n", rI, rL);
         setup(this.getClass().getDeclaredMethods());
-        setup(MyValue.class.getDeclaredMethods());
+        setup(MyValue1.class.getDeclaredMethods());
+        setup(MyValue2.class.getDeclaredMethods());
 
         // Execute tests
         for (Method test : tests.values()) {
             Method verifier = getClass().getDeclaredMethod(test.getName() + "_verifier", boolean.class);
             // Warmup using verifier method
             for (int i = 0; i < WARMUP; ++i) {
                 verifier.invoke(this, true);
             }
             // Trigger compilation
             WHITE_BOX.enqueueMethodForCompilation(test, COMP_LEVEL_FULL_OPTIMIZATION);
-            Asserts.assertTrue(WHITE_BOX.isMethodCompiled(test, false));
+            Asserts.assertTrue(!USE_COMPILER || WHITE_BOX.isMethodCompiled(test, false), test + " not compiled");
             // Check result
             verifier.invoke(this, false);
         }
     }
 }
< prev index next >