< prev index next >

test/compiler/valhalla/valuetypes/ValueTypeTestBench.java

Print this page




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 // TODO add bugid and summary
  25 
  26 /*
  27  * @test
  28  * @library /testlibrary /test/lib /compiler/whitebox /
  29  * @requires os.simpleArch == "x64"
  30  * @build compiler.valhalla.valuetypes.ValueTypeTestBench
  31  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  32  * @run main ClassFileInstaller jdk.test.lib.Platform
  33  * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  34  *                   -XX:+UnlockExperimentalVMOptions -XX:+ValueTypePassFieldsAsArgs -XX:+ValueArrayFlatten -XX:+VerifyAdapterSharing
  35  *                   -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench

  36  * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  37  *                   -XX:+UnlockExperimentalVMOptions -XX:-ValueTypePassFieldsAsArgs -XX:-ValueArrayFlatten
  38  *                   -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench

  39  * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  40  *                   -XX:+UnlockExperimentalVMOptions -XX:+AlwaysIncrementalInline -XX:+ValueArrayFlatten
  41  *                   -XX:-TieredCompilation compiler.valhalla.valuetypes.ValueTypeTestBench

  42  */
  43 
  44 package compiler.valhalla.valuetypes;
  45 
  46 import compiler.whitebox.CompilerWhiteBoxTest;
  47 import jdk.internal.misc.Unsafe;
  48 import jdk.test.lib.Asserts;
  49 import jdk.test.lib.Platform;
  50 import jdk.test.lib.ProcessTools;
  51 import jdk.test.lib.OutputAnalyzer;
  52 import jdk.test.lib.Utils;
  53 import sun.hotspot.WhiteBox;
  54 
  55 import java.lang.annotation.Retention;
  56 import java.lang.annotation.RetentionPolicy;
  57 import java.lang.annotation.Repeatable;
  58 import java.lang.invoke.*;
  59 import java.lang.reflect.Method;
  60 import java.util.ArrayList;
  61 import java.util.Arrays;
  62 import java.util.Hashtable;
  63 import java.util.List;
  64 import java.util.regex.Matcher;
  65 import java.util.regex.Pattern;
  66 import jdk.experimental.value.*;
  67 
  68 // Test value types
  69 __ByValue final class MyValue1 {
  70     static int s;
  71     static final long sf = ValueTypeTestBench.rL;
  72     final int x;
  73     final long y;
  74     final short z;


  75     final MyValue2 v1;
  76     final MyValue2 v2;
  77     static final MyValue2 v3 = MyValue2.createInline(ValueTypeTestBench.rI, true);
  78     final int c;
  79 
  80     private MyValue1(int x, long y, short z, MyValue2 v1, MyValue2 v2, int c) {
  81         s = x;
  82         this.x = x;
  83         this.y = y;
  84         this.z = z;


  85         this.v1 = v1;
  86         this.v2 = v2;
  87         this.c = c;
  88     }
  89 
  90     private MyValue1() {
  91         s = 0;
  92         this.x = 0;
  93         this.y = 0;
  94         this.z = 0;


  95         this.v1 = MyValue2.createDefaultInline();
  96         this.v2 = MyValue2.createDefaultInline();
  97         this.c = 0;
  98     }
  99 
 100     @DontInline
 101     public static MyValue1 createDontInline(int x, long y) {
 102         return __Make MyValue1(x, y, (short)x, MyValue2.createInline(x, true), MyValue2.createInline(x, false), ValueTypeTestBench.rI);

 103     }
 104 
 105     @ForceInline
 106     public static MyValue1 createInline(int x, long y) {
 107         return __Make MyValue1(x, y, (short)x, MyValue2.createInline(x, true), MyValue2.createInline(x, false), ValueTypeTestBench.rI);

 108     }
 109 
 110     @DontInline
 111     __ValueFactory static MyValue1 createDefaultDontInline() {
 112         return __MakeDefault MyValue1();
 113     }
 114 
 115     @ForceInline
 116     __ValueFactory static MyValue1 createDefaultInline() {
 117         return __MakeDefault MyValue1();
 118     }
 119 
 120     @DontInline
 121     static MyValue1 createWithFieldsDontInline(int x, long y) {
 122         MyValue1 v = createDefaultInline();
 123         v = setX(v, x);
 124         v = setY(v, y);
 125         v = setZ(v, (short)x);



 126         v = setV1(v, MyValue2.createWithFieldsInline(x, x < y));
 127         v = setV2(v, MyValue2.createWithFieldsInline(x, x > y));
 128         v = setC(v, ValueTypeTestBench.rI);
 129         return v;
 130     }
 131 
 132     @ForceInline
 133     static MyValue1 createWithFieldsInline(int x, long y) {
 134         MyValue1 v = createDefaultInline();
 135         v = setX(v, x);
 136         v = setY(v, y);
 137         v = setZ(v, (short)x);



 138         v = setV1(v, MyValue2.createWithFieldsInline(x, x < y));
 139         v = setV2(v, MyValue2.createWithFieldsInline(x, x > y));
 140         v = setC(v, ValueTypeTestBench.rI);
 141         return v;
 142     }
 143 

 144     @ForceInline
 145     public long hash() {
 146         return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash();
 147     }
 148 





 149     @DontCompile
 150     public long hashInterpreted() {
 151         return s + sf + x + y + z + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted();
 152     }
 153 
 154     @ForceInline
 155     public void print() {
 156         System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", v1[");
 157         v1.print();
 158         System.out.print("], v2[");
 159         v2.print();
 160         System.out.print("], v3[");
 161         v3.print();
 162         System.out.print("], c=" + c);
 163     }
 164 
 165     @ForceInline
 166     __ValueFactory static MyValue1 setX(MyValue1 v, int x) {
 167         v.x = x;
 168         return v;
 169     }
 170 
 171     @ForceInline
 172     __ValueFactory static MyValue1 setY(MyValue1 v, long y) {
 173         v.y = y;
 174         return v;
 175     }
 176 
 177     @ForceInline
 178     __ValueFactory static MyValue1 setZ(MyValue1 v, short z) {
 179         v.z = z;
 180         return v;
 181     }
 182 
 183     @ForceInline












 184     __ValueFactory static MyValue1 setC(MyValue1 v, int c) {
 185         v.c = c;
 186         return v;
 187     }
 188 
 189     @ForceInline
 190     __ValueFactory static MyValue1 setV1(MyValue1 v, MyValue2 v1) {
 191         v.v1 = v1;
 192         return v;
 193     }
 194 
 195     @ForceInline
 196     __ValueFactory static MyValue1 setV2(MyValue1 v, MyValue2 v2) {
 197         v.v2 = v2;
 198         return v;
 199     }
 200 }
 201 
 202 __ByValue final class MyValue2 {
 203     final int x;


 470         Asserts.assertEQ(v.y, hash(rI + 1, rL + 1) + 1);
 471     }
 472 
 473     // Merge value types created in a loop (not inlined)
 474     @Test(failOn = ALLOC + STORE + TRAP)
 475     public long test10(int x, long y) {
 476         MyValue1 v = MyValue1.createDontInline(x, y);
 477         for (int i = 0; i < 10; ++i) {
 478             v = MyValue1.createDontInline(v.x + 1, v.y + 1);
 479         }
 480         return v.hash();
 481     }
 482 
 483     @DontCompile
 484     public void test10_verifier(boolean warmup) {
 485         long result = test10(rI, rL);
 486         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 487     }
 488 
 489     // Merge value types created in a loop (inlined)
 490     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
 491     public long test11(int x, long y) {
 492         MyValue1 v = MyValue1.createInline(x, y);
 493         for (int i = 0; i < 10; ++i) {
 494             v = MyValue1.createInline(v.x + 1, v.y + 1);
 495         }
 496         return v.hash();
 497     }
 498 
 499     @DontCompile
 500     public void test11_verifier(boolean warmup) {
 501         long result = test11(rI, rL);
 502         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 503     }
 504 
 505     // Test loop with uncommon trap referencing a value type
 506     @Test(match = {TRAP, SCOBJ}, matchCount = {1, -1 /* at least 1 */}, failOn = LOAD)
 507     public long test12(boolean b) {
 508         MyValue1 v = MyValue1.createInline(rI, rL);
 509         MyValue1[] va = new MyValue1[Math.abs(rI) % 10];
 510         for (int i = 0; i < va.length; ++i) {


 649 
 650     @DontCompile
 651     public long sumValue(MyValue1 v, MyValue1 dummy) {
 652         return v.hash();
 653     }
 654 
 655     @DontCompile
 656     public void test19_verifier(boolean warmup) {
 657         long result = test19();
 658         Asserts.assertEQ(result, hash());
 659     }
 660 
 661     // Create a value type (array) in compiled code and pass it to the
 662     // interpreter via a call. The value type is live at the uncommon
 663     // trap: verify that deoptimization causes the value type to be
 664     // correctly allocated.
 665     @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = LOAD + ALLOC + STORE)
 666     @Test(valid = ValueTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {2}, failOn = LOAD)
 667     public long test20(boolean deopt) {
 668         MyValue1 v = MyValue1.createInline(rI, rL);
 669         MyValue1[] va = new MyValue1[3];
 670         if (deopt) {
 671             // uncommon trap
 672             WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test20"));
 673         }
 674         return v.hashInterpreted() + va[0].hashInterpreted() +
 675                 va[1].hashInterpreted() + va[2].hashInterpreted();
 676     }
 677 
 678     @DontCompile
 679     public void test20_verifier(boolean warmup) {
 680         MyValue1[] va = new MyValue1[42];
 681         long result = test20(!warmup);
 682         Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash());
 683     }
 684 
 685     // Value type fields in regular object
 686     MyValue1 val1;
 687     MyValue2 val2;
 688     final MyValue1 val3;
 689     static MyValue1 val4;
 690     static final MyValue1 val5 = MyValue1.createInline(rI, rL);
 691 
 692     // Test value type fields in objects
 693     @Test(match = {ALLOC}, matchCount = {1}, failOn = (TRAP))
 694     public long test21(int x, long y) {
 695         // Compute hash of value type fields
 696         long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash();
 697         // Update fields
 698         val1 = MyValue1.createInline(x, y);
 699         val2 = MyValue2.createInline(x, true);
 700         val4 = MyValue1.createInline(x, y);


1153     }
1154 
1155     // Test returning a value type array received from the interpreter
1156     @Test(failOn = ALLOC + ALLOCA + LOAD + LOADP + STORE + LOOP + TRAP)
1157     public MyValue1[] test44(MyValue1[] va) {
1158         return va;
1159     }
1160 
1161     @DontCompile
1162     public void test44_verifier(boolean warmup) {
1163         MyValue1[] va = new MyValue1[10];
1164         for (int i = 0; i < 10; ++i) {
1165             va[i] = MyValue1.createDontInline(rI + i, rL + i);
1166         }
1167         va = test44(va);
1168         for (int i = 0; i < 10; ++i) {
1169             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
1170         }
1171     }
1172 

