< prev index next >

test/compiler/valhalla/valuetypes/ValueTypeTestBench.java

Print this page




  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  * @modules java.base/jdk.experimental.bytecode
  31  *          java.base/jdk.experimental.value
  32  *          java.base/jdk.internal.misc:+open
  33  *          jdk.incubator.mvt
  34  * @compile -XDenableValueTypes ValueCapableClass1.java ValueCapableClass2.java ValueTypeTestBench.java
  35  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  36  * @run main ClassFileInstaller jdk.test.lib.Platform
  37  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  38  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+VerifyAdapterSharing -XX:+VerifyStack
  39  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  40  *                   -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  41  *                   -Djdk.lang.reflect.DVT=true
  42  *                   compiler.valhalla.valuetypes.ValueTypeTestBench
  43  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  44  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+VerifyStack
  45  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:-ValueArrayFlatten
  46  *                   -Djdk.lang.reflect.DVT=true
  47  *                   compiler.valhalla.valuetypes.ValueTypeTestBench







  48  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  49  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+AlwaysIncrementalInline
  50  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  51  *                   -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  52  *                   -Djdk.lang.reflect.DVT=true
  53  *                   compiler.valhalla.valuetypes.ValueTypeTestBench






  54  */
  55 


  56 package compiler.valhalla.valuetypes;
  57 
  58 import compiler.whitebox.CompilerWhiteBoxTest;
  59 import jdk.experimental.bytecode.MacroCodeBuilder.CondKind;
  60 import jdk.experimental.bytecode.TypeTag;
  61 import jdk.experimental.value.MethodHandleBuilder;
  62 import jdk.incubator.mvt.ValueType;
  63 import jdk.test.lib.Asserts;
  64 import jdk.test.lib.management.InputArguments;
  65 import jdk.test.lib.Platform;
  66 import jdk.test.lib.process.ProcessTools;
  67 import jdk.test.lib.process.OutputAnalyzer;
  68 import jdk.test.lib.Utils;
  69 import sun.hotspot.WhiteBox;
  70 
  71 import java.lang.annotation.Retention;
  72 import java.lang.annotation.RetentionPolicy;
  73 import java.lang.annotation.Repeatable;
  74 import java.lang.invoke.*;
  75 import java.lang.reflect.Method;
  76 import java.util.ArrayList;
  77 import java.util.Arrays;
  78 import java.util.Hashtable;
  79 import java.util.LinkedHashMap;
  80 import java.util.List;
  81 import java.util.Map;
  82 import java.util.regex.Matcher;
  83 import java.util.regex.Pattern;

  84 
  85 // Test value types
  86 __ByValue final class MyValue1 {
  87     static int s;
  88     static final long sf = ValueTypeTestBench.rL;
  89     final int x;
  90     final long y;
  91     final short z;
  92     final Integer o;
  93     final int[] oa;
  94     final MyValue2 v1;
  95     final MyValue2 v2;
  96     static final MyValue2 v3 = MyValue2.createWithFieldsInline(ValueTypeTestBench.rI, true);
  97     final int c;
  98 
  99     private MyValue1() {
 100         s = 0;
 101         this.x = 0;
 102         this.y = 0;
 103         this.z = 0;


 115 
 116     @ForceInline
 117     __ValueFactory static MyValue1 createDefaultInline() {
 118         return __MakeDefault MyValue1();
 119     }
 120 
 121     @DontInline
 122     static MyValue1 createWithFieldsDontInline(int x, long y) {
 123         return createWithFieldsInline(x, y);
 124     }
 125 
 126     @ForceInline
 127     static MyValue1 createWithFieldsInline(int x, long y) {
 128         MyValue1 v = createDefaultInline();
 129         v = setX(v, x);
 130         v = setY(v, y);
 131         v = setZ(v, (short)x);
 132         v = setO(v, new Integer(x));
 133         int[] oa = {x};
 134         v = setOA(v, oa);
 135         v = setV1(v, MyValue2.createWithFieldsInline(x, x < y));
 136         v = setV2(v, MyValue2.createWithFieldsInline(x, x > y));
 137         v = setC(v, ValueTypeTestBench.rI);
 138         return v;
 139     }
 140 
 141     // Hash only primitive and value type fields to avoid NullPointerException
 142     @ForceInline
 143     public long hashPrimitive() {
 144         return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash();
 145     }
 146 
 147     @ForceInline
 148     public long hash() {
 149         return hashPrimitive() + o + oa[0];
 150     }
 151 
 152     @DontCompile
 153     public long hashInterpreted() {
 154         return s + sf + x + y + z + o + oa[0] + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted();
 155     }
 156 
 157     @ForceInline
 158     public void print() {
 159         System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", o=" + (o != null ? (Integer)o : "NULL") + ", v1[");
 160         v1.print();
 161         System.out.print("], v2[");
 162         v2.print();
 163         System.out.print("], v3[");
 164         v3.print();
 165         System.out.print("], c=" + c);
 166     }
 167 
 168     @ForceInline
 169     __ValueFactory static MyValue1 setX(MyValue1 v, int x) {
 170         v.x = x;
 171         return v;
 172     }
 173 
 174     @ForceInline
 175     __ValueFactory static MyValue1 setY(MyValue1 v, long y) {
 176         v.y = y;
 177         return v;
 178     }
 179 


 197 
 198     @ForceInline
 199     __ValueFactory static MyValue1 setC(MyValue1 v, int c) {
 200         v.c = c;
 201         return v;
 202     }
 203 
 204     @ForceInline
 205     __ValueFactory static MyValue1 setV1(MyValue1 v, MyValue2 v1) {
 206         v.v1 = v1;
 207         return v;
 208     }
 209 
 210     @ForceInline
 211     __ValueFactory static MyValue1 setV2(MyValue1 v, MyValue2 v2) {
 212         v.v2 = v2;
 213         return v;
 214     }
 215 }
 216 



































 217 __ByValue final class MyValue2 {
 218     final int x;
 219     final byte y;
 220     final boolean b;
 221     final long c;
 222 
 223     private MyValue2() {
 224         this.x = 0;
 225         this.y = 0;
 226         this.b = false;
 227         this.c = 0;
 228     }
 229 
 230     @ForceInline
 231     __ValueFactory public static MyValue2 createDefaultInline() {
 232         return __MakeDefault MyValue2();
 233     }
 234 
 235     @ForceInline
 236     public static MyValue2 createWithFieldsInline(int x, boolean b) {
 237         MyValue2 v = createDefaultInline();
 238         v = setX(v, x);
 239         v = setY(v, (byte)x);
 240         v = setB(v, b);
 241         v = setC(v, ValueTypeTestBench.rL);
 242         return v;
 243     }
 244 
 245     @ForceInline
 246     public long hash() {
 247         return x + y + (b ? 0 : 1) + c;
 248     }
 249 
 250     @DontInline
 251     public long hashInterpreted() {
 252         return x + y + (b ? 0 : 1) + c;
 253     }
 254 
 255     @ForceInline
 256     public void print() {
 257         System.out.print("x=" + x + "y=" + y + ", b=" + b + ", c=" + c);
 258     }
 259 
 260     @ForceInline
 261     __ValueFactory static MyValue2 setX(MyValue2 v, int x) {
 262         v.x = x;
 263         return v;
 264     }
 265 
 266     @ForceInline
 267     __ValueFactory static MyValue2 setY(MyValue2 v, byte y) {
 268         v.y = y;
 269         return v;
 270     }
 271 
 272     @ForceInline
 273     __ValueFactory static MyValue2 setC(MyValue2 v, long c) {
 274         v.c = c;
 275         return v;
 276     }










 277 
 278     @ForceInline
 279     __ValueFactory static MyValue2 setB(MyValue2 v, boolean b) {
 280         v.b = b;



















 281         return v;
 282     }
 283 }
 284 
 285 // Value type definition to stress test return of a value in registers
 286 // (uses all registers of calling convention on x86_64)
 287 __ByValue final class MyValue3 {
 288     final char c;
 289     final byte bb;
 290     final short s;
 291     final int i;
 292     final long l;
 293     final Object o;
 294     final float f1;
 295     final double f2;
 296     final float f3;
 297     final double f4;
 298     final float f5;
 299     final double f6;
 300     final float f7;
 301     final double f8;
 302 
 303     private MyValue3(char c,
 304             byte bb,
 305             short s,
 306             int i,
 307             long l,
 308             Object o,
 309             float f1,
 310             double f2,
 311             float f3,
 312             double f4,
 313             float f5,
 314             double f6,
 315             float f7,
 316             double f8) {
 317         this.c = c;
 318         this.bb = bb;
 319         this.s = s;
 320         this.i = i;
 321         this.l = l;
 322         this.o = o;
 323         this.f1 = f1;
 324         this.f2 = f2;
 325         this.f3 = f3;
 326         this.f4 = f4;
 327         this.f5 = f5;
 328         this.f6 = f6;
 329         this.f7 = f7;
 330         this.f8 = f8;
 331     }
 332 
 333     private MyValue3() {
 334         this.c = 0;
 335         this.bb = 0;
 336         this.s = 0;
 337         this.i = 0;
 338         this.l = 0;
 339         this.o = null;
 340         this.f1 = 0;
 341         this.f2 = 0;
 342         this.f3 = 0;
 343         this.f4 = 0;
 344         this.f5 = 0;
 345         this.f6 = 0;
 346         this.f7 = 0;
 347         this.f8 = 0;
 348     }
 349 
 350     @ForceInline
 351     __ValueFactory static MyValue3 setC(MyValue3 v, char c) {
 352         v.c = c;
 353         return v;
 354     }
 355 
 356     @ForceInline
 357     __ValueFactory static MyValue3 setBB(MyValue3 v, byte bb) {
 358         v.bb = bb;
 359         return v;
 360     }
 361 
 362     @ForceInline
 363     __ValueFactory static MyValue3 setS(MyValue3 v, short s) {
 364         v.s = s;
 365         return v;
 366     }
 367 


 403 
 404     @ForceInline
 405     __ValueFactory static MyValue3 setF4(MyValue3 v, double f4) {
 406         v.f4 = f4;
 407         return v;
 408     }
 409 
 410     @ForceInline
 411     __ValueFactory static MyValue3 setF5(MyValue3 v, float f5) {
 412         v.f5 = f5;
 413         return v;
 414     }
 415 
 416     @ForceInline
 417     __ValueFactory static MyValue3 setF6(MyValue3 v, double f6) {
 418         v.f6 = f6;
 419         return v;
 420     }
 421 
 422     @ForceInline
 423     __ValueFactory static MyValue3 setF7(MyValue3 v, float f7) {
 424         v.f7 = f7;
 425         return v;
 426     }
 427 
 428     @ForceInline
 429     __ValueFactory static MyValue3 setF8(MyValue3 v, double f8) {
 430         v.f8 = f8;
 431         return v;
 432     }
 433 
 434     @ForceInline
 435     __ValueFactory public static MyValue3 createDefault() {
 436         return __MakeDefault MyValue3();
 437     }
 438 
 439     @ForceInline
 440     public static MyValue3 create() {
 441         java.util.Random r = Utils.getRandomInstance();
 442         MyValue3 v = createDefault();
 443         v = setC(v, (char)r.nextInt());
 444         v = setBB(v, (byte)r.nextInt());
 445         v = setS(v, (short)r.nextInt());
 446         v = setI(v, r.nextInt());
 447         v = setL(v, r.nextLong());
 448         v = setO(v, new Object());
 449         v = setF1(v, r.nextFloat());
 450         v = setF2(v, r.nextDouble());
 451         v = setF3(v, r.nextFloat());
 452         v = setF4(v, r.nextDouble());
 453         v = setF5(v, r.nextFloat());
 454         v = setF6(v, r.nextDouble());
 455         v = setF7(v, r.nextFloat());
 456         v = setF8(v, r.nextDouble());
 457         return v;
 458     }
 459 
 460     @DontInline
 461     public static MyValue3 createDontInline() {
 462         return create();
 463     }
 464 
 465     @ForceInline
 466     public static MyValue3 copy(MyValue3 other) {
 467         MyValue3 v = createDefault();
 468         v = setC(v, other.c);
 469         v = setBB(v, other.bb);
 470         v = setS(v, other.s);
 471         v = setI(v, other.i);
 472         v = setL(v, other.l);
 473         v = setO(v, other.o);
 474         v = setF1(v, other.f1);
 475         v = setF2(v, other.f2);
 476         v = setF3(v, other.f3);
 477         v = setF4(v, other.f4);
 478         v = setF5(v, other.f5);
 479         v = setF6(v, other.f6);
 480         v = setF7(v, other.f7);
 481         v = setF8(v, other.f8);
 482         return v;
 483     }
 484 
 485     @DontInline
 486     public void verify(MyValue3 other) {
 487         Asserts.assertEQ(c, other.c);
 488         Asserts.assertEQ(bb, other.bb);
 489         Asserts.assertEQ(s, other.s);
 490         Asserts.assertEQ(i, other.i);
 491         Asserts.assertEQ(l, other.l);
 492         Asserts.assertEQ(o, other.o);
 493         Asserts.assertEQ(f1, other.f1);
 494         Asserts.assertEQ(f2, other.f2);
 495         Asserts.assertEQ(f3, other.f3);
 496         Asserts.assertEQ(f4, other.f4);
 497         Asserts.assertEQ(f5, other.f5);
 498         Asserts.assertEQ(f6, other.f6);
 499         Asserts.assertEQ(f7, other.f7);
 500         Asserts.assertEQ(f8, other.f8);
 501     }
 502 }
 503 
 504 // Value type definition with too many fields to return in registers
 505 __ByValue final class MyValue4 {
 506     final MyValue3 v1;
 507     final MyValue3 v2;
 508 
 509     private MyValue4(MyValue3 v1, MyValue3 v2) {
 510         this.v1 = v1;
 511         this.v2 = v2;
 512     }
 513 
 514     private MyValue4() {
 515         this.v1 = MyValue3.createDefault();
 516         this.v2 = MyValue3.createDefault();
 517     }
 518 
 519     @ForceInline
 520     __ValueFactory static MyValue4 setV1(MyValue4 v, MyValue3 v1) {
 521         v.v1 = v1;
 522         return v;
 523     }
 524 
 525     @ForceInline
 526     __ValueFactory static MyValue4 setV2(MyValue4 v, MyValue3 v2) {
 527         v.v2 = v2;
 528         return v;
 529     }
 530 
 531     @ForceInline
 532     __ValueFactory public static MyValue4 createDefault() {
 533         return __MakeDefault MyValue4();


 989         Asserts.assertEQ(val1.hash(), hash(rI + 1, rL + 1));
 990         Asserts.assertEQ(val2.hash(), MyValue2.createWithFieldsInline(rI + 1, true).hash());
 991         Asserts.assertEQ(val4.hash(), hash(rI + 1, rL + 1));
 992     }
 993 
 994     // Test folding of constant value type fields
 995     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
 996     public long test22() {
 997         // This should be constant folded
 998         return val5.hash() + val5.v3.hash();
 999     }
1000 
1001     @DontCompile
1002     public void test22_verifier(boolean warmup) {
1003         long result = test22();
1004         Asserts.assertEQ(result, val5.hash() + val5.v3.hash());
1005     }
1006 
1007     // Test OSR compilation
1008     @Test()

1009     public long test23() {
1010         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1011         MyValue1[] va = new MyValue1[Math.abs(rI) % 3];
1012         for (int i = 0; i < va.length; ++i) {
1013             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1014         }
1015         long result = 0;
1016         // Long loop to trigger OSR compilation
1017         for (int i = 0 ; i < 100_000; ++i) {
1018             // Reference local value type in interpreter state
1019             result = v.hash();
1020             for (int j = 0; j < va.length; ++j) {
1021                 result += va[j].hash();
1022             }
1023         }
1024         return result;
1025     }
1026 
1027     @DontCompile
1028     public void test23_verifier(boolean warmup) {


1662 
1663     // Test allocation elimination of unused object with initialized value type field
1664     @Test(failOn = ALLOC + LOAD + STORE + LOOP)
1665     public void test56(boolean deopt) {
1666         TestClass56 unused = new TestClass56();
1667         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1668         unused.v = v;
1669         if (deopt) {
1670             // uncommon trap
1671             WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test56"));
1672         }
1673     }
1674 
1675     @DontCompile
1676     public void test56_verifier(boolean warmup) {
1677         test56(!warmup);
1678     }
1679 
1680     // Test loop peeling
1681     @Test(failOn = ALLOC + LOAD + STORE)

1682     public void test57() {
1683         MyValue1 v = MyValue1.createWithFieldsInline(0, 1);
1684         // Trigger OSR compilation and loop peeling
1685         for (int i = 0; i < 100_000; ++i) {
1686             if (v.x != i || v.y != i + 1) {
1687                 // Uncommon trap
1688                 throw new RuntimeException("test57 failed");
1689             }
1690             v = MyValue1.createWithFieldsInline(i + 1, i + 2);
1691         }
1692     }
1693 
1694     @DontCompile
1695     public void test57_verifier(boolean warmup) {
1696         test57();
1697     }
1698 
1699     // Test loop peeling and unrolling
1700     @Test()

1701     public void test58() {
1702         MyValue1 v1 = MyValue1.createWithFieldsInline(0, 0);
1703         MyValue1 v2 = MyValue1.createWithFieldsInline(1, 1);
1704         // Trigger OSR compilation and loop peeling
1705         for (int i = 0; i < 100_000; ++i) {
1706             if (v1.x != 2*i || v2.x != i+1 || v2.y != i+1) {
1707                 // Uncommon trap
1708                 throw new RuntimeException("test58 failed");
1709             }
1710             v1 = MyValue1.createWithFieldsInline(2*(i+1), 0);
1711             v2 = MyValue1.createWithFieldsInline(i+2, i+2);
1712         }
1713     }
1714 
1715     @DontCompile
1716     public void test58_verifier(boolean warmup) {
1717         test58();
1718     }
1719 
1720     // When calling a method on __Value, passing fields as arguments is impossible


2557         vt = MyValue3.setI(vt, (int)vt.c);
2558         // vt is not equal to staticVal3, so C2 should not re-use the oop
2559         va[0] = vt;
2560         staticVal3 = vt;
2561         vt.verify(staticVal3);
2562         return vt;
2563     }
2564 
2565     @DontCompile
2566     public void test92_verifier(boolean warmup) {
2567         staticVal3 = MyValue3.create();
2568         MyValue3[] va = new MyValue3[1];
2569         MyValue3 vt = test92(va);
2570         Asserts.assertEQ(staticVal3.i, (int)staticVal3.c);
2571         Asserts.assertEQ(va[0].i, (int)staticVal3.c);
2572         Asserts.assertEQ(vt.i, (int)staticVal3.c);
2573     }
2574 
2575     // Test correct handling of __Value merges through PhiNodes
2576     @Test()

2577     public long test93() throws Throwable {
2578         // Create a new value type
2579         final MethodHandle dvt = MethodHandleBuilder.loadCode(MethodHandles.lookup(), "createValueType",
2580                                      MethodType.methodType(ValueType.forClass(ValueCapableClass1.class).valueClass()),
2581                                      CODE -> {
2582                                          CODE.
2583                                          iconst_1().
2584                                          anewarray(ValueType.forClass(ValueCapableClass1.class).valueClass()).
2585                                          iconst_0().
2586                                          vaload().
2587                                          vreturn();
2588                                      });
2589         // Box the value type
2590         final MethodHandle box = MethodHandleBuilder.loadCode(MethodHandles.lookup(), "boxValueType",
2591                                      MethodType.methodType(ValueCapableClass1.class, ValueType.forClass(ValueCapableClass1.class).valueClass()),
2592                                      CODE -> {
2593                                          CODE.
2594                                          vload(0).
2595                                          vbox(ValueCapableClass1.class).
2596                                          areturn();


3023     public void test105_verifier(boolean warmup) throws Throwable {
3024         test105_i++;
3025         long hash = test105();
3026         boolean b = (test105_i % 100) == 0;
3027         Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+test105_i * (b ? 1 : -1), b).hash());
3028     }
3029 
3030 
3031     // OSR compilation with __Value local
3032     @DontCompile
3033     public __Value test106_init() {
3034         return MyValue1.createWithFieldsInline(rI, rL);
3035     }
3036 
3037     @DontCompile
3038     public __Value test106_body() {
3039         return MyValue1.createWithFieldsInline(rI, rL);
3040     }
3041 
3042     @Test()

3043     public __Value test106() throws Throwable {
3044         __Value vt = test106_init();
3045         for (int i = 0; i < 50_000; i++) {
3046             if (i % 2 == 1) {
3047                 vt = test106_body();
3048             }
3049         }
3050         return vt;
3051     }
3052 
3053     @DontCompile
3054     public void test106_verifier(boolean warmup) throws Throwable {
3055         test106();
3056     }
3057 
3058     // ========== Test infrastructure ==========
3059 





























3060     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
3061     private static final int ValueTypePassFieldsAsArgsOn = 0x1;
3062     private static final int ValueTypePassFieldsAsArgsOff = 0x2;
3063     private static final int ValueTypeArrayFlattenOn = 0x4;
3064     private static final int ValueTypeArrayFlattenOff = 0x8;
3065     private static final int ValueTypeReturnedAsFieldsOn = 0x10;
3066     private static final int ValueTypeReturnedAsFieldsOff = 0x20;
3067     static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn;
3068     private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
3069     private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
3070     private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
3071     private static final int COMP_LEVEL_ANY = -2;
3072     private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
3073     private static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
3074     private static final int WARMUP = 251;
3075     private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
3076     private static boolean PRINT_IDEAL  = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
3077     private static boolean XCOMP = Platform.isComp();
3078 
3079     // Regular expressions used to match nodes in the PrintIdeal output
3080     private static final String START = "(\\d+\\t(.*";
3081     private static final String MID = ".*)+\\t===.*";
3082     private static final String END = ")|";
3083     private static final String ALLOC  = "(.*precise klass compiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_instance_Java" + END;
3084     private static final String ALLOCA = "(.*precise klass \\[Qcompiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_array_Java" + END;
3085     private static final String LOAD   = START + "Load(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
3086     private static final String LOADP  = START + "Load(P|N)" + MID + "valuetype\\*" + END;
3087     private static final String LOADK  = START + "LoadK" + MID + END;
3088     private static final String STORE  = START + "Store(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
3089     private static final String STOREP = START + "Store(P|N)" + MID + "valuetype\\*" + END;
3090     private static final String LOOP   = START + "Loop" + MID + "" + END;
3091     private static final String TRAP   = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END;
3092     private static final String RETURN = START + "Return" + MID + "returns" + END;
3093     private static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END;
3094     private static final String NPE = START + "CallStaticJava" + MID + "null_check" + END;
3095     private static final String CCE = START + "CallStaticJava" + MID + "class_check" + END;
3096     private static final String CALL = START + "CallStaticJava" + MID + END;
3097     private static final String STOREVALUETYPEFIELDS = START + "CallStaticJava" + MID + "store_value_type_fields" + END;
3098     private static final String SCOBJ = "(.*# ScObj.*" + END;
3099 
3100     static {




3101         // Gather all test methods and put them in Hashtable
3102         for (Method m : ValueTypeTestBench.class.getDeclaredMethods()) {
3103             Test[] annos = m.getAnnotationsByType(Test.class);
3104             if (annos.length != 0) {


3105                 tests.put("ValueTypeTestBench::" + m.getName(), m);
3106             }
3107         }
3108     }
3109 
3110     private static void execute_vm(String... args) throws Throwable {
3111         Asserts.assertFalse(tests.isEmpty(), "no tests to execute");
3112         ArrayList<String> all_args = new ArrayList(List.of(args));



3113         // Run tests in own process and verify output
3114         all_args.add(ValueTypeTestBench.class.getName());
3115         all_args.add("run");
3116         // Spawn process with default JVM options from the test's run command
3117         String[] vmInputArgs = InputArguments.getVmInputArgs();
3118         String[] cmds = Arrays.copyOf(vmInputArgs, vmInputArgs.length + all_args.size());
3119         System.arraycopy(all_args.toArray(), 0, cmds, vmInputArgs.length, all_args.size());
3120         OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds);
3121         // If ideal graph printing is enabled/supported, verify output
3122         String output = oa.getOutput();
3123         oa.shouldHaveExitValue(0);
3124         boolean verifyIR = output.contains("PrintIdeal enabled") &&
3125                 !output.contains("ValueTypePassFieldsAsArgs is not supported on this platform");
3126         if (verifyIR) {
3127             parseOutput(output);
3128         } else {

3129             System.out.println("WARNING: IR verification disabled! Running with -Xint, -Xcomp or release build?");
3130         }
3131     }
3132 
3133     public static void main(String[] args) throws Throwable {
3134         //tests.values().removeIf(p -> !p.getName().equals("test106")); // Run single test
3135         if (args.length == 0) {
3136             execute_vm("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-BackgroundCompilation",
3137                     "-XX:+PrintCompilation", "-XX:+PrintInlining", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly",
3138                     "-XX:CICompilerCount=1",
3139                     "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*",
3140                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue1::*",
3141                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2::*",
3142                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue3::*",
3143                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue4::*",
3144                     "-XX:CompileCommand=compileonly,java.lang.Object::<init>",
3145                     "-XX:CompileCommand=inline,java.lang.__Value::hashCode",
3146                     "-XX:CompileCommand=compileonly,java.lang.invoke.*::*",
3147                     "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueCapableClass2_*::*",
3148                     "-XX:CompileCommand=compileonly,java.lang.Long::sum");
3149         } else {
3150             // Execute tests
3151             ValueTypeTestBench bench = new ValueTypeTestBench();
3152             bench.run();
3153         }
3154     }
3155 
3156     public static void parseOutput(String output) throws Exception {
3157         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");
3158         Matcher m = comp_re.matcher(output);
3159         Map<String,String> compilations = new LinkedHashMap<>();
3160         int prev = 0;
3161         String methodName = null;
3162         while (m.find()) {
3163             if (prev == 0) {
3164                 // Print header
3165                 System.out.print(output.substring(0, m.start()+1));
3166             } else if (methodName != null) {
3167                 compilations.put(methodName, output.substring(prev, m.start()+1));
3168             }
3169             if (m.group("osr") != null) {
3170                 methodName = null;
3171             } else {
3172                 methodName = m.group("name");
3173             }
3174             prev = m.end();
3175         }
3176         if (prev == 0) {


3265                 WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_ANY, true);
3266                 WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_ANY, false);
3267                 WHITE_BOX.testSetDontInlineMethod(m, true);
3268             }
3269             if (m.isAnnotationPresent(ForceInline.class)) {
3270                 WHITE_BOX.testSetForceInlineMethod(m, true);
3271             } else if (m.isAnnotationPresent(DontInline.class)) {
3272                 WHITE_BOX.testSetDontInlineMethod(m, true);
3273             }
3274         }
3275     }
3276 
3277     public void run() throws Exception {
3278         if (USE_COMPILER && PRINT_IDEAL && !XCOMP) {
3279             System.out.println("PrintIdeal enabled");
3280         }
3281         System.out.format("rI = %d, rL = %d\n", rI, rL);
3282         setup(this.getClass().getDeclaredMethods());
3283         setup(MyValue1.class.getDeclaredMethods());
3284         setup(MyValue2.class.getDeclaredMethods());

3285         setup(MyValue3.class.getDeclaredMethods());

3286         setup(MyValue4.class.getDeclaredMethods());
3287 
3288         // Compile class initializers
3289         WHITE_BOX.enqueueInitializerForCompilation(this.getClass(), COMP_LEVEL_FULL_OPTIMIZATION);
3290         WHITE_BOX.enqueueInitializerForCompilation(MyValue1.class, COMP_LEVEL_FULL_OPTIMIZATION);
3291         WHITE_BOX.enqueueInitializerForCompilation(MyValue2.class, COMP_LEVEL_FULL_OPTIMIZATION);

3292         WHITE_BOX.enqueueInitializerForCompilation(MyValue3.class, COMP_LEVEL_FULL_OPTIMIZATION);

3293         WHITE_BOX.enqueueInitializerForCompilation(MyValue4.class, COMP_LEVEL_FULL_OPTIMIZATION);
3294 
3295         // Execute tests

3296         for (Method test : tests.values()) {

3297             Method verifier = getClass().getDeclaredMethod(test.getName() + "_verifier", boolean.class);
3298             // Warmup using verifier method
3299             Warmup anno = test.getAnnotation(Warmup.class);
3300             int warmup = anno == null ? WARMUP : anno.value();
3301             for (int i = 0; i < warmup; ++i) {
3302                 verifier.invoke(this, true);
3303             }
3304             // Trigger compilation
3305             WHITE_BOX.enqueueMethodForCompilation(test, COMP_LEVEL_FULL_OPTIMIZATION);
3306             Asserts.assertTrue(!USE_COMPILER || WHITE_BOX.isMethodCompiled(test, false), test + " not compiled");
3307             // Check result
3308             verifier.invoke(this, false);













3309         }
3310     }
3311 }
3312 
3313 // Mark method as test
3314 @Retention(RetentionPolicy.RUNTIME)
3315 @Repeatable(Tests.class)
3316 @interface Test {
3317     // Regular expression used to match forbidden IR nodes
3318     // in the C2 IR emitted for this test.
3319     String failOn() default "";
3320     // Regular expressions used to match and count IR nodes.
3321     String[] match() default { };
3322     int[] matchCount() default { };
3323     int valid() default ValueTypeTestBench.AllFlags;
3324 }
3325 
3326 @Retention(RetentionPolicy.RUNTIME)
3327 @interface Tests {
3328     Test[] value();
3329 }
3330 
3331 // Force method inlining during compilation
3332 @Retention(RetentionPolicy.RUNTIME)
3333 @interface ForceInline { }
3334 
3335 // Prevent method inlining during compilation
3336 @Retention(RetentionPolicy.RUNTIME)
3337 @interface DontInline { }
3338 
3339 // Prevent method compilation
3340 @Retention(RetentionPolicy.RUNTIME)
3341 @interface DontCompile { }
3342 

