1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  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 package compiler.valhalla.valuetypes;
  25 
  26 import java.lang.invoke.*;
  27 
  28 import jdk.experimental.value.MethodHandleBuilder;
  29 import jdk.experimental.bytecode.MacroCodeBuilder;
  30 import jdk.experimental.bytecode.MacroCodeBuilder.CondKind;
  31 import jdk.experimental.bytecode.TypeTag;
  32 import jdk.test.lib.Asserts;
  33 
  34 /*
  35  * @test
  36  * @summary Test value types in LWorld.
  37  * @modules java.base/jdk.experimental.bytecode
  38  *          java.base/jdk.experimental.value
  39  * @library /testlibrary /test/lib /compiler/whitebox /
  40  * @requires os.simpleArch == "x64"
  41  * @build GetNullAsm RarelyUsedValueUserAsm
  42  * @compile -XDenableValueTypes -XDallowFlattenabilityModifiers TestLWorld.java
  43  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  44  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  45  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  46  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  47  *                   -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  48  *                   compiler.valhalla.valuetypes.TestLWorld
  49  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  50  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedOops -XX:-UseOptoBiasInlining
  51  *                   -XX:+EnableValhalla -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  52  *                   -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  53  *                   compiler.valhalla.valuetypes.TestLWorld
  54  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  55  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedOops -XX:-UseBiasedLocking
  56  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:-ValueArrayFlatten
  57  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0
  58  *                   -DVerifyIR=false compiler.valhalla.valuetypes.TestLWorld
  59  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  60  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline -XX:-UseBiasedLocking
  61  *                   -XX:+EnableValhalla -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  62  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0
  63  *                   -XX:-MonomorphicArrayCheck
  64  *                   -DVerifyIR=false compiler.valhalla.valuetypes.TestLWorld
  65  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  66  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI
  67  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  68  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  69  *                   -XX:-MonomorphicArrayCheck
  70  *                   -DVerifyIR=false compiler.valhalla.valuetypes.TestLWorld
  71  */
  72 public class TestLWorld extends ValueTypeTest {
  73 
  74     public static void main(String[] args) throws Throwable {
  75         TestLWorld test = new TestLWorld();
  76         test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class, Test65Value.class);
  77     }
  78 
  79     // Helper methods
  80 
  81     private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL);
  82     private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, true);
  83 
  84     protected long hash() {
  85         return testValue1.hash();
  86     }
  87 
  88     // Test passing a value type as an Object
  89     @DontInline
  90     public Object test1_dontinline1(Object o) {
  91         return o;
  92     }
  93 
  94     @DontInline
  95     public MyValue1 test1_dontinline2(Object o) {
  96         return (MyValue1)o;
  97     }
  98 
  99     @ForceInline
 100     public Object test1_inline1(Object o) {
 101         return o;
 102     }
 103 
 104     @ForceInline
 105     public MyValue1 test1_inline2(Object o) {
 106         return (MyValue1)o;
 107     }
 108 
 109     @Test()
 110     public MyValue1 test1() {
 111         MyValue1 vt = testValue1;
 112         vt = (MyValue1)test1_dontinline1(vt);
 113         vt =           test1_dontinline2(vt);
 114         vt = (MyValue1)test1_inline1(vt);
 115         vt =           test1_inline2(vt);
 116         return vt;
 117     }
 118 
 119     @DontCompile
 120     public void test1_verifier(boolean warmup) {
 121         Asserts.assertEQ(test1().hash(), hash());
 122     }
 123 
 124     // Test storing/loading value types to/from Object and value type fields
 125     Object objectField1 = null;
 126     Object objectField2 = null;
 127     Object objectField3 = null;
 128     Object objectField4 = null;
 129     Object objectField5 = null;
 130     Object objectField6 = null;
 131 
 132     __Flattenable  MyValue1 valueField1 = testValue1;
 133     __Flattenable  MyValue1 valueField2 = testValue1;
 134     __NotFlattened MyValue1 valueField3 = testValue1;
 135     __Flattenable  MyValue1 valueField4;
 136     __NotFlattened MyValue1 valueField5;
 137 
 138     static __NotFlattened MyValue1 staticValueField1 = testValue1;
 139     static __Flattenable  MyValue1 staticValueField2 = testValue1;
 140     static __Flattenable  MyValue1 staticValueField3;
 141     static __NotFlattened MyValue1 staticValueField4;
 142 
 143     @DontInline
 144     public Object readValueField5() {
 145         return (Object)valueField5;
 146     }
 147 
 148     @DontInline
 149     public Object readStaticValueField4() {
 150         return (Object)staticValueField4;
 151     }
 152 
 153     @Test()
 154     public long test2(MyValue1 vt1, Object vt2) {
 155         objectField1 = vt1;
 156         objectField2 = (MyValue1)vt2;
 157         objectField3 = testValue1;
 158         objectField4 = MyValue1.createWithFieldsDontInline(rI, rL);
 159         objectField5 = valueField1;
 160         objectField6 = valueField3;
 161         valueField1 = (MyValue1)objectField1;
 162         valueField2 = (MyValue1)vt2;
 163         valueField3 = (MyValue1)vt2;
 164         staticValueField1 = (MyValue1)objectField1;
 165         staticValueField2 = (MyValue1)vt1;
 166         // Don't inline these methods because reading NULL will trigger a deoptimization
 167         if (readValueField5() != null || readStaticValueField4() != null) {
 168             throw new RuntimeException("Should be null");
 169         }
 170         return ((MyValue1)objectField1).hash() + ((MyValue1)objectField2).hash() +
 171                ((MyValue1)objectField3).hash() + ((MyValue1)objectField4).hash() +
 172                ((MyValue1)objectField5).hash() + ((MyValue1)objectField6).hash() +
 173                 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() +
 174                 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive();
 175     }
 176 
 177     @DontCompile
 178     public void test2_verifier(boolean warmup) {
 179         MyValue1 vt = testValue1;
 180         MyValue1 def = MyValue1.createDefaultDontInline();
 181         long result = test2(vt, vt);
 182         Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive());
 183     }
 184 
 185     // Test merging value types and objects
 186     @Test()
 187     public Object test3(int state) {
 188         Object res = null;
 189         if (state == 0) {
 190             res = new Integer(rI);
 191         } else if (state == 1) {
 192             res = MyValue1.createWithFieldsInline(rI, rL);
 193         } else if (state == 2) {
 194             res = MyValue1.createWithFieldsDontInline(rI, rL);
 195         } else if (state == 3) {
 196             res = (MyValue1)objectField1;
 197         } else if (state == 4) {
 198             res = valueField1;
 199         } else if (state == 5) {
 200             res = null;
 201         } else if (state == 6) {
 202             res = MyValue2.createWithFieldsInline(rI, true);
 203         } else if (state == 7) {
 204             res = testValue2;
 205         }
 206         return res;
 207     }
 208 
 209     @DontCompile
 210     public void test3_verifier(boolean warmup) {
 211         objectField1 = valueField1;
 212         Object result = null;
 213         result = test3(0);
 214         Asserts.assertEQ((Integer)result, rI);
 215         result = test3(1);
 216         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 217         result = test3(2);
 218         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 219         result = test3(3);
 220         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 221         result = test3(4);
 222         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 223         result = test3(5);
 224         Asserts.assertEQ(result, null);
 225         result = test3(6);
 226         Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash());
 227         result = test3(7);
 228         Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash());
 229     }
 230 
 231     // Test merging value types and objects in loops
 232     @Test()
 233     public Object test4(int iters) {
 234         Object res = new Integer(rI);
 235         for (int i = 0; i < iters; ++i) {
 236             if (res instanceof Integer) {
 237                 res = MyValue1.createWithFieldsInline(rI, rL);
 238             } else {
 239                 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL);
 240             }
 241         }
 242         return res;
 243     }
 244 
 245     @DontCompile
 246     public void test4_verifier(boolean warmup) {
 247         Integer result1 = (Integer)test4(0);
 248         Asserts.assertEQ(result1, rI);
 249         int iters = (Math.abs(rI) % 10) + 1;
 250         MyValue1 result2 = (MyValue1)test4(iters);
 251         MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL);
 252         Asserts.assertEQ(result2.hash(), vt.hash());
 253     }
 254 
 255     // Test value types in object variables that are live at safepoint
 256     @Test(failOn = ALLOC + STORE + LOOP)
 257     public long test5(MyValue1 arg, boolean deopt) {
 258         Object vt1 = MyValue1.createWithFieldsInline(rI, rL);
 259         Object vt2 = MyValue1.createWithFieldsDontInline(rI, rL);
 260         Object vt3 = arg;
 261         Object vt4 = valueField1;
 262         if (deopt) {
 263             // uncommon trap
 264             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test5"));
 265         }
 266         return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() +
 267                ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash();
 268     }
 269 
 270     @DontCompile
 271     public void test5_verifier(boolean warmup) {
 272         long result = test5(valueField1, !warmup);
 273         Asserts.assertEQ(result, 4*hash());
 274     }
 275 
 276     // Test comparing value types with objects
 277     @Test(failOn = ALLOC + LOAD + STORE + LOOP)
 278     public boolean test6(Object arg) {
 279         Object vt = MyValue1.createWithFieldsInline(rI, rL);
 280         if (vt == arg || vt == (Object)valueField1 || vt == objectField1 || vt == null ||
 281             arg == vt || (Object)valueField1 == vt || objectField1 == vt || null == vt) {
 282             return true;
 283         }
 284         return false;
 285     }
 286 
 287     @DontCompile
 288     public void test6_verifier(boolean warmup) {
 289         boolean result = test6(null);
 290         Asserts.assertFalse(result);
 291     }
 292 
 293     // Test correct handling of null-ness of value types
 294 
 295     __NotFlattened MyValue1 nullField;
 296 
 297     @Test
 298     @Warmup(10000) // Warmup to make sure 'callTest7WithNull' is compiled
 299     public long test7(MyValue1 vt) {
 300         long result = 0;
 301         try {
 302             result = vt.hash();
 303             throw new RuntimeException("NullPointerException expected");
 304         } catch (NullPointerException e) {
 305             // Expected
 306         }
 307         return result;
 308     }
 309 
 310     private static final MethodHandle callTest7WithNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
 311         "callTest7WithNull",
 312         MethodType.methodType(void.class, TestLWorld.class),
 313         CODE -> {
 314             CODE.
 315             aload_0().
 316             aconst_null().
 317             invokevirtual(TestLWorld.class, "test7", "(Lcompiler/valhalla/valuetypes/MyValue1;)J", false).
 318             return_();
 319         }
 320         );
 321 
 322     @DontCompile
 323     public void test7_verifier(boolean warmup) throws Throwable {
 324         long result = (long)callTest7WithNull.invoke(this);
 325         Asserts.assertEquals(result, 0L);
 326     }
 327 
 328     @Test
 329     public long test8(MyValue1 vt) {
 330         long result = 0;
 331         try {
 332             result = vt.hashInterpreted();
 333             throw new RuntimeException("NullPointerException expected");
 334         } catch (NullPointerException e) {
 335             // Expected
 336         }
 337         return result;
 338     }
 339 
 340     @DontCompile
 341     public void test8_verifier(boolean warmup) {
 342         long result = test8(nullField);
 343         Asserts.assertEquals(result, 0L);
 344     }
 345 
 346     @Test
 347     public long test9() {
 348         long result = 0;
 349         try {
 350             if ((Object)nullField != null) {
 351                 throw new RuntimeException("nullField should be null");
 352             }
 353             result = nullField.hash();
 354             throw new RuntimeException("NullPointerException expected");
 355         } catch (NullPointerException e) {
 356             // Expected
 357         }
 358         return result;
 359     }
 360 
 361     @DontCompile
 362     public void test9_verifier(boolean warmup) {
 363         long result = test9();
 364         Asserts.assertEquals(result, 0L);
 365     }
 366 
 367     @Test
 368     public void test10() {
 369         try {
 370             valueField1 = nullField;
 371             throw new RuntimeException("NullPointerException expected");
 372         } catch (NullPointerException e) {
 373             // Expected
 374         }
 375     }
 376 
 377     @DontCompile
 378     public void test10_verifier(boolean warmup) {
 379         test10();
 380     }
 381 
 382     @Test
 383     public MyValue1 test11(MyValue1 vt) {
 384         try {
 385             Object o = vt;
 386             vt = (MyValue1)o;
 387             throw new RuntimeException("NullPointerException expected");
 388         } catch (NullPointerException e) {
 389             // Expected
 390         }
 391 
 392         // Should not throw
 393         vt = test11_dontinline(vt);
 394         vt = test11_inline(vt);
 395         return vt;
 396     }
 397 
 398     @DontCompile
 399     public void test11_verifier(boolean warmup) {
 400         MyValue1 vt = test11(nullField);
 401         Asserts.assertEquals((Object)vt, null);
 402     }
 403 
 404     @DontInline
 405     public MyValue1 test11_dontinline(MyValue1 vt) {
 406         return vt;
 407     }
 408 
 409     @ForceInline
 410     public MyValue1 test11_inline(MyValue1 vt) {
 411         return vt;
 412     }
 413 
 414     @Test
 415     public MyValue1 test12(Object obj) {
 416         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 417         try {
 418             vt = (MyValue1)obj;
 419             throw new RuntimeException("NullPointerException expected");
 420         } catch (NullPointerException e) {
 421             // Expected
 422         }
 423         return vt;
 424     }
 425 
 426     @DontCompile
 427     public void test12_verifier(boolean warmup) {
 428         MyValue1 vt = test12(null);
 429         Asserts.assertEquals(vt.hash(), hash());
 430     }
 431 
 432     private static final MethodHandle getNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
 433         "getNull",
 434         MethodType.methodType(MyValue1.class),
 435         CODE -> {
 436             CODE.
 437             aconst_null().
 438             areturn();
 439         }
 440         );
 441 
 442     @Test
 443     public void test13() throws Throwable {
 444         try {
 445             valueField1 = (MyValue1)getNull.invoke();
 446             throw new RuntimeException("NullPointerException expected");
 447         } catch (NullPointerException e) {
 448             // Expected
 449         }
 450 
 451         try {
 452             valueField1 = (MyValue1)GetNullAsm.invoke();
 453             throw new RuntimeException("NullPointerException expected");
 454         } catch (NullPointerException e) {
 455             // Expected
 456         }
 457 
 458         nullField = (MyValue1)getNull.invoke(); // Should not throw
 459         nullField = (MyValue1)GetNullAsm.invoke(); // Should not throw
 460     }
 461 
 462     @DontCompile
 463     public void test13_verifier(boolean warmup) throws Throwable {
 464         test13();
 465     }
 466 
 467     // null constant
 468     private static final MethodHandle setNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
 469         "setNull",
 470         MethodType.methodType(void.class, TestLWorld.class),
 471         CODE -> {
 472             CODE.
 473             aload_0().
 474             aconst_null().
 475             putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;").
 476             return_();
 477         }
 478         );
 479 
 480     @Test
 481     public void test14() throws Throwable {
 482         try {
 483             setNull.invoke(this);
 484             throw new RuntimeException("NullPointerException expected");
 485         } catch (NullPointerException e) {
 486             // Expected
 487         }
 488     }
 489 
 490     @DontCompile
 491     public void test14_verifier(boolean warmup) throws Throwable {
 492         test14();
 493     }
 494 
 495     // merge of 2 values, one being null
 496     @Test
 497     public void test15(boolean flag1) {
 498         MyValue1 v;
 499         if (flag1) {
 500             v = valueField1;
 501         } else {
 502             v = valueField5;
 503         }
 504         valueField1 = v;
 505     }
 506 
 507     @DontCompile
 508     public void test15_verifier(boolean warmup) {
 509         test15(true);
 510         try {
 511             test15(false);
 512             throw new RuntimeException("NullPointerException expected");
 513         } catch (NullPointerException e) {
 514             // Expected
 515         }
 516     }
 517 
 518     // null constant
 519     private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
 520         "mergeNull",
 521         MethodType.methodType(void.class, TestLWorld.class, boolean.class),
 522         CODE -> {
 523             CODE.
 524             iload_1().
 525             iconst_0().
 526             ifcmp(TypeTag.I, CondKind.EQ, "null").
 527             aload_0().
 528             getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;").
 529             goto_("continue").
 530             label("null").
 531             aconst_null().
 532             label("continue").
 533             aload_0().
 534             swap().
 535             putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;").
 536             return_();
 537         }
 538         );
 539 
 540     @Test
 541     public void test16(boolean flag) throws Throwable {
 542         mergeNull.invoke(this, flag);
 543     }
 544 
 545     @DontCompile
 546     public void test16_verifier(boolean warmup) throws Throwable {
 547         test16(true);
 548         try {
 549             test16(false);
 550             throw new RuntimeException("NullPointerException expected");
 551         } catch (NullPointerException e) {
 552             // Expected
 553         }
 554     }
 555 
 556     // merge of value and non value
 557     @Test
 558     public Object test17(boolean flag) {
 559         Object res = null;
 560         if (flag) {
 561             res = valueField1;
 562         } else {
 563             res = objectField1;
 564         }
 565         return res;
 566     }
 567 
 568     @DontCompile
 569     public void test17_verifier(boolean warmup) {
 570         test17(true);
 571         test17(false);
 572     }
 573 
 574     @Test
 575     public Object test18(boolean flag) {
 576         Object res = null;
 577         if (flag) {
 578             res = objectField1;
 579         } else {
 580             res = valueField1;
 581         }
 582         return res;
 583     }
 584 
 585     @DontCompile
 586     public void test18_verifier(boolean warmup) {
 587         test18(true);
 588         test18(false);
 589     }
 590 
 591     // null constant
 592     private static final MethodHandle mergeNull2 = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
 593         "mergeNull2",
 594         MethodType.methodType(void.class, TestLWorld.class, boolean.class),
 595         CODE -> {
 596             CODE.
 597             iload_1().
 598             iconst_0().
 599             ifcmp(TypeTag.I, CondKind.EQ, "not_null").
 600             aconst_null().
 601             goto_("continue").
 602             label("not_null").
 603             aload_0().
 604             getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;").
 605             label("continue").
 606             aload_0().
 607             swap().
 608             putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;").
 609             return_();
 610         }
 611         );
 612 
 613     @Test
 614     public void test19(boolean flag) throws Throwable {
 615         mergeNull2.invoke(this, flag);
 616     }
 617 
 618     @DontCompile
 619     public void test19_verifier(boolean warmup) throws Throwable {
 620         test19(false);
 621         try {
 622             test19(true);
 623             throw new RuntimeException("NullPointerException expected");
 624         } catch (NullPointerException e) {
 625             // Expected
 626         }
 627     }
 628 
 629     // merge of values in a loop, stored in an object local
 630     @Test
 631     public Object test20() {
 632         Object o = valueField1;
 633         for (int i = 1; i < 100; i *= 2) {
 634             MyValue1 v = (MyValue1)o;
 635             o = MyValue1.setX(v, v.x + 1);
 636         }
 637         return o;
 638     }
 639 
 640     @DontCompile
 641     public void test20_verifier(boolean warmup) {
 642         test20();
 643     }
 644 
 645     // merge of values in an object local
 646     public Object test21_helper() {
 647         return valueField1;
 648     }
 649 
 650     @Test(failOn = ALLOC + LOAD + STORE)
 651     public void test21(boolean flag) {
 652         Object o = null;
 653         if (flag) {
 654             o = valueField1;
 655         } else {
 656             o = test21_helper();
 657         }
 658         valueField1 = (MyValue1)o;
 659     }
 660 
 661     @DontCompile
 662     public void test21_verifier(boolean warmup) {
 663         test21(true);
 664         test21(false);
 665     }
 666 
 667     // null return
 668     int test_22_cnt;
 669 
 670     @DontInline
 671     public MyValue1 test22_helper() {
 672         test_22_cnt++;
 673         return valueField5;
 674     }
 675 
 676     @Test
 677     public void test22() {
 678         valueField1 = test22_helper();
 679     }
 680 
 681     @DontCompile
 682     public void test22_verifier(boolean warmup) {
 683         try {
 684             test_22_cnt = 0;
 685             test22();
 686             throw new RuntimeException("NullPointerException expected");
 687         } catch (NullPointerException e) {
 688             // Expected
 689         }
 690         if (test_22_cnt != 1) {
 691             throw new RuntimeException("call executed twice");
 692         }
 693     }
 694 
 695     // null return at virtual call
 696     class A {
 697         public MyValue1 test23_helper() {
 698             return valueField5;
 699         }
 700     }
 701 
 702     class B extends A {
 703         public MyValue1 test23_helper() {
 704             return valueField5;
 705         }
 706     }
 707 
 708     class C extends A {
 709         public MyValue1 test23_helper() {
 710             return valueField5;
 711         }
 712     }
 713 
 714     class D extends A {
 715         public MyValue1 test23_helper() {
 716             return valueField5;
 717         }
 718     }
 719 
 720     @Test
 721     public void test23(A a) {
 722         valueField1 = a.test23_helper();
 723     }
 724 
 725     @DontCompile
 726     public void test23_verifier(boolean warmup) {
 727         A b = new B();
 728         A c = new C();
 729         A d = new D();
 730         try {
 731             test23(b);
 732             throw new RuntimeException("NullPointerException expected");
 733         } catch (NullPointerException e) {
 734             // Expected
 735         }
 736         try {
 737             test23(c);
 738             throw new RuntimeException("NullPointerException expected");
 739         } catch (NullPointerException e) {
 740             // Expected
 741         }
 742         try {
 743             test23(d);
 744             throw new RuntimeException("NullPointerException expected");
 745         } catch (NullPointerException e) {
 746             // Expected
 747         }
 748     }
 749 
 750 
 751     // Interface tests
 752 
 753     @DontInline
 754     public MyInterface test24_dontinline1(MyInterface o) {
 755         return o;
 756     }
 757 
 758     @DontInline
 759     public MyValue1 test24_dontinline2(MyInterface o) {
 760         return (MyValue1)o;
 761     }
 762 
 763     @ForceInline
 764     public MyInterface test24_inline1(MyInterface o) {
 765         return o;
 766     }
 767 
 768     @ForceInline
 769     public MyValue1 test24_inline2(MyInterface o) {
 770         return (MyValue1)o;
 771     }
 772 
 773     @Test()
 774     public MyValue1 test24() {
 775         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 776         vt = (MyValue1)test24_dontinline1(vt);
 777         vt =           test24_dontinline2(vt);
 778         vt = (MyValue1)test24_inline1(vt);
 779         vt =           test24_inline2(vt);
 780         return vt;
 781     }
 782 
 783     @DontCompile
 784     public void test24_verifier(boolean warmup) {
 785         Asserts.assertEQ(test24().hash(), hash());
 786     }
 787 
 788     // Test storing/loading value types to/from interface and value type fields
 789     MyInterface interfaceField1 = null;
 790     MyInterface interfaceField2 = null;
 791     MyInterface interfaceField3 = null;
 792     MyInterface interfaceField4 = null;
 793     MyInterface interfaceField5 = null;
 794     MyInterface interfaceField6 = null;
 795 
 796     @DontInline
 797     public MyInterface readValueField5AsInterface() {
 798         return (MyInterface)valueField5;
 799     }
 800 
 801     @DontInline
 802     public MyInterface readStaticValueField4AsInterface() {
 803         return (MyInterface)staticValueField4;
 804     }
 805 
 806     @Test()
 807     public long test25(MyValue1 vt1, MyInterface vt2) {
 808         interfaceField1 = vt1;
 809         interfaceField2 = (MyValue1)vt2;
 810         interfaceField3 = MyValue1.createWithFieldsInline(rI, rL);
 811         interfaceField4 = MyValue1.createWithFieldsDontInline(rI, rL);
 812         interfaceField5 = valueField1;
 813         interfaceField6 = valueField3;
 814         valueField1 = (MyValue1)interfaceField1;
 815         valueField2 = (MyValue1)vt2;
 816         valueField3 = (MyValue1)vt2;
 817         staticValueField1 = (MyValue1)interfaceField1;
 818         staticValueField2 = (MyValue1)vt1;
 819         // Don't inline these methods because reading NULL will trigger a deoptimization
 820         if (readValueField5AsInterface() != null || readStaticValueField4AsInterface() != null) {
 821             throw new RuntimeException("Should be null");
 822         }
 823         return ((MyValue1)interfaceField1).hash() + ((MyValue1)interfaceField2).hash() +
 824                ((MyValue1)interfaceField3).hash() + ((MyValue1)interfaceField4).hash() +
 825                ((MyValue1)interfaceField5).hash() + ((MyValue1)interfaceField6).hash() +
 826                 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() +
 827                 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive();
 828     }
 829 
 830     @DontCompile
 831     public void test25_verifier(boolean warmup) {
 832         MyValue1 vt = testValue1;
 833         MyValue1 def = MyValue1.createDefaultDontInline();
 834         long result = test25(vt, vt);
 835         Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive());
 836     }
 837 
 838     class MyObject implements MyInterface {
 839         public int x;
 840 
 841         public MyObject(int x) {
 842             this.x = x;
 843         }
 844 
 845         @ForceInline
 846         public long hash() {
 847             return x;
 848         }
 849     }
 850 
 851     // Test merging value types and interfaces
 852     @Test()
 853     public MyInterface test26(int state) {
 854         MyInterface res = null;
 855         if (state == 0) {
 856             res = new MyObject(rI);
 857         } else if (state == 1) {
 858             res = MyValue1.createWithFieldsInline(rI, rL);
 859         } else if (state == 2) {
 860             res = MyValue1.createWithFieldsDontInline(rI, rL);
 861         } else if (state == 3) {
 862             res = (MyValue1)objectField1;
 863         } else if (state == 4) {
 864             res = valueField1;
 865         } else if (state == 5) {
 866             res = null;
 867         }
 868         return res;
 869     }
 870 
 871     @DontCompile
 872     public void test26_verifier(boolean warmup) {
 873         objectField1 = valueField1;
 874         MyInterface result = null;
 875         result = test26(0);
 876         Asserts.assertEQ(((MyObject)result).x, rI);
 877         result = test26(1);
 878         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 879         result = test26(2);
 880         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 881         result = test26(3);
 882         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 883         result = test26(4);
 884         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 885         result = test26(5);
 886         Asserts.assertEQ(result, null);
 887     }
 888 
 889     // Test merging value types and interfaces in loops
 890     @Test()
 891     public MyInterface test27(int iters) {
 892         MyInterface res = new MyObject(rI);
 893         for (int i = 0; i < iters; ++i) {
 894             if (res instanceof MyObject) {
 895                 res = MyValue1.createWithFieldsInline(rI, rL);
 896             } else {
 897                 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL);
 898             }
 899         }
 900         return res;
 901     }
 902 
 903     @DontCompile
 904     public void test27_verifier(boolean warmup) {
 905         MyObject result1 = (MyObject)test27(0);
 906         Asserts.assertEQ(result1.x, rI);
 907         int iters = (Math.abs(rI) % 10) + 1;
 908         MyValue1 result2 = (MyValue1)test27(iters);
 909         MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL);
 910         Asserts.assertEQ(result2.hash(), vt.hash());
 911     }
 912 
 913     // Test value types in interface variables that are live at safepoint
 914     @Test(failOn = ALLOC + STORE + LOOP)
 915     public long test28(MyValue1 arg, boolean deopt) {
 916         MyInterface vt1 = MyValue1.createWithFieldsInline(rI, rL);
 917         MyInterface vt2 = MyValue1.createWithFieldsDontInline(rI, rL);
 918         MyInterface vt3 = arg;
 919         MyInterface vt4 = valueField1;
 920         if (deopt) {
 921             // uncommon trap
 922             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test5"));
 923         }
 924         return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() +
 925                ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash();
 926     }
 927 
 928     @DontCompile
 929     public void test28_verifier(boolean warmup) {
 930         long result = test28(valueField1, !warmup);
 931         Asserts.assertEQ(result, 4*hash());
 932     }
 933 
 934     // Test comparing value types with interfaces
 935     @Test(failOn = ALLOC + LOAD + STORE + LOOP)
 936     public boolean test29(Object arg) {
 937         MyInterface vt = MyValue1.createWithFieldsInline(rI, rL);
 938         if (vt == arg || vt == (MyInterface)valueField1 || vt == interfaceField1 || vt == null ||
 939             arg == vt || (MyInterface)valueField1 == vt || interfaceField1 == vt || null == vt) {
 940             return true;
 941         }
 942         return false;
 943     }
 944 
 945     @DontCompile
 946     public void test29_verifier(boolean warmup) {
 947         boolean result = test29(null);
 948         Asserts.assertFalse(result);
 949     }
 950 
 951     // Test subtype check when casting to value type
 952     @Test
 953     public MyValue1 test30(MyValue1 vt, Object obj) {
 954         try {
 955             vt = (MyValue1)obj;
 956             throw new RuntimeException("ClassCastException expected");
 957         } catch (ClassCastException e) {
 958             // Expected
 959         }
 960         return vt;
 961     }
 962 
 963     @DontCompile
 964     public void test30_verifier(boolean warmup) {
 965         MyValue1 vt = testValue1;
 966         MyValue1 result = test30(vt, new Integer(rI));
 967         Asserts.assertEquals(result.hash(), vt.hash());
 968     }
 969 
 970     @Test
 971     public MyValue1 test31(MyValue1 vt) {
 972         Object obj = vt;
 973         vt = (MyValue1)obj;
 974         return vt;
 975     }
 976 
 977     @DontCompile
 978     public void test31_verifier(boolean warmup) {
 979         MyValue1 vt = testValue1;
 980         MyValue1 result = test31(vt);
 981         Asserts.assertEquals(result.hash(), vt.hash());
 982     }
 983 
 984     @Test
 985     public void test32(MyValue1 vt) {
 986         Object obj = vt;
 987         try {
 988             MyValue2 vt2 = (MyValue2)obj;
 989             throw new RuntimeException("ClassCastException expected");
 990         } catch (ClassCastException e) {
 991             // Expected
 992         }
 993     }
 994 
 995     @DontCompile
 996     public void test32_verifier(boolean warmup) {
 997         test32(valueField1);
 998     }
 999 