1173     @Test(failOn = (TRAP))
1174     public MyValue1[] test45(boolean b) {
1175         MyValue1[] va;
1176         if (b) {
1177             va = new MyValue1[5];
1178             for (int i = 0; i < 5; ++i) {
1179                 va[i] = MyValue1.createInline(rI, rL);
1180             }
1181         } else {
1182             va = new MyValue1[10];
1183             for (int i = 0; i < 10; ++i) {
1184                 va[i] = MyValue1.createInline(rI + i, rL + i);
1185             }
1186         }
1187         long sum = va[0].hashInterpreted();
1188         if (b) {
1189             va[0] = MyValue1.createDontInline(rI, sum);
1190         } else {
1191             va[0] = MyValue1.createDontInline(rI + 1, sum + 1);
1192         }


1204         va = test45(false);
1205         Asserts.assertEQ(va.length, 10);
1206         Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1));
1207         for (int i = 1; i < 10; ++i) {
1208             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
1209         }
1210     }
1211 
1212     // Test creation of value type array with single element
1213     @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOAD + LOOP + TRAP))
1214     @Test(valid = ValueTypeArrayFlattenOn, failOn = (ALLOCA + LOAD + LOOP + TRAP))
1215     public MyValue1 test46() {
1216         MyValue1[] va = new MyValue1[1];
1217         return va[0];
1218     }
1219 
1220     @DontCompile
1221     public void test46_verifier(boolean warmup) {
1222         MyValue1[] va = new MyValue1[1];
1223         MyValue1 v = test46();
1224         Asserts.assertEQ(v.hash(), va[0].hash());
1225     }
1226 
1227     // Test default initialization of value type arrays
1228     @Test(failOn = LOAD)
1229     public MyValue1[] test47(int len) {
1230         return new MyValue1[len];
1231     }
1232 
1233     @DontCompile
1234     public void test47_verifier(boolean warmup) {
1235         int len = Math.abs(rI % 10);
1236         MyValue1[] va = new MyValue1[len];
1237         MyValue1[] var = test47(len);
1238         for (int i = 0; i < len; ++i) {
1239             Asserts.assertEQ(va[i].hash(), var[i].hash());
1240         }
1241     }
1242 
1243     // Test creation of value type array with zero length
1244     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
1245     public MyValue1[] test48() {
1246         return new MyValue1[0];
1247     }
1248 
1249     @DontCompile
1250     public void test48_verifier(boolean warmup) {
1251         MyValue1[] va = test48();
1252         Asserts.assertEQ(va.length, 0);
1253     }
1254 
1255     static MyValue1[] test49_va;
1256 
1257     // Test that value type array loaded from field has correct type
1258     @Test(failOn = (LOOP))
1259     public long test49() {


1269     }
1270 
1271     // test vdefault
1272     @Test(failOn = ALLOC + LOAD + LOADP + STORE + LOOP + TRAP)
1273     public long test50() {
1274         MyValue2 v = MyValue2.createDefaultInline();
1275         return v.hash();
1276     }
1277 
1278     @DontCompile
1279     public void test50_verifier(boolean warmup) {
1280         long result = test50();
1281         Asserts.assertEQ(result, MyValue2.createDefaultInline().hash());
1282     }
1283 
1284     // test vdefault
1285     @Test(failOn = ALLOC + STORE + LOOP + TRAP)
1286     public long test51() {
1287         MyValue1 v1 = MyValue1.createDefaultInline();
1288         MyValue1 v2 = MyValue1.createDefaultDontInline();
1289         return v1.hash() + v2.hash();
1290     }
1291 
1292     @DontCompile
1293     public void test51_verifier(boolean warmup) {
1294         long result = test51();
1295         Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hash());
1296     }
1297 
1298     // test vwithfield
1299     @Test(failOn = ALLOC + LOAD + LOADP + STORE + LOOP + TRAP)
1300     public long test52() {
1301         MyValue2 v = MyValue2.createWithFieldsInline(rI, true);
1302         return v.hash();
1303     }
1304 
1305     @DontCompile
1306     public void test52_verifier(boolean warmup) {
1307         long result = test52();
1308         Asserts.assertEQ(result, MyValue2.createWithFieldsInline(rI, true).hash());
1309     }
1310 
1311     // test vwithfield
1312     @Test(failOn = ALLOC + STORE + LOOP + TRAP)
1313     public long test53() {
1314         MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL);
1315         MyValue1 v2 = MyValue1.createWithFieldsDontInline(rI, rL);


