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