1000     @Test
1001     public void test33(MyValue1 vt) {
1002         Object obj = vt;
1003         try {
1004             Integer i = (Integer)obj;
1005             throw new RuntimeException("ClassCastException expected");
1006         } catch (ClassCastException e) {
1007             // Expected
1008         }
1009     }
1010 
1011     @DontCompile
1012     public void test33_verifier(boolean warmup) {
1013         test33(valueField1);
1014     }
1015 
1016 
1017     // Array tests
1018 
1019     private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1,
1020                                                                       testValue1,
1021                                                                       testValue1};
1022 
1023     private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array,
1024                                                                            testValue1Array,
1025                                                                            testValue1Array};
1026 
1027     private static final MyValue2[] testValue2Array = new MyValue2[] {testValue2,
1028                                                                       testValue2,
1029                                                                       testValue2};
1030 
1031     private static final Integer[] testIntegerArray = new Integer[42];
1032 
1033     // Test load from (flattened) value type array disguised as object array
1034     @Test()
1035     public Object test34(Object[] oa, int index) {
1036         return oa[index];
1037     }
1038 
1039     @DontCompile
1040     public void test34_verifier(boolean warmup) {
1041         MyValue1 result = (MyValue1)test34(testValue1Array, Math.abs(rI) % 3);
1042         Asserts.assertEQ(result.hash(), hash());
1043     }
1044 
1045     // Test load from (flattened) value type array disguised as interface array
1046     @Test()
1047     public Object test35(MyInterface[] ia, int index) {
1048         return ia[index];
1049     }
1050 
1051     @DontCompile
1052     public void test35_verifier(boolean warmup) {
1053         MyValue1 result = (MyValue1)test35(testValue1Array, Math.abs(rI) % 3);
1054         Asserts.assertEQ(result.hash(), hash());
1055     }
1056 
1057     // Test value store to (flattened) value type array disguised as object array
1058 
1059     @ForceInline
1060     public void test36_inline(Object[] oa, Object o, int index) {
1061         oa[index] = o;
1062     }
1063 
1064     @Test()
1065     public void test36(Object[] oa, MyValue1 vt, int index) {
1066         test36_inline(oa, vt, index);
1067     }
1068 
1069     @DontCompile
1070     public void test36_verifier(boolean warmup) {
1071         int index = Math.abs(rI) % 3;
1072         MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1073         test36(testValue1Array, vt, index);
1074         Asserts.assertEQ(testValue1Array[index].hash(), vt.hash());
1075         testValue1Array[index] = testValue1;
1076         try {
1077             test36(testValue2Array, vt, index);
1078             throw new RuntimeException("No ArrayStoreException thrown");
1079         } catch (ArrayStoreException e) {
1080             // Expected
1081         }
1082         Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash());
1083     }
1084 
1085     @ForceInline
1086     public void test37_inline(Object[] oa, Object o, int index) {
1087         oa[index] = o;
1088     }
1089 
1090     @Test()
1091     public void test37(Object[] oa, MyValue1 vt, int index) {
1092         test37_inline(oa, vt, index);
1093     }
1094 
1095     @DontCompile
1096     public void test37_verifier(boolean warmup) {
1097         int index = Math.abs(rI) % 3;
1098         try {
1099             test37(testIntegerArray, testValue1, index);
1100             throw new RuntimeException("No ArrayStoreException thrown");
1101         } catch (ArrayStoreException e) {
1102             // Expected
1103         }
1104     }
1105 
1106     @ForceInline
1107     public void test38_inline(Object[] oa, Object o, int index) {
1108         oa[index] = o;
1109     }
1110 
1111     @Test()
1112     public void test38(Object[] oa, MyValue1 vt, int index) {
1113         test38_inline(oa, vt, index);
1114     }
1115 
1116     @DontCompile
1117     public void test38_verifier(boolean warmup) {
1118         int index = Math.abs(rI) % 3;
1119         try {
1120             test38(null, testValue1, index);
1121             throw new RuntimeException("No NPE thrown");
1122         } catch (NullPointerException e) {
1123             // Expected
1124         }
1125     }
1126 
1127     // Test value store to (flattened) value type array disguised as interface array
1128 
1129     @ForceInline
1130     public void test39_inline(MyInterface[] ia, MyInterface i, int index) {
1131         ia[index] = i;
1132     }
1133 
1134     @Test()
1135     public void test39(MyInterface[] ia, MyValue1 vt, int index) {
1136       test39_inline(ia, vt, index);
1137     }
1138 
1139     @DontCompile
1140     public void test39_verifier(boolean warmup) {
1141         int index = Math.abs(rI) % 3;
1142         MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1143         test39(testValue1Array, vt, index);
1144         Asserts.assertEQ(testValue1Array[index].hash(), vt.hash());
1145         testValue1Array[index] = testValue1;
1146         try {
1147             test39(testValue2Array, vt, index);
1148             throw new RuntimeException("No ArrayStoreException thrown");
1149         } catch (ArrayStoreException e) {
1150             // Expected
1151         }
1152         Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash());
1153     }
1154 
1155     @ForceInline
1156     public void test40_inline(MyInterface[] ia, MyInterface i, int index) {
1157         ia[index] = i;
1158     }
1159 
1160     @Test()
1161     public void test40(MyInterface[] ia, MyValue1 vt, int index) {
1162         test40_inline(ia, vt, index);
1163     }
1164 
1165     @DontCompile
1166     public void test40_verifier(boolean warmup) {
1167         int index = Math.abs(rI) % 3;
1168         try {
1169             test40(null, testValue1, index);
1170             throw new RuntimeException("No NPE thrown");
1171         } catch (NullPointerException e) {
1172             // Expected
1173         }
1174     }
1175 
1176     // Test object store to (flattened) value type array disguised as object array
1177 
1178     @ForceInline
1179     public void test41_inline(Object[] oa, Object o, int index) {
1180         oa[index] = o;
1181     }
1182 
1183     @Test()
1184     public void test41(Object[] oa, Object o, int index) {
1185         test41_inline(oa, o, index);
1186     }
1187 
1188     @DontCompile
1189     public void test41_verifier(boolean warmup) {
1190         int index = Math.abs(rI) % 3;
1191         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1192         test41(testValue1Array, vt1, index);
1193         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1194         try {
1195             test41(testValue1Array, testValue2, index);
1196             throw new RuntimeException("No ArrayStoreException thrown");
1197         } catch (ArrayStoreException e) {
1198             // Expected
1199         }
1200         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1201         testValue1Array[index] = testValue1;
1202     }
1203 
1204     @ForceInline
1205     public void test42_inline(Object[] oa, Object o, int index) {
1206         oa[index] = o;
1207     }
1208 
1209     @Test()
1210     public void test42(Object[] oa, Object o, int index) {
1211         test42_inline(oa, o, index);
1212     }
1213 
1214     @DontCompile
1215     public void test42_verifier(boolean warmup) {
1216         int index = Math.abs(rI) % 3;
1217         try {
1218             test42(testValue2Array, testValue1, index);
1219             throw new RuntimeException("No ArrayStoreException thrown");
1220         } catch (ArrayStoreException e) {
1221             // Expected
1222         }
1223         Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash());
1224     }
1225 
1226     @ForceInline
1227     public void test43_inline(Object[] oa, Object o, int index) {
1228         oa[index] = o;
1229     }
1230 
1231     @Test()
1232     public void test43(Object[] oa, Object o, int index) {
1233         test43_inline(oa, o, index);
1234     }
1235 
1236     @DontCompile
1237     public void test43_verifier(boolean warmup) {
1238         int index = Math.abs(rI) % 3;
1239         try {
1240             test43(testIntegerArray, testValue1, index);
1241             throw new RuntimeException("No ArrayStoreException thrown");
1242         } catch (ArrayStoreException e) {
1243             // Expected
1244         }
1245     }
1246 
1247     // Test value store to (flattened) value type array disguised as interface array
1248 
1249     @ForceInline
1250     public void test43_inline(MyInterface[] ia, MyInterface i, int index) {
1251         ia[index] = i;
1252     }
1253 
1254     @Test()
1255     public void test44(MyInterface[] ia, MyInterface i, int index) {
1256         test43_inline(ia, i, index);
1257     }
1258 
1259     @DontCompile
1260     public void test44_verifier(boolean warmup) {
1261         int index = Math.abs(rI) % 3;
1262         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1263         test44(testValue1Array, vt1, index);
1264         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1265         try {
1266             test44(testValue1Array, testValue2, index);
1267             throw new RuntimeException("No ArrayStoreException thrown");
1268         } catch (ArrayStoreException e) {
1269             // Expected
1270         }
1271         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1272         testValue1Array[index] = testValue1;
1273     }
1274 
1275     @ForceInline
1276     public void test45_inline(MyInterface[] ia, MyInterface i, int index) {
1277         ia[index] = i;
1278     }
1279 
1280     @Test()
1281     public void test45(MyInterface[] ia, MyInterface i, int index) {
1282         test45_inline(ia, i, index);
1283     }
1284 
1285     @DontCompile
1286     public void test45_verifier(boolean warmup) {
1287         int index = Math.abs(rI) % 3;
1288         try {
1289             test45(testValue2Array, testValue1, index);
1290             throw new RuntimeException("No ArrayStoreException thrown");
1291         } catch (ArrayStoreException e) {
1292             // Expected
1293         }
1294     }
1295 
1296     // Test writing null to a (flattened) value type array disguised as object array
1297 
1298     @ForceInline
1299     public void test46_inline(Object[] oa, Object o, int index) {
1300         oa[index] = o;
1301     }
1302 
1303     @Test()
1304     public void test46(Object[] oa, Object o, int index) {
1305         test46_inline(oa, o, index);
1306     }
1307 
1308     @DontCompile
1309     public void test46_verifier(boolean warmup) {
1310         int index = Math.abs(rI) % 3;
1311         try {
1312             test46(testValue1Array, null, index);
1313             throw new RuntimeException("No NPE thrown");
1314         } catch (NullPointerException e) {
1315             // Expected
1316         }
1317         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1318     }
1319 
1320     // Test writing constant null to a (flattened) value type array disguised as object array
1321 
1322     @ForceInline
1323     public void test47_inline(Object[] oa, Object o, int index) {
1324         oa[index] = o;
1325     }
1326 
1327     @Test()
1328     public void test47(Object[] oa, int index) {
1329         test47_inline(oa, null, index);
1330     }
1331 
1332     @DontCompile
1333     public void test47_verifier(boolean warmup) {
1334         int index = Math.abs(rI) % 3;
1335         try {
1336             test47(testValue1Array, index);
1337             throw new RuntimeException("No NPE thrown");
1338         } catch (NullPointerException e) {
1339             // Expected
1340         }
1341         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1342     }
1343 
1344     // Test writing null to a (flattened) value type array
1345 
1346     @ForceInline
1347     public void test48_inline(Object[] oa, Object o, int index) {
1348         oa[index] = o;
1349     }
1350 
1351     @Test()
1352     public void test48(MyValue1[] va, int index) {
1353         test48_inline(va, nullField, index);
1354     }
1355 
1356     @DontCompile
1357     public void test48_verifier(boolean warmup) {
1358         int index = Math.abs(rI) % 3;
1359         try {
1360             test48(testValue1Array, index);
1361             throw new RuntimeException("No NPE thrown");
1362         } catch (NullPointerException e) {
1363             // Expected
1364         }
1365         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1366     }
1367 
1368     // Test writing constant null to a (flattened) value type array
1369 
1370     private static final MethodHandle setArrayElementNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
1371         "setArrayElementNull",
1372         MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class),
1373         CODE -> {
1374             CODE.
1375             aload_1().
1376             iload_2().
1377             aconst_null().
1378             aastore().
1379             return_();
1380         }
1381         );
1382 
1383     @Test()
1384     public void test49(MyValue1[] va, int index) throws Throwable {
1385         setArrayElementNull.invoke(this, va, index);
1386     }
1387 
1388     @DontCompile
1389     public void test49_verifier(boolean warmup) throws Throwable {
1390         int index = Math.abs(rI) % 3;
1391         try {
1392             test49(testValue1Array, index);
1393             throw new RuntimeException("No NPE thrown");
1394         } catch (NullPointerException e) {
1395             // Expected
1396         }
1397         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1398     }
1399 
1400     // Test writing a value type to a null value type array
1401     @Test()
1402     public void test50(MyValue1[] va, MyValue1 vt, int index) {
1403         va[index] = vt;
1404     }
1405 
1406     @DontCompile
1407     public void test50_verifier(boolean warmup) {
1408         int index = Math.abs(rI) % 3;
1409         try {
1410             test50(null, testValue1Array[index], index);
1411             throw new RuntimeException("No NPE thrown");
1412         } catch (NullPointerException e) {
1413             // Expected
1414         }
1415     }
1416 
1417     // Test incremental inlining
1418 
1419     @ForceInline
1420     public void test51_inline(Object[] oa, Object o, int index) {
1421         oa[index] = o;
1422     }
1423 
1424     @Test()
1425     public void test51(MyValue1[] va, Object o, int index) {
1426         test51_inline(va, o, index);
1427     }
1428 
1429     @DontCompile
1430     public void test51_verifier(boolean warmup) {
1431         int index = Math.abs(rI) % 3;
1432         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1433         test51(testValue1Array, vt1, index);
1434         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1435         try {
1436             test51(testValue1Array, testValue2, index);
1437             throw new RuntimeException("No ArrayStoreException thrown");
1438         } catch (ArrayStoreException e) {
1439             // Expected
1440         }
1441         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1442         testValue1Array[index] = testValue1;
1443     }
1444 
1445     // Test merging of value type arrays
1446 
1447     @ForceInline
1448     public Object[] test52_inline() {
1449         return new MyValue1[42];
1450     }
1451 
1452     @Test()
1453     public Object[] test52(Object[] oa, Object o, int i1, int i2, int num) {
1454         Object[] result = null;
1455         switch (num) {
1456         case 0:
1457             result = test52_inline();
1458             break;
1459         case 1:
1460             result = oa;
1461             break;
1462         case 2:
1463             result = testValue1Array;
1464             break;
1465         case 3:
1466             result = testValue2Array;
1467             break;
1468         case 4:
1469             result = testIntegerArray;
1470             break;
1471         case 5:
1472             result = null;
1473             break;
1474         case 6:
1475             result = testValue1Array2;
1476             break;
1477         }
1478         result[i1] = result[i2];
1479         result[i2] = o;
1480         return result;
1481     }
1482 
1483     @DontCompile
1484     public void test52_verifier(boolean warmup) {
1485         int index = Math.abs(rI) % 3;
1486         MyValue1[] va = new MyValue1[42];
1487         Object[] result = test52(null, testValue1, index, index, 0);
1488         Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash());
1489         result = test52(testValue1Array, testValue1, index, index, 1);
1490         Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash());
1491         result = test52(null, testValue1, index, index, 2);
1492         Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash());
1493         result = test52(null, testValue2, index, index, 3);
1494         Asserts.assertEQ(((MyValue2)result[index]).hash(), testValue2.hash());
1495         try {
1496             result = test52(null, null, index, index, 3);
1497             throw new RuntimeException("No NPE thrown");
1498         } catch (NullPointerException e) {
1499             // Expected
1500         }
1501         result = test52(null, null, index, index, 4);
1502         try {
1503             result = test52(null, testValue1, index, index, 4);
1504             throw new RuntimeException("No ArrayStoreException thrown");
1505         } catch (ArrayStoreException e) {
1506             // Expected
1507         }
1508         try {
1509             result = test52(null, testValue1, index, index, 5);
1510             throw new RuntimeException("No NPE thrown");
1511         } catch (NullPointerException e) {
1512             // Expected
1513         }
1514         result = test52(null, testValue1Array, index, index, 6);
1515         Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash());
1516     }
1517 
1518     // Same as above but merging into Object instead of Object[]
1519     @Test()
1520     public Object test53(Object oa, Object o, int i1, int i2, int num) {
1521         Object result = null;
1522         switch (num) {
1523         case 0:
1524             result = test52_inline();
1525             break;
1526         case 1:
1527             result = oa;
1528             break;
1529         case 2:
1530             result = testValue1Array;
1531             break;
1532         case 3:
1533             result = testValue2Array;
1534             break;
1535         case 4:
1536             result = testIntegerArray;
1537             break;
1538         case 5:
1539             result = null;
1540             break;
1541         case 6:
1542             result = testValue1;
1543             break;
1544         case 7:
1545             result = testValue2;
1546             break;
1547         case 8:
1548             result = MyValue1.createWithFieldsInline(rI, rL);
1549             break;
1550         case 9:
1551             result = new Integer(42);
1552             break;
1553         case 10:
1554             result = testValue1Array2;
1555             break;
1556         }
1557         if (result instanceof Object[]) {
1558             ((Object[])result)[i1] = ((Object[])result)[i2];
1559             ((Object[])result)[i2] = o;
1560         }
1561         return result;
1562     }
1563 
1564     @DontCompile
1565     public void test53_verifier(boolean warmup) {
1566         int index = Math.abs(rI) % 3;
1567         MyValue1[] va = new MyValue1[42];
1568         Object result = test53(null, testValue1, index, index, 0);
1569         Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash());
1570         result = test53(testValue1Array, testValue1, index, index, 1);
1571         Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash());
1572         result = test53(null, testValue1, index, index, 2);
1573         Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash());
1574         result = test53(null, testValue2, index, index, 3);
1575         Asserts.assertEQ(((MyValue2[])result)[index].hash(), testValue2.hash());
1576         try {
1577             result = test53(null, null, index, index, 3);
1578             throw new RuntimeException("No NPE thrown");
1579         } catch (NullPointerException e) {
1580             // Expected
1581         }
1582         result = test53(null, null, index, index, 4);
1583         try {
1584             result = test53(null, testValue1, index, index, 4);
1585             throw new RuntimeException("No ArrayStoreException thrown");
1586         } catch (ArrayStoreException e) {
1587             // Expected
1588         }
1589         result = test53(null, testValue1, index, index, 5);
1590         Asserts.assertEQ(result, null);
1591         result = test53(null, testValue1, index, index, 6);
1592         Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash());
1593         result = test53(null, testValue1, index, index, 7);
1594         Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash());
1595         result = test53(null, testValue1, index, index, 8);
1596         Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash());
1597         result = test53(null, testValue1, index, index, 9);
1598         Asserts.assertEQ(((Integer)result), 42);
1599         result = test53(null, testValue1Array, index, index, 10);
1600         Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash());
1601     }
1602 
1603     // Test instanceof with value types and arrays
1604     @Test()
1605     public long test54(Object o, int index) {
1606         if (o instanceof MyValue1) {
1607           return ((MyValue1)o).hashInterpreted();
1608         } else if (o instanceof MyValue1[]) {
1609           return ((MyValue1[])o)[index].hashInterpreted();
1610         } else if (o instanceof MyValue2) {
1611           return ((MyValue2)o).hash();
1612         } else if (o instanceof MyValue2[]) {
1613           return ((MyValue2[])o)[index].hash();
1614         } else if (o instanceof MyValue1[][]) {
1615           return ((MyValue1[][])o)[index][index].hash();
1616         } else if (o instanceof Long) {
1617           return (long)o;
1618         }
1619         return 0;
1620     }
1621 
1622     @DontCompile
1623     public void test54_verifier(boolean warmup) {
1624         int index = Math.abs(rI) % 3;
1625         long result = test54(testValue1, 0);
1626         Asserts.assertEQ(result, testValue1.hash());
1627         result = test54(testValue1Array, index);
1628         Asserts.assertEQ(result, testValue1.hash());
1629         result = test54(testValue2, index);
1630         Asserts.assertEQ(result, testValue2.hash());
1631         result = test54(testValue2Array, index);
1632         Asserts.assertEQ(result, testValue2.hash());
1633         result = test54(testValue1Array2, index);
1634         Asserts.assertEQ(result, testValue1.hash());
1635         result = test54(new Long(42), index);
1636         Asserts.assertEQ(result, 42L);
1637     }
1638 
1639     // Test for bug in Escape Analysis
1640     @DontInline
1641     public void test55_dontinline(Object o) {
1642         Asserts.assertEQ(o, rI);
1643     }
1644 
1645     @Test()
1646     public void test55() {
1647         MyValue1[] vals = new MyValue1[] {testValue1};
1648         test55_dontinline(vals[0].oa[0]);
1649         test55_dontinline(vals[0].oa[0]);
1650     }
1651 
1652     @DontCompile
1653     public void test55_verifier(boolean warmup) {
1654         test55();
1655     }
1656 
1657     // Test for bug in Escape Analysis
1658     private static __NotFlattened final MyValue1 test56VT1 = MyValue1.createWithFieldsInline(rI, rL);
1659     private static __NotFlattened final MyValue1 test56VT2 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1660 
1661     @Test()
1662     public void test56() {
1663         MyValue1[] vals = new MyValue1[] {test56VT1, test56VT2};
1664         Asserts.assertEQ(vals[0].hash(), test56VT1.hash());
1665         Asserts.assertEQ(vals[1].hash(), test56VT2.hash());
1666     }
1667 
1668     @DontCompile
1669     public void test56_verifier(boolean warmup) {
1670         if (!warmup) test56(); // We need -Xcomp behavior
1671     }
1672 
1673     // Test for bug in Escape Analysis
1674     @Test()
1675     public long test57(boolean deopt) {
1676         MyValue1[] vals = new MyValue1[] {test56VT1, test56VT2};
1677 
1678         if (deopt) {
1679             // uncommon trap
1680             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test57"));
1681             Asserts.assertEQ(vals[0].hash(), test56VT1.hash());
1682             Asserts.assertEQ(vals[1].hash(), test56VT2.hash());
1683         }
1684 
1685         return vals[0].hash();
1686     }
1687 
1688     @DontCompile
1689     public void test57_verifier(boolean warmup) {
1690         test57(!warmup);
1691     }
1692 
1693     // Tests writing an array element with a (statically known) incompatible type
1694     private static final MethodHandle setArrayElementIncompatible = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
1695         "setArrayElementIncompatible",
1696         MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class),
1697         CODE -> {
1698             CODE.
1699             aload_1().
1700             iload_2().
1701             aload_3().
1702             aastore().
1703             return_();
1704         }
1705         );
1706 
1707     @Test()
1708     public void test58(MyValue1[] va, int index, MyValue2 v) throws Throwable {
1709         setArrayElementIncompatible.invoke(this, va, index, v);
1710     }
1711 
1712     @DontCompile
1713     public void test58_verifier(boolean warmup) throws Throwable {
1714         int index = Math.abs(rI) % 3;
1715         try {
1716             test58(testValue1Array, index, testValue2);
1717             throw new RuntimeException("No ArrayStoreException thrown");
1718         } catch (ArrayStoreException e) {
1719             // Expected
1720         }
1721         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1722     }
1723 
1724     // Tests writing an array element with a (statically known) incompatible type
1725     @ForceInline
1726     public void test59_inline(Object[] oa, Object o, int index) {
1727         oa[index] = o;
1728     }
1729 
1730     @Test()
1731     public void test59(MyValue1[] va, int index, MyValue2 v) throws Throwable {
1732         test59_inline(va, v, index);
1733     }
1734 
1735     @DontCompile
1736     public void test59_verifier(boolean warmup) throws Throwable {
1737         int index = Math.abs(rI) % 3;
1738         try {
1739             test59(testValue1Array, index, testValue2);
1740             throw new RuntimeException("No ArrayStoreException thrown");
1741         } catch (ArrayStoreException e) {
1742             // Expected
1743         }
1744         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1745     }
1746 
1747     // instanceof tests with values
1748     @Test
1749     public boolean test60(MyValue1 vt) {
1750         Object obj = vt;
1751         return obj instanceof MyValue1;
1752     }
1753 
1754     @DontCompile
1755     public void test60_verifier(boolean warmup) {
1756         MyValue1 vt = testValue1;
1757         boolean result = test60(vt);
1758         Asserts.assertTrue(result);
1759     }
1760 
1761     @Test
1762     public boolean test61(MyValue1 vt) {
1763         Object obj = vt;
1764         return obj instanceof MyValue2;
1765     }
1766 
1767     @DontCompile
1768     public void test61_verifier(boolean warmup) {
1769         MyValue1 vt = testValue1;
1770         boolean result = test61(vt);
1771         Asserts.assertFalse(result);
1772     }
1773 
1774     @Test
1775     public boolean test62(Object obj) {
1776         return obj instanceof MyValue1;
1777     }
1778 
1779     @DontCompile
1780     public void test62_verifier(boolean warmup) {
1781         MyValue1 vt = testValue1;
1782         boolean result = test62(vt);
1783         Asserts.assertTrue(result);
1784     }
1785 
1786     @Test
1787     public boolean test63(Object obj) {
1788         return obj instanceof MyValue2;
1789     }
1790 
1791     @DontCompile
1792     public void test63_verifier(boolean warmup) {
1793         MyValue1 vt = testValue1;
1794         boolean result = test63(vt);
1795         Asserts.assertFalse(result);
1796     }
1797 
1798     @Test
1799     public boolean test64(Object obj) {
1800         return obj instanceof MyValue1;
1801     }
1802 
1803     @DontCompile
1804     public void test64_verifier(boolean warmup) {
1805         boolean result = test63(new Integer(42));
1806         Asserts.assertFalse(result);
1807     }
1808 
1809     // Value type with some non-flattened fields
1810     __ByValue final class Test65Value {
1811         final Object objectField1 = null;
1812         final Object objectField2 = null;
1813         final Object objectField3 = null;
1814         final Object objectField4 = null;
1815         final Object objectField5 = null;
1816         final Object objectField6 = null;
1817 
1818         final __Flattenable  MyValue1 valueField1;
1819         final __Flattenable  MyValue1 valueField2;
1820         final __NotFlattened MyValue1 valueField3;
1821         final __Flattenable  MyValue1 valueField4;
1822         final __NotFlattened MyValue1 valueField5;
1823 
1824         private Test65Value() {
1825             valueField1 = testValue1;
1826             valueField2 = testValue1;
1827             valueField3 = testValue1;
1828             valueField4 = MyValue1.createDefaultDontInline();
1829             valueField5 = MyValue1.createDefaultDontInline();
1830         }
1831 
1832         public Test65Value init() {
1833             Test65Value vt = __WithField(this.valueField1, testValue1);
1834             vt = __WithField(vt.valueField2, testValue1);
1835             vt = __WithField(vt.valueField3, testValue1);
1836             return vt;
1837         }
1838 
1839         @ForceInline
1840         public long test(Test65Value holder, MyValue1 vt1, Object vt2) {
1841             holder = __WithField(holder.objectField1, vt1);
1842             holder = __WithField(holder.objectField2, (MyValue1)vt2);
1843             holder = __WithField(holder.objectField3, testValue1);
1844             holder = __WithField(holder.objectField4, MyValue1.createWithFieldsDontInline(rI, rL));
1845             holder = __WithField(holder.objectField5, holder.valueField1);
1846             holder = __WithField(holder.objectField6, holder.valueField3);
1847             holder = __WithField(holder.valueField1, (MyValue1)holder.objectField1);
1848             holder = __WithField(holder.valueField2, (MyValue1)vt2);
1849             holder = __WithField(holder.valueField3, (MyValue1)vt2);
1850 
1851             return ((MyValue1)holder.objectField1).hash() +
1852                    ((MyValue1)holder.objectField2).hash() +
1853                    ((MyValue1)holder.objectField3).hash() +
1854                    ((MyValue1)holder.objectField4).hash() +
1855                    ((MyValue1)holder.objectField5).hash() +
1856                    ((MyValue1)holder.objectField6).hash() +
1857                    holder.valueField1.hash() +
1858                    holder.valueField2.hash() +
1859                    holder.valueField3.hash() +
1860                    holder.valueField4.hashPrimitive();
1861         }
1862     }
1863 
1864     // Same as test2 but with field holder being a value type
1865     @Test()
1866     public long test65(Test65Value holder, MyValue1 vt1, Object vt2) {
1867         return holder.test(holder, vt1, vt2);
1868     }
1869 
1870     @DontCompile
1871     public void test65_verifier(boolean warmup) {
1872         MyValue1 vt = testValue1;
1873         MyValue1 def = MyValue1.createDefaultDontInline();
1874         Test65Value holder = __MakeDefault Test65Value();
1875         Asserts.assertEQ(testValue1.hash(), vt.hash());
1876         holder = holder.init();
1877         Asserts.assertEQ(holder.valueField1.hash(), vt.hash());
1878         long result = test65(holder, vt, vt);
1879         Asserts.assertEQ(result, 9*vt.hash() + def.hashPrimitive());
1880     }
1881 
1882     // Access non-flattened, uninitialized value type field with value type holder
1883     @Test()
1884     public void test66(Test65Value holder) {
1885         if ((Object)holder.valueField5 != null) {
1886             throw new RuntimeException("Should be null");
1887         }
1888     }
1889 
1890     @DontCompile
1891     public void test66_verifier(boolean warmup) {
1892         Test65Value vt = __MakeDefault Test65Value();
1893         test66(vt);
1894     }
1895 
1896     // Merging value types of different types
1897     @Test()
1898     public Object test67(Object o, boolean b) {
1899         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1900         return b ? vt : o;
1901     }
1902 
1903     @DontCompile
1904     public void test67_verifier(boolean warmup) {
1905         test67(new Object(), false);
1906         MyValue1 result = (MyValue1)test67(new Object(), true);
1907         Asserts.assertEQ(result.hash(), hash());
1908     }
1909 
1910     @Test()
1911     public Object test68(boolean b) {
1912         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1913         return b ? vt : testValue2;
1914     }
1915 
1916     @DontCompile
1917     public void test68_verifier(boolean warmup) {
1918         MyValue1 result1 = (MyValue1)test68(true);
1919         Asserts.assertEQ(result1.hash(), hash());
1920         MyValue2 result2 = (MyValue2)test68(false);
1921         Asserts.assertEQ(result2.hash(), testValue2.hash());
1922     }
1923 
1924     @Test()
1925     public Object test69(boolean b) {
1926         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI, rL);
1927         MyValue2 vt2 = MyValue2.createWithFieldsInline(rI, true);
1928         return b ? vt1 : vt2;
1929     }
1930 
1931     @DontCompile
1932     public void test69_verifier(boolean warmup) {
1933         MyValue1 result1 = (MyValue1)test69(true);
1934         Asserts.assertEQ(result1.hash(), hash());
1935         MyValue2 result2 = (MyValue2)test69(false);
1936         Asserts.assertEQ(result2.hash(), testValue2.hash());
1937     }
1938 
1939     // Test synchronization on value types
1940     @Test()
1941     public void test70(Object vt) {
1942         synchronized (vt) {
1943             throw new RuntimeException("test70 failed: synchronization on value type should not succeed");
1944         }
1945     }
1946 
1947     @DontCompile
1948     public void test70_verifier(boolean warmup) {
1949         try {
1950             test70(testValue1);
1951             throw new RuntimeException("test70 failed: no exception thrown");
1952         } catch (IllegalMonitorStateException ex) {
1953             // Expected
1954         }
1955     }
1956 
1957     @ForceInline
1958     public void test71_inline(Object vt) {
1959         synchronized (vt) {
1960             throw new RuntimeException("test71 failed: synchronization on value type should not succeed");
1961         }
1962     }
1963 
1964     @Test()
1965     public void test71(MyValue1 vt) {
1966         test71_inline(vt);
1967     }
1968 
1969     @DontCompile
1970     public void test71_verifier(boolean warmup) {
1971         try {
1972             test71(testValue1);
1973             throw new RuntimeException("test71 failed: no exception thrown");
1974         } catch (IllegalMonitorStateException ex) {
1975             // Expected
1976         }
1977     }
1978 
1979     @ForceInline
1980     public void test72_inline(Object vt) {
1981         synchronized (vt) {
1982             throw new RuntimeException("test72 failed: synchronization on value type should not succeed");
1983         }
1984     }
1985 
1986     @Test()
1987     public void test72() {
1988         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1989         test72_inline(vt);
1990     }
1991 
1992     @DontCompile
1993     public void test72_verifier(boolean warmup) {
1994         try {
1995             test72();
1996             throw new RuntimeException("test72 failed: no exception thrown");
1997         } catch (IllegalMonitorStateException ex) {
1998             // Expected
1999         }
2000     }
2001 
2002     @Test()
2003     public void test73(Object o, boolean b) {
2004         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2005         Object sync = b ? vt : o;
2006         synchronized (sync) {
2007             if (b) {
2008                 throw new RuntimeException("test73 failed: synchronization on value type should not succeed");
2009             }
2010         }
2011     }
2012 
2013     @DontCompile
2014     public void test73_verifier(boolean warmup) {
2015         test73(new Object(), false);
2016         try {
2017             test73(new Object(), true);
2018             throw new RuntimeException("test73 failed: no exception thrown");
2019         } catch (IllegalMonitorStateException ex) {
2020             // Expected
2021         }
2022     }
2023 
2024     @Test()
2025     public void test74(boolean b) {
2026         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2027         Object sync = b ? vt : testValue2;
2028         synchronized (sync) {
2029             throw new RuntimeException("test74 failed: synchronization on value type should not succeed");
2030         }
2031     }
2032 
2033     @DontCompile
2034     public void test74_verifier(boolean warmup) {
2035         try {
2036             test74(false);
2037             throw new RuntimeException("test74 failed: no exception thrown");
2038         } catch (IllegalMonitorStateException ex) {
2039             // Expected
2040         }
2041         try {
2042             test74(true);
2043             throw new RuntimeException("test74 failed: no exception thrown");
2044         } catch (IllegalMonitorStateException ex) {
2045             // Expected
2046         }
2047     }
2048 
2049     // Test catching the IllegalMonitorStateException in compiled code
2050     @Test()
2051     public void test75(Object vt) {
2052         boolean thrown = false;
2053         try {
2054             synchronized (vt) {
2055                 throw new RuntimeException("test75 failed: no exception thrown");
2056             }
2057         } catch (IllegalMonitorStateException ex) {
2058             thrown = true;
2059         }
2060         if (!thrown) {
2061             throw new RuntimeException("test75 failed: no exception thrown");
2062         }
2063     }
2064 
2065     @DontCompile
2066     public void test75_verifier(boolean warmup) {
2067         test75(testValue1);
2068     }
2069 
2070     @Test()
2071     public void test76(Object o) {
2072         try {
2073             synchronized (o) { }
2074         } catch (IllegalMonitorStateException ex) {
2075             // Expected
2076             return;
2077         }
2078         throw new RuntimeException("test76 failed: no exception thrown");
2079     }
2080 
2081     @DontCompile
2082     public void test76_verifier(boolean warmup) {
2083         test76(testValue1);
2084     }
2085 
2086     // Test synchronization without any instructions in the synchronized block
2087     @Test()
2088     public void test77(Object o) {
2089         synchronized (o) { }
2090     }
2091 
2092     @DontCompile
2093     public void test77_verifier(boolean warmup) {
2094         try {
2095             test77(testValue1);
2096         } catch (IllegalMonitorStateException ex) {
2097             // Expected
2098             return;
2099         }
2100         throw new RuntimeException("test77 failed: no exception thrown");
2101     }
2102     
2103     // Test the null check of VT return values in callee.
2104     @Test()
2105     @Warmup(1)
2106     public void test78() {
2107        int n = RarelyUsedValueUser.doit();
2108         if (n != 1234) {
2109             throw new RuntimeException("Should be 1234 but got " + n);
2110         }
2111     }
2112 
2113     @DontCompile
2114     public void test78_verifier(boolean warmup) {
2115         if (warmup) {
2116             // Invoke RarelyUsedValueUserAsm.invoke() before RarelyUsedValue
2117             // has been loaded. This means Method::check_returning_vt() cannot
2118             // decide whether RarelyUsedValueUserAsm.legacy_areturn_null()
2119             // is returning a VT or not.
2120             RarelyUsedValueUserAsm.legacy_areturn_null();
2121 
2122             // Make sure all constants RarelyUsedValueUser.doit in are resolved
2123             // so we won't get uncommon traps.
2124             RarelyUsedValueUser.warmup();
2125         } else {
2126             test78();
2127         }
2128     }
2129 }
2130 
2131 // Don't use this class in any test cases except for TestLWorld.test78. We want to make sure this
2132 // class is NOT loaded during other test cases.
2133 final __ByValue class RarelyUsedValue {
2134     public final int v;
2135     RarelyUsedValue () {
2136         v = 0;
2137     }
2138     public static RarelyUsedValue makeRarelyUsedValue(int v) {
2139         RarelyUsedValue p = __MakeDefault RarelyUsedValue();
2140         p = __WithField(p.v, v);
2141         return p;
2142     }
2143 }
2144 
2145 class RarelyUsedValueUser {
2146     static {
2147         TestLWorld.setup(RarelyUsedValueUser.class);
2148         TestLWorld.setup(RarelyUsedValueUserAsm.class);
2149     }
2150 
2151     @DontCompile
2152     static void warmup() {
2153         doit();
2154     }
2155 
2156     @ForceInline
2157     static int doit() {
2158         try {
2159             RarelyUsedValue x = RarelyUsedValueUserAsm.legacy_areturn_null();
2160             return x.v;
2161         } catch (Throwable t) {
2162             return 1234;
2163         }
2164     }
2165 }