1427     public void test58() {
1428         MyValue1 v1 = MyValue1.createInline(0, 0);
1429         MyValue1 v2 = MyValue1.createInline(1, 1);
1430         // Trigger OSR compilation and loop peeling
1431         for (int i = 0; i < 100_000; ++i) {
1432             if (v1.x != 2*i || v2.x != i+1 || v2.y != i+1) {
1433                 // Uncommon trap
1434                 throw new RuntimeException("test58 failed");
1435             }
1436             v1 = MyValue1.createInline(2*(i+1), 0);
1437             v2 = MyValue1.createInline(i+2, i+2);
1438         }
1439     }
1440 
1441     @DontCompile
1442     public void test58_verifier(boolean warmup) {
1443         test58();
1444     }
1445 
1446     // When calling a method on __Value, passing fields as arguments is impossible
1447     @Test(valid = ValueTypePassFieldsAsArgsOn, match = {ALLOC, STORE}, matchCount={1, 0})
1448     @Test(valid = ValueTypePassFieldsAsArgsOff, failOn = STORE + LOAD)
1449     public String test59(MyValue1 v) {
1450         return v.toString();
1451     }
1452 
1453     @DontCompile
1454     public void test59_verifier(boolean warmup) {
1455         boolean failed = false;
1456         try {
1457             test59(val1);
1458             failed = true;
1459         } catch (UnsupportedOperationException uoe) {
1460         }
1461         Asserts.assertFalse(failed);
1462     }
1463 
1464     // Same as above, but the method on __Value is inlined
1465     // hashCode allocates an exception so can't really check the graph shape
1466     @Test()
1467     public int test60(MyValue1 v) {
1468         return v.hashCode();


1639                 MethodType.methodType(long.class, Object.class, boolean.class),
1640                 CODE -> {
1641                     CODE.
1642                     iload_1().
1643                     iconst_1().
1644                     if_icmpne((short)14).
1645                     aload_0().
1646                     vunbox(ValueType.forClass(ValueCapableClass1.class).valueClass()).
1647                     vbox(ValueCapableClass1.class).
1648                     getfield(ValueCapableClass1.class, "t", "J").
1649                     lreturn().
1650                     aload_0().
1651                     vunbox(ValueType.forClass(ValueCapableClass2.class).valueClass()).
1652                     vbox(ValueCapableClass1.class).
1653                     getfield(ValueCapableClass1.class, "t", "J").
1654                     lreturn();
1655                }
1656                 );
1657     }
1658 



















