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