3343 @Retention(RetentionPolicy.RUNTIME)
3344 @interface Warmup {
3345     int value();
3346 }






  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  * @modules java.base/jdk.experimental.bytecode
  31  *          java.base/jdk.experimental.value
  32  *          java.base/jdk.internal.misc:+open
  33  *          jdk.incubator.mvt
  34  * @compile -XDenableValueTypes ValueCapableClass1.java ValueCapableClass2.java ValueTypeTestBench.java
  35  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  36  * @run main ClassFileInstaller jdk.test.lib.Platform
  37  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  38  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+AlwaysIncrementalInline
  39  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  40  *                   -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  41  *                   -XX:ValueTypesBufferMaxMemory=0
  42  *                   -Djdk.lang.reflect.DVT=true compiler.valhalla.valuetypes.ValueTypeTestBench
  43  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  44  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:-UseCompressedOops
  45  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  46  *                   -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  47  *                   -XX:ValueTypesBufferMaxMemory=0
  48  *                   -Djdk.lang.reflect.DVT=true compiler.valhalla.valuetypes.ValueTypeTestBench
  49  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  50  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:-UseCompressedOops
  51  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:-ValueArrayFlatten
  52  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0
  53  *                   -XX:ValueTypesBufferMaxMemory=0
  54  *                   -Djdk.lang.reflect.DVT=true -DVerifyIR=false compiler.valhalla.valuetypes.ValueTypeTestBench
  55  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  56  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation -XX:+AlwaysIncrementalInline
  57  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:-ValueArrayFlatten
  58  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0
  59  *                   -XX:ValueTypesBufferMaxMemory=0
  60  *                   -Djdk.lang.reflect.DVT=true -DVerifyIR=false compiler.valhalla.valuetypes.ValueTypeTestBench
  61  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  62  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-TieredCompilation
  63  *                   -XX:+EnableValhalla -XX:+EnableMVT -XX:+ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  64  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  65  *                   -XX:ValueTypesBufferMaxMemory=0
  66  *                   -Djdk.lang.reflect.DVT=true -DVerifyIR=false compiler.valhalla.valuetypes.ValueTypeTestBench
  67  */
  68 
  69 // TODO remove -XX:ValueTypesBufferMaxMemory=0 when interpreter buffering is fixed
  70 
  71 package compiler.valhalla.valuetypes;
  72 
  73 import compiler.whitebox.CompilerWhiteBoxTest;
  74 import jdk.experimental.bytecode.MacroCodeBuilder.CondKind;
  75 import jdk.experimental.bytecode.TypeTag;
  76 import jdk.experimental.value.MethodHandleBuilder;
  77 import jdk.incubator.mvt.ValueType;
  78 import jdk.test.lib.Asserts;
  79 import jdk.test.lib.management.InputArguments;
  80 import jdk.test.lib.Platform;
  81 import jdk.test.lib.process.ProcessTools;
  82 import jdk.test.lib.process.OutputAnalyzer;
  83 import jdk.test.lib.Utils;
  84 import sun.hotspot.WhiteBox;
  85 
  86 import java.lang.annotation.Retention;
  87 import java.lang.annotation.RetentionPolicy;
  88 import java.lang.annotation.Repeatable;
  89 import java.lang.invoke.*;
  90 import java.lang.reflect.Method;
  91 import java.util.ArrayList;
  92 import java.util.Arrays;
  93 import java.util.Hashtable;
  94 import java.util.LinkedHashMap;
  95 import java.util.List;
  96 import java.util.Map;
  97 import java.util.regex.Matcher;
  98 import java.util.regex.Pattern;
  99 import java.util.TreeMap;
 100 
 101 // Test value types
 102 __ByValue final class MyValue1 {
 103     static int s;
 104     static final long sf = ValueTypeTestBench.rL;
 105     final int x;
 106     final long y;
 107     final short z;
 108     final Integer o;
 109     final int[] oa;
 110     final MyValue2 v1;
 111     final MyValue2 v2;
 112     static final MyValue2 v3 = MyValue2.createWithFieldsInline(ValueTypeTestBench.rI, true);
 113     final int c;
 114 
 115     private MyValue1() {
 116         s = 0;
 117         this.x = 0;
 118         this.y = 0;
 119         this.z = 0;


 131 
 132     @ForceInline
 133     __ValueFactory static MyValue1 createDefaultInline() {
 134         return __MakeDefault MyValue1();
 135     }
 136 
 137     @DontInline
 138     static MyValue1 createWithFieldsDontInline(int x, long y) {
 139         return createWithFieldsInline(x, y);
 140     }
 141 
 142     @ForceInline
 143     static MyValue1 createWithFieldsInline(int x, long y) {
 144         MyValue1 v = createDefaultInline();
 145         v = setX(v, x);
 146         v = setY(v, y);
 147         v = setZ(v, (short)x);
 148         v = setO(v, new Integer(x));
 149         int[] oa = {x};
 150         v = setOA(v, oa);
 151         v = setV1(v, MyValue2.createWithFieldsInline(x, true));
 152         v = setV2(v, MyValue2.createWithFieldsInline(x, false));
 153         v = setC(v, ValueTypeTestBench.rI);
 154         return v;
 155     }
 156 
 157     // Hash only primitive and value type fields to avoid NullPointerException
 158     @ForceInline
 159     public long hashPrimitive() {
 160         return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash();
 161     }
 162 
 163     @ForceInline
 164     public long hash() {
 165         return hashPrimitive() + o + oa[0];
 166     }
 167 
 168     @DontCompile
 169     public long hashInterpreted() {
 170         return s + sf + x + y + z + o + oa[0] + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted();
 171     }
 172 
 173     @ForceInline
 174     public void print() {
 175         System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", o=" + (o != null ? (Integer)o : "NULL") + ", oa=" + oa[0] + ", v1[");
 176         v1.print();
 177         System.out.print("], v2[");
 178         v2.print();
 179         System.out.print("], v3[");
 180         v3.print();
 181         System.out.print("], c=" + c);
 182     }
 183 
 184     @ForceInline
 185     __ValueFactory static MyValue1 setX(MyValue1 v, int x) {
 186         v.x = x;
 187         return v;
 188     }
 189 
 190     @ForceInline
 191     __ValueFactory static MyValue1 setY(MyValue1 v, long y) {
 192         v.y = y;
 193         return v;
 194     }
 195 


 213 
 214     @ForceInline
 215     __ValueFactory static MyValue1 setC(MyValue1 v, int c) {
 216         v.c = c;
 217         return v;
 218     }
 219 
 220     @ForceInline
 221     __ValueFactory static MyValue1 setV1(MyValue1 v, MyValue2 v1) {
 222         v.v1 = v1;
 223         return v;
 224     }
 225 
 226     @ForceInline
 227     __ValueFactory static MyValue1 setV2(MyValue1 v, MyValue2 v2) {
 228         v.v2 = v2;
 229         return v;
 230     }
 231 }
 232 
 233 __ByValue final class MyValue2Inline {
 234     final boolean b;
 235     final long c;
 236 
 237     private MyValue2Inline() {
 238         this.b = false;
 239         this.c = 0;
 240     }
 241 
 242     @ForceInline
 243     __ValueFactory static MyValue2Inline setB(MyValue2Inline v, boolean b) {
 244         v.b = b;
 245         return v;
 246     }
 247 
 248     @ForceInline
 249     __ValueFactory static MyValue2Inline setC(MyValue2Inline v, long c) {
 250         v.c = c;
 251         return v;
 252     }
 253 
 254     @ForceInline
 255     __ValueFactory public static MyValue2Inline createDefault() {
 256         return __MakeDefault MyValue2Inline();
 257     }
 258 
 259     @ForceInline
 260     public static MyValue2Inline createWithFieldsInline(boolean b, long c) {
 261         MyValue2Inline v = MyValue2Inline.createDefault();
 262         v = MyValue2Inline.setB(v, b);
 263         v = MyValue2Inline.setC(v, c);
 264         return v;
 265     }
 266 }
 267 
 268 __ByValue final class MyValue2 {
 269     final int x;
 270     final byte y;
 271     final MyValue2Inline v1;

 272 
 273     private MyValue2() {
 274         this.x = 0;
 275         this.y = 0;
 276         this.v1 = MyValue2Inline.createDefault();

 277     }
 278 
 279     @ForceInline
 280     __ValueFactory public static MyValue2 createDefaultInline() {
 281         return __MakeDefault MyValue2();
 282     }
 283 
 284     @ForceInline
 285     public static MyValue2 createWithFieldsInline(int x, boolean b) {
 286         MyValue2 v = createDefaultInline();
 287         v = setX(v, x);
 288         v = setY(v, (byte)x);
 289         v = setV1(v, MyValue2Inline.createWithFieldsInline(b, ValueTypeTestBench.rL));

 290         return v;
 291     }
 292 
 293     @ForceInline
 294     public long hash() {
 295         return x + y + (v1.b ? 0 : 1) + v1.c;
 296     }
 297 
 298     @DontInline
 299     public long hashInterpreted() {
 300         return x + y + (v1.b ? 0 : 1) + v1.c;
 301     }
 302 
 303     @ForceInline
 304     public void print() {
 305         System.out.print("x=" + x + ", y=" + y + ", b=" + v1.b + ", c=" + v1.c);
 306     }
 307 
 308     @ForceInline
 309     __ValueFactory static MyValue2 setX(MyValue2 v, int x) {
 310         v.x = x;
 311         return v;
 312     }
 313 
 314     @ForceInline
 315     __ValueFactory static MyValue2 setY(MyValue2 v, byte y) {
 316         v.y = y;
 317         return v;
 318     }
 319 
 320     @ForceInline
 321     __ValueFactory static MyValue2 setV1(MyValue2 v, MyValue2Inline v1) {
 322         v.v1 = v1;
 323         return v;
 324     }
 325 }
 326 
 327 __ByValue final class MyValue3Inline {
 328     final float f7;
 329     final double f8;
 330 
 331     private MyValue3Inline() {
 332         this.f7 = 0;
 333         this.f8 = 0;
 334     }
 335 
 336     @ForceInline
 337     __ValueFactory static MyValue3Inline setF7(MyValue3Inline v, float f7) {
 338         v.f7 = f7;
 339         return v;
 340     }
 341 
 342     @ForceInline
 343     __ValueFactory static MyValue3Inline setF8(MyValue3Inline v, double f8) {
 344         v.f8 = f8;
 345         return v;
 346     }
 347 
 348     @ForceInline
 349     __ValueFactory public static MyValue3Inline createDefault() {
 350         return __MakeDefault MyValue3Inline();
 351     }
 352 
 353     @ForceInline
 354     public static MyValue3Inline createWithFieldsInline(float f7, double f8) {
 355         MyValue3Inline v = createDefault();
 356         v = setF7(v, f7);
 357         v = setF8(v, f8);
 358         return v;
 359     }
 360 }
 361 
 362 // Value type definition to stress test return of a value in registers
 363 // (uses all registers of calling convention on x86_64)
 364 __ByValue final class MyValue3 {
 365     final char c;
 366     final byte bb;
 367     final short s;
 368     final int i;
 369     final long l;
 370     final Object o;
 371     final float f1;
 372     final double f2;
 373     final float f3;
 374     final double f4;
 375     final float f5;
 376     final double f6;
 377     final MyValue3Inline v1;































 378 
 379     private MyValue3() {
 380         this.c = 0;
 381         this.bb = 0;
 382         this.s = 0;
 383         this.i = 0;
 384         this.l = 0;
 385         this.o = null;
 386         this.f1 = 0;
 387         this.f2 = 0;
 388         this.f3 = 0;
 389         this.f4 = 0;
 390         this.f5 = 0;
 391         this.f6 = 0;
 392         this.v1 = MyValue3Inline.createDefault();

 393     }
 394 
 395     @ForceInline
 396     __ValueFactory static MyValue3 setC(MyValue3 v, char c) {
 397         v.c = c;
 398         return v;
 399     }
 400 
 401     @ForceInline
 402     __ValueFactory static MyValue3 setBB(MyValue3 v, byte bb) {
 403         v.bb = bb;
 404         return v;
 405     }
 406 
 407     @ForceInline
 408     __ValueFactory static MyValue3 setS(MyValue3 v, short s) {
 409         v.s = s;
 410         return v;
 411     }
 412 


 448 
 449     @ForceInline
 450     __ValueFactory static MyValue3 setF4(MyValue3 v, double f4) {
 451         v.f4 = f4;
 452         return v;
 453     }
 454 
 455     @ForceInline
 456     __ValueFactory static MyValue3 setF5(MyValue3 v, float f5) {
 457         v.f5 = f5;
 458         return v;
 459     }
 460 
 461     @ForceInline
 462     __ValueFactory static MyValue3 setF6(MyValue3 v, double f6) {
 463         v.f6 = f6;
 464         return v;
 465     }
 466 
 467     @ForceInline
 468     __ValueFactory static MyValue3 setV1(MyValue3 v, MyValue3Inline v1) {
 469         v.v1 = v1;






 470         return v;
 471     }
 472 
 473     @ForceInline
 474     __ValueFactory public static MyValue3 createDefault() {
 475         return __MakeDefault MyValue3();
 476     }
 477 
 478     @ForceInline
 479     public static MyValue3 create() {
 480         java.util.Random r = Utils.getRandomInstance();
 481         MyValue3 v = createDefault();
 482         v = setC(v, (char)r.nextInt());
 483         v = setBB(v, (byte)r.nextInt());
 484         v = setS(v, (short)r.nextInt());
 485         v = setI(v, r.nextInt());
 486         v = setL(v, r.nextLong());
 487         v = setO(v, new Object());
 488         v = setF1(v, r.nextFloat());
 489         v = setF2(v, r.nextDouble());
 490         v = setF3(v, r.nextFloat());
 491         v = setF4(v, r.nextDouble());
 492         v = setF5(v, r.nextFloat());
 493         v = setF6(v, r.nextDouble());
 494         v = setV1(v, MyValue3Inline.createWithFieldsInline(r.nextFloat(), r.nextDouble()));

 495         return v;
 496     }
 497 
 498     @DontInline
 499     public static MyValue3 createDontInline() {
 500         return create();
 501     }
 502 
 503     @ForceInline
 504     public static MyValue3 copy(MyValue3 other) {
 505         MyValue3 v = createDefault();
 506         v = setC(v, other.c);
 507         v = setBB(v, other.bb);
 508         v = setS(v, other.s);
 509         v = setI(v, other.i);
 510         v = setL(v, other.l);
 511         v = setO(v, other.o);
 512         v = setF1(v, other.f1);
 513         v = setF2(v, other.f2);
 514         v = setF3(v, other.f3);
 515         v = setF4(v, other.f4);
 516         v = setF5(v, other.f5);
 517         v = setF6(v, other.f6);
 518         v = setV1(v, other.v1);

 519         return v;
 520     }
 521 
 522     @DontInline
 523     public void verify(MyValue3 other) {
 524         Asserts.assertEQ(c, other.c);
 525         Asserts.assertEQ(bb, other.bb);
 526         Asserts.assertEQ(s, other.s);
 527         Asserts.assertEQ(i, other.i);
 528         Asserts.assertEQ(l, other.l);
 529         Asserts.assertEQ(o, other.o);
 530         Asserts.assertEQ(f1, other.f1);
 531         Asserts.assertEQ(f2, other.f2);
 532         Asserts.assertEQ(f3, other.f3);
 533         Asserts.assertEQ(f4, other.f4);
 534         Asserts.assertEQ(f5, other.f5);
 535         Asserts.assertEQ(f6, other.f6);
 536         Asserts.assertEQ(v1.f7, other.v1.f7);
 537         Asserts.assertEQ(v1.f8, other.v1.f8);
 538     }
 539 }
 540 
 541 // Value type definition with too many fields to return in registers
 542 __ByValue final class MyValue4 {
 543     final MyValue3 v1;
 544     final MyValue3 v2;
 545 





 546     private MyValue4() {
 547         this.v1 = MyValue3.createDefault();
 548         this.v2 = MyValue3.createDefault();
 549     }
 550 
 551     @ForceInline
 552     __ValueFactory static MyValue4 setV1(MyValue4 v, MyValue3 v1) {
 553         v.v1 = v1;
 554         return v;
 555     }
 556 
 557     @ForceInline
 558     __ValueFactory static MyValue4 setV2(MyValue4 v, MyValue3 v2) {
 559         v.v2 = v2;
 560         return v;
 561     }
 562 
 563     @ForceInline
 564     __ValueFactory public static MyValue4 createDefault() {
 565         return __MakeDefault MyValue4();


1021         Asserts.assertEQ(val1.hash(), hash(rI + 1, rL + 1));
1022         Asserts.assertEQ(val2.hash(), MyValue2.createWithFieldsInline(rI + 1, true).hash());
1023         Asserts.assertEQ(val4.hash(), hash(rI + 1, rL + 1));
1024     }
1025 
1026     // Test folding of constant value type fields
1027     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
1028     public long test22() {
1029         // This should be constant folded
1030         return val5.hash() + val5.v3.hash();
1031     }
1032 
1033     @DontCompile
1034     public void test22_verifier(boolean warmup) {
1035         long result = test22();
1036         Asserts.assertEQ(result, val5.hash() + val5.v3.hash());
1037     }
1038 
1039     // Test OSR compilation
1040     @Test()
1041     @Slow
1042     public long test23() {
1043         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1044         MyValue1[] va = new MyValue1[Math.abs(rI) % 3];
1045         for (int i = 0; i < va.length; ++i) {
1046             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1047         }
1048         long result = 0;
1049         // Long loop to trigger OSR compilation
1050         for (int i = 0 ; i < 100_000; ++i) {
1051             // Reference local value type in interpreter state
1052             result = v.hash();
1053             for (int j = 0; j < va.length; ++j) {
1054                 result += va[j].hash();
1055             }
1056         }
1057         return result;
1058     }
1059 
1060     @DontCompile
1061     public void test23_verifier(boolean warmup) {


1695 
1696     // Test allocation elimination of unused object with initialized value type field
1697     @Test(failOn = ALLOC + LOAD + STORE + LOOP)
1698     public void test56(boolean deopt) {
1699         TestClass56 unused = new TestClass56();
1700         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1701         unused.v = v;
1702         if (deopt) {
1703             // uncommon trap
1704             WHITE_BOX.deoptimizeMethod(tests.get("ValueTypeTestBench::test56"));
1705         }
1706     }
1707 
1708     @DontCompile
1709     public void test56_verifier(boolean warmup) {
1710         test56(!warmup);
1711     }
1712 
1713     // Test loop peeling
1714     @Test(failOn = ALLOC + LOAD + STORE)
1715     @Slow
1716     public void test57() {
1717         MyValue1 v = MyValue1.createWithFieldsInline(0, 1);
1718         // Trigger OSR compilation and loop peeling
1719         for (int i = 0; i < 100_000; ++i) {
1720             if (v.x != i || v.y != i + 1) {
1721                 // Uncommon trap
1722                 throw new RuntimeException("test57 failed");
1723             }
1724             v = MyValue1.createWithFieldsInline(i + 1, i + 2);
1725         }
1726     }
1727 
1728     @DontCompile
1729     public void test57_verifier(boolean warmup) {
1730         test57();
1731     }
1732 
1733     // Test loop peeling and unrolling
1734     @Test()
1735     @Slow
1736     public void test58() {
1737         MyValue1 v1 = MyValue1.createWithFieldsInline(0, 0);
1738         MyValue1 v2 = MyValue1.createWithFieldsInline(1, 1);
1739         // Trigger OSR compilation and loop peeling
1740         for (int i = 0; i < 100_000; ++i) {
1741             if (v1.x != 2*i || v2.x != i+1 || v2.y != i+1) {
1742                 // Uncommon trap
1743                 throw new RuntimeException("test58 failed");
1744             }
1745             v1 = MyValue1.createWithFieldsInline(2*(i+1), 0);
1746             v2 = MyValue1.createWithFieldsInline(i+2, i+2);
1747         }
1748     }
1749 
1750     @DontCompile
1751     public void test58_verifier(boolean warmup) {
1752         test58();
1753     }
1754 
1755     // When calling a method on __Value, passing fields as arguments is impossible


2592         vt = MyValue3.setI(vt, (int)vt.c);
2593         // vt is not equal to staticVal3, so C2 should not re-use the oop
2594         va[0] = vt;
2595         staticVal3 = vt;
2596         vt.verify(staticVal3);
2597         return vt;
2598     }
2599 
2600     @DontCompile
2601     public void test92_verifier(boolean warmup) {
2602         staticVal3 = MyValue3.create();
2603         MyValue3[] va = new MyValue3[1];
2604         MyValue3 vt = test92(va);
2605         Asserts.assertEQ(staticVal3.i, (int)staticVal3.c);
2606         Asserts.assertEQ(va[0].i, (int)staticVal3.c);
2607         Asserts.assertEQ(vt.i, (int)staticVal3.c);
2608     }
2609 
2610     // Test correct handling of __Value merges through PhiNodes
2611     @Test()
2612     @Slow
2613     public long test93() throws Throwable {
2614         // Create a new value type
2615         final MethodHandle dvt = MethodHandleBuilder.loadCode(MethodHandles.lookup(), "createValueType",
2616                                      MethodType.methodType(ValueType.forClass(ValueCapableClass1.class).valueClass()),
2617                                      CODE -> {
2618                                          CODE.
2619                                          iconst_1().
2620                                          anewarray(ValueType.forClass(ValueCapableClass1.class).valueClass()).
2621                                          iconst_0().
2622                                          vaload().
2623                                          vreturn();
2624                                      });
2625         // Box the value type
2626         final MethodHandle box = MethodHandleBuilder.loadCode(MethodHandles.lookup(), "boxValueType",
2627                                      MethodType.methodType(ValueCapableClass1.class, ValueType.forClass(ValueCapableClass1.class).valueClass()),
2628                                      CODE -> {
2629                                          CODE.
2630                                          vload(0).
2631                                          vbox(ValueCapableClass1.class).
2632                                          areturn();


3059     public void test105_verifier(boolean warmup) throws Throwable {
3060         test105_i++;
3061         long hash = test105();
3062         boolean b = (test105_i % 100) == 0;
3063         Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+test105_i * (b ? 1 : -1), b).hash());
3064     }
3065 
3066 
3067     // OSR compilation with __Value local
3068     @DontCompile
3069     public __Value test106_init() {
3070         return MyValue1.createWithFieldsInline(rI, rL);
3071     }
3072 
3073     @DontCompile
3074     public __Value test106_body() {
3075         return MyValue1.createWithFieldsInline(rI, rL);
3076     }
3077 
3078     @Test()
3079     @Slow
3080     public __Value test106() throws Throwable {
3081         __Value vt = test106_init();
3082         for (int i = 0; i < 50_000; i++) {
3083             if (i % 2 == 1) {
3084                 vt = test106_body();
3085             }
3086         }
3087         return vt;
3088     }
3089 
3090     @DontCompile
3091     public void test106_verifier(boolean warmup) throws Throwable {
3092         test106();
3093     }
3094 
3095     // ========== Test infrastructure ==========
3096 
3097     // User defined settings
3098     private static final boolean SKIP_SLOW = Boolean.parseBoolean(System.getProperty("SkipSlow", "false"));
3099     private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false"));
3100     private static final boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true"));
3101     private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")); 
3102     private static final String TESTLIST = System.getProperty("Testlist", "");
3103     private static final int WARMUP = Integer.parseInt(System.getProperty("Warmup", "251"));
3104 
3105     // Pre defined settings
3106     private static final List<String> defaultFlags = Arrays.asList(
3107         "-XX:-BackgroundCompilation", "-XX:CICompilerCount=1",
3108         "-XX:+PrintCompilation", "-XX:+PrintInlining", "-XX:+PrintIdeal", "-XX:+PrintOptoAssembly",
3109         "-XX:CompileCommand=quiet",
3110         "-XX:CompileCommand=compileonly,java.lang.invoke.*::*",
3111         "-XX:CompileCommand=compileonly,java.lang.Long::sum",
3112         "-XX:CompileCommand=compileonly,java.lang.Object::<init>",
3113         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue1::*",
3114         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2::*",
3115         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue2Inline::*",
3116         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue3::*",
3117         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue3Inline::*",
3118         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.MyValue4::*",
3119         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueCapableClass2_*::*",
3120         "-XX:CompileCommand=compileonly,compiler.valhalla.valuetypes.ValueTypeTestBench::*",
3121         "-XX:CompileCommand=inline,java.lang.__Value::hashCode");
3122     private static final List<String> verifyFlags = Arrays.asList(
3123         "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", "-XX:+VerifyAfterGC",
3124         "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing", "-XX:+StressValueTypeReturnedAsFields");
3125 
3126     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
3127     private static final int ValueTypePassFieldsAsArgsOn = 0x1;
3128     private static final int ValueTypePassFieldsAsArgsOff = 0x2;
3129     private static final int ValueTypeArrayFlattenOn = 0x4;
3130     private static final int ValueTypeArrayFlattenOff = 0x8;
3131     private static final int ValueTypeReturnedAsFieldsOn = 0x10;
3132     private static final int ValueTypeReturnedAsFieldsOff = 0x20;
3133     static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn;
3134     private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
3135     private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
3136     private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
3137     private static final int COMP_LEVEL_ANY = -2;
3138     private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
3139     private static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
3140     private static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
3141     private static final boolean PRINT_IDEAL  = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
3142     private static final boolean XCOMP = Platform.isComp();

3143 
3144     // Regular expressions used to match nodes in the PrintIdeal output
3145     private static final String START = "(\\d+\\t(.*";
3146     private static final String MID = ".*)+\\t===.*";
3147     private static final String END = ")|";
3148     private static final String ALLOC  = "(.*precise klass compiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_instance_Java" + END;
3149     private static final String ALLOCA = "(.*precise klass \\[Qcompiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_array_Java" + END;
3150     private static final String LOAD   = START + "Load(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
3151     private static final String LOADP  = START + "Load(P|N)" + MID + "valuetype\\*" + END;
3152     private static final String LOADK  = START + "LoadK" + MID + END;
3153     private static final String STORE  = START + "Store(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
3154     private static final String STOREP = START + "Store(P|N)" + MID + "valuetype\\*" + END;
3155     private static final String LOOP   = START + "Loop" + MID + "" + END;
3156     private static final String TRAP   = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END;
3157     private static final String RETURN = START + "Return" + MID + "returns" + END;
3158     private static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END;
3159     private static final String NPE = START + "CallStaticJava" + MID + "null_check" + END;
3160     private static final String CCE = START + "CallStaticJava" + MID + "class_check" + END;
3161     private static final String CALL = START + "CallStaticJava" + MID + END;
3162     private static final String STOREVALUETYPEFIELDS = START + "CallStaticJava" + MID + "store_value_type_fields" + END;
3163     private static final String SCOBJ = "(.*# ScObj.*" + END;
3164 
3165     static {
3166         List<String> list = null;
3167         if (!TESTLIST.isEmpty()) {
3168            list = Arrays.asList(TESTLIST.split(","));
3169         }
3170         // Gather all test methods and put them in Hashtable
3171         for (Method m : ValueTypeTestBench.class.getDeclaredMethods()) {
3172             Test[] annos = m.getAnnotationsByType(Test.class);
3173             if (annos.length != 0 && 
3174                 (list == null || list.contains(m.getName())) &&
3175                 !(SKIP_SLOW && m.isAnnotationPresent(Slow.class))) {
3176                 tests.put("ValueTypeTestBench::" + m.getName(), m);
3177             }
3178         }
3179     }
3180 
3181     private static void execute_vm() throws Throwable {
3182         Asserts.assertFalse(tests.isEmpty(), "no tests to execute");
3183         ArrayList<String> args = new ArrayList<String>(defaultFlags);
3184         if (VERIFY_VM) {
3185             args.addAll(verifyFlags);
3186         }
3187         // Run tests in own process and verify output
3188         args.add(ValueTypeTestBench.class.getName());
3189         args.add("run");
3190         // Spawn process with default JVM options from the test's run command
3191         String[] vmInputArgs = InputArguments.getVmInputArgs();
3192         String[] cmds = Arrays.copyOf(vmInputArgs, vmInputArgs.length + args.size());
3193         System.arraycopy(args.toArray(), 0, cmds, vmInputArgs.length, args.size());
3194         OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds);
3195         // If ideal graph printing is enabled/supported, verify output
3196         String output = oa.getOutput();
3197         oa.shouldHaveExitValue(0);
3198         boolean verifyIR = VERIFY_IR && output.contains("PrintIdeal enabled") &&
3199                 !output.contains("ValueTypePassFieldsAsArgs is not supported on this platform");
3200         if (verifyIR) {
3201             parseOutput(output);
3202         } else {
3203             System.out.println(output);
3204             System.out.println("WARNING: IR verification disabled! Running with -Xint, -Xcomp or release build?");
3205         }
3206     }
3207 
3208     public static void main(String[] args) throws Throwable {

3209         if (args.length == 0) {
3210             // Spawn a new VM instance
3211             execute_vm();











3212         } else {
3213             // Execute tests
3214             ValueTypeTestBench bench = new ValueTypeTestBench();
3215             bench.run();
3216         }
3217     }
3218 
3219     private static void parseOutput(String output) throws Exception {
3220         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");
3221         Matcher m = comp_re.matcher(output);
3222         Map<String,String> compilations = new LinkedHashMap<>();
3223         int prev = 0;
3224         String methodName = null;
3225         while (m.find()) {
3226             if (prev == 0) {
3227                 // Print header
3228                 System.out.print(output.substring(0, m.start()+1));
3229             } else if (methodName != null) {
3230                 compilations.put(methodName, output.substring(prev, m.start()+1));
3231             }
3232             if (m.group("osr") != null) {
3233                 methodName = null;
3234             } else {
3235                 methodName = m.group("name");
3236             }
3237             prev = m.end();
3238         }
3239         if (prev == 0) {


3328                 WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_ANY, true);
3329                 WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_ANY, false);
3330                 WHITE_BOX.testSetDontInlineMethod(m, true);
3331             }
3332             if (m.isAnnotationPresent(ForceInline.class)) {
3333                 WHITE_BOX.testSetForceInlineMethod(m, true);
3334             } else if (m.isAnnotationPresent(DontInline.class)) {
3335                 WHITE_BOX.testSetDontInlineMethod(m, true);
3336             }
3337         }
3338     }
3339 
3340     public void run() throws Exception {
3341         if (USE_COMPILER && PRINT_IDEAL && !XCOMP) {
3342             System.out.println("PrintIdeal enabled");
3343         }
3344         System.out.format("rI = %d, rL = %d\n", rI, rL);
3345         setup(this.getClass().getDeclaredMethods());
3346         setup(MyValue1.class.getDeclaredMethods());
3347         setup(MyValue2.class.getDeclaredMethods());
3348         setup(MyValue2Inline.class.getDeclaredMethods());
3349         setup(MyValue3.class.getDeclaredMethods());
3350         setup(MyValue3Inline.class.getDeclaredMethods());
3351         setup(MyValue4.class.getDeclaredMethods());
3352 
3353         // Compile class initializers
3354         WHITE_BOX.enqueueInitializerForCompilation(this.getClass(), COMP_LEVEL_FULL_OPTIMIZATION);
3355         WHITE_BOX.enqueueInitializerForCompilation(MyValue1.class, COMP_LEVEL_FULL_OPTIMIZATION);
3356         WHITE_BOX.enqueueInitializerForCompilation(MyValue2.class, COMP_LEVEL_FULL_OPTIMIZATION);
3357         WHITE_BOX.enqueueInitializerForCompilation(MyValue2Inline.class, COMP_LEVEL_FULL_OPTIMIZATION);
3358         WHITE_BOX.enqueueInitializerForCompilation(MyValue3.class, COMP_LEVEL_FULL_OPTIMIZATION);
3359         WHITE_BOX.enqueueInitializerForCompilation(MyValue3Inline.class, COMP_LEVEL_FULL_OPTIMIZATION);
3360         WHITE_BOX.enqueueInitializerForCompilation(MyValue4.class, COMP_LEVEL_FULL_OPTIMIZATION);
3361 
3362         // Execute tests
3363         TreeMap<Long, String> durations = PRINT_TIMES ? new TreeMap<Long, String>() : null;
3364         for (Method test : tests.values()) {
3365             long startTime = System.nanoTime();
3366             Method verifier = getClass().getDeclaredMethod(test.getName() + "_verifier", boolean.class);
3367             // Warmup using verifier method
3368             Warmup anno = test.getAnnotation(Warmup.class);
3369             int warmup = anno == null ? WARMUP : anno.value();
3370             for (int i = 0; i < warmup; ++i) {
3371                 verifier.invoke(this, true);
3372             }
3373             // Trigger compilation
3374             WHITE_BOX.enqueueMethodForCompilation(test, COMP_LEVEL_FULL_OPTIMIZATION);
3375             Asserts.assertTrue(!USE_COMPILER || WHITE_BOX.isMethodCompiled(test, false), test + " not compiled");
3376             // Check result
3377             verifier.invoke(this, false);
3378             if (PRINT_TIMES) {
3379                 long endTime = System.nanoTime();
3380                 long duration = (endTime - startTime);
3381                 durations.put(duration, test.getName());
3382             }
3383         }
3384 
3385         // Print execution times
3386         if (PRINT_TIMES) {
3387           System.out.println("\n\nTest execution times:");
3388           for (Map.Entry<Long, String> entry : durations.entrySet()) {
3389               System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey());
3390           }
3391         }
3392     }
3393 }
3394 
3395 // Mark method as test
3396 @Retention(RetentionPolicy.RUNTIME)
3397 @Repeatable(Tests.class)
3398 @interface Test {
3399     // Regular expression used to match forbidden IR nodes
3400     // in the C2 IR emitted for this test.
3401     String failOn() default "";
3402     // Regular expressions used to match and count IR nodes.
3403     String[] match() default { };
3404     int[] matchCount() default { };
3405     int valid() default ValueTypeTestBench.AllFlags;
3406 }
3407 
3408 @Retention(RetentionPolicy.RUNTIME)
3409 @interface Tests {
3410     Test[] value();
3411 }
3412 
3413 // Force method inlining during compilation
3414 @Retention(RetentionPolicy.RUNTIME)
3415 @interface ForceInline { }
3416 
3417 // Prevent method inlining during compilation
3418 @Retention(RetentionPolicy.RUNTIME)
3419 @interface DontInline { }
3420 
3421 // Prevent method compilation
3422 @Retention(RetentionPolicy.RUNTIME)
3423 @interface DontCompile { }
3424 
3425 // Number of warmup iterations
3426 @Retention(RetentionPolicy.RUNTIME)
3427 @interface Warmup {
3428     int value();
3429 }
3430 
3431 // Mark test as slow
3432 @Retention(RetentionPolicy.RUNTIME)
3433 @interface Slow { }
< prev index next >