1659     // ========== Test infrastructure ==========
1660 
1661     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
1662     private static final int ValueTypePassFieldsAsArgsOn = 0x1;
1663     private static final int ValueTypePassFieldsAsArgsOff = 0x2;
1664     private static final int ValueTypeArrayFlattenOn = 0x4;
1665     private static final int ValueTypeArrayFlattenOff = 0x8;
1666     private static final int AlwaysIncrementalInlineOff = 0x10;
1667     private static final int AlwaysIncrementalInlineOn = 0x20;
1668     static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | AlwaysIncrementalInlineOff | AlwaysIncrementalInlineOn;
1669     private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
1670     private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
1671     private static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline");
1672     private static final int COMP_LEVEL_ANY = -1;
1673     private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
1674     private static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
1675     private static final int WARMUP = 251;
1676     private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
1677     private static boolean PRINT_IDEAL  = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
1678     // TODO use Platform.isComp() after merge with JDK 9
1679     private static boolean XCOMP = System.getProperty("java.vm.info").startsWith("compiled ");
1680 
1681     // Regular expressions used  to match nodes in the PrintIdeal output
1682     private static final String START = "(\\d+\\t(.*";
1683     private static final String MID = ".*)+\\t===.*";
1684     private static final String END = ")|";
1685     private static final String ALLOC  = START + "CallStaticJava" + MID + "_new_instance_Java" + END;
1686     private static final String ALLOCA = START + "CallStaticJava" + MID + "_new_array_Java" + END;
1687     private static final String LOAD   = START + "Load(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
1688     private static final String LOADP  = START + "Load(P|N)" + MID + "valuetype\\*" + END;
1689     private static final String STORE  = START + "Store(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
1690     private static final String STOREP = START + "Store(P|N)" + MID + "valuetype\\*" + END;
1691     private static final String LOOP   = START + "Loop" + MID + "" + END;
1692     private static final String TRAP   = START + "CallStaticJava" + MID + "uncommon_trap" + END;
1693     private static final String RETURN = START + "Return" + MID + "returns" + END;
1694     private static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END;
1695     private static final String NPE = START + "CallStaticJava" + MID + "null_check" + END;
1696     private static final String CCE = START + "CallStaticJava" + MID + "class_check" + END;
1697     // TODO: match field values of scalar replaced object
1698     private static final String SCOBJ = "(.*# ScObj.*" + END;
1699 
1700     static {
1701         // Gather all test methods and put them in Hashtable
1702         for (Method m : ValueTypeTestBench.class.getDeclaredMethods()) {
1703             Test[] annos = m.getAnnotationsByType(Test.class);
1704             if (annos.length != 0) {
1705                 tests.put("ValueTypeTestBench::" + m.getName(), m);
1706             }
1707         }
1708     }
1709 
1710     private static void execute_vm(String... args) throws Throwable {
1711         Asserts.assertFalse(tests.isEmpty(), "no tests to execute");
1712         ArrayList<String> all_args = new ArrayList(List.of(args));




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 // TODO add bugid and summary
  25 
  26 /*
  27  * @test
  28  * @library /testlibrary /test/lib /compiler/whitebox /
  29  * @requires os.simpleArch == "x64"
  30  * @build compiler.valhalla.valuetypes.ValueTypeTestBench
  31  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  32  * @run main ClassFileInstaller jdk.test.lib.Platform
  33  * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  34  *                   -XX:+UnlockExperimentalVMOptions -XX:+ValueTypePassFieldsAsArgs -XX:+ValueArrayFlatten -XX:+VerifyAdapterSharing
  35  *                   -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 -XX:-TieredCompilation
  36  *                   compiler.valhalla.valuetypes.ValueTypeTestBench
  37  * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  38  *                   -XX:+UnlockExperimentalVMOptions -XX:-ValueTypePassFieldsAsArgs -XX:-ValueArrayFlatten
  39  *                   -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 -XX:-TieredCompilation
  40  *                   compiler.valhalla.valuetypes.ValueTypeTestBench
  41  * @run main/othervm -ea -noverify -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  42  *                   -XX:+UnlockExperimentalVMOptions -XX:+AlwaysIncrementalInline -XX:+ValueArrayFlatten
  43  *                   -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 -XX:-TieredCompilation
  44  *                   compiler.valhalla.valuetypes.ValueTypeTestBench
  45  */
  46 
  47 package compiler.valhalla.valuetypes;
  48 
  49 import compiler.whitebox.CompilerWhiteBoxTest;
  50 import jdk.internal.misc.Unsafe;
  51 import jdk.test.lib.Asserts;
  52 import jdk.test.lib.Platform;
  53 import jdk.test.lib.ProcessTools;
  54 import jdk.test.lib.OutputAnalyzer;
  55 import jdk.test.lib.Utils;
  56 import sun.hotspot.WhiteBox;
  57 
  58 import java.lang.annotation.Retention;
  59 import java.lang.annotation.RetentionPolicy;
  60 import java.lang.annotation.Repeatable;
  61 import java.lang.invoke.*;
  62 import java.lang.reflect.Method;
  63 import java.util.ArrayList;
  64 import java.util.Arrays;
  65 import java.util.Hashtable;
  66 import java.util.List;
  67 import java.util.regex.Matcher;
  68 import java.util.regex.Pattern;
  69 import jdk.experimental.value.*;
  70 
  71 // Test value types
  72 __ByValue final class MyValue1 {
  73     static int s;
  74     static final long sf = ValueTypeTestBench.rL;
  75     final int x;
  76     final long y;
  77     final short z;
  78     final Integer o;
  79     final int[] oa;
  80     final MyValue2 v1;
  81     final MyValue2 v2;
  82     static final MyValue2 v3 = MyValue2.createInline(ValueTypeTestBench.rI, true);
  83     final int c;
  84 
  85     private MyValue1(int x, long y, short z, Integer o, int[] oa, MyValue2 v1, MyValue2 v2, int c) {
  86         s = x;
  87         this.x = x;
  88         this.y = y;
  89         this.z = z;
  90         this.o = o;
  91         this.oa = oa;
  92         this.v1 = v1;
  93         this.v2 = v2;
  94         this.c = c;
  95     }
  96 
  97     private MyValue1() {
  98         s = 0;
  99         this.x = 0;
 100         this.y = 0;
 101         this.z = 0;
 102         this.o = null;
 103         this.oa = null;
 104         this.v1 = MyValue2.createDefaultInline();
 105         this.v2 = MyValue2.createDefaultInline();
 106         this.c = 0;
 107     }
 108 
 109     @DontInline
 110     public static MyValue1 createDontInline(int x, long y) {
 111         int[] oa = {x};
 112         return __Make MyValue1(x, y, (short)x, new Integer(x), oa, MyValue2.createInline(x, true), MyValue2.createInline(x, false), ValueTypeTestBench.rI);
 113     }
 114 
 115     @ForceInline
 116     public static MyValue1 createInline(int x, long y) {
 117         int[] oa = {x};
 118         return __Make MyValue1(x, y, (short)x, new Integer(x), oa, MyValue2.createInline(x, true), MyValue2.createInline(x, false), ValueTypeTestBench.rI);
 119     }
 120 
 121     @DontInline
 122     __ValueFactory static MyValue1 createDefaultDontInline() {
 123         return __MakeDefault MyValue1();
 124     }
 125 
 126     @ForceInline
 127     __ValueFactory static MyValue1 createDefaultInline() {
 128         return __MakeDefault MyValue1();
 129     }
 130 
 131     @DontInline
 132     static MyValue1 createWithFieldsDontInline(int x, long y) {
 133         MyValue1 v = createDefaultInline();
 134         v = setX(v, x);
 135         v = setY(v, y);
 136         v = setZ(v, (short)x);
 137         v = setO(v, new Integer(x));
 138         int[] oa = {x};
 139         v = setOA(v, oa);
 140         v = setV1(v, MyValue2.createWithFieldsInline(x, x < y));
 141         v = setV2(v, MyValue2.createWithFieldsInline(x, x > y));
 142         v = setC(v, ValueTypeTestBench.rI);
 143         return v;
 144     }
 145 
 146     @ForceInline
 147     static MyValue1 createWithFieldsInline(int x, long y) {
 148         MyValue1 v = createDefaultInline();
 149         v = setX(v, x);
 150         v = setY(v, y);
 151         v = setZ(v, (short)x);
 152         v = setO(v, new Integer(x));
 153         int[] oa = {x};
 154         v = setOA(v, oa);
 155         v = setV1(v, MyValue2.createWithFieldsInline(x, x < y));
 156         v = setV2(v, MyValue2.createWithFieldsInline(x, x > y));
 157         v = setC(v, ValueTypeTestBench.rI);
 158         return v;
 159     }
 160 
 161     // Hash only primitive and value type fields to avoid NullPointerException
 162     @ForceInline
 163     public long hashPrimitive() {
 164         return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash();
 165     }
 166 
 167     @ForceInline
 168     public long hash() {
 169         return hashPrimitive() + o + oa[0];
 170     }
 171 
 172     @DontCompile
 173     public long hashInterpreted() {
 174         return s + sf + x + y + z + o + oa[0] + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted();
 175     }
 176 
 177     @ForceInline
 178     public void print() {
 179         System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", o=" + (o != null ? (Integer)o : "NULL") + ", v1[");
 180         v1.print();
 181         System.out.print("], v2[");
 182         v2.print();
 183         System.out.print("], v3[");
 184         v3.print();
 185         System.out.print("], c=" + c);
 186     }
 187 
 188     @ForceInline
 189     __ValueFactory static MyValue1 setX(MyValue1 v, int x) {
 190         v.x = x;
 191         return v;
 192     }
 193 
 194     @ForceInline
 195     __ValueFactory static MyValue1 setY(MyValue1 v, long y) {
 196         v.y = y;
 197         return v;
 198     }
 199 
 200     @ForceInline
 201     __ValueFactory static MyValue1 setZ(MyValue1 v, short z) {
 202         v.z = z;
 203         return v;
 204     }
 205 
 206     @ForceInline
 207     __ValueFactory static MyValue1 setO(MyValue1 v, Integer o) {
 208         v.o = o;
 209         return v;
 210     }
 211 
 212     @ForceInline
 213     __ValueFactory static MyValue1 setOA(MyValue1 v, int[] oa) {
 214         v.oa = oa;
 215         return v;
 216     }
 217 
 218     @ForceInline
 219     __ValueFactory static MyValue1 setC(MyValue1 v, int c) {
 220         v.c = c;
 221         return v;
 222     }
 223 
 224     @ForceInline
 225     __ValueFactory static MyValue1 setV1(MyValue1 v, MyValue2 v1) {
 226         v.v1 = v1;
 227         return v;
 228     }
 229 
 230     @ForceInline
 231     __ValueFactory static MyValue1 setV2(MyValue1 v, MyValue2 v2) {
 232         v.v2 = v2;
 233         return v;
 234     }
 235 }
 236 
 237 __ByValue final class MyValue2 {
 238     final int x;


 505         Asserts.assertEQ(v.y, hash(rI + 1, rL + 1) + 1);
 506     }
 507 
 508     // Merge value types created in a loop (not inlined)
 509     @Test(failOn = ALLOC + STORE + TRAP)
 510     public long test10(int x, long y) {
 511         MyValue1 v = MyValue1.createDontInline(x, y);
 512         for (int i = 0; i < 10; ++i) {
 513             v = MyValue1.createDontInline(v.x + 1, v.y + 1);
 514         }
 515         return v.hash();
 516     }
 517 
 518     @DontCompile
 519     public void test10_verifier(boolean warmup) {
 520         long result = test10(rI, rL);
 521         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 522     }
 523 
 524     // Merge value types created in a loop (inlined)
 525     @Test(failOn = ALLOC + LOAD + STORE + TRAP)
 526     public long test11(int x, long y) {
 527         MyValue1 v = MyValue1.createInline(x, y);
 528         for (int i = 0; i < 10; ++i) {
 529             v = MyValue1.createInline(v.x + 1, v.y + 1);
 530         }
 531         return v.hash();
 532     }
 533 
 534     @DontCompile
 535     public void test11_verifier(boolean warmup) {
 536         long result = test11(rI, rL);
 537         Asserts.assertEQ(result, hash(rI + 10, rL + 10));
 538     }
 539 
 540     // Test loop with uncommon trap referencing a value type
 541     @Test(match = {TRAP, SCOBJ}, matchCount = {1, -1 /* at least 1 */}, failOn = LOAD)
 542     public long test12(boolean b) {
 543         MyValue1 v = MyValue1.createInline(rI, rL);
 544         MyValue1[] va = new MyValue1[Math.abs(rI) % 10];
 545         for (int i = 0; i < va.length; ++i) {


 684 
 685     @DontCompile
 686     public long sumValue(MyValue1 v, MyValue1 dummy) {
 687         return v.hash();
 688     }
 689 
 690     @DontCompile
 691     public void test19_verifier(boolean warmup) {
 692         long result = test19();
 693         Asserts.assertEQ(result, hash());
 694     }
 695 
 696     // Create a value type (array) in compiled code and pass it to the
 697     // interpreter via a call. The value type is live at the uncommon
 698     // trap: verify that deoptimization causes the value type to be
 699     // correctly allocated.
 700     @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = LOAD + ALLOC + STORE)
 701     @Test(valid = ValueTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {2}, failOn = LOAD)
 702     public long test20(boolean deopt) {
 703         MyValue1 v = MyValue1.createInline(rI, rL);
 704         MyValue2[] va = new MyValue2[3];
 705         if (deopt) {
 706             // uncommon trap
 707             WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test20"));
 708         }
 709         return v.hashInterpreted() + va[0].hashInterpreted() +
 710                 va[1].hashInterpreted() + va[2].hashInterpreted();
 711     }
 712 
 713     @DontCompile
 714     public void test20_verifier(boolean warmup) {
 715         MyValue2[] va = new MyValue2[42];
 716         long result = test20(!warmup);
 717         Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash());
 718     }
 719 
 720     // Value type fields in regular object
 721     MyValue1 val1;
 722     MyValue2 val2;
 723     final MyValue1 val3;
 724     static MyValue1 val4;
 725     static final MyValue1 val5 = MyValue1.createInline(rI, rL);
 726 
 727     // Test value type fields in objects
 728     @Test(match = {ALLOC}, matchCount = {1}, failOn = (TRAP))
 729     public long test21(int x, long y) {
 730         // Compute hash of value type fields
 731         long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash();
 732         // Update fields
 733         val1 = MyValue1.createInline(x, y);
 734         val2 = MyValue2.createInline(x, true);
 735         val4 = MyValue1.createInline(x, y);


1188     }
1189 
1190     // Test returning a value type array received from the interpreter
1191     @Test(failOn = ALLOC + ALLOCA + LOAD + LOADP + STORE + LOOP + TRAP)
1192     public MyValue1[] test44(MyValue1[] va) {
1193         return va;
1194     }
1195 
1196     @DontCompile
1197     public void test44_verifier(boolean warmup) {
1198         MyValue1[] va = new MyValue1[10];
1199         for (int i = 0; i < 10; ++i) {
1200             va[i] = MyValue1.createDontInline(rI + i, rL + i);
1201         }
1202         va = test44(va);
1203         for (int i = 0; i < 10; ++i) {
1204             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
1205         }
1206     }
1207 
1208     // Merge value type arrays created from two branches
1209     @Test(failOn = (TRAP))
1210     public MyValue1[] test45(boolean b) {
1211         MyValue1[] va;
1212         if (b) {
1213             va = new MyValue1[5];
1214             for (int i = 0; i < 5; ++i) {
1215                 va[i] = MyValue1.createInline(rI, rL);
1216             }
1217         } else {
1218             va = new MyValue1[10];
1219             for (int i = 0; i < 10; ++i) {
1220                 va[i] = MyValue1.createInline(rI + i, rL + i);
1221             }
1222         }
1223         long sum = va[0].hashInterpreted();
1224         if (b) {
1225             va[0] = MyValue1.createDontInline(rI, sum);
1226         } else {
1227             va[0] = MyValue1.createDontInline(rI + 1, sum + 1);
1228         }


1240         va = test45(false);
1241         Asserts.assertEQ(va.length, 10);
1242         Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1));
1243         for (int i = 1; i < 10; ++i) {
1244             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
1245         }
1246     }
1247 
1248     // Test creation of value type array with single element
1249     @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOAD + LOOP + TRAP))
1250     @Test(valid = ValueTypeArrayFlattenOn, failOn = (ALLOCA + LOAD + LOOP + TRAP))
1251     public MyValue1 test46() {
1252         MyValue1[] va = new MyValue1[1];
1253         return va[0];
1254     }
1255 
1256     @DontCompile
1257     public void test46_verifier(boolean warmup) {
1258         MyValue1[] va = new MyValue1[1];
1259         MyValue1 v = test46();
1260         Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive());
1261     }
1262 
1263     // Test default initialization of value type arrays
1264     @Test(failOn = LOAD)
1265     public MyValue1[] test47(int len) {
1266         return new MyValue1[len];
1267     }
1268 
1269     @DontCompile
1270     public void test47_verifier(boolean warmup) {
1271         int len = Math.abs(rI % 10);
1272         MyValue1[] va = new MyValue1[len];
1273         MyValue1[] var = test47(len);
1274         for (int i = 0; i < len; ++i) {
1275             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1276         }
1277     }
1278 
1279     // Test creation of value type array with zero length
1280     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
1281     public MyValue1[] test48() {
1282         return new MyValue1[0];
1283     }
1284 
1285     @DontCompile
1286     public void test48_verifier(boolean warmup) {
1287         MyValue1[] va = test48();
1288         Asserts.assertEQ(va.length, 0);
1289     }
1290 
1291     static MyValue1[] test49_va;
1292 
1293     // Test that value type array loaded from field has correct type
1294     @Test(failOn = (LOOP))
1295     public long test49() {


1305     }
1306 
1307     // test vdefault
1308     @Test(failOn = ALLOC + LOAD + LOADP + STORE + LOOP + TRAP)
1309     public long test50() {
1310         MyValue2 v = MyValue2.createDefaultInline();
1311         return v.hash();
1312     }
1313 
1314     @DontCompile
1315     public void test50_verifier(boolean warmup) {
1316         long result = test50();
1317         Asserts.assertEQ(result, MyValue2.createDefaultInline().hash());
1318     }
1319 
1320     // test vdefault
1321     @Test(failOn = ALLOC + STORE + LOOP + TRAP)
1322     public long test51() {
1323         MyValue1 v1 = MyValue1.createDefaultInline();
1324         MyValue1 v2 = MyValue1.createDefaultDontInline();
1325         return v1.hashPrimitive() + v2.hashPrimitive();
1326     }
1327 
1328     @DontCompile
1329     public void test51_verifier(boolean warmup) {
1330         long result = test51();
1331         Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hashPrimitive());
1332     }
1333 
1334     // test vwithfield
1335     @Test(failOn = ALLOC + LOAD + LOADP + STORE + LOOP + TRAP)
1336     public long test52() {
1337         MyValue2 v = MyValue2.createWithFieldsInline(rI, true);
1338         return v.hash();
1339     }
1340 
1341     @DontCompile
1342     public void test52_verifier(boolean warmup) {
1343         long result = test52();
1344         Asserts.assertEQ(result, MyValue2.createWithFieldsInline(rI, true).hash());
1345     }
1346 
1347     // test vwithfield
1348     @Test(failOn = ALLOC + STORE + LOOP + TRAP)
1349     public long test53() {
1350         MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL);
1351         MyValue1 v2 = MyValue1.createWithFieldsDontInline(rI, rL);


