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