< prev index next >
test/compiler/valhalla/valuetypes/ValueTypeTestBench.java
Print this page
@@ -31,20 +31,20 @@
* @compile -XDenableValueTypes ValueCapableClass1.java ValueCapableClass2.java ValueTypeTestBench.java
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main ClassFileInstaller jdk.test.lib.Platform
* @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
* -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+VerifyAdapterSharing
- * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueArrayFlatten
+ * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
* -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 -XX:+FullGCALotWithValueTypes
* compiler.valhalla.valuetypes.ValueTypeTestBench
* @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
* -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation
- * -XX:+EnableValhalla -XX:+EnableMVT -XX:-ValueTypePassFieldsAsArgs -XX:-ValueArrayFlatten
+ * -XX:+EnableValhalla -XX:+EnableMVT -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:-ValueArrayFlatten
* compiler.valhalla.valuetypes.ValueTypeTestBench
* @run main/othervm -Xbootclasspath/a:. -ea -noverify -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
* -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+AlwaysIncrementalInline
- * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueArrayFlatten
+ * -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
* -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
* compiler.valhalla.valuetypes.ValueTypeTestBench
*/
package compiler.valhalla.valuetypes;
@@ -65,11 +65,13 @@
import java.lang.invoke.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jdk.experimental.value.*;
// Test value types
@@ -299,10 +301,252 @@
v.b = b;
return v;
}
}
+// Value type definition to stress test return of a value in registers
+// (uses all registers of calling convention on x86_64)
+__ByValue final class MyValue3 {
+ final char c;
+ final byte bb;
+ final short s;
+ final int i;
+ final long l;
+ final Object o;
+ final float f1;
+ final double f2;
+ final float f3;
+ final double f4;
+ final float f5;
+ final double f6;
+ final float f7;
+ final double f8;
+
+ private MyValue3(char c,
+ byte bb,
+ short s,
+ int i,
+ long l,
+ Object o,
+ float f1,
+ double f2,
+ float f3,
+ double f4,
+ float f5,
+ double f6,
+ float f7,
+ double f8) {
+ this.c = c;
+ this.bb = bb;
+ this.s = s;
+ this.i = i;
+ this.l = l;
+ this.o = o;
+ this.f1 = f1;
+ this.f2 = f2;
+ this.f3 = f3;
+ this.f4 = f4;
+ this.f5 = f5;
+ this.f6 = f6;
+ this.f7 = f7;
+ this.f8 = f8;
+ }
+
+ private MyValue3() {
+ this.c = 0;
+ this.bb = 0;
+ this.s = 0;
+ this.i = 0;
+ this.l = 0;
+ this.o = null;
+ this.f1 = 0;
+ this.f2 = 0;
+ this.f3 = 0;
+ this.f4 = 0;
+ this.f5 = 0;
+ this.f6 = 0;
+ this.f7 = 0;
+ this.f8 = 0;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setC(MyValue3 v, char c) {
+ v.c = c;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setBB(MyValue3 v, byte bb) {
+ v.bb = bb;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setS(MyValue3 v, short s) {
+ v.s = s;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setI(MyValue3 v, int i) {
+ v.i = i;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setL(MyValue3 v, long l) {
+ v.l = l;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setO(MyValue3 v, Object o) {
+ v.o = o;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF1(MyValue3 v, float f1) {
+ v.f1 = f1;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF2(MyValue3 v, double f2) {
+ v.f2 = f2;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF3(MyValue3 v, float f3) {
+ v.f3 = f3;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF4(MyValue3 v, double f4) {
+ v.f4 = f4;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF5(MyValue3 v, float f5) {
+ v.f5 = f5;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF6(MyValue3 v, double f6) {
+ v.f6 = f6;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF7(MyValue3 v, float f7) {
+ v.f7 = f7;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue3 setF8(MyValue3 v, double f8) {
+ v.f8 = f8;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory public static MyValue3 createDefault() {
+ return __MakeDefault MyValue3();
+ }
+
+ @ForceInline
+ public static MyValue3 create() {
+ java.util.Random r = Utils.getRandomInstance();
+ MyValue3 v = createDefault();
+ v = setC(v, (char)r.nextInt());
+ v = setBB(v, (byte)r.nextInt());
+ v = setS(v, (short)r.nextInt());
+ v = setI(v, r.nextInt());
+ v = setL(v, r.nextLong());
+ v = setO(v, new Object());
+ v = setF1(v, r.nextFloat());
+ v = setF2(v, r.nextDouble());
+ v = setF3(v, r.nextFloat());
+ v = setF4(v, r.nextDouble());
+ v = setF5(v, r.nextFloat());
+ v = setF6(v, r.nextDouble());
+ v = setF7(v, r.nextFloat());
+ v = setF8(v, r.nextDouble());
+ return v;
+ }
+
+ public void verify(MyValue3 other) {
+ Asserts.assertEQ(c, other.c);
+ Asserts.assertEQ(bb, other.bb);
+ Asserts.assertEQ(s, other.s);
+ Asserts.assertEQ(i, other.i);
+ Asserts.assertEQ(l, other.l);
+ Asserts.assertEQ(o, other.o);
+ Asserts.assertEQ(f1, other.f1);
+ Asserts.assertEQ(f2, other.f2);
+ Asserts.assertEQ(f3, other.f3);
+ Asserts.assertEQ(f4, other.f4);
+ Asserts.assertEQ(f5, other.f5);
+ Asserts.assertEQ(f6, other.f6);
+ Asserts.assertEQ(f7, other.f7);
+ Asserts.assertEQ(f8, other.f8);
+ }
+}
+
+// Value type definition with too many fields to return in registers
+__ByValue final class MyValue4 {
+ final MyValue3 v1;
+ final MyValue3 v2;
+
+ private MyValue4(MyValue3 v1, MyValue3 v2) {
+ this.v1 = v1;
+ this.v2 = v2;
+ }
+
+ private MyValue4() {
+ this.v1 = MyValue3.createDefault();
+ this.v2 = MyValue3.createDefault();
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue4 setV1(MyValue4 v, MyValue3 v1) {
+ v.v1 = v1;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory static MyValue4 setV2(MyValue4 v, MyValue3 v2) {
+ v.v2 = v2;
+ return v;
+ }
+
+ @ForceInline
+ __ValueFactory public static MyValue4 createDefault() {
+ return __MakeDefault MyValue4();
+ }
+
+ @ForceInline
+ public static MyValue4 create() {
+ MyValue4 v = createDefault();
+ MyValue3 v1 = MyValue3.create();
+ v = setV1(v, v1);
+ MyValue3 v2 = MyValue3.create();
+ v = setV2(v, v2);
+ return v;
+ }
+
+ public void verify(MyValue4 other) {
+ v1.verify(other.v1);
+ v2.verify(other.v2);
+ }
+}
+
+
public class ValueTypeTestBench {
// Print ideal graph after execution of each test
private static final boolean PRINT_GRAPH = true;
// Random test values
@@ -1503,12 +1747,11 @@
/* The compiler is supposed to determine that the value to be
* unboxed in nullcvvUnboxLoadLong is always null. Therefore, the
* compiler generates only the path leading to the corresponding
* uncommon trap. */
- @Test(valid = AlwaysIncrementalInlineOff, failOn = RETURN)
- @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1})
+ @Test(failOn = RETURN)
public long test61() throws Throwable {
return (long)nullvccUnboxLoadLongMH.invokeExact();
}
@DontCompile
@@ -1536,12 +1779,11 @@
/* The compiler is supposed to determine that the allocated
* ValueCapableClass1 instance is never null (and therefore not
* generate a null check). Also, the source and target type match
* (known at compile time), so no type check is needed either.*/
- @Test(valid = AlwaysIncrementalInlineOff, failOn = NPE)
- @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1})
+ @Test(failOn = NPE)
public long test62() throws Throwable {
return (long)checkedvccUnboxLoadLongMH.invokeExact();
}
@DontCompile
@@ -1566,12 +1808,11 @@
/* The compiler is supposed to emit a runtime null check because
* it does not have enough information to determine that the value
* to be unboxed is not null (and either that it is null). The
* declared type of the */
- @Test(valid = AlwaysIncrementalInlineOff, match = {NPE}, matchCount = {1})
- @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1})
+ @Test(match = {NPE}, matchCount = {1})
public long test63(ValueCapableClass1 vcc) throws Throwable {
return (long)vccUnboxLoadLongMH.invokeExact(vcc);
}
@DontCompile
@@ -1584,12 +1825,11 @@
}
/* Attempt to unbox an object that is not a subclass of the
* value-capable class derived from the value type specified in
* the vunbox bytecode. */
- @Test(valid = AlwaysIncrementalInlineOff, match = {NPE,CCE}, matchCount = {1,1})
- @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1})
+ @Test(match = {NPE,CCE}, matchCount = {1,1})
public long test64(Object vcc) throws Throwable {
return (long)objectUnboxLoadLongMH.invokeExact(vcc);
}
@DontCompile
@@ -1624,12 +1864,11 @@
}
/* Generate an if-then-else construct with one path that contains
* an invalid boxing operation (boxing of a value-type to a
* non-matching value-capable class).*/
- @Test(valid = AlwaysIncrementalInlineOff, match = {NPE,CCE}, matchCount = {2,3})
- @Test(valid = AlwaysIncrementalInlineOn, match = {LINKTOSTATIC}, matchCount= {1})
+ @Test(match = {NPE,CCE}, matchCount = {2,3})
public long test65(Object obj, boolean warmup) throws Throwable {
return (long)objectBoxMH.invokeExact(obj, warmup);
}
@DontCompile
@@ -1676,23 +1915,267 @@
lreturn();
}
);
}
+ // Test deoptimization at call return with return value in registers
+ @DontCompile
+ public MyValue2 test66_interp(boolean deopt) {
+ if (deopt) {
+ // uncommon trap
+ WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test66"));
+ }
+ return MyValue2.createWithFieldsInline(rI, true);
+ }
+
+ @Test()
+ public MyValue2 test66(boolean flag) {
+ return test66_interp(flag);
+ }
+
+ @DontCompile
+ public void test66_verifier(boolean warmup) {
+ MyValue2 result = test66(!warmup);
+ MyValue2 v = MyValue2.createWithFieldsInline(rI, true);
+ Asserts.assertEQ(result.hash(), v.hash());
+ }
+
+ // Return value types in registers from interpreter -> compiled
+ final MyValue3 test67_vt = MyValue3.create();
+ @DontCompile
+ public MyValue3 test67_interp() {
+ return test67_vt;
+ }
+
+ MyValue3 test67_vt2;
+ @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP)
+ @Test(valid = ValueTypeReturnedAsFieldsOff)
+ public void test67() {
+ test67_vt2 = test67_interp();
+ }
+
+ @DontCompile
+ public void test67_verifier(boolean warmup) {
+ test67();
+ test67_vt.verify(test67_vt2);
+ }
+
+ // Return value types in registers from compiled -> interpreter
+ final MyValue3 test68_vt = MyValue3.create();
+ @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + STORE + TRAP)
+ @Test(valid = ValueTypeReturnedAsFieldsOff)
+ public MyValue3 test68() {
+ return test68_vt;
+ }
+
+ @DontCompile
+ public void test68_verifier(boolean warmup) {
+ MyValue3 vt = test68();
+ test68_vt.verify(vt);
+ }
+
+ // Return value types in registers from compiled -> compiled
+ final MyValue3 test69_vt = MyValue3.create();
+ @DontInline
+ public MyValue3 test69_comp() {
+ return test69_vt;
+ }
+
+ MyValue3 test69_vt2;
+ @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP)
+ @Test(valid = ValueTypeReturnedAsFieldsOff)
+ public void test69() {
+ test69_vt2 = test69_comp();
+ }
+
+ @DontCompile
+ public void test69_verifier(boolean warmup) throws Exception {
+ Method helper_m = getClass().getDeclaredMethod("test69_comp");
+ if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) {
+ WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION);
+ Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test69_comp not compiled");
+ }
+ test69();
+ test69_vt.verify(test69_vt2);
+ }
+
+ // Same tests as above but with a value type that cannot be returned in registers
+
+ // Return value types in registers from interpreter -> compiled
+ final MyValue4 test70_vt = MyValue4.create();
+ @DontCompile
+ public MyValue4 test70_interp() {
+ return test70_vt;
+ }
+
+ MyValue4 test70_vt2;
+ @Test
+ public void test70() {
+ test70_vt2 = test70_interp();
+ }
+
+ @DontCompile
+ public void test70_verifier(boolean warmup) {
+ test70();
+ test70_vt.verify(test70_vt2);
+ }
+
+ // Return value types in registers from compiled -> interpreter
+ final MyValue4 test71_vt = MyValue4.create();
+ @Test
+ public MyValue4 test71() {
+ return test71_vt;
+ }
+
+ @DontCompile
+ public void test71_verifier(boolean warmup) {
+ MyValue4 vt = test71();
+ test71_vt.verify(vt);
+ }
+
+ // Return value types in registers from compiled -> compiled
+ final MyValue4 test72_vt = MyValue4.create();
+ @DontInline
+ public MyValue4 test72_comp() {
+ return test72_vt;
+ }
+
+ MyValue4 test72_vt2;
+ @Test
+ public void test72() {
+ test72_vt2 = test72_comp();
+ }
+
+ @DontCompile
+ public void test72_verifier(boolean warmup) throws Exception {
+ Method helper_m = getClass().getDeclaredMethod("test72_comp");
+ if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) {
+ WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION);
+ Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test72_comp not compiled");
+ }
+ test72();
+ test72_vt.verify(test72_vt2);
+ }
+
+ // Return values and method handles tests
+
+ // Everything inlined
+ final MyValue3 test73_vt = MyValue3.create();
+ @ForceInline
+ MyValue3 test73_target() {
+ return test73_vt;
+ }
+
+ static final MethodHandle test73_mh;
+
+ @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + STORE + CALL)
+ @Test(valid = ValueTypeReturnedAsFieldsOff, match = { ALLOC, STORE }, matchCount = { 1, 11 })
+ MyValue3 test73() throws Throwable {
+ return (MyValue3)test73_mh.invokeExact(this);
+ }
+
+ @DontCompile
+ public void test73_verifier(boolean warmup) throws Throwable {
+ MyValue3 vt = test73();
+ test73_vt.verify(vt);
+ }
+
+ // Leaf method not inlined but returned type is known
+ final MyValue3 test74_vt = MyValue3.create();
+ @DontInline
+ MyValue3 test74_target() {
+ return test74_vt;
+ }
+
+ static final MethodHandle test74_mh;
+
+ @Test
+ MyValue3 test74() throws Throwable {
+ return (MyValue3)test74_mh.invokeExact(this);
+ }
+
+ @DontCompile
+ public void test74_verifier(boolean warmup) throws Throwable {
+ Method helper_m = getClass().getDeclaredMethod("test74_target");
+ if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) {
+ WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION);
+ Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test74_target not compiled");
+ }
+ MyValue3 vt = test74();
+ test74_vt.verify(vt);
+ }
+
+ // Leaf method not inlined and returned type not known
+ final MyValue3 test75_vt = MyValue3.create();
+ @DontInline
+ MyValue3 test75_target() {
+ return test75_vt;
+ }
+
+ static final MethodHandle test75_mh;
+
+ @Test
+ MyValue3 test75() throws Throwable {
+ return (MyValue3)test75_mh.invokeExact(this);
+ }
+
+ @DontCompile
+ public void test75_verifier(boolean warmup) throws Throwable {
+ // hack so C2 doesn't know the target of the invoke call
+ Class c = Class.forName("java.lang.invoke.DirectMethodHandle");
+ Method m = c.getDeclaredMethod("internalMemberName", Object.class);
+ WHITE_BOX.testSetDontInlineMethod(m, warmup);
+ MyValue3 vt = test75();
+ test75_vt.verify(vt);
+ }
+
+ // Test no result from inlined method for incremental inlining
+ final MyValue3 test76_vt = MyValue3.create();
+ public MyValue3 test76_inlined() {
+ throw new RuntimeException();
+ }
+
+ @Test
+ public MyValue3 test76() {
+ try {
+ return test76_inlined();
+ } catch (RuntimeException ex) {
+ return test76_vt;
+ }
+ }
+
+ @DontCompile
+ public void test76_verifier(boolean warmup) throws Exception {
+ MyValue3 vt = test76();
+ test76_vt.verify(vt);
+ }
+
+ static {
+ try {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.fromMethodDescriptorString("()Qcompiler/valhalla/valuetypes/MyValue3;", ValueTypeTestBench.class.getClassLoader());
+ test73_mh = lookup.findVirtual(ValueTypeTestBench.class, "test73_target", mt);
+ test74_mh = lookup.findVirtual(ValueTypeTestBench.class, "test74_target", mt);
+ test75_mh = lookup.findVirtual(ValueTypeTestBench.class, "test75_target", mt);
+ } catch (NoSuchMethodException|IllegalAccessException e) {
+ throw new RuntimeException("method handle lookup fails");
+ }
+ }
+
// ========== 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;
- private static final int AlwaysIncrementalInlineOff = 0x10;
- private static final int AlwaysIncrementalInlineOn = 0x20;
- static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | AlwaysIncrementalInlineOff | AlwaysIncrementalInlineOn;
+ private static final int ValueTypeReturnedAsFieldsOn = 0x10;
+ private static final int ValueTypeReturnedAsFieldsOff = 0x20;
+ static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn;
private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
- private static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline");
+ private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
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 = 251;
private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
@@ -1713,10 +2196,11 @@
private static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END;
private static final String RETURN = START + "Return" + MID + "returns" + END;
private static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END;
private static final String NPE = START + "CallStaticJava" + MID + "null_check" + END;
private static final String CCE = START + "CallStaticJava" + MID + "class_check" + END;
+ private static final String CALL = START + "CallStaticJava" + MID + END;
private static final String SCOBJ = "(.*# ScObj.*" + END;
static {
// Gather all test methods and put them in Hashtable
for (Method m : ValueTypeTestBench.class.getDeclaredMethods()) {
@@ -1749,45 +2233,64 @@
System.out.println("WARNING: IR verification disabled! Running with -Xint, -Xcomp or release build?");
}
}
public static void main(String[] args) throws Throwable {
- //tests.values().removeIf(p -> !p.getName().equals("test64")); // Run single test
+ //tests.values().removeIf(p -> !p.getName().equals("test74")); // Run single test
if (args.length == 0) {
execute_vm("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-BackgroundCompilation",
"-XX:+PrintCompilation", "-XX:+PrintInlining", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly",
+ "-XX:CICompilerCount=1",
"-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*",
"-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue1::*",
"-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2::*",
"-XX:CompileCommand=compileonly,java.lang.Object::<init>",
- "-XX:CompileCommand=inline,java.lang.__Value::hashCode");
+ "-XX:CompileCommand=inline,java.lang.__Value::hashCode",
+ "-XX:CompileCommand=compileonly,java.lang.invoke.*::*");
} else {
// Execute tests
ValueTypeTestBench bench = new ValueTypeTestBench();
bench.run();
}
}
public static void parseOutput(String output) throws Exception {
- String split = "b compiler.valhalla.valuetypes.";
- String[] compilations = output.split(split);
+ 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");
+ Matcher m = comp_re.matcher(output);
+ Map<String,String> compilations = new LinkedHashMap<>();
+ int prev = 0;
+ String methodName = null;
+ while (m.find()) {
+ if (prev == 0) {
// Print header
- System.out.println(compilations[0]);
- // Iterate over compilation output
- for (String graph : compilations) {
- String[] lines = graph.split("\\n");
- if (lines[0].contains("@")) {
- continue; // Ignore OSR compilations
+ System.out.print(output.substring(0, m.start()+1));
+ } else if (methodName != null) {
+ compilations.put(methodName, output.substring(prev, m.start()+1));
}
- String testName = lines[0].split(" ")[0];
+ if (m.group("osr") != null) {
+ methodName = null;
+ } else {
+ methodName = m.group("name");
+ }
+ prev = m.end();
+ }
+ if (prev == 0) {
+ // Print header
+ System.out.print(output);
+ } else if (methodName != null) {
+ compilations.put(methodName, output.substring(prev));
+ }
+ // Iterate over compilation output
+ for (String testName : compilations.keySet()) {
Method test = tests.get(testName);
if (test == null) {
// Skip helper methods
continue;
}
+ String graph = compilations.get(testName);
if (PRINT_GRAPH) {
- System.out.println("\nGraph for " + graph);
+ System.out.println("\nGraph for " + testName + "\n" + graph);
}
// Parse graph using regular expressions to determine if it contains forbidden nodes
Test[] annos = test.getAnnotationsByType(Test.class);
Test anno = null;
for (Test a : annos) {
@@ -1801,14 +2304,14 @@
assert anno == null;
anno = a;
} else if ((a.valid() & ValueTypeArrayFlattenOff) != 0 && !ValueTypeArrayFlatten) {
assert anno == null;
anno = a;
- } else if ((a.valid() & AlwaysIncrementalInlineOff) != 0 && !AlwaysIncrementalInline) {
+ } else if ((a.valid() & ValueTypeReturnedAsFieldsOn) != 0 && ValueTypeReturnedAsFields) {
assert anno == null;
anno = a;
- } else if ((a.valid() & AlwaysIncrementalInlineOn) != 0 && AlwaysIncrementalInline) {
+ } else if ((a.valid() & ValueTypeReturnedAsFieldsOff) != 0 && !ValueTypeReturnedAsFields) {
assert anno == null;
anno = a;
}
}
assert anno != null;
< prev index next >