--- old/test/compiler/valhalla/valuetypes/ValueTypeTestBench.java 2016-12-20 14:34:24.387342885 +0100 +++ new/test/compiler/valhalla/valuetypes/ValueTypeTestBench.java 2016-12-20 14:34:24.271342891 +0100 @@ -51,6 +51,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Repeatable; +import java.lang.invoke.*; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -58,6 +59,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import jdk.experimental.value.*; // Test value types __ByValue final class MyValue1 { @@ -81,12 +83,12 @@ @DontInline 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); + return __Make MyValue1(x, y, MyValue2.createInline(x, true), MyValue2.createInline(x, false), ValueTypeTestBench.rI); } @ForceInline 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); + return __Make MyValue1(x, y, MyValue2.createInline(x, true), MyValue2.createInline(x, false), ValueTypeTestBench.rI); } @ForceInline @@ -127,7 +129,7 @@ } } -public class ValueTypeTestBench { +public class ValueTypeTestBench { // Print ideal graph after execution of each test private static final boolean PRINT_GRAPH = true; @@ -139,6 +141,14 @@ val3 = MyValue1.createInline(rI, rL); } + // MethodHandles and value-capable class instance needed for testing vbox/vunbox + private static final MethodHandle vccUnboxLoadLongMH = generateVCCUnboxLoadLongMH(); + private static final MethodHandle vccUnboxLoadIntMH = generateVCCUnboxLoadIntMH(); + private static final MethodHandle vccUnboxBoxMH = generateVCCUnboxBoxMH(); + private static final MethodHandle vccUnboxBoxLoadIntMH = generateVCCUnboxBoxLoadIntMH(); + + private static final ValueCapableClass1 vcc = ValueCapableClass1.create(15L, 31, (short)63, (short)127); + // ========== Helper methods ========== public long hash() { @@ -776,6 +786,134 @@ } } + // Test vbox and vunbox + @Test + public long test37() throws Throwable { + return (long)vccUnboxLoadLongMH.invokeExact(vcc); + } + + @DontCompile + public void test37_verifier(boolean warmup) { + try { + long result = test37(); + Asserts.assertEQ(vcc.t, result, "Field t of input and result must be equal."); + } catch (Throwable t) { + throw new RuntimeException("test 37 failed", t); + } + } + + // Generate a MethodHandle that obtains field t of the + // derived value type + private static MethodHandle generateVCCUnboxLoadLongMH() { + return MethodHandleBuilder.loadCode(MethodHandles.lookup(), + "vccUnboxLoadLong", + MethodType.methodType(long.class, ValueCapableClass1.class), + CODE -> { + CODE. + aload_0(). + vunbox(ValueType.forClass(ValueCapableClass1.class).valueClass()). + vgetfield(ValueType.forClass(ValueCapableClass1.class).valueClass(), "t", "J"). + lreturn(); + } + ); + } + + + @Test + public int test38() throws Throwable { + return (int)vccUnboxLoadIntMH.invokeExact(vcc); + } + + @DontCompile + public void test38_verifier(boolean warmup) { + try { + int result = test38(); + Asserts.assertEQ(vcc.x, result, "Field x of input and result must be equal."); + } catch (Throwable t) { + throw new RuntimeException("test 38 failed", t); + } + } + + // Generate a MethodHandle that obtains field x of the + // derived value type + private static MethodHandle generateVCCUnboxLoadIntMH() { + return MethodHandleBuilder.loadCode(MethodHandles.lookup(), + "vccUnboxLoadInt", + MethodType.methodType(int.class, ValueCapableClass1.class), + CODE -> { + CODE. + aload_0(). + vunbox(ValueType.forClass(ValueCapableClass1.class).valueClass()). + vgetfield(ValueType.forClass(ValueCapableClass1.class).valueClass(), "x", "I"). + ireturn(); + } + ); + } + + @Test + public ValueCapableClass1 test39() throws Throwable { + return (ValueCapableClass1)vccUnboxBoxMH.invokeExact(vcc); + } + + @DontCompile + public void test39_verifier(boolean warmup) { + try { + ValueCapableClass1 result = test39(); + Asserts.assertEQ(vcc.value(), result.value(), "Value of VCC and returned VCC must be equal"); + } catch (Throwable t) { + throw new RuntimeException("test 39 failed", t); + } + } + + // Generate a MethodHandle that takes a value-capable class, + // unboxes it, then boxes it again and returns it. + private static MethodHandle generateVCCUnboxBoxMH() { + return MethodHandleBuilder.loadCode(MethodHandles.lookup(), + "vccUnboxBox", + MethodType.methodType(ValueCapableClass1.class, ValueCapableClass1.class), + CODE -> { + CODE. + aload_0(). + vunbox(ValueType.forClass(ValueCapableClass1.class).valueClass()). + vbox(ValueCapableClass1.class). + areturn(); + } + ); + } + + @Test + public int test40() throws Throwable { + return (int)vccUnboxBoxLoadIntMH.invokeExact(vcc); + } + + @DontCompile + public void test40_verifier(boolean warmup) { + try { + int result = test40(); + Asserts.assertEQ(vcc.x, result, "Field x of VCC and result must be equal"); + } catch (Throwable t) { + throw new RuntimeException("Test failed in the interpeter", t); + } + } + + // Generate a MethodHandle that takes a value-capable class, + // unboxes it, boxes it, reads a field from it, and returns the + // field. + private static MethodHandle generateVCCUnboxBoxLoadIntMH() { + return MethodHandleBuilder.loadCode(MethodHandles.lookup(), + "vccUnboxBoxLoadInt", + MethodType.methodType(int.class, ValueCapableClass1.class), + CODE -> { + CODE. + aload_0(). + vunbox(ValueType.forClass(ValueCapableClass1.class).valueClass()). + vbox(ValueCapableClass1.class). + getfield(ValueCapableClass1.class, "x", "I"). + ireturn(); + } + ); + } + // ========== Test infrastructure ========== private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); @@ -786,7 +924,7 @@ private static final int COMP_LEVEL_ANY = -1; private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; private static final Hashtable tests = new Hashtable(); - private static final int WARMUP = 10; + private static final int WARMUP = 250; private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); private static boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal"); // TODO use Platform.isComp() after merge with JDK 9