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