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