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