1463     public void test58() {
1464         MyValue1 v1 = MyValue1.createInline(0, 0);
1465         MyValue1 v2 = MyValue1.createInline(1, 1);
1466         // Trigger OSR compilation and loop peeling
1467         for (int i = 0; i < 100_000; ++i) {
1468             if (v1.x != 2*i || v2.x != i+1 || v2.y != i+1) {
1469                 // Uncommon trap
1470                 throw new RuntimeException("test58 failed");
1471             }
1472             v1 = MyValue1.createInline(2*(i+1), 0);
1473             v2 = MyValue1.createInline(i+2, i+2);
1474         }
1475     }
1476 
1477     @DontCompile
1478     public void test58_verifier(boolean warmup) {
1479         test58();
1480     }
1481 
1482     // When calling a method on __Value, passing fields as arguments is impossible
1483     @Test(failOn = ALLOC + STORE + LOAD)

1484     public String test59(MyValue1 v) {
1485         return v.toString();
1486     }
1487 
1488     @DontCompile
1489     public void test59_verifier(boolean warmup) {
1490         boolean failed = false;
1491         try {
1492             test59(val1);
1493             failed = true;
1494         } catch (UnsupportedOperationException uoe) {
1495         }
1496         Asserts.assertFalse(failed);
1497     }
1498 
1499     // Same as above, but the method on __Value is inlined
1500     // hashCode allocates an exception so can't really check the graph shape
1501     @Test()
1502     public int test60(MyValue1 v) {
1503         return v.hashCode();


1674                 MethodType.methodType(long.class, Object.class, boolean.class),
1675                 CODE -> {
1676                     CODE.
1677                     iload_1().
1678                     iconst_1().
1679                     if_icmpne((short)14).
1680                     aload_0().
1681                     vunbox(ValueType.forClass(ValueCapableClass1.class).valueClass()).
1682                     vbox(ValueCapableClass1.class).
1683                     getfield(ValueCapableClass1.class, "t", "J").
1684                     lreturn().
1685                     aload_0().
1686                     vunbox(ValueType.forClass(ValueCapableClass2.class).valueClass()).
1687                     vbox(ValueCapableClass1.class).
1688                     getfield(ValueCapableClass1.class, "t", "J").
1689                     lreturn();
1690                 }
1691                 );
1692     }
1693 
1694     // Test GC with heap allocated value type containing reference field
1695     @Test()
1696     public long test66() {
1697         MyValue1 v = MyValue1.createInline(rI, rL);
1698         long result = 0;
1699         for (int i = 0 ; i < 10_000; ++i) {
1700             // The C2I adapter allocates the value type at every call which
1701             // triggers intermittent GCs that scan the stack frames for oops.
1702             result = v.hashInterpreted();
1703         }
1704         return result;
1705     }
1706 
1707     @DontCompile
1708     public void test66_verifier(boolean warmup) {
1709         long result = test66();
1710         Asserts.assertEQ(result, hash());
1711     }
1712 
1713     // ========== Test infrastructure ==========
1714 
1715     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
1716     private static final int ValueTypePassFieldsAsArgsOn = 0x1;
1717     private static final int ValueTypePassFieldsAsArgsOff = 0x2;
1718     private static final int ValueTypeArrayFlattenOn = 0x4;
1719     private static final int ValueTypeArrayFlattenOff = 0x8;
1720     private static final int AlwaysIncrementalInlineOff = 0x10;
1721     private static final int AlwaysIncrementalInlineOn = 0x20;
1722     static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | AlwaysIncrementalInlineOff | AlwaysIncrementalInlineOn;
1723     private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
1724     private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
1725     private static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline");
1726     private static final int COMP_LEVEL_ANY = -1;
1727     private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
1728     private static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
1729     private static final int WARMUP = 251;
1730     private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
1731     private static boolean PRINT_IDEAL  = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
1732     // TODO use Platform.isComp() after merge with JDK 9
1733     private static boolean XCOMP = System.getProperty("java.vm.info").startsWith("compiled ");
1734 
1735     // Regular expressions used  to match nodes in the PrintIdeal output
1736     private static final String START = "(\\d+\\t(.*";
1737     private static final String MID = ".*)+\\t===.*";
1738     private static final String END = ")|";
1739     private static final String ALLOC  = "(.*RSI, precise klass compiler/valhalla/valuetypes/MyValue.*" + END;
1740     private static final String ALLOCA = "(.*RSI, precise klass \\[Qcompiler/valhalla/valuetypes/MyValue.*" + END;
1741     private static final String LOAD   = START + "Load(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
1742     private static final String LOADP  = START + "Load(P|N)" + MID + "valuetype\\*" + END;
1743     private static final String STORE  = START + "Store(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
1744     private static final String STOREP = START + "Store(P|N)" + MID + "valuetype\\*" + END;
1745     private static final String LOOP   = START + "Loop" + MID + "" + END;
1746     private static final String TRAP   = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END;
1747     private static final String RETURN = START + "Return" + MID + "returns" + END;
1748     private static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END;
1749     private static final String NPE = START + "CallStaticJava" + MID + "null_check" + END;
1750     private static final String CCE = START + "CallStaticJava" + MID + "class_check" + END;
1751     // TODO: match field values of scalar replaced object
1752     private static final String SCOBJ = "(.*# ScObj.*" + END;
1753 
1754     static {
1755         // Gather all test methods and put them in Hashtable
1756         for (Method m : ValueTypeTestBench.class.getDeclaredMethods()) {
1757             Test[] annos = m.getAnnotationsByType(Test.class);
1758             if (annos.length != 0) {
1759                 tests.put("ValueTypeTestBench::" + m.getName(), m);
1760             }
1761         }
1762     }
1763 
1764     private static void execute_vm(String... args) throws Throwable {
1765         Asserts.assertFalse(tests.isEmpty(), "no tests to execute");
1766         ArrayList<String> all_args = new ArrayList(List.of(args));


< prev index next >