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