1 /*
   2  * Copyright (c) 2019, 2024, 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.inlinetypes;
  25 
  26 import compiler.lib.ir_framework.*;
  27 import jdk.test.lib.Asserts;
  28 import test.java.lang.invoke.lib.OldInstructionHelper;
  29 
  30 
  31 import java.lang.invoke.MethodHandle;
  32 import java.lang.invoke.MethodHandles;
  33 import java.lang.invoke.MethodType;
  34 import java.lang.reflect.Method;
  35 import jdk.experimental.bytecode.TypeTag;
  36 import java.util.Arrays;
  37 import java.util.Objects;
  38 
  39 import jdk.internal.value.ValueClass;
  40 import jdk.internal.vm.annotation.ImplicitlyConstructible;
  41 import jdk.internal.vm.annotation.LooselyConsistentValue;
  42 import jdk.internal.vm.annotation.NullRestricted;
  43 
  44 import static compiler.valhalla.inlinetypes.InlineTypeIRNode.*;
  45 import static compiler.valhalla.inlinetypes.InlineTypes.*;
  46 
  47 /*
  48  * @test
  49  * @key randomness
  50  * @summary Test inline types in LWorld.
  51  * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common /
  52  * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
  53  * @enablePreview
  54  * @modules java.base/jdk.internal.value
  55  *          java.base/jdk.internal.vm.annotation
  56  * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.OldInstructionHelper
  57  * @run main/othervm/timeout=450 compiler.valhalla.inlinetypes.TestLWorld
  58  */
  59 
  60 @ForceCompileClassInitializer
  61 public class TestLWorld {
  62 
  63     public static void main(String[] args) {
  64         // Make sure Test140Value is loaded but not linked
  65         Class<?> class1 = Test140Value.class;
  66         // Make sure Test141Value is linked but not initialized
  67         Class<?> class2 = Test141Value.class;
  68         class2.getDeclaredFields();
  69 
  70         Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS;
  71         scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1");
  72         scenarios[4].addFlags("-XX:-MonomorphicArrayCheck");
  73 
  74         InlineTypes.getFramework()
  75                    .addScenarios(scenarios)
  76                    .addHelperClasses(MyValue1.class,
  77                                      MyValue2.class,
  78                                      MyValue2Inline.class,
  79                                      MyValue3.class,
  80                                      MyValue3Inline.class)
  81                    .start();
  82     }
  83 
  84     static {
  85         // Make sure RuntimeException is loaded to prevent uncommon traps in IR verified tests
  86         RuntimeException tmp = new RuntimeException("42");
  87     }
  88 
  89     // Helper methods
  90 
  91     @NullRestricted
  92     private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL);
  93     @NullRestricted
  94     private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, rD);
  95 
  96     protected long hash() {
  97         return testValue1.hash();
  98     }
  99 
 100     // Test passing an inline type as an Object
 101     @DontInline
 102     public Object test1_dontinline1(Object o) {
 103         return o;
 104     }
 105 
 106     @DontInline
 107     public MyValue1 test1_dontinline2(Object o) {
 108         return (MyValue1)o;
 109     }
 110 
 111     @ForceInline
 112     public Object test1_inline1(Object o) {
 113         return o;
 114     }
 115 
 116     @ForceInline
 117     public MyValue1 test1_inline2(Object o) {
 118         return (MyValue1)o;
 119     }
 120 
 121     @Test
 122     @IR(failOn = {ALLOC_G})
 123     public MyValue1 test1() {
 124         MyValue1 vt = testValue1;
 125         vt = (MyValue1)test1_dontinline1(vt);
 126         vt =           test1_dontinline2(vt);
 127         vt = (MyValue1)test1_inline1(vt);
 128         vt =           test1_inline2(vt);
 129         return vt;
 130     }
 131 
 132     @Run(test = "test1")
 133     public void test1_verifier() {
 134         Asserts.assertEQ(test1().hash(), hash());
 135     }
 136 
 137     // Test storing/loading inline types to/from Object and inline type fields
 138     Object objectField1 = null;
 139     Object objectField2 = null;
 140     Object objectField3 = null;
 141     Object objectField4 = null;
 142     Object objectField5 = null;
 143     Object objectField6 = null;
 144 
 145     @NullRestricted
 146     MyValue1 valueField1 = testValue1;
 147     @NullRestricted
 148     MyValue1 valueField2 = testValue1;
 149     MyValue1 valueField3 = testValue1;
 150     @NullRestricted
 151     MyValue1 valueField4;
 152     MyValue1 valueField5;
 153 
 154     static MyValue1 staticValueField1 = testValue1;
 155     @NullRestricted
 156     static MyValue1 staticValueField2 = testValue1;
 157     @NullRestricted
 158     static MyValue1 staticValueField3;
 159     static MyValue1 staticValueField4;
 160 
 161     @DontInline
 162     public Object readValueField5() {
 163         return (Object)valueField5;
 164     }
 165 
 166     @DontInline
 167     public Object readStaticValueField4() {
 168         return (Object)staticValueField4;
 169     }
 170 
 171     @Test
 172     public long test2(MyValue1 vt1, Object vt2) {
 173         objectField1 = vt1;
 174         objectField2 = (MyValue1)vt2;
 175         objectField3 = testValue1;
 176         objectField4 = MyValue1.createWithFieldsDontInline(rI, rL);
 177         objectField5 = valueField1;
 178         objectField6 = valueField3;
 179         valueField1 = (MyValue1)objectField1;
 180         valueField2 = (MyValue1)vt2;
 181         valueField3 = (MyValue1)vt2;
 182         staticValueField1 = (MyValue1)objectField1;
 183         staticValueField2 = (MyValue1)vt1;
 184         // Don't inline these methods because reading NULL will trigger a deoptimization
 185         if (readValueField5() != null || readStaticValueField4() != null) {
 186             throw new RuntimeException("Should be null");
 187         }
 188         return ((MyValue1)objectField1).hash() + ((MyValue1)objectField2).hash() +
 189                ((MyValue1)objectField3).hash() + ((MyValue1)objectField4).hash() +
 190                ((MyValue1)objectField5).hash() + ((MyValue1)objectField6).hash() +
 191                 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() +
 192                 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive();
 193     }
 194 
 195     @Run(test = "test2")
 196     public void test2_verifier() {
 197         MyValue1 vt = testValue1;
 198         MyValue1 def = MyValue1.createDefaultDontInline();
 199         long result = test2(vt, vt);
 200         Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive());
 201     }
 202 
 203     // Test merging inline types and objects
 204     @Test
 205     public Object test3(int state) {
 206         Object res = null;
 207         if (state == 0) {
 208             res = new NonValueClass(rI);
 209         } else if (state == 1) {
 210             res = MyValue1.createWithFieldsInline(rI, rL);
 211         } else if (state == 2) {
 212             res = MyValue1.createWithFieldsDontInline(rI, rL);
 213         } else if (state == 3) {
 214             res = (MyValue1)objectField1;
 215         } else if (state == 4) {
 216             res = valueField1;
 217         } else if (state == 5) {
 218             res = null;
 219         } else if (state == 6) {
 220             res = MyValue2.createWithFieldsInline(rI, rD);
 221         } else if (state == 7) {
 222             res = testValue2;
 223         }
 224         return res;
 225     }
 226 
 227     @Run(test = "test3")
 228     public void test3_verifier() {
 229         objectField1 = valueField1;
 230         Object result = null;
 231         result = test3(0);
 232         Asserts.assertEQ(((NonValueClass)result).x, rI);
 233         result = test3(1);
 234         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 235         result = test3(2);
 236         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 237         result = test3(3);
 238         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 239         result = test3(4);
 240         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 241         result = test3(5);
 242         Asserts.assertEQ(result, null);
 243         result = test3(6);
 244         Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash());
 245         result = test3(7);
 246         Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash());
 247     }
 248 
 249     // Test merging inline types and objects in loops
 250     @Test
 251     public Object test4(int iters) {
 252         Object res = new NonValueClass(rI);
 253         for (int i = 0; i < iters; ++i) {
 254             if (res instanceof NonValueClass) {
 255                 res = MyValue1.createWithFieldsInline(rI, rL);
 256             } else {
 257                 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL);
 258             }
 259         }
 260         return res;
 261     }
 262 
 263     @Run(test = "test4")
 264     public void test4_verifier() {
 265         NonValueClass result1 = (NonValueClass)test4(0);
 266         Asserts.assertEQ(result1.x, rI);
 267         int iters = (Math.abs(rI) % 10) + 1;
 268         MyValue1 result2 = (MyValue1)test4(iters);
 269         MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL);
 270         Asserts.assertEQ(result2.hash(), vt.hash());
 271     }
 272 
 273     // Test inline types in object variables that are live at safepoint
 274     @Test
 275     @IR(failOn = {ALLOC, STORE, LOOP})
 276     public long test5(MyValue1 arg, boolean deopt, Method m) {
 277         Object vt1 = MyValue1.createWithFieldsInline(rI, rL);
 278         Object vt2 = MyValue1.createWithFieldsDontInline(rI, rL);
 279         Object vt3 = arg;
 280         Object vt4 = valueField1;
 281         if (deopt) {
 282             // uncommon trap
 283             TestFramework.deoptimize(m);
 284         }
 285         return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() +
 286                ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash();
 287     }
 288 
 289     @Run(test = "test5")
 290     public void test5_verifier(RunInfo info) {
 291         long result = test5(valueField1, !info.isWarmUp(), info.getTest());
 292         Asserts.assertEQ(result, 4*hash());
 293     }
 294 
 295     // Test comparing inline types with objects
 296     @Test
 297     public boolean test6(Object arg) {
 298         Object vt = MyValue1.createWithFieldsInline(rI, rL);
 299         if (vt == arg || vt == (Object)valueField1 || vt == objectField1 || vt == null ||
 300             arg == vt || (Object)valueField1 == vt || objectField1 == vt || null == vt) {
 301             return true;
 302         }
 303         return false;
 304     }
 305 
 306     @Run(test = "test6")
 307     public void test6_verifier() {
 308         boolean result = test6(null);
 309         Asserts.assertFalse(result);
 310     }
 311 
 312     // merge of inline type and non-inline type
 313     @Test
 314     public Object test7(boolean flag) {
 315         Object res = null;
 316         if (flag) {
 317             res = valueField1;
 318         } else {
 319             res = objectField1;
 320         }
 321         return res;
 322     }
 323 
 324     @Run(test = "test7")
 325     public void test7_verifier() {
 326         test7(true);
 327         test7(false);
 328     }
 329 
 330     @Test
 331     public Object test8(boolean flag) {
 332         Object res = null;
 333         if (flag) {
 334             res = objectField1;
 335         } else {
 336             res = valueField1;
 337         }
 338         return res;
 339     }
 340 
 341     @Run(test = "test8")
 342     public void test8_verifier() {
 343         test8(true);
 344         test8(false);
 345     }
 346 
 347     // merge of inline types in a loop, stored in an object local
 348     @Test
 349     public Object test9() {
 350         Object o = valueField1;
 351         for (int i = 1; i < 100; i *= 2) {
 352             MyValue1 v = (MyValue1)o;
 353             o = MyValue1.setX(v, v.x + 1);
 354         }
 355         return o;
 356     }
 357 
 358     @Run(test = "test9")
 359     public void test9_verifier() {
 360         test9();
 361     }
 362 
 363     // merge of inline types in an object local
 364     @ForceInline
 365     public Object test10_helper() {
 366         return valueField1;
 367     }
 368 
 369     @Test
 370     @IR(failOn = {ALLOC_G})
 371     public void test10(boolean flag) {
 372         Object o = null;
 373         if (flag) {
 374             o = valueField1;
 375         } else {
 376             o = test10_helper();
 377         }
 378         valueField1 = (MyValue1)o;
 379     }
 380 
 381     @Run(test = "test10")
 382     public void test10_verifier() {
 383         test10(true);
 384         test10(false);
 385     }
 386 
 387     // Interface tests
 388 
 389     @DontInline
 390     public MyInterface test11_dontinline1(MyInterface o) {
 391         return o;
 392     }
 393 
 394     @DontInline
 395     public MyValue1 test11_dontinline2(MyInterface o) {
 396         return (MyValue1)o;
 397     }
 398 
 399     @ForceInline
 400     public MyInterface test11_inline1(MyInterface o) {
 401         return o;
 402     }
 403 
 404     @ForceInline
 405     public MyValue1 test11_inline2(MyInterface o) {
 406         return (MyValue1)o;
 407     }
 408 
 409     @Test
 410     public MyValue1 test11() {
 411         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 412         vt = (MyValue1)test11_dontinline1(vt);
 413         vt =           test11_dontinline2(vt);
 414         vt = (MyValue1)test11_inline1(vt);
 415         vt =           test11_inline2(vt);
 416         return vt;
 417     }
 418 
 419     @Run(test = "test11")
 420     public void test11_verifier() {
 421         Asserts.assertEQ(test11().hash(), hash());
 422     }
 423 
 424     // Test storing/loading inline types to/from interface and inline type fields
 425     MyInterface interfaceField1 = null;
 426     MyInterface interfaceField2 = null;
 427     MyInterface interfaceField3 = null;
 428     MyInterface interfaceField4 = null;
 429     MyInterface interfaceField5 = null;
 430     MyInterface interfaceField6 = null;
 431 
 432     @DontInline
 433     public MyInterface readValueField5AsInterface() {
 434         return (MyInterface)valueField5;
 435     }
 436 
 437     @DontInline
 438     public MyInterface readStaticValueField4AsInterface() {
 439         return (MyInterface)staticValueField4;
 440     }
 441 
 442     @Test
 443     public long test12(MyValue1 vt1, MyInterface vt2) {
 444         interfaceField1 = vt1;
 445         interfaceField2 = (MyValue1)vt2;
 446         interfaceField3 = MyValue1.createWithFieldsInline(rI, rL);
 447         interfaceField4 = MyValue1.createWithFieldsDontInline(rI, rL);
 448         interfaceField5 = valueField1;
 449         interfaceField6 = valueField3;
 450         valueField1 = (MyValue1)interfaceField1;
 451         valueField2 = (MyValue1)vt2;
 452         valueField3 = (MyValue1)vt2;
 453         staticValueField1 = (MyValue1)interfaceField1;
 454         staticValueField2 = (MyValue1)vt1;
 455         // Don't inline these methods because reading NULL will trigger a deoptimization
 456         if (readValueField5AsInterface() != null || readStaticValueField4AsInterface() != null) {
 457             throw new RuntimeException("Should be null");
 458         }
 459         return ((MyValue1)interfaceField1).hash() + ((MyValue1)interfaceField2).hash() +
 460                ((MyValue1)interfaceField3).hash() + ((MyValue1)interfaceField4).hash() +
 461                ((MyValue1)interfaceField5).hash() + ((MyValue1)interfaceField6).hash() +
 462                 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() +
 463                 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive();
 464     }
 465 
 466     @Run(test = "test12")
 467     public void test12_verifier() {
 468         MyValue1 vt = testValue1;
 469         MyValue1 def = MyValue1.createDefaultDontInline();
 470         long result = test12(vt, vt);
 471         Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive());
 472     }
 473 
 474     class MyObject1 implements MyInterface {
 475         public int x;
 476 
 477         public MyObject1(int x) {
 478             this.x = x;
 479         }
 480 
 481         @ForceInline
 482         public long hash() {
 483             return x;
 484         }
 485     }
 486 
 487     // Test merging inline types and interfaces
 488     @Test
 489     public MyInterface test13(int state) {
 490         MyInterface res = null;
 491         if (state == 0) {
 492             res = new MyObject1(rI);
 493         } else if (state == 1) {
 494             res = MyValue1.createWithFieldsInline(rI, rL);
 495         } else if (state == 2) {
 496             res = MyValue1.createWithFieldsDontInline(rI, rL);
 497         } else if (state == 3) {
 498             res = (MyValue1)objectField1;
 499         } else if (state == 4) {
 500             res = valueField1;
 501         } else if (state == 5) {
 502             res = null;
 503         }
 504         return res;
 505     }
 506 
 507     @Run(test = "test13")
 508     public void test13_verifier() {
 509         objectField1 = valueField1;
 510         MyInterface result = null;
 511         result = test13(0);
 512         Asserts.assertEQ(((MyObject1)result).x, rI);
 513         result = test13(1);
 514         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 515         result = test13(2);
 516         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 517         result = test13(3);
 518         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 519         result = test13(4);
 520         Asserts.assertEQ(((MyValue1)result).hash(), hash());
 521         result = test13(5);
 522         Asserts.assertEQ(result, null);
 523     }
 524 
 525     // Test merging inline types and interfaces in loops
 526     @Test
 527     public MyInterface test14(int iters) {
 528         MyInterface res = new MyObject1(rI);
 529         for (int i = 0; i < iters; ++i) {
 530             if (res instanceof MyObject1) {
 531                 res = MyValue1.createWithFieldsInline(rI, rL);
 532             } else {
 533                 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL);
 534             }
 535         }
 536         return res;
 537     }
 538 
 539     @Run(test = "test14")
 540     public void test14_verifier() {
 541         MyObject1 result1 = (MyObject1)test14(0);
 542         Asserts.assertEQ(result1.x, rI);
 543         int iters = (Math.abs(rI) % 10) + 1;
 544         MyValue1 result2 = (MyValue1)test14(iters);
 545         MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL);
 546         Asserts.assertEQ(result2.hash(), vt.hash());
 547     }
 548 
 549     // Test inline types in interface variables that are live at safepoint
 550     @Test
 551     @IR(failOn = {ALLOC, STORE, LOOP})
 552     public long test15(MyValue1 arg, boolean deopt, Method m) {
 553         MyInterface vt1 = MyValue1.createWithFieldsInline(rI, rL);
 554         MyInterface vt2 = MyValue1.createWithFieldsDontInline(rI, rL);
 555         MyInterface vt3 = arg;
 556         MyInterface vt4 = valueField1;
 557         return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() +
 558                ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash();
 559     }
 560 
 561     @Run(test = "test15")
 562     public void test15_verifier(RunInfo info) {
 563         long result = test15(valueField1, !info.isWarmUp(), info.getTest());
 564         Asserts.assertEQ(result, 4*hash());
 565     }
 566 
 567     // Test comparing inline types with interfaces
 568     @Test
 569     public boolean test16(Object arg) {
 570         MyInterface vt = MyValue1.createWithFieldsInline(rI, rL);
 571         if (vt == arg || vt == (MyInterface)valueField1 || vt == interfaceField1 || vt == null ||
 572             arg == vt || (MyInterface)valueField1 == vt || interfaceField1 == vt || null == vt) {
 573             return true;
 574         }
 575         return false;
 576     }
 577 
 578     @Run(test = "test16")
 579     public void test16_verifier() {
 580         boolean result = test16(null);
 581         Asserts.assertFalse(result);
 582     }
 583 
 584     // Test subtype check when casting to inline type
 585     @Test
 586     @IR(failOn = {ALLOC})
 587     public MyValue1 test17(MyValue1 vt, Object obj) {
 588         try {
 589             vt = (MyValue1)obj;
 590             throw new RuntimeException("ClassCastException expected");
 591         } catch (ClassCastException e) {
 592             // Expected
 593         }
 594         return vt;
 595     }
 596 
 597     @Run(test = "test17")
 598     public void test17_verifier() {
 599         MyValue1 vt = testValue1;
 600         MyValue1 result = test17(vt, new NonValueClass(rI));
 601         Asserts.assertEquals(result.hash(), vt.hash());
 602     }
 603 
 604     @Test
 605     public MyValue1 test18(MyValue1 vt) {
 606         Object obj = vt;
 607         vt = (MyValue1)obj;
 608         return vt;
 609     }
 610 
 611     @Run(test = "test18")
 612     public void test18_verifier() {
 613         MyValue1 vt = testValue1;
 614         MyValue1 result = test18(vt);
 615         Asserts.assertEquals(result.hash(), vt.hash());
 616     }
 617 
 618     @Test
 619     @IR(failOn = {ALLOC_G})
 620     public void test19(MyValue1 vt) {
 621         if (vt == null) {
 622             return;
 623         }
 624         Object obj = vt;
 625         try {
 626             MyValue2 vt2 = (MyValue2)obj;
 627             throw new RuntimeException("ClassCastException expected");
 628         } catch (ClassCastException e) {
 629             // Expected
 630         }
 631     }
 632 
 633     @Run(test = "test19")
 634     public void test19_verifier() {
 635         test19(valueField1);
 636     }
 637 
 638     @Test
 639     @IR(failOn = {ALLOC_G})
 640     public void test20(MyValue1 vt) {
 641         if (vt == null) {
 642             return;
 643         }
 644         Object obj = vt;
 645         try {
 646             NonValueClass i = (NonValueClass)obj;
 647             throw new RuntimeException("ClassCastException expected");
 648         } catch (ClassCastException e) {
 649             // Expected
 650         }
 651     }
 652 
 653     @Run(test = "test20")
 654     public void test20_verifier() {
 655         test20(valueField1);
 656     }
 657 
 658     // Array tests
 659 
 660     private static final MyValue1[] testValue1Array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 3);
 661     static {
 662         for (int i = 0; i < 3; ++i) {
 663             testValue1Array[i] = testValue1;
 664         }
 665     }
 666 
 667     private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array,
 668                                                                            testValue1Array,
 669                                                                            testValue1Array};
 670 
 671     private static final MyValue2[] testValue2Array = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 3);
 672     static {
 673         for (int i = 0; i < 3; ++i) {
 674             testValue2Array[i] = testValue2;
 675         }
 676     }
 677 
 678     private static final NonValueClass[] testNonValueArray = new NonValueClass[42];
 679 
 680     // Test load from (flattened) inline type array disguised as object array
 681     @Test
 682     public Object test21(Object[] oa, int index) {
 683         return oa[index];
 684     }
 685 
 686     @Run(test = "test21")
 687     public void test21_verifier() {
 688         MyValue1 result = (MyValue1)test21(testValue1Array, Math.abs(rI) % 3);
 689         Asserts.assertEQ(result.hash(), hash());
 690     }
 691 
 692     // Test load from (flattened) inline type array disguised as interface array
 693     @Test
 694     public Object test22Interface(MyInterface[] ia, int index) {
 695         return ia[index];
 696     }
 697 
 698     @Run(test = "test22Interface")
 699     public void test22Interface_verifier() {
 700         MyValue1 result = (MyValue1)test22Interface(testValue1Array, Math.abs(rI) % 3);
 701         Asserts.assertEQ(result.hash(), hash());
 702     }
 703 
 704     // Test load from (flattened) inline type array disguised as abstract array
 705     @Test
 706     public Object test22Abstract(MyAbstract[] ia, int index) {
 707         return ia[index];
 708     }
 709 
 710     @Run(test = "test22Abstract")
 711     public void test22Abstract_verifier() {
 712         MyValue1 result = (MyValue1)test22Abstract(testValue1Array, Math.abs(rI) % 3);
 713         Asserts.assertEQ(result.hash(), hash());
 714     }
 715 
 716     // Test inline store to (flattened) inline type array disguised as object array
 717     @ForceInline
 718     public void test23_inline(Object[] oa, Object o, int index) {
 719         oa[index] = o;
 720     }
 721 
 722     @Test
 723     public void test23(Object[] oa, MyValue1 vt, int index) {
 724         test23_inline(oa, vt, index);
 725     }
 726 
 727     @Run(test = "test23")
 728     public void test23_verifier() {
 729         int index = Math.abs(rI) % 3;
 730         MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 731         test23(testValue1Array, vt, index);
 732         Asserts.assertEQ(testValue1Array[index].hash(), vt.hash());
 733         testValue1Array[index] = testValue1;
 734         try {
 735             test23(testValue2Array, vt, index);
 736             throw new RuntimeException("No ArrayStoreException thrown");
 737         } catch (ArrayStoreException e) {
 738             // Expected
 739         }
 740         Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash());
 741     }
 742 
 743     @ForceInline
 744     public void test24_inline(Object[] oa, Object o, int index) {
 745         oa[index] = o;
 746     }
 747 
 748     @Test
 749     public void test24(Object[] oa, MyValue1 vt, int index) {
 750         test24_inline(oa, vt, index);
 751     }
 752 
 753     @Run(test = "test24")
 754     public void test24_verifier() {
 755         int index = Math.abs(rI) % 3;
 756         try {
 757             test24(testNonValueArray, testValue1, index);
 758             throw new RuntimeException("No ArrayStoreException thrown");
 759         } catch (ArrayStoreException e) {
 760             // Expected
 761         }
 762     }
 763 
 764     @ForceInline
 765     public void test25_inline(Object[] oa, Object o, int index) {
 766         oa[index] = o;
 767     }
 768 
 769     @Test
 770     public void test25(Object[] oa, MyValue1 vt, int index) {
 771         test25_inline(oa, vt, index);
 772     }
 773 
 774     @Run(test = "test25")
 775     public void test25_verifier() {
 776         int index = Math.abs(rI) % 3;
 777         try {
 778             test25(null, testValue1, index);
 779             throw new RuntimeException("No NPE thrown");
 780         } catch (NullPointerException e) {
 781             // Expected
 782         }
 783     }
 784 
 785     // Test inline store to (flattened) inline type array disguised as interface array
 786     @ForceInline
 787     public void test26Interface_inline(MyInterface[] ia, MyInterface i, int index) {
 788         ia[index] = i;
 789     }
 790 
 791     @Test
 792     public void test26Interface(MyInterface[] ia, MyValue1 vt, int index) {
 793       test26Interface_inline(ia, vt, index);
 794     }
 795 
 796     @Run(test = "test26Interface")
 797     public void test26Interface_verifier() {
 798         int index = Math.abs(rI) % 3;
 799         MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 800         test26Interface(testValue1Array, vt, index);
 801         Asserts.assertEQ(testValue1Array[index].hash(), vt.hash());
 802         testValue1Array[index] = testValue1;
 803         try {
 804             test26Interface(testValue2Array, vt, index);
 805             throw new RuntimeException("No ArrayStoreException thrown");
 806         } catch (ArrayStoreException e) {
 807             // Expected
 808         }
 809         Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash());
 810     }
 811 
 812     @ForceInline
 813     public void test27Interface_inline(MyInterface[] ia, MyInterface i, int index) {
 814         ia[index] = i;
 815     }
 816 
 817     @Test
 818     public void test27Interface(MyInterface[] ia, MyValue1 vt, int index) {
 819         test27Interface_inline(ia, vt, index);
 820     }
 821 
 822     @Run(test = "test27Interface")
 823     public void test27Interface_verifier() {
 824         int index = Math.abs(rI) % 3;
 825         try {
 826             test27Interface(null, testValue1, index);
 827             throw new RuntimeException("No NPE thrown");
 828         } catch (NullPointerException e) {
 829             // Expected
 830         }
 831     }
 832 
 833     // Test inline store to (flattened) inline type array disguised as abstract array
 834     @ForceInline
 835     public void test26Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) {
 836         ia[index] = i;
 837     }
 838 
 839     @Test
 840     public void test26Abstract(MyAbstract[] ia, MyValue1 vt, int index) {
 841       test26Abstract_inline(ia, vt, index);
 842     }
 843 
 844     @Run(test = "test26Abstract")
 845     public void test26Abstract_verifier() {
 846         int index = Math.abs(rI) % 3;
 847         MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 848         test26Abstract(testValue1Array, vt, index);
 849         Asserts.assertEQ(testValue1Array[index].hash(), vt.hash());
 850         testValue1Array[index] = testValue1;
 851         try {
 852             test26Abstract(testValue2Array, vt, index);
 853             throw new RuntimeException("No ArrayStoreException thrown");
 854         } catch (ArrayStoreException e) {
 855             // Expected
 856         }
 857         Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash());
 858     }
 859 
 860     @ForceInline
 861     public void test27Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) {
 862         ia[index] = i;
 863     }
 864 
 865     @Test
 866     public void test27Abstract(MyAbstract[] ia, MyValue1 vt, int index) {
 867         test27Abstract_inline(ia, vt, index);
 868     }
 869 
 870     @Run(test = "test27Abstract")
 871     public void test27Abstract_verifier() {
 872         int index = Math.abs(rI) % 3;
 873         try {
 874             test27Abstract(null, testValue1, index);
 875             throw new RuntimeException("No NPE thrown");
 876         } catch (NullPointerException e) {
 877             // Expected
 878         }
 879     }
 880 
 881     // Test object store to (flattened) inline type array disguised as object array
 882     @ForceInline
 883     public void test28_inline(Object[] oa, Object o, int index) {
 884         oa[index] = o;
 885     }
 886 
 887     @Test
 888     public void test28(Object[] oa, Object o, int index) {
 889         test28_inline(oa, o, index);
 890     }
 891 
 892     @Run(test = "test28")
 893     public void test28_verifier() {
 894         int index = Math.abs(rI) % 3;
 895         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 896         test28(testValue1Array, vt1, index);
 897         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
 898         try {
 899             test28(testValue1Array, testValue2, index);
 900             throw new RuntimeException("No ArrayStoreException thrown");
 901         } catch (ArrayStoreException e) {
 902             // Expected
 903         }
 904         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
 905         testValue1Array[index] = testValue1;
 906     }
 907 
 908     @ForceInline
 909     public void test29_inline(Object[] oa, Object o, int index) {
 910         oa[index] = o;
 911     }
 912 
 913     @Test
 914     public void test29(Object[] oa, Object o, int index) {
 915         test29_inline(oa, o, index);
 916     }
 917 
 918     @Run(test = "test29")
 919     public void test29_verifier() {
 920         int index = Math.abs(rI) % 3;
 921         try {
 922             test29(testValue2Array, testValue1, index);
 923             throw new RuntimeException("No ArrayStoreException thrown");
 924         } catch (ArrayStoreException e) {
 925             // Expected
 926         }
 927         Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash());
 928     }
 929 
 930     @ForceInline
 931     public void test30_inline(Object[] oa, Object o, int index) {
 932         oa[index] = o;
 933     }
 934 
 935     @Test
 936     public void test30(Object[] oa, Object o, int index) {
 937         test30_inline(oa, o, index);
 938     }
 939 
 940     @Run(test = "test30")
 941     public void test30_verifier() {
 942         int index = Math.abs(rI) % 3;
 943         try {
 944             test30(testNonValueArray, testValue1, index);
 945             throw new RuntimeException("No ArrayStoreException thrown");
 946         } catch (ArrayStoreException e) {
 947             // Expected
 948         }
 949     }
 950 
 951     // Test inline store to (flattened) inline type array disguised as interface array
 952     @ForceInline
 953     public void test31Interface_inline(MyInterface[] ia, MyInterface i, int index) {
 954         ia[index] = i;
 955     }
 956 
 957     @Test
 958     public void test31Interface(MyInterface[] ia, MyInterface i, int index) {
 959         test31Interface_inline(ia, i, index);
 960     }
 961 
 962     @Run(test = "test31Interface")
 963     public void test31Interface_verifier() {
 964         int index = Math.abs(rI) % 3;
 965         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 966         test31Interface(testValue1Array, vt1, index);
 967         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
 968         try {
 969             test31Interface(testValue1Array, testValue2, index);
 970             throw new RuntimeException("No ArrayStoreException thrown");
 971         } catch (ArrayStoreException e) {
 972             // Expected
 973         }
 974         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
 975         testValue1Array[index] = testValue1;
 976     }
 977 
 978     @ForceInline
 979     public void test32Interface_inline(MyInterface[] ia, MyInterface i, int index) {
 980         ia[index] = i;
 981     }
 982 
 983     @Test
 984     public void test32Interface(MyInterface[] ia, MyInterface i, int index) {
 985         test32Interface_inline(ia, i, index);
 986     }
 987 
 988     @Run(test = "test32Interface")
 989     public void test32Interface_verifier() {
 990         int index = Math.abs(rI) % 3;
 991         try {
 992             test32Interface(testValue2Array, testValue1, index);
 993             throw new RuntimeException("No ArrayStoreException thrown");
 994         } catch (ArrayStoreException e) {
 995             // Expected
 996         }
 997     }
 998 
 999     // Test inline store to (flattened) inline type array disguised as abstract array
1000     @ForceInline
1001     public void test31Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) {
1002         ia[index] = i;
1003     }
1004 
1005     @Test
1006     public void test31Abstract(MyAbstract[] ia, MyAbstract i, int index) {
1007         test31Abstract_inline(ia, i, index);
1008     }
1009 
1010     @Run(test = "test31Abstract")
1011     public void test31Abstract_verifier() {
1012         int index = Math.abs(rI) % 3;
1013         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1014         test31Abstract(testValue1Array, vt1, index);
1015         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1016         try {
1017             test31Abstract(testValue1Array, testValue2, index);
1018             throw new RuntimeException("No ArrayStoreException thrown");
1019         } catch (ArrayStoreException e) {
1020             // Expected
1021         }
1022         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1023         testValue1Array[index] = testValue1;
1024     }
1025 
1026     @ForceInline
1027     public void test32Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) {
1028         ia[index] = i;
1029     }
1030 
1031     @Test
1032     public void test32Abstract(MyAbstract[] ia, MyAbstract i, int index) {
1033         test32Abstract_inline(ia, i, index);
1034     }
1035 
1036     @Run(test = "test32Abstract")
1037     public void test32Abstract_verifier() {
1038         int index = Math.abs(rI) % 3;
1039         try {
1040             test32Abstract(testValue2Array, testValue1, index);
1041             throw new RuntimeException("No ArrayStoreException thrown");
1042         } catch (ArrayStoreException e) {
1043             // Expected
1044         }
1045     }
1046 
1047     // Test writing null to a (flattened) inline type array disguised as object array
1048     @ForceInline
1049     public void test33_inline(Object[] oa, Object o, int index) {
1050         oa[index] = o;
1051     }
1052 
1053     @Test
1054     public void test33(Object[] oa, Object o, int index) {
1055         test33_inline(oa, o, index);
1056     }
1057 
1058     @Run(test = "test33")
1059     public void test33_verifier() {
1060         int index = Math.abs(rI) % 3;
1061         try {
1062             test33(testValue1Array, null, index);
1063             throw new RuntimeException("No NPE thrown");
1064         } catch (NullPointerException e) {
1065             // Expected
1066         }
1067         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1068     }
1069 
1070     // Test writing constant null to a (flattened) inline type array disguised as object array
1071 
1072     @ForceInline
1073     public void test34_inline(Object[] oa, Object o, int index) {
1074         oa[index] = o;
1075     }
1076 
1077     @Test
1078     public void test34(Object[] oa, int index) {
1079         test34_inline(oa, null, index);
1080     }
1081 
1082     @Run(test = "test34")
1083     public void test34_verifier() {
1084         int index = Math.abs(rI) % 3;
1085         try {
1086             test34(testValue1Array, index);
1087             throw new RuntimeException("No NPE thrown");
1088         } catch (NullPointerException e) {
1089             // Expected
1090         }
1091         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1092     }
1093 
1094     // Test writing constant null to a (flattened) inline type array
1095 
1096     private static final MethodHandle setArrayElementNull = OldInstructionHelper.loadCode(MethodHandles.lookup(),
1097         "setArrayElementNull",
1098         MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class),
1099         CODE -> {
1100             CODE.
1101             aload_1().
1102             iload_2().
1103             aconst_null().
1104             aastore().
1105             return_();
1106         });
1107 
1108     @Test
1109     public void test35(MyValue1[] va, int index) throws Throwable {
1110         setArrayElementNull.invoke(this, va, index);
1111     }
1112 
1113     @Run(test = "test35")
1114     @Warmup(10000)
1115     public void test35_verifier() throws Throwable {
1116         int index = Math.abs(rI) % 3;
1117         try {
1118             test35(testValue1Array, index);
1119             throw new RuntimeException("No NPE thrown");
1120         } catch (NullPointerException e) {
1121             // Expected
1122         }
1123         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1124     }
1125 
1126     // Test writing an inline type to a null inline type array
1127     @Test
1128     public void test36(MyValue1[] va, MyValue1 vt, int index) {
1129         va[index] = vt;
1130     }
1131 
1132     @Run(test = "test36")
1133     public void test36_verifier() {
1134         int index = Math.abs(rI) % 3;
1135         try {
1136             test36(null, testValue1Array[index], index);
1137             throw new RuntimeException("No NPE thrown");
1138         } catch (NullPointerException e) {
1139             // Expected
1140         }
1141     }
1142 
1143     // Test incremental inlining
1144     @ForceInline
1145     public void test37_inline(Object[] oa, Object o, int index) {
1146         oa[index] = o;
1147     }
1148 
1149     @Test
1150     @IR(failOn = {ALLOC_G})
1151     public void test37(MyValue1[] va, Object o, int index) {
1152         test37_inline(va, o, index);
1153     }
1154 
1155     @Run(test = "test37")
1156     public void test37_verifier() {
1157         int index = Math.abs(rI) % 3;
1158         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1159         test37(testValue1Array, vt1, index);
1160         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1161         try {
1162             test37(testValue1Array, testValue2, index);
1163             throw new RuntimeException("No ArrayStoreException thrown");
1164         } catch (ArrayStoreException e) {
1165             // Expected
1166         }
1167         Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash());
1168         testValue1Array[index] = testValue1;
1169     }
1170 
1171     // Test merging of inline type arrays
1172 
1173     @ForceInline
1174     public Object[] test38_inline() {
1175         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42);
1176     }
1177 
1178     @Test
1179     @IR(failOn = {ALLOC})
1180     public Object[] test38(Object[] oa, Object o, int i1, int i2, int num) {
1181         Object[] result = null;
1182         switch (num) {
1183         case 0:
1184             result = test38_inline();
1185             break;
1186         case 1:
1187             result = oa;
1188             break;
1189         case 2:
1190             result = testValue1Array;
1191             break;
1192         case 3:
1193             result = testValue2Array;
1194             break;
1195         case 4:
1196             result = testNonValueArray;
1197             break;
1198         case 5:
1199             result = null;
1200             break;
1201         case 6:
1202             result = testValue1Array2;
1203             break;
1204         }
1205         result[i1] = result[i2];
1206         result[i2] = o;
1207         return result;
1208     }
1209 
1210     @Run(test = "test38")
1211     public void test38_verifier() {
1212         int index = Math.abs(rI) % 3;
1213         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42);
1214         Object[] result = test38(null, testValue1, index, index, 0);
1215         Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash());
1216         result = test38(testValue1Array, testValue1, index, index, 1);
1217         Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash());
1218         result = test38(null, testValue1, index, index, 2);
1219         Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash());
1220         result = test38(null, testValue2, index, index, 3);
1221         Asserts.assertEQ(((MyValue2)result[index]).hash(), testValue2.hash());
1222         try {
1223             result = test38(null, null, index, index, 3);
1224             throw new RuntimeException("No NPE thrown");
1225         } catch (NullPointerException e) {
1226             // Expected
1227         }
1228         result = test38(null, null, index, index, 4);
1229         try {
1230             result = test38(null, testValue1, index, index, 4);
1231             throw new RuntimeException("No ArrayStoreException thrown");
1232         } catch (ArrayStoreException e) {
1233             // Expected
1234         }
1235         try {
1236             result = test38(null, testValue1, index, index, 5);
1237             throw new RuntimeException("No NPE thrown");
1238         } catch (NullPointerException e) {
1239             // Expected
1240         }
1241         result = test38(null, testValue1Array, index, index, 6);
1242         Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash());
1243     }
1244 
1245     @ForceInline
1246     public Object test39_inline() {
1247         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42);
1248     }
1249 
1250     // Same as above but merging into Object instead of Object[]
1251     @Test
1252     public Object test39(Object oa, Object o, int i1, int i2, int num) {
1253         Object result = null;
1254         switch (num) {
1255         case 0:
1256             result = test39_inline();
1257             break;
1258         case 1:
1259             result = oa;
1260             break;
1261         case 2:
1262             result = testValue1Array;
1263             break;
1264         case 3:
1265             result = testValue2Array;
1266             break;
1267         case 4:
1268             result = testNonValueArray;
1269             break;
1270         case 5:
1271             result = null;
1272             break;
1273         case 6:
1274             result = testValue1;
1275             break;
1276         case 7:
1277             result = testValue2;
1278             break;
1279         case 8:
1280             result = MyValue1.createWithFieldsInline(rI, rL);
1281             break;
1282         case 9:
1283             result = new NonValueClass(42);
1284             break;
1285         case 10:
1286             result = testValue1Array2;
1287             break;
1288         }
1289         if (result instanceof Object[]) {
1290             ((Object[])result)[i1] = ((Object[])result)[i2];
1291             ((Object[])result)[i2] = o;
1292         }
1293         return result;
1294     }
1295 
1296     @Run(test = "test39")
1297     public void test39_verifier() {
1298         int index = Math.abs(rI) % 3;
1299         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42);
1300         Object result = test39(null, testValue1, index, index, 0);
1301         Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash());
1302         result = test39(testValue1Array, testValue1, index, index, 1);
1303         Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash());
1304         result = test39(null, testValue1, index, index, 2);
1305         Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash());
1306         result = test39(null, testValue2, index, index, 3);
1307         Asserts.assertEQ(((MyValue2[])result)[index].hash(), testValue2.hash());
1308         try {
1309             result = test39(null, null, index, index, 3);
1310             throw new RuntimeException("No NPE thrown");
1311         } catch (NullPointerException e) {
1312             // Expected
1313         }
1314         result = test39(null, null, index, index, 4);
1315         try {
1316             result = test39(null, testValue1, index, index, 4);
1317             throw new RuntimeException("No ArrayStoreException thrown");
1318         } catch (ArrayStoreException e) {
1319             // Expected
1320         }
1321         result = test39(null, testValue1, index, index, 5);
1322         Asserts.assertEQ(result, null);
1323         result = test39(null, testValue1, index, index, 6);
1324         Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash());
1325         result = test39(null, testValue1, index, index, 7);
1326         Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash());
1327         result = test39(null, testValue1, index, index, 8);
1328         Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash());
1329         result = test39(null, testValue1, index, index, 9);
1330         Asserts.assertEQ(((NonValueClass)result).x, 42);
1331         result = test39(null, testValue1Array, index, index, 10);
1332         Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash());
1333     }
1334 
1335     // Test instanceof with inline types and arrays
1336     @Test
1337     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
1338         failOn = {ALLOC_G})
1339     public long test40(Object o, int index) {
1340         if (o instanceof MyValue1) {
1341           return ((MyValue1)o).hashInterpreted();
1342         } else if (o instanceof MyValue1[]) {
1343           return ((MyValue1[])o)[index].hashInterpreted();
1344         } else if (o instanceof MyValue2) {
1345           return ((MyValue2)o).hash();
1346         } else if (o instanceof MyValue2[]) {
1347           return ((MyValue2[])o)[index].hash();
1348         } else if (o instanceof MyValue1[][]) {
1349           return ((MyValue1[][])o)[index][index].hash();
1350         } else if (o instanceof Long) {
1351           return (long)o;
1352         }
1353         return 0;
1354     }
1355 
1356     @Run(test = "test40")
1357     public void test40_verifier() {
1358         int index = Math.abs(rI) % 3;
1359         long result = test40(testValue1, 0);
1360         Asserts.assertEQ(result, testValue1.hashInterpreted());
1361         result = test40(testValue1Array, index);
1362         Asserts.assertEQ(result, testValue1.hashInterpreted());
1363         result = test40(testValue2, index);
1364         Asserts.assertEQ(result, testValue2.hash());
1365         result = test40(testValue2Array, index);
1366         Asserts.assertEQ(result, testValue2.hash());
1367         result = test40(testValue1Array2, index);
1368         Asserts.assertEQ(result, testValue1.hash());
1369         result = test40(Long.valueOf(42), index);
1370         Asserts.assertEQ(result, 42L);
1371     }
1372 
1373     // Test for bug in Escape Analysis
1374     // TODO 8325106 Re-enable
1375     /*
1376     @DontInline
1377     public void test41_dontinline(Object o) {
1378         Asserts.assertEQ(o, rI);
1379     }
1380 
1381     @Test
1382     @IR(failOn = {ALLOC})
1383     public void test41() {
1384         MyValue1[] vals = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
1385         vals[0] = testValue1;
1386         test41_dontinline(vals[0].oa[0]);
1387         test41_dontinline(vals[0].oa[0]);
1388     }
1389 
1390     @Run(test = "test41")
1391     public void test41_verifier() {
1392         test41();
1393     }
1394     */
1395 
1396     // Test for bug in Escape Analysis
1397     private static final MyValue1 test42VT1 = MyValue1.createWithFieldsInline(rI, rL);
1398     private static final MyValue1 test42VT2 = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
1399 
1400     @Test
1401     @IR(failOn = {ALLOC})
1402     public void test42() {
1403         MyValue1[] vals = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1404         vals[0] = test42VT1;
1405         vals[1] = test42VT2;
1406         Asserts.assertEQ(vals[0].hash(), test42VT1.hash());
1407         Asserts.assertEQ(vals[1].hash(), test42VT2.hash());
1408     }
1409 
1410     @Run(test = "test42")
1411     public void test42_verifier(RunInfo info) {
1412         if (!info.isWarmUp()) test42(); // We need -Xcomp behavior
1413     }
1414 
1415     // Test for bug in Escape Analysis
1416     @Test
1417     @IR(failOn = {ALLOC})
1418     public long test43(boolean deopt, Method m) {
1419         MyValue1[] vals = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1420         vals[0] = test42VT1;
1421         vals[1] = test42VT2;
1422 
1423         if (deopt) {
1424             // uncommon trap
1425             TestFramework.deoptimize(m);
1426             Asserts.assertEQ(vals[0].hash(), test42VT1.hash());
1427             Asserts.assertEQ(vals[1].hash(), test42VT2.hash());
1428         }
1429 
1430         return vals[0].hash();
1431     }
1432 
1433     @Run(test = "test43")
1434     public void test43_verifier(RunInfo info) {
1435         test43(!info.isWarmUp(), info.getTest());
1436     }
1437 
1438     // Tests writing an array element with a (statically known) incompatible type
1439     private static final MethodHandle setArrayElementIncompatible = OldInstructionHelper.loadCode(MethodHandles.lookup(),
1440         "setArrayElementIncompatible",
1441         MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class),
1442         CODE -> {
1443             CODE.
1444             aload_1().
1445             iload_2().
1446             aload_3().
1447             aastore().
1448             return_();
1449         });
1450 
1451     @Test
1452     public void test44(MyValue1[] va, int index, MyValue2 v) throws Throwable {
1453         setArrayElementIncompatible.invoke(this, va, index, v);
1454     }
1455 
1456     @Run(test = "test44")
1457     @Warmup(10000)
1458     public void test44_verifier() throws Throwable {
1459         int index = Math.abs(rI) % 3;
1460         try {
1461             test44(testValue1Array, index, testValue2);
1462             throw new RuntimeException("No ArrayStoreException thrown");
1463         } catch (ArrayStoreException e) {
1464             // Expected
1465         }
1466         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1467     }
1468 
1469     // Tests writing an array element with a (statically known) incompatible type
1470     @ForceInline
1471     public void test45_inline(Object[] oa, Object o, int index) {
1472         oa[index] = o;
1473     }
1474 
1475     @Test
1476     public void test45(MyValue1[] va, int index, MyValue2 v) throws Throwable {
1477         test45_inline(va, v, index);
1478     }
1479 
1480     @Run(test = "test45")
1481     public void test45_verifier() throws Throwable {
1482         int index = Math.abs(rI) % 3;
1483         try {
1484             test45(testValue1Array, index, testValue2);
1485             throw new RuntimeException("No ArrayStoreException thrown");
1486         } catch (ArrayStoreException e) {
1487             // Expected
1488         }
1489         Asserts.assertEQ(testValue1Array[index].hash(), hash());
1490     }
1491 
1492     // instanceof tests with inline types
1493     @Test
1494     @IR(failOn = {ALLOC_G})
1495     public boolean test46(MyValue1 vt) {
1496         Object obj = vt;
1497         return obj instanceof MyValue1;
1498     }
1499 
1500     @Run(test = "test46")
1501     public void test46_verifier() {
1502         MyValue1 vt = testValue1;
1503         boolean result = test46(vt);
1504         Asserts.assertTrue(result);
1505     }
1506 
1507     @Test
1508     @IR(failOn = {ALLOC_G})
1509     public boolean test47(MyValue1 vt) {
1510         Object obj = vt;
1511         return obj instanceof MyValue2;
1512     }
1513 
1514     @Run(test = "test47")
1515     public void test47_verifier() {
1516         MyValue1 vt = testValue1;
1517         boolean result = test47(vt);
1518         Asserts.assertFalse(result);
1519     }
1520 
1521     @Test
1522     @IR(failOn = {ALLOC_G})
1523     public boolean test48(Object obj) {
1524         return obj instanceof MyValue1;
1525     }
1526 
1527     @Run(test = "test48")
1528     public void test48_verifier() {
1529         MyValue1 vt = testValue1;
1530         boolean result = test48(vt);
1531         Asserts.assertTrue(result);
1532     }
1533 
1534     @Test
1535     @IR(failOn = {ALLOC_G})
1536     public boolean test49(Object obj) {
1537         return obj instanceof MyValue2;
1538     }
1539 
1540     @Run(test = "test49")
1541     public void test49_verifier() {
1542         MyValue1 vt = testValue1;
1543         boolean result = test49(vt);
1544         Asserts.assertFalse(result);
1545     }
1546 
1547     @Test
1548     @IR(failOn = {ALLOC_G})
1549     public boolean test50(Object obj) {
1550         return obj instanceof MyValue1;
1551     }
1552 
1553     @Run(test = "test50")
1554     public void test50_verifier() {
1555         Asserts.assertFalse(test49(new NonValueClass(42)));
1556     }
1557 
1558     // Inline type with some non-flattened fields
1559     @ImplicitlyConstructible
1560     @LooselyConsistentValue
1561     value class Test51Value {
1562         Object objectField1;
1563         Object objectField2;
1564         Object objectField3;
1565         Object objectField4;
1566         Object objectField5;
1567         Object objectField6;
1568 
1569         @NullRestricted
1570         MyValue1 valueField1;
1571         @NullRestricted
1572         MyValue1 valueField2;
1573         MyValue1 valueField3;
1574         @NullRestricted
1575         MyValue1 valueField4;
1576         MyValue1 valueField5;
1577 
1578         public Test51Value() {
1579             objectField1 = null;
1580             objectField2 = null;
1581             objectField3 = null;
1582             objectField4 = null;
1583             objectField5 = null;
1584             objectField6 = null;
1585             valueField1 = testValue1;
1586             valueField2 = testValue1;
1587             valueField3 = testValue1;
1588             valueField4 = MyValue1.createDefaultDontInline();
1589             valueField5 = MyValue1.createDefaultDontInline();
1590         }
1591 
1592         public Test51Value(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6,
1593                            MyValue1 vt1, MyValue1 vt2, MyValue1 vt3, MyValue1 vt4, MyValue1 vt5) {
1594             objectField1 = o1;
1595             objectField2 = o2;
1596             objectField3 = o3;
1597             objectField4 = o4;
1598             objectField5 = o5;
1599             objectField6 = o6;
1600             valueField1 = vt1;
1601             valueField2 = vt2;
1602             valueField3 = vt3;
1603             valueField4 = vt4;
1604             valueField5 = vt5;
1605         }
1606 
1607         @ForceInline
1608         public long test(Test51Value holder, MyValue1 vt1, Object vt2) {
1609             holder = new Test51Value(vt1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6,
1610                                      holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5);
1611             holder = new Test51Value(holder.objectField1, (MyValue1)vt2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6,
1612                                      holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5);
1613             holder = new Test51Value(holder.objectField1, holder.objectField2, testValue1, holder.objectField4, holder.objectField5, holder.objectField6,
1614                                      holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5);
1615             holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, MyValue1.createWithFieldsDontInline(rI, rL), holder.objectField5, holder.objectField6,
1616                                      holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5);
1617             holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.valueField1, holder.objectField6,
1618                                      holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5);
1619             holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.valueField3,
1620                                      holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5);
1621             holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6,
1622                                      (MyValue1)holder.objectField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5);
1623             holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6,
1624                                      holder.valueField1, (MyValue1)vt2, holder.valueField3, holder.valueField4, holder.valueField5);
1625             holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6,
1626                                      holder.valueField1, holder.valueField2, (MyValue1)vt2, holder.valueField4, holder.valueField5);
1627 
1628             return ((MyValue1)holder.objectField1).hash() +
1629                    ((MyValue1)holder.objectField2).hash() +
1630                    ((MyValue1)holder.objectField3).hash() +
1631                    ((MyValue1)holder.objectField4).hash() +
1632                    ((MyValue1)holder.objectField5).hash() +
1633                    ((MyValue1)holder.objectField6).hash() +
1634                    holder.valueField1.hash() +
1635                    holder.valueField2.hash() +
1636                    holder.valueField3.hash() +
1637                    holder.valueField4.hashPrimitive();
1638         }
1639     }
1640 
1641     // Pass arguments via fields to avoid exzessive spilling leading to compilation bailouts
1642     @NullRestricted
1643     static Test51Value test51_arg1;
1644     @NullRestricted
1645     static MyValue1 test51_arg2;
1646     static Object test51_arg3;
1647 
1648     // Same as test2 but with field holder being an inline type
1649     @Test
1650     public long test51() {
1651         return test51_arg1.test(test51_arg1, test51_arg2, test51_arg3);
1652     }
1653 
1654     @Run(test = "test51")
1655     public void test51_verifier() {
1656         MyValue1 vt = testValue1;
1657         MyValue1 def = MyValue1.createDefaultDontInline();
1658         Test51Value holder = new Test51Value();
1659         Asserts.assertEQ(testValue1.hash(), vt.hash());
1660         Asserts.assertEQ(holder.valueField1.hash(), vt.hash());
1661         test51_arg1 = holder;
1662         test51_arg2 = vt;
1663         test51_arg3 = vt;
1664         long result = test51();
1665         Asserts.assertEQ(result, 9*vt.hash() + def.hashPrimitive());
1666     }
1667 
1668     // Access non-flattened, uninitialized inline type field with inline type holder
1669     @Test
1670     @IR(failOn = {ALLOC})
1671     public void test52(Test51Value holder) {
1672         if ((Object)holder.valueField5 != null) {
1673             throw new RuntimeException("Should be null");
1674         }
1675     }
1676 
1677     @Run(test = "test52")
1678     public void test52_verifier() {
1679         Test51Value vt = new Test51Value(null, null, null, null, null, null,
1680                                          MyValue1.createDefaultInline(), MyValue1.createDefaultInline(), null, MyValue1.createDefaultInline(), null);
1681         test52(vt);
1682     }
1683 
1684     // Merging inline types of different types
1685     @Test
1686     public Object test53(Object o, boolean b) {
1687         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1688         return b ? vt : o;
1689     }
1690 
1691     @Run(test = "test53")
1692     public void test53_verifier() {
1693         test53(new Object(), false);
1694         MyValue1 result = (MyValue1)test53(new Object(), true);
1695         Asserts.assertEQ(result.hash(), hash());
1696     }
1697 
1698     @Test
1699     public Object test54(boolean b) {
1700         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1701         return b ? vt : testValue2;
1702     }
1703 
1704     @Run(test = "test54")
1705     public void test54_verifier() {
1706         MyValue1 result1 = (MyValue1)test54(true);
1707         Asserts.assertEQ(result1.hash(), hash());
1708         MyValue2 result2 = (MyValue2)test54(false);
1709         Asserts.assertEQ(result2.hash(), testValue2.hash());
1710     }
1711 
1712     @Test
1713     public Object test55(boolean b) {
1714         MyValue1 vt1 = MyValue1.createWithFieldsInline(rI, rL);
1715         MyValue2 vt2 = MyValue2.createWithFieldsInline(rI, rD);
1716         return b ? vt1 : vt2;
1717     }
1718 
1719     @Run(test = "test55")
1720     public void test55_verifier() {
1721         MyValue1 result1 = (MyValue1)test55(true);
1722         Asserts.assertEQ(result1.hash(), hash());
1723         MyValue2 result2 = (MyValue2)test55(false);
1724         Asserts.assertEQ(result2.hash(), testValue2.hash());
1725     }
1726 
1727     // Test synchronization on inline types
1728     @Test
1729     public void test56(Object vt) {
1730         synchronized (vt) {
1731             throw new RuntimeException("test56 failed: synchronization on inline type should not succeed");
1732         }
1733     }
1734 
1735     @Run(test = "test56")
1736     public void test56_verifier() {
1737         try {
1738             test56(testValue1);
1739             throw new RuntimeException("test56 failed: no exception thrown");
1740         } catch (IllegalMonitorStateException ex) {
1741             // Expected
1742         }
1743     }
1744 
1745     @ForceInline
1746     public void test57_inline(Object vt) {
1747         synchronized (vt) {
1748             throw new RuntimeException("test57 failed: synchronization on inline type should not succeed");
1749         }
1750     }
1751 
1752     @Test
1753     @IR(failOn = {ALLOC_G})
1754     public void test57(MyValue1 vt) {
1755         test57_inline(vt);
1756     }
1757 
1758     @Run(test = "test57")
1759     public void test57_verifier() {
1760         try {
1761             test57(testValue1);
1762             throw new RuntimeException("test57 failed: no exception thrown");
1763         } catch (IllegalMonitorStateException ex) {
1764             // Expected
1765         }
1766     }
1767 
1768     @ForceInline
1769     public void test58_inline(Object vt) {
1770         synchronized (vt) {
1771             throw new RuntimeException("test58 failed: synchronization on inline type should not succeed");
1772         }
1773     }
1774 
1775     @Test
1776     @IR(failOn = {ALLOC})
1777     public void test58() {
1778         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1779         test58_inline(vt);
1780     }
1781 
1782     @Run(test = "test58")
1783     public void test58_verifier() {
1784         try {
1785             test58();
1786             throw new RuntimeException("test58 failed: no exception thrown");
1787         } catch (IllegalMonitorStateException ex) {
1788             // Expected
1789         }
1790     }
1791 
1792     @Test
1793     public void test59(Object o, boolean b) {
1794         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1795         Object sync = b ? vt : o;
1796         synchronized (sync) {
1797             if (b) {
1798                 throw new RuntimeException("test59 failed: synchronization on inline type should not succeed");
1799             }
1800         }
1801     }
1802 
1803     @Run(test = "test59")
1804     public void test59_verifier() {
1805         test59(new Object(), false);
1806         try {
1807             test59(new Object(), true);
1808             throw new RuntimeException("test59 failed: no exception thrown");
1809         } catch (IllegalMonitorStateException ex) {
1810             // Expected
1811         }
1812     }
1813 
1814     @Test
1815     public void test60(boolean b) {
1816         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
1817         Object sync = b ? vt : testValue2;
1818         synchronized (sync) {
1819             throw new RuntimeException("test60 failed: synchronization on inline type should not succeed");
1820         }
1821     }
1822 
1823     @Run(test = "test60")
1824     public void test60_verifier() {
1825         try {
1826             test60(false);
1827             throw new RuntimeException("test60 failed: no exception thrown");
1828         } catch (IllegalMonitorStateException ex) {
1829             // Expected
1830         }
1831         try {
1832             test60(true);
1833             throw new RuntimeException("test60 failed: no exception thrown");
1834         } catch (IllegalMonitorStateException ex) {
1835             // Expected
1836         }
1837     }
1838 
1839     // Test catching the IllegalMonitorStateException in compiled code
1840     @Test
1841     public void test61(Object vt) {
1842         boolean thrown = false;
1843         try {
1844             synchronized (vt) {
1845                 throw new RuntimeException("test61 failed: no exception thrown");
1846             }
1847         } catch (IllegalMonitorStateException ex) {
1848             thrown = true;
1849         }
1850         if (!thrown) {
1851             throw new RuntimeException("test61 failed: no exception thrown");
1852         }
1853     }
1854 
1855     @Run(test = "test61")
1856     public void test61_verifier() {
1857         test61(testValue1);
1858     }
1859 
1860     @Test
1861     public void test62(Object o) {
1862         try {
1863             synchronized (o) { }
1864         } catch (IllegalMonitorStateException ex) {
1865             // Expected
1866             return;
1867         }
1868         throw new RuntimeException("test62 failed: no exception thrown");
1869     }
1870 
1871     @Run(test = "test62")
1872     public void test62_verifier() {
1873         test62(testValue1);
1874     }
1875 
1876     // Test synchronization without any instructions in the synchronized block
1877     @Test
1878     public void test63(Object o) {
1879         synchronized (o) { }
1880     }
1881 
1882     @Run(test = "test63")
1883     public void test63_verifier() {
1884         try {
1885             test63(testValue1);
1886         } catch (IllegalMonitorStateException ex) {
1887             // Expected
1888             return;
1889         }
1890         throw new RuntimeException("test63 failed: no exception thrown");
1891     }
1892 
1893     // type system test with interface and inline type
1894     @ForceInline
1895     public MyInterface test64Interface_helper(MyValue1 vt) {
1896         return vt;
1897     }
1898 
1899     @Test
1900     public MyInterface test64Interface(MyValue1 vt) {
1901         return test64Interface_helper(vt);
1902     }
1903 
1904     @Run(test = "test64Interface")
1905     public void test64Interface_verifier() {
1906         test64Interface(testValue1);
1907     }
1908 
1909     // type system test with abstract and inline type
1910     @ForceInline
1911     public MyAbstract test64Abstract_helper(MyValue1 vt) {
1912         return vt;
1913     }
1914 
1915     @Test
1916     public MyAbstract test64Abstract(MyValue1 vt) {
1917         return test64Abstract_helper(vt);
1918     }
1919 
1920     @Run(test = "test64Abstract")
1921     public void test64Abstract_verifier() {
1922         test64Abstract(testValue1);
1923     }
1924 
1925     // Array store tests
1926     @Test
1927     public void test65(Object[] array, MyValue1 vt) {
1928         array[0] = vt;
1929     }
1930 
1931     @Run(test = "test65")
1932     public void test65_verifier() {
1933         Object[] array = new Object[1];
1934         test65(array, testValue1);
1935         Asserts.assertEQ(((MyValue1)array[0]).hash(), testValue1.hash());
1936     }
1937 
1938     @Test
1939     public void test66(Object[] array, MyValue1 vt) {
1940         array[0] = vt;
1941     }
1942 
1943     @Run(test = "test66")
1944     public void test66_verifier() {
1945         MyValue1[] array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
1946         test66(array, testValue1);
1947         Asserts.assertEQ(array[0].hash(), testValue1.hash());
1948     }
1949 
1950     @Test
1951     public void test67(Object[] array, Object vt) {
1952         array[0] = vt;
1953     }
1954 
1955     @Run(test = "test67")
1956     public void test67_verifier() {
1957         MyValue1[] array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
1958         test67(array, testValue1);
1959         Asserts.assertEQ(array[0].hash(), testValue1.hash());
1960     }
1961 
1962     @Test
1963     public void test68(Object[] array, NonValueClass o) {
1964         array[0] = o;
1965     }
1966 
1967     @Run(test = "test68")
1968     public void test68_verifier() {
1969         NonValueClass[] array = new NonValueClass[1];
1970         NonValueClass obj = new NonValueClass(1);
1971         test68(array, obj);
1972         Asserts.assertEQ(array[0], obj);
1973     }
1974 
1975     // Test convertion between an inline type and java.lang.Object without an allocation
1976     @ForceInline
1977     public Object test69_sum(Object a, Object b) {
1978         int sum = ((MyValue1)a).x + ((MyValue1)b).x;
1979         return MyValue1.setX(((MyValue1)a), sum);
1980     }
1981 
1982     @Test
1983     @IR(failOn = {ALLOC_G, STORE})
1984     public int test69(MyValue1[] array) {
1985         MyValue1 result = MyValue1.createDefaultInline();
1986         for (int i = 0; i < array.length; ++i) {
1987             result = (MyValue1)test69_sum(result, array[i]);
1988         }
1989         return result.x;
1990     }
1991 
1992     @Run(test = "test69")
1993     public void test69_verifier() {
1994         int result = test69(testValue1Array);
1995         Asserts.assertEQ(result, rI * testValue1Array.length);
1996     }
1997 
1998     // Same as test69 but with an Interface
1999     @ForceInline
2000     public MyInterface test70Interface_sum(MyInterface a, MyInterface b) {
2001         int sum = ((MyValue1)a).x + ((MyValue1)b).x;
2002         return MyValue1.setX(((MyValue1)a), sum);
2003     }
2004 
2005     @Test
2006     @IR(failOn = {ALLOC_G, STORE})
2007     public int test70Interface(MyValue1[] array) {
2008         MyValue1 result = MyValue1.createDefaultInline();
2009         for (int i = 0; i < array.length; ++i) {
2010             result = (MyValue1)test70Interface_sum(result, array[i]);
2011         }
2012         return result.x;
2013     }
2014 
2015     @Run(test = "test70Interface")
2016     public void test70Interface_verifier() {
2017         int result = test70Interface(testValue1Array);
2018         Asserts.assertEQ(result, rI * testValue1Array.length);
2019     }
2020 
2021     // Same as test69 but with an Abstract
2022     @ForceInline
2023     public MyAbstract test70Abstract_sum(MyAbstract a, MyAbstract b) {
2024         int sum = ((MyValue1)a).x + ((MyValue1)b).x;
2025         return MyValue1.setX(((MyValue1)a), sum);
2026     }
2027 
2028     @Test
2029     @IR(failOn = {ALLOC_G, STORE})
2030     public int test70Abstract(MyValue1[] array) {
2031         MyValue1 result = MyValue1.createDefaultInline();
2032         for (int i = 0; i < array.length; ++i) {
2033             result = (MyValue1)test70Abstract_sum(result, array[i]);
2034         }
2035         return result.x;
2036     }
2037 
2038     @Run(test = "test70Abstract")
2039     public void test70Abstract_verifier() {
2040         int result = test70Abstract(testValue1Array);
2041         Asserts.assertEQ(result, rI * testValue1Array.length);
2042     }
2043 
2044     // Test that allocated inline type is not used in non-dominated path
2045     public MyValue1 test71_inline(Object obj) {
2046         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2047         try {
2048             vt = (MyValue1)Objects.requireNonNull(obj);
2049             throw new RuntimeException("NullPointerException expected");
2050         } catch (NullPointerException e) {
2051             // Expected
2052         }
2053         return vt;
2054     }
2055 
2056     @Test
2057     @IR(failOn = {ALLOC})
2058     public MyValue1 test71() {
2059         return test71_inline(null);
2060     }
2061 
2062     @Run(test = "test71")
2063     public void test71_verifier() {
2064         MyValue1 vt = test71();
2065         Asserts.assertEquals(vt.hash(), hash());
2066     }
2067 
2068     // Test calling a method on an uninitialized inline type
2069     @ImplicitlyConstructible
2070     @LooselyConsistentValue
2071     value class Test72Value {
2072         int x = 0;
2073 
2074         public int get() {
2075             return x;
2076         }
2077     }
2078 
2079     // Make sure Test72Value is loaded but not initialized
2080     public void unused(Test72Value vt) { }
2081 
2082     @Test
2083     @IR(failOn = {ALLOC_G})
2084     public int test72() {
2085         Test72Value vt = new Test72Value();
2086         return vt.get();
2087     }
2088 
2089     @Run(test = "test72")
2090     @Warmup(0)
2091     public void test72_verifier() {
2092         int result = test72();
2093         Asserts.assertEquals(result, 0);
2094     }
2095 
2096     // Tests for loading/storing unkown values
2097     @Test
2098     public Object test73(Object[] va) {
2099         return va[0];
2100     }
2101 
2102     @Run(test = "test73")
2103     public void test73_verifier() {
2104         MyValue1 vt = (MyValue1)test73(testValue1Array);
2105         Asserts.assertEquals(testValue1Array[0].hash(), vt.hash());
2106     }
2107 
2108     @Test
2109     public void test74(Object[] va, Object vt) {
2110         va[0] = vt;
2111     }
2112 
2113     @Run(test = "test74")
2114     public void test74_verifier() {
2115         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2116         test74(va, testValue1);
2117         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2118     }
2119 
2120     // Verify that mixing instances and arrays with the clone api
2121     // doesn't break anything
2122     @Test
2123     @IR(failOn = {ALLOC_G})
2124     public Object test75(Object o) {
2125         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2126         Object[] next = va;
2127         Object[] arr = va;
2128         for (int i = 0; i < 10; i++) {
2129             arr = next;
2130             next = new NonValueClass[1];
2131         }
2132         return arr[0];
2133     }
2134 
2135     @Run(test = "test75")
2136     public void test75_verifier() {
2137         test75(42);
2138     }
2139 
2140     // Casting an NonValueClass to a inline type should throw a ClassCastException
2141     @ForceInline
2142     public MyValue1 test77_helper(Object o) {
2143         return (MyValue1)o;
2144     }
2145 
2146     @Test
2147     @IR(failOn = {ALLOC_G})
2148     public MyValue1 test77(NonValueClass obj) throws Throwable {
2149         return test77_helper(obj);
2150     }
2151 
2152     @Run(test = "test77")
2153     public void test77_verifier() throws Throwable {
2154         try {
2155             test77(new NonValueClass(42));
2156             throw new RuntimeException("ClassCastException expected");
2157         } catch (ClassCastException e) {
2158             // Expected
2159         } catch (Exception e) {
2160             throw new RuntimeException("test77 failed: unexpected exception", e);
2161         }
2162     }
2163 
2164     // Casting a null NonValueClass to a nullable inline type should not throw
2165     @ForceInline
2166     public MyValue1 test78_helper(Object o) {
2167         return (MyValue1)o;
2168     }
2169 
2170     @Test
2171     @IR(failOn = {ALLOC_G})
2172     public MyValue1 test78(NonValueClass obj) throws Throwable {
2173         return test78_helper(obj);
2174     }
2175 
2176     @Run(test = "test78")
2177     public void test78_verifier() throws Throwable {
2178         try {
2179             test78(null); // Should not throw
2180         } catch (Exception e) {
2181             throw new RuntimeException("test78 failed: unexpected exception", e);
2182         }
2183     }
2184 
2185     // Casting an NonValueClass to a nullable inline type should throw a ClassCastException
2186     @ForceInline
2187     public MyValue1 test79_helper(Object o) {
2188         return (MyValue1)o;
2189     }
2190 
2191     @Test
2192     @IR(failOn = {ALLOC_G})
2193     public MyValue1 test79(NonValueClass obj) throws Throwable {
2194         return test79_helper(obj);
2195     }
2196 
2197     @Run(test = "test79")
2198     public void test79_verifier() throws Throwable {
2199         try {
2200             test79(new NonValueClass(42));
2201             throw new RuntimeException("ClassCastException expected");
2202         } catch (ClassCastException e) {
2203             // Expected
2204         } catch (Exception e) {
2205             throw new RuntimeException("test79 failed: unexpected exception", e);
2206         }
2207     }
2208 
2209     // Test flattened field with non-flattenend (but flattenable) inline type field
2210     @ImplicitlyConstructible
2211     @LooselyConsistentValue
2212     static value class Small {
2213         int i;
2214         @NullRestricted
2215         Big big; // Too big to be flattened
2216 
2217         private Small() {
2218             i = rI;
2219             big = new Big();
2220         }
2221     }
2222 
2223     @ImplicitlyConstructible
2224     @LooselyConsistentValue
2225     static value class Big {
2226         long l0,l1,l2,l3,l4,l5,l6,l7,l8,l9;
2227         long l10,l11,l12,l13,l14,l15,l16,l17,l18,l19;
2228         long l20,l21,l22,l23,l24,l25,l26,l27,l28,l29;
2229 
2230         private Big() {
2231             l0 = l1 = l2 = l3 = l4 = l5 = l6 = l7 = l8 = l9 = rL;
2232             l10 = l11 = l12 = l13 = l14 = l15 = l16 = l17 = l18 = l19 = rL+1;
2233             l20 = l21 = l22 = l23 = l24 = l25 = l26 = l27 = l28 = l29 = rL+2;
2234         }
2235     }
2236 
2237     @NullRestricted
2238     Small small = new Small();
2239     @NullRestricted
2240     Small smallDefault;
2241     @NullRestricted
2242     Big big = new Big();
2243     @NullRestricted
2244     Big bigDefault;
2245 
2246     @Test
2247     public long test80() {
2248         return small.i + small.big.l0 + smallDefault.i + smallDefault.big.l29 + big.l0 + bigDefault.l29;
2249     }
2250 
2251     @Run(test = "test80")
2252     public void test80_verifier() throws Throwable {
2253         long result = test80();
2254         Asserts.assertEQ(result, rI + 2*rL);
2255     }
2256 
2257     // Test scalarization with exceptional control flow
2258     public int test81Callee(MyValue1 vt)  {
2259         return vt.x;
2260     }
2261 
2262     @Test
2263     @IR(failOn = {ALLOC_G, LOAD, STORE})
2264     public int test81()  {
2265         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2266         int result = 0;
2267         for (int i = 0; i < 10; i++) {
2268             try {
2269                 result += test81Callee(vt);
2270             } catch (NullPointerException npe) {
2271                 result += rI;
2272             }
2273         }
2274         return result;
2275     }
2276 
2277     @Run(test = "test81")
2278     public void test81_verifier() {
2279         int result = test81();
2280         Asserts.assertEQ(result, 10*rI);
2281     }
2282 
2283     // Test check for null free array when storing to inline tpye array
2284     @Test
2285     public void test82(Object[] dst, Object v) {
2286         dst[0] = v;
2287     }
2288 
2289     @Run(test = "test82")
2290     public void test82_verifier(RunInfo info) {
2291         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1);
2292         test82(dst, testValue2);
2293         if (!info.isWarmUp()) {
2294             try {
2295                 test82(dst, null);
2296                 throw new RuntimeException("No ArrayStoreException thrown");
2297             } catch (NullPointerException e) {
2298                 // Expected
2299             }
2300         }
2301     }
2302 
2303     @Test
2304     @IR(failOn = {ALLOC_G})
2305     public void test83(Object[] dst, Object v, boolean flag) {
2306         if (dst == null) { // null check
2307         }
2308         if (flag) {
2309             if (dst.getClass() == MyValue1[].class) { // trigger split if
2310             }
2311         } else {
2312             dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1); // constant null free property
2313         }
2314         dst[0] = v;
2315     }
2316 
2317     @Run(test = "test83")
2318     @Warmup(10000)
2319     public void test83_verifier(RunInfo info) {
2320         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1);
2321         test83(dst, testValue2, false);
2322         test83(dst, testValue2, true);
2323         if (!info.isWarmUp()) {
2324             try {
2325                 test83(dst, null, true);
2326                 throw new RuntimeException("No ArrayStoreException thrown");
2327             } catch (NullPointerException e) {
2328                 // Expected
2329             }
2330         }
2331     }
2332 
2333     private void rerun_and_recompile_for(Method m, int num, Runnable test) {
2334         for (int i = 1; i < num; i++) {
2335             test.run();
2336 
2337             if (!TestFramework.isCompiled(m)) {
2338                 TestFramework.compile(m, CompLevel.C2);
2339             }
2340         }
2341     }
2342 
2343     // Tests for the Loop Unswitching optimization
2344     // Should make 2 copies of the loop, one for non flattened arrays, one for other cases.
2345     @Test
2346     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2347         counts = {COUNTEDLOOP_MAIN, "= 2"})
2348     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2349         counts = {COUNTEDLOOP_MAIN, "= 1"})
2350     public void test84(Object[] src, Object[] dst) {
2351         for (int i = 0; i < src.length; i++) {
2352             dst[i] = src[i];
2353         }
2354     }
2355 
2356     @Run(test = "test84")
2357     @Warmup(0)
2358     public void test84_verifier(RunInfo info) {
2359         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
2360         Arrays.fill(src, testValue2);
2361         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
2362         rerun_and_recompile_for(info.getTest(), 10,
2363                                 () ->  { test84(src, dst);
2364                                          Asserts.assertTrue(Arrays.equals(src, dst)); });
2365     }
2366 
2367     @Test
2368     @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"},
2369         counts = {COUNTEDLOOP, "= 2", LOAD_UNKNOWN_INLINE, "= 1"})
2370     @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"},
2371         counts = {COUNTEDLOOP_MAIN, "= 2", LOAD_UNKNOWN_INLINE, "= 4"})
2372     public void test85(Object[] src, Object[] dst) {
2373         for (int i = 0; i < src.length; i++) {
2374             dst[i] = src[i];
2375         }
2376     }
2377 
2378     @Run(test = "test85")
2379     @Warmup(0)
2380     public void test85_verifier(RunInfo info) {
2381         Object[] src = new Object[100];
2382         Arrays.fill(src, new Object());
2383         src[0] = null;
2384         Object[] dst = new Object[100];
2385         rerun_and_recompile_for(info.getTest(), 10,
2386                                 () -> { test85(src, dst);
2387                                         Asserts.assertTrue(Arrays.equals(src, dst)); });
2388     }
2389 
2390     @Test
2391     @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"},
2392         counts = {COUNTEDLOOP, "= 2"})
2393     @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"},
2394         counts = {COUNTEDLOOP_MAIN, "= 2"})
2395     public void test86(Object[] src, Object[] dst) {
2396         for (int i = 0; i < src.length; i++) {
2397             dst[i] = src[i];
2398         }
2399     }
2400 
2401     @Run(test = "test86")
2402     @Warmup(0)
2403     public void test86_verifier(RunInfo info) {
2404         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
2405         Arrays.fill(src, testValue2);
2406         Object[] dst = new Object[100];
2407         rerun_and_recompile_for(info.getTest(), 10,
2408                                 () -> { test86(src, dst);
2409                                         Asserts.assertTrue(Arrays.equals(src, dst)); });
2410     }
2411 
2412     @Test
2413     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2414         counts = {COUNTEDLOOP_MAIN, "= 2"})
2415     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2416         counts = {COUNTEDLOOP_MAIN, "= 1"})
2417     public void test87(Object[] src, Object[] dst) {
2418         for (int i = 0; i < src.length; i++) {
2419             dst[i] = src[i];
2420         }
2421     }
2422 
2423     @Run(test = "test87")
2424     @Warmup(0)
2425     public void test87_verifier(RunInfo info) {
2426         Object[] src = new Object[100];
2427         Arrays.fill(src, testValue2);
2428         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
2429 
2430         rerun_and_recompile_for(info.getTest(), 10,
2431                                 () -> { test87(src, dst);
2432                                         Asserts.assertTrue(Arrays.equals(src, dst)); });
2433     }
2434 
2435     @Test
2436     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2437         counts = {COUNTEDLOOP_MAIN, "= 2"})
2438     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2439         counts = {COUNTEDLOOP_MAIN, "= 0"})
2440     public void test88(Object[] src1, Object[] dst1, Object[] src2, Object[] dst2) {
2441         for (int i = 0; i < src1.length; i++) {
2442             dst1[i] = src1[i];
2443             dst2[i] = src2[i];
2444         }
2445     }
2446 
2447     @Run(test = "test88")
2448     @Warmup(0)
2449     public void test88_verifier(RunInfo info) {
2450         MyValue2[] src1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
2451         Arrays.fill(src1, testValue2);
2452         MyValue2[] dst1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
2453         Object[] src2 = new Object[100];
2454         Arrays.fill(src2, new Object());
2455         Object[] dst2 = new Object[100];
2456 
2457         rerun_and_recompile_for(info.getTest(), 10,
2458                                 () -> { test88(src1, dst1, src2, dst2);
2459                                         Asserts.assertTrue(Arrays.equals(src1, dst1));
2460                                         Asserts.assertTrue(Arrays.equals(src2, dst2)); });
2461     }
2462 
2463     @Test
2464     public boolean test89(Object obj) {
2465         return obj.getClass() == NonValueClass.class;
2466     }
2467 
2468     @Run(test = "test89")
2469     public void test89_verifier() {
2470         Asserts.assertTrue(test89(new NonValueClass(42)));
2471         Asserts.assertFalse(test89(new Object()));
2472     }
2473 
2474     @Test
2475     public NonValueClass test90(Object obj) {
2476         return (NonValueClass)obj;
2477     }
2478 
2479     @Run(test = "test90")
2480     public void test90_verifier() {
2481         test90(new NonValueClass(42));
2482         try {
2483             test90(new Object());
2484             throw new RuntimeException("ClassCastException expected");
2485         } catch (ClassCastException e) {
2486             // Expected
2487         }
2488     }
2489 
2490     @Test
2491     public boolean test91(Object obj) {
2492         return obj.getClass() == MyValue2[].class;
2493     }
2494 
2495     @Run(test = "test91")
2496     public void test91_verifier() {
2497         Asserts.assertFalse(test91((MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1)));
2498         Asserts.assertTrue(test91(new MyValue2[1]));
2499         Asserts.assertFalse(test91(new Object()));
2500     }
2501 
2502     @ImplicitlyConstructible
2503     @LooselyConsistentValue
2504     static value class Test92Value {
2505         int field;
2506 
2507         public Test92Value() {
2508             field = 0x42;
2509         }
2510     }
2511 
2512     @Test
2513     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2514         counts = {CLASS_CHECK_TRAP, "= 2"},
2515         failOn = {LOAD_UNKNOWN_INLINE, ALLOC_G, MEMBAR})
2516     public Object test92(Object[] array) {
2517         // Dummy loops to ensure we run enough passes of split if
2518         for (int i = 0; i < 2; i++) {
2519             for (int j = 0; j < 2; j++) {
2520               for (int k = 0; k < 2; k++) {
2521               }
2522             }
2523         }
2524 
2525         return (NonValueClass)array[0];
2526     }
2527 
2528     @Run(test = "test92")
2529     @Warmup(10000)
2530     public void test92_verifier() {
2531         Object[] array = new Object[1];
2532         Object obj = new NonValueClass(rI);
2533         array[0] = obj;
2534         Object result = test92(array);
2535         Asserts.assertEquals(result, obj);
2536     }
2537 
2538     // If the class check succeeds, the flattened array check that
2539     // precedes will never succeed and the flat array branch should
2540     // trigger an uncommon trap.
2541     @Test
2542     public Object test93(Object[] array) {
2543         for (int i = 0; i < 2; i++) {
2544             for (int j = 0; j < 2; j++) {
2545             }
2546         }
2547 
2548         Object v = (NonValueClass)array[0];
2549         return v;
2550     }
2551 
2552     @Run(test = "test93")
2553     @Warmup(10000)
2554     public void test93_verifier(RunInfo info) {
2555         if (info.isWarmUp()) {
2556             Object[] array = new Object[1];
2557             array[0] = new NonValueClass(42);
2558             Object result = test93(array);
2559             Asserts.assertEquals(((NonValueClass)result).x, 42);
2560         } else {
2561             Object[] array = (Test92Value[])ValueClass.newNullRestrictedArray(Test92Value.class, 1);
2562             Method m = info.getTest();
2563             int extra = 3;
2564             for (int j = 0; j < extra; j++) {
2565                 for (int i = 0; i < 10; i++) {
2566                     try {
2567                         test93(array);
2568                     } catch (ClassCastException cce) {
2569                     }
2570                 }
2571                 boolean compiled = TestFramework.isCompiled(m);
2572                 boolean compilationSkipped = info.isCompilationSkipped();
2573                 Asserts.assertTrue(compilationSkipped || compiled || (j != extra-1));
2574                 if (!compilationSkipped && !compiled) {
2575                     TestFramework.compile(m, CompLevel.ANY);
2576                 }
2577             }
2578         }
2579     }
2580 
2581     @Test
2582     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2583         counts = {CLASS_CHECK_TRAP, "= 2", LOOP, "= 1"},
2584         failOn = {LOAD_UNKNOWN_INLINE, ALLOC_G, MEMBAR})
2585     public int test94(Object[] array) {
2586         int res = 0;
2587         for (int i = 1; i < 4; i *= 2) {
2588             Object v = array[i];
2589             res += ((NonValueClass)v).x;
2590         }
2591         return res;
2592     }
2593 
2594     @Run(test = "test94")
2595     @Warmup(10000)
2596     public void test94_verifier() {
2597         Object[] array = new Object[4];
2598         Object obj = new NonValueClass(rI);
2599         array[0] = obj;
2600         array[1] = obj;
2601         array[2] = obj;
2602         array[3] = obj;
2603         int result = test94(array);
2604         Asserts.assertEquals(result, rI * 2);
2605     }
2606 
2607     @Test
2608     public boolean test95(Object o1, Object o2) {
2609         return o1 == o2;
2610     }
2611 
2612     @Run(test = "test95")
2613     @Warmup(10000)
2614     public void test95_verifier() {
2615         Object o1 = new Object();
2616         Object o2 = new Object();
2617         Asserts.assertTrue(test95(o1, o1));
2618         Asserts.assertTrue(test95(null, null));
2619         Asserts.assertFalse(test95(o1, null));
2620         Asserts.assertFalse(test95(o1, o2));
2621     }
2622 
2623     @Test
2624     public boolean test96(Object o1, Object o2) {
2625         return o1 == o2;
2626     }
2627 
2628     @Run(test = "test96")
2629     @Warmup(10000)
2630     public void test96_verifier(RunInfo info) {
2631         Object o1 = new Object();
2632         Object o2 = new Object();
2633         Asserts.assertTrue(test96(o1, o1));
2634         Asserts.assertFalse(test96(o1, o2));
2635         if (!info.isWarmUp()) {
2636             Asserts.assertTrue(test96(null, null));
2637             Asserts.assertFalse(test96(o1, null));
2638         }
2639     }
2640 
2641     // Abstract class tests
2642 
2643     @DontInline
2644     public MyAbstract test97_dontinline1(MyAbstract o) {
2645         return o;
2646     }
2647 
2648     @DontInline
2649     public MyValue1 test97_dontinline2(MyAbstract o) {
2650         return (MyValue1)o;
2651     }
2652 
2653     @ForceInline
2654     public MyAbstract test97_inline1(MyAbstract o) {
2655         return o;
2656     }
2657 
2658     @ForceInline
2659     public MyValue1 test97_inline2(MyAbstract o) {
2660         return (MyValue1)o;
2661     }
2662 
2663     @Test
2664     public MyValue1 test97() {
2665         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2666         vt = (MyValue1)test97_dontinline1(vt);
2667         vt =           test97_dontinline2(vt);
2668         vt = (MyValue1)test97_inline1(vt);
2669         vt =           test97_inline2(vt);
2670         return vt;
2671     }
2672 
2673     @Run(test = "test97")
2674     public void test97_verifier() {
2675         Asserts.assertEQ(test97().hash(), hash());
2676     }
2677 
2678     // Test storing/loading inline types to/from abstract and inline type fields
2679     MyAbstract abstractField1 = null;
2680     MyAbstract abstractField2 = null;
2681     MyAbstract abstractField3 = null;
2682     MyAbstract abstractField4 = null;
2683     MyAbstract abstractField5 = null;
2684     MyAbstract abstractField6 = null;
2685 
2686     @DontInline
2687     public MyAbstract readValueField5AsAbstract() {
2688         return (MyAbstract)valueField5;
2689     }
2690 
2691     @DontInline
2692     public MyAbstract readStaticValueField4AsAbstract() {
2693         return (MyAbstract)staticValueField4;
2694     }
2695 
2696     @Test
2697     public long test98(MyValue1 vt1, MyAbstract vt2) {
2698         abstractField1 = vt1;
2699         abstractField2 = (MyValue1)vt2;
2700         abstractField3 = MyValue1.createWithFieldsInline(rI, rL);
2701         abstractField4 = MyValue1.createWithFieldsDontInline(rI, rL);
2702         abstractField5 = valueField1;
2703         abstractField6 = valueField3;
2704         valueField1 = (MyValue1)abstractField1;
2705         valueField2 = (MyValue1)vt2;
2706         valueField3 = (MyValue1)vt2;
2707         staticValueField1 = (MyValue1)abstractField1;
2708         staticValueField2 = (MyValue1)vt1;
2709         // Don't inline these methods because reading NULL will trigger a deoptimization
2710         if (readValueField5AsAbstract() != null || readStaticValueField4AsAbstract() != null) {
2711             throw new RuntimeException("Should be null");
2712         }
2713         return ((MyValue1)abstractField1).hash() + ((MyValue1)abstractField2).hash() +
2714                ((MyValue1)abstractField3).hash() + ((MyValue1)abstractField4).hash() +
2715                ((MyValue1)abstractField5).hash() + ((MyValue1)abstractField6).hash() +
2716                 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() +
2717                 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive();
2718     }
2719 
2720     @Run(test = "test98")
2721     public void test98_verifier() {
2722         MyValue1 vt = testValue1;
2723         MyValue1 def = MyValue1.createDefaultDontInline();
2724         long result = test98(vt, vt);
2725         Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive());
2726     }
2727 
2728     value class MyObject2 extends MyAbstract {
2729         public int x;
2730 
2731         public MyObject2(int x) {
2732             this.x = x;
2733         }
2734 
2735         @ForceInline
2736         public long hash() {
2737             return x;
2738         }
2739     }
2740 
2741     // Test merging inline types and abstract classes
2742     @Test
2743     public MyAbstract test99(int state) {
2744         MyAbstract res = null;
2745         if (state == 0) {
2746             res = new MyObject2(rI);
2747         } else if (state == 1) {
2748             res = MyValue1.createWithFieldsInline(rI, rL);
2749         } else if (state == 2) {
2750             res = MyValue1.createWithFieldsDontInline(rI, rL);
2751         } else if (state == 3) {
2752             res = (MyValue1)objectField1;
2753         } else if (state == 4) {
2754             res = valueField1;
2755         } else if (state == 5) {
2756             res = null;
2757         }
2758         return res;
2759     }
2760 
2761     @Run(test = "test99")
2762     public void test99_verifier() {
2763         objectField1 = valueField1;
2764         MyAbstract result = null;
2765         result = test99(0);
2766         Asserts.assertEQ(((MyObject2)result).x, rI);
2767         result = test99(1);
2768         Asserts.assertEQ(((MyValue1)result).hash(), hash());
2769         result = test99(2);
2770         Asserts.assertEQ(((MyValue1)result).hash(), hash());
2771         result = test99(3);
2772         Asserts.assertEQ(((MyValue1)result).hash(), hash());
2773         result = test99(4);
2774         Asserts.assertEQ(((MyValue1)result).hash(), hash());
2775         result = test99(5);
2776         Asserts.assertEQ(result, null);
2777     }
2778 
2779     // Test merging inline types and abstract classes in loops
2780     @Test
2781     public MyAbstract test100(int iters) {
2782         MyAbstract res = new MyObject2(rI);
2783         for (int i = 0; i < iters; ++i) {
2784             if (res instanceof MyObject2) {
2785                 res = MyValue1.createWithFieldsInline(rI, rL);
2786             } else {
2787                 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL);
2788             }
2789         }
2790         return res;
2791     }
2792 
2793     @Run(test = "test100")
2794     public void test100_verifier() {
2795         MyObject2 result1 = (MyObject2)test100(0);
2796         Asserts.assertEQ(result1.x, rI);
2797         int iters = (Math.abs(rI) % 10) + 1;
2798         MyValue1 result2 = (MyValue1)test100(iters);
2799         MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL);
2800         Asserts.assertEQ(result2.hash(), vt.hash());
2801     }
2802 
2803     // Test inline types in abstract class variables that are live at safepoint
2804     @Test
2805     @IR(failOn = {ALLOC, STORE, LOOP})
2806     public long test101(MyValue1 arg, boolean deopt, Method m) {
2807         MyAbstract vt1 = MyValue1.createWithFieldsInline(rI, rL);
2808         MyAbstract vt2 = MyValue1.createWithFieldsDontInline(rI, rL);
2809         MyAbstract vt3 = arg;
2810         MyAbstract vt4 = valueField1;
2811         if (deopt) {
2812             // uncommon trap
2813             TestFramework.deoptimize(m);
2814         }
2815         return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() +
2816                ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash();
2817     }
2818 
2819     @Run(test = "test101")
2820     public void test101_verifier(RunInfo info) {
2821         long result = test101(valueField1, !info.isWarmUp(), info.getTest());
2822         Asserts.assertEQ(result, 4*hash());
2823     }
2824 
2825     // Test comparing inline types with abstract classes
2826     @Test
2827     public boolean test102(Object arg) {
2828         MyAbstract vt = MyValue1.createWithFieldsInline(rI, rL);
2829         if (vt == arg || vt == (MyAbstract)valueField1 || vt == abstractField1 || vt == null ||
2830             arg == vt || (MyAbstract)valueField1 == vt || abstractField1 == vt || null == vt) {
2831             return true;
2832         }
2833         return false;
2834     }
2835 
2836     @Run(test = "test102")
2837     public void test102_verifier() {
2838         boolean result = test102(null);
2839         Asserts.assertFalse(result);
2840     }
2841 
2842     // An abstract class with a non-static field can never be implemented by an inline type
2843     abstract class NoValueImplementors1 {
2844         int field = 42;
2845     }
2846 
2847     class MyObject3 extends NoValueImplementors1 {
2848 
2849     }
2850 
2851     class MyObject4 extends NoValueImplementors1 {
2852 
2853     }
2854 
2855     // Loading from an abstract class array does not require a flatness check if the abstract class has a non-static field
2856     @Test
2857     @IR(failOn = {ALLOC_G, MEMBAR, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
2858     public NoValueImplementors1 test103(NoValueImplementors1[] array, int i) {
2859         return array[i];
2860     }
2861 
2862     @Run(test = "test103")
2863     public void test103_verifier() {
2864         NoValueImplementors1[] array1 = new NoValueImplementors1[3];
2865         MyObject3[] array2 = new MyObject3[3];
2866         MyObject4[] array3 = new MyObject4[3];
2867         NoValueImplementors1 result = test103(array1, 0);
2868         Asserts.assertEquals(result, array1[0]);
2869 
2870         result = test103(array2, 1);
2871         Asserts.assertEquals(result, array1[1]);
2872 
2873         result = test103(array3, 2);
2874         Asserts.assertEquals(result, array1[2]);
2875     }
2876 
2877     // Storing to an abstract class array does not require a flatness/null check if the abstract class has a non-static field
2878     @Test
2879     @IR(failOn = {ALLOC_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
2880     public NoValueImplementors1 test104(NoValueImplementors1[] array, NoValueImplementors1 v, MyObject3 o, int i) {
2881         array[0] = v;
2882         array[1] = array[0];
2883         array[2] = o;
2884         return array[i];
2885     }
2886 
2887     @Run(test = "test104")
2888     public void test104_verifier() {
2889         MyObject4 v = new MyObject4();
2890         MyObject3 o = new MyObject3();
2891         NoValueImplementors1[] array1 = new NoValueImplementors1[3];
2892         MyObject3[] array2 = new MyObject3[3];
2893         MyObject4[] array3 = new MyObject4[3];
2894         NoValueImplementors1 result = test104(array1, v, o, 0);
2895         Asserts.assertEquals(array1[0], v);
2896         Asserts.assertEquals(array1[1], v);
2897         Asserts.assertEquals(array1[2], o);
2898         Asserts.assertEquals(result, v);
2899 
2900         result = test104(array2, o, o, 1);
2901         Asserts.assertEquals(array2[0], o);
2902         Asserts.assertEquals(array2[1], o);
2903         Asserts.assertEquals(array2[2], o);
2904         Asserts.assertEquals(result, o);
2905 
2906         result = test104(array3, v, null, 1);
2907         Asserts.assertEquals(array3[0], v);
2908         Asserts.assertEquals(array3[1], v);
2909         Asserts.assertEquals(array3[2], null);
2910         Asserts.assertEquals(result, v);
2911     }
2912 
2913     // An abstract class with a single, non-inline implementor
2914     abstract class NoValueImplementors2 {
2915 
2916     }
2917 
2918     class MyObject5 extends NoValueImplementors2 {
2919 
2920     }
2921 
2922     // Loading from an abstract class array does not require a flatness check if the abstract class has no inline implementor
2923     @Test
2924     @IR(failOn = {ALLOC_G, MEMBAR, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
2925     public NoValueImplementors2 test105(NoValueImplementors2[] array, int i) {
2926         return array[i];
2927     }
2928 
2929     @Run(test = "test105")
2930     public void test105_verifier() {
2931         NoValueImplementors2[] array1 = new NoValueImplementors2[3];
2932         MyObject5[] array2 = new MyObject5[3];
2933         NoValueImplementors2 result = test105(array1, 0);
2934         Asserts.assertEquals(result, array1[0]);
2935 
2936         result = test105(array2, 1);
2937         Asserts.assertEquals(result, array1[1]);
2938     }
2939 
2940     // Storing to an abstract class array does not require a flatness/null check if the abstract class has no inline implementor
2941     @Test
2942     @IR(failOn = {ALLOC_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
2943     public NoValueImplementors2 test106(NoValueImplementors2[] array, NoValueImplementors2 v, MyObject5 o, int i) {
2944         array[0] = v;
2945         array[1] = array[0];
2946         array[2] = o;
2947         return array[i];
2948     }
2949 
2950     @Run(test = "test106")
2951     public void test106_verifier() {
2952         MyObject5 v = new MyObject5();
2953         NoValueImplementors2[] array1 = new NoValueImplementors2[3];
2954         MyObject5[] array2 = new MyObject5[3];
2955         NoValueImplementors2 result = test106(array1, v, null, 0);
2956         Asserts.assertEquals(array1[0], v);
2957         Asserts.assertEquals(array1[1], v);
2958         Asserts.assertEquals(array1[2], null);
2959         Asserts.assertEquals(result, v);
2960 
2961         result = test106(array2, v, v, 1);
2962         Asserts.assertEquals(array2[0], v);
2963         Asserts.assertEquals(array2[1], v);
2964         Asserts.assertEquals(array2[2], v);
2965         Asserts.assertEquals(result, v);
2966     }
2967 
2968     // More tests for the Loop Unswitching optimization (similar to test84 and following)
2969     Object oFld1, oFld2;
2970 
2971     @Test
2972     @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"},
2973         failOn = {STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD},
2974         counts = {COUNTEDLOOP, "= 2", LOAD_UNKNOWN_INLINE, "= 2"})
2975     @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"},
2976         failOn = {STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD},
2977         counts = {COUNTEDLOOP, "= 3", LOAD_UNKNOWN_INLINE, "= 2"})
2978     public void test107(Object[] src1, Object[] src2) {
2979         for (int i = 0; i < src1.length; i++) {
2980             oFld1 = src1[i];
2981             oFld2 = src2[i];
2982         }
2983     }
2984 
2985     @Run(test = "test107")
2986     @Warmup(0)
2987     public void test107_verifier(RunInfo info) {
2988         MyValue2[] src1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
2989         Arrays.fill(src1, testValue2);
2990         Object[] src2 = new Object[100];
2991         Object obj = new Object();
2992         Arrays.fill(src2, obj);
2993         rerun_and_recompile_for(info.getTest(), 10,
2994                                 () -> { test107(src1, src2);
2995                                         Asserts.assertEquals(oFld1, testValue2);
2996                                         Asserts.assertEquals(oFld2, obj);
2997                                         test107(src2, src1);
2998                                         Asserts.assertEquals(oFld1, obj);
2999                                         Asserts.assertEquals(oFld2, testValue2);  });
3000     }
3001 
3002     @Test
3003     @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"},
3004         failOn = {LOAD_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD},
3005         counts = {COUNTEDLOOP, "= 4", STORE_UNKNOWN_INLINE, "= 9"})
3006     @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"},
3007         failOn = {LOAD_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD},
3008         counts = {COUNTEDLOOP, "= 4", STORE_UNKNOWN_INLINE, "= 12"})
3009     public void test108(Object[] dst1, Object[] dst2, Object o1, Object o2) {
3010         for (int i = 0; i < dst1.length; i++) {
3011             dst1[i] = o1;
3012             dst2[i] = o2;
3013         }
3014     }
3015 
3016     @Run(test = "test108")
3017     @Warmup(0)
3018     public void test108_verifier(RunInfo info) {
3019         MyValue2[] dst1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100);
3020         Object[] dst2 = new Object[100];
3021         Object o1 = new Object();
3022         rerun_and_recompile_for(info.getTest(), 10,
3023                                 () -> { test108(dst1, dst2, testValue2, o1);
3024                                         for (int i = 0; i < dst1.length; i++) {
3025                                             Asserts.assertEquals(dst1[i], testValue2);
3026                                             Asserts.assertEquals(dst2[i], o1);
3027                                         }
3028                                         test108(dst2, dst1, o1, testValue2);
3029                                         for (int i = 0; i < dst1.length; i++) {
3030                                             Asserts.assertEquals(dst1[i], testValue2);
3031                                             Asserts.assertEquals(dst2[i], o1);
3032                                         } });
3033     }
3034 
3035     // Escape analysis tests
3036 
3037     static interface WrapperInterface {
3038         long value();
3039 
3040         final static WrapperInterface ZERO = new LongWrapper(0);
3041 
3042         @ForceInline
3043         static WrapperInterface wrap(long val) {
3044             return (val == 0L) ? ZERO : new LongWrapper(val);
3045         }
3046     }
3047 
3048     @ForceCompileClassInitializer
3049     @ImplicitlyConstructible
3050     @LooselyConsistentValue
3051     static value class LongWrapper implements WrapperInterface {
3052         @NullRestricted
3053         final static LongWrapper ZERO = new LongWrapper(0);
3054         private long val;
3055 
3056         @ForceInline
3057         LongWrapper(long val) {
3058             this.val = val;
3059         }
3060 
3061         @ForceInline
3062         static LongWrapper wrap(long val) {
3063             return (val == 0L) ? ZERO : new LongWrapper(val);
3064         }
3065 
3066         @ForceInline
3067         public long value() {
3068             return val;
3069         }
3070     }
3071 
3072     static class InterfaceBox {
3073         WrapperInterface content;
3074 
3075         @ForceInline
3076         InterfaceBox(WrapperInterface content) {
3077             this.content = content;
3078         }
3079 
3080         @ForceInline
3081         static InterfaceBox box_sharp(long val) {
3082             return new InterfaceBox(LongWrapper.wrap(val));
3083         }
3084 
3085         @ForceInline
3086         static InterfaceBox box(long val) {
3087             return new InterfaceBox(WrapperInterface.wrap(val));
3088         }
3089     }
3090 
3091     static class ObjectBox {
3092         Object content;
3093 
3094         @ForceInline
3095         ObjectBox(Object content) {
3096             this.content = content;
3097         }
3098 
3099         @ForceInline
3100         static ObjectBox box_sharp(long val) {
3101             return new ObjectBox(LongWrapper.wrap(val));
3102         }
3103 
3104         @ForceInline
3105         static ObjectBox box(long val) {
3106             return new ObjectBox(WrapperInterface.wrap(val));
3107         }
3108     }
3109 
3110     static class RefBox {
3111         LongWrapper content;
3112 
3113         @ForceInline
3114         RefBox(LongWrapper content) {
3115             this.content = content;
3116         }
3117 
3118         @ForceInline
3119         static RefBox box_sharp(long val) {
3120             return new RefBox(LongWrapper.wrap(val));
3121         }
3122 
3123         @ForceInline
3124         static RefBox box(long val) {
3125             return new RefBox((LongWrapper)WrapperInterface.wrap(val));
3126         }
3127     }
3128 
3129     static class InlineBox {
3130         @NullRestricted
3131         LongWrapper content;
3132 
3133         @ForceInline
3134         InlineBox(long val) {
3135             this.content = LongWrapper.wrap(val);
3136         }
3137 
3138         @ForceInline
3139         static InlineBox box(long val) {
3140             return new InlineBox(val);
3141         }
3142     }
3143 
3144     static class GenericBox<T> {
3145         T content;
3146 
3147         @ForceInline
3148         static GenericBox<LongWrapper> box_sharp(long val) {
3149             GenericBox<LongWrapper> res = new GenericBox<>();
3150             res.content = LongWrapper.wrap(val);
3151             return res;
3152         }
3153 
3154         @ForceInline
3155         static GenericBox<WrapperInterface> box(long val) {
3156             GenericBox<WrapperInterface> res = new GenericBox<>();
3157             res.content = WrapperInterface.wrap(val);
3158             return res;
3159         }
3160     }
3161 
3162     long[] lArr = {0L, rL, 0L, rL, 0L, rL, 0L, rL, 0L, rL};
3163 
3164     // Test removal of allocations when inline type instance is wrapped into box object
3165     @Test
3166     @IR(failOn = {ALLOC_G, MEMBAR},
3167         counts = {PREDICATE_TRAP, "= 1"})
3168     public long test109() {
3169         long res = 0;
3170         for (int i = 0; i < lArr.length; i++) {
3171             res += InterfaceBox.box(lArr[i]).content.value();
3172         }
3173         return res;
3174     }
3175 
3176     @Run(test = "test109")
3177     @Warmup(10000) // Make sure interface calls are inlined
3178     public void test109_verifier() {
3179         long res = test109();
3180         Asserts.assertEquals(res, 5*rL);
3181     }
3182 
3183     @Test
3184     @IR(failOn = {ALLOC_G, MEMBAR},
3185         counts = {PREDICATE_TRAP, "= 1"})
3186     @IR(failOn = {ALLOC_G, MEMBAR})
3187     public long test109_sharp() {
3188         long res = 0;
3189         for (int i = 0; i < lArr.length; i++) {
3190             res += InterfaceBox.box_sharp(lArr[i]).content.value();
3191         }
3192         return res;
3193     }
3194 
3195     @Run(test = "test109_sharp")
3196     @Warmup(10000) // Make sure interface calls are inlined
3197     public void test109_sharp_verifier() {
3198         long res = test109_sharp();
3199         Asserts.assertEquals(res, 5*rL);
3200     }
3201 
3202     // Same as test109 but with ObjectBox
3203     @Test
3204     @IR(failOn = {ALLOC_G, MEMBAR},
3205         counts = {PREDICATE_TRAP, "= 1"})
3206     public long test110() {
3207         long res = 0;
3208         for (int i = 0; i < lArr.length; i++) {
3209             res += ((WrapperInterface)ObjectBox.box(lArr[i]).content).value();
3210         }
3211         return res;
3212     }
3213 
3214     @Run(test = "test110")
3215     @Warmup(10000) // Make sure interface calls are inlined
3216     public void test110_verifier() {
3217         long res = test110();
3218         Asserts.assertEquals(res, 5*rL);
3219     }
3220 
3221     @Test
3222     @IR(failOn = {ALLOC_G, MEMBAR},
3223         counts = {PREDICATE_TRAP, "= 1"})
3224     @IR(failOn = {ALLOC_G, MEMBAR})
3225     public long test110_sharp() {
3226         long res = 0;
3227         for (int i = 0; i < lArr.length; i++) {
3228             res += ((WrapperInterface)ObjectBox.box_sharp(lArr[i]).content).value();
3229         }
3230         return res;
3231     }
3232 
3233     @Run(test = "test110_sharp")
3234     @Warmup(10000) // Make sure interface calls are inlined
3235     public void test110_sharp_verifier() {
3236         long res = test110_sharp();
3237         Asserts.assertEquals(res, 5*rL);
3238     }
3239 
3240     // Same as test109 but with RefBox
3241     @Test
3242     @IR(failOn = {ALLOC_G, MEMBAR},
3243         counts = {PREDICATE_TRAP, "= 1"})
3244     public long test111() {
3245         long res = 0;
3246         for (int i = 0; i < lArr.length; i++) {
3247             res += RefBox.box(lArr[i]).content.value();
3248         }
3249         return res;
3250     }
3251 
3252     @Run(test = "test111")
3253     public void test111_verifier() {
3254         long res = test111();
3255         Asserts.assertEquals(res, 5*rL);
3256     }
3257 
3258     @Test
3259     @IR(failOn = {ALLOC_G, MEMBAR},
3260         counts = {PREDICATE_TRAP, "= 1"})
3261     public long test111_sharp() {
3262         long res = 0;
3263         for (int i = 0; i < lArr.length; i++) {
3264             res += RefBox.box_sharp(lArr[i]).content.value();
3265         }
3266         return res;
3267     }
3268 
3269     @Run(test = "test111_sharp")
3270     public void test111_sharp_verifier() {
3271         long res = test111_sharp();
3272         Asserts.assertEquals(res, 5*rL);
3273     }
3274 
3275     // Same as test109 but with InlineBox
3276     @Test
3277     @IR(failOn = {ALLOC_G, MEMBAR},
3278         counts = {PREDICATE_TRAP, "= 1"})
3279     public long test112() {
3280         long res = 0;
3281         for (int i = 0; i < lArr.length; i++) {
3282             res += InlineBox.box(lArr[i]).content.value();
3283         }
3284         return res;
3285     }
3286 
3287     @Run(test = "test112")
3288     public void test112_verifier() {
3289         long res = test112();
3290         Asserts.assertEquals(res, 5*rL);
3291     }
3292 
3293     // Same as test109 but with GenericBox
3294     @Test
3295     @IR(failOn = {ALLOC_G, MEMBAR},
3296         counts = {PREDICATE_TRAP, "= 1"})
3297     public long test113() {
3298         long res = 0;
3299         for (int i = 0; i < lArr.length; i++) {
3300             res += GenericBox.box(lArr[i]).content.value();
3301         }
3302         return res;
3303     }
3304 
3305     @Run(test = "test113")
3306     @Warmup(10000) // Make sure interface calls are inlined
3307     public void test113_verifier() {
3308         long res = test113();
3309         Asserts.assertEquals(res, 5*rL);
3310     }
3311 
3312     @Test
3313     @IR(failOn = {ALLOC_G, MEMBAR})
3314         // TODO 8326401
3315         // counts = {PREDICATE_TRAP, "= 1"})
3316     public long test113_sharp() {
3317         long res = 0;
3318         for (int i = 0; i < lArr.length; i++) {
3319             res += GenericBox.box_sharp(lArr[i]).content.value();
3320         }
3321         return res;
3322     }
3323 
3324     @Run(test = "test113_sharp")
3325     @Warmup(10000) // Make sure interface calls are inlined
3326     public void test113_sharp_verifier() {
3327         long res = test113_sharp();
3328         Asserts.assertEquals(res, 5*rL);
3329     }
3330 
3331     static interface WrapperInterface2 {
3332         public long value();
3333 
3334         static final InlineWrapper ZERO = new InlineWrapper(0);
3335 
3336         @ForceInline
3337         public static WrapperInterface2 wrap(long val) {
3338             return (val == 0) ? ZERO.content : new LongWrapper2(val);
3339         }
3340 
3341         @ForceInline
3342         public static WrapperInterface2 wrap_default(long val) {
3343             return (val == 0) ? new LongWrapper2(0) : new LongWrapper2(val);
3344         }
3345     }
3346 
3347     @ImplicitlyConstructible
3348     @LooselyConsistentValue
3349     static value class LongWrapper2 implements WrapperInterface2 {
3350         private long val;
3351 
3352         @ForceInline
3353         public LongWrapper2(long val) {
3354             this.val = val;
3355         }
3356 
3357         @ForceInline
3358         public long value() {
3359             return val;
3360         }
3361     }
3362 
3363     @ImplicitlyConstructible
3364     @LooselyConsistentValue
3365     static value class InlineWrapper {
3366         WrapperInterface2 content;
3367 
3368         @ForceInline
3369         public InlineWrapper(long val) {
3370             content = new LongWrapper2(val);
3371         }
3372     }
3373 
3374     static class InterfaceBox2 {
3375         WrapperInterface2 content;
3376 
3377         @ForceInline
3378         public InterfaceBox2(long val, boolean def) {
3379             this.content = def ? WrapperInterface2.wrap_default(val) : WrapperInterface2.wrap(val);
3380         }
3381 
3382         @ForceInline
3383         static InterfaceBox2 box(long val) {
3384             return new InterfaceBox2(val, false);
3385         }
3386 
3387         @ForceInline
3388         static InterfaceBox2 box_default(long val) {
3389             return new InterfaceBox2(val, true);
3390         }
3391     }
3392 
3393     // Same as tests above but with ZERO hidden in field of another inline type
3394     @Test
3395     @IR(failOn = {ALLOC_G, MEMBAR},
3396         counts = {PREDICATE_TRAP, "= 1"})
3397     public long test114() {
3398         long res = 0;
3399         for (int i = 0; i < lArr.length; i++) {
3400             res += InterfaceBox2.box(lArr[i]).content.value();
3401         }
3402         return res;
3403     }
3404 
3405     @Run(test = "test114")
3406     @Warmup(10000)
3407     public void test114_verifier() {
3408         long res = test114();
3409         Asserts.assertEquals(res, 5*rL);
3410     }
3411 
3412     // Same as test114 but with default instead of ZERO field
3413     @Test
3414     @IR(failOn = {ALLOC_G, MEMBAR},
3415         counts = {PREDICATE_TRAP, "= 1"})
3416     public long test115() {
3417         long res = 0;
3418         for (int i = 0; i < lArr.length; i++) {
3419             res += InterfaceBox2.box_default(lArr[i]).content.value();
3420         }
3421         return res;
3422     }
3423 
3424     @Run(test = "test115")
3425     @Warmup(10000)
3426     public void test115_verifier() {
3427         long res = test115();
3428         Asserts.assertEquals(res, 5*rL);
3429     }
3430 
3431     @NullRestricted
3432     static MyValueEmpty fEmpty1;
3433     static MyValueEmpty fEmpty2 = new MyValueEmpty();
3434     @NullRestricted
3435            MyValueEmpty fEmpty3;
3436            MyValueEmpty fEmpty4 = new MyValueEmpty();
3437 
3438     // Test fields loads/stores with empty inline types
3439     @Test
3440     @IR(failOn = {ALLOC_G, TRAP})
3441     public void test116() {
3442         fEmpty1 = fEmpty4;
3443         fEmpty2 = fEmpty1;
3444         fEmpty3 = fEmpty2;
3445         fEmpty4 = fEmpty3;
3446     }
3447 
3448     @Run(test = "test116")
3449     public void test116_verifier() {
3450         test116();
3451         Asserts.assertEquals(fEmpty1, fEmpty2);
3452         Asserts.assertEquals(fEmpty2, fEmpty3);
3453         Asserts.assertEquals(fEmpty3, fEmpty4);
3454     }
3455 
3456     // Test array loads/stores with empty inline types
3457     @Test
3458     @IR(failOn = {ALLOC_G})
3459     public MyValueEmpty test117(MyValueEmpty[] arr1, MyValueEmpty[] arr2) {
3460         arr1[0] = arr2[0];
3461         arr2[0] = new MyValueEmpty();
3462         return arr1[0];
3463     }
3464 
3465     @Run(test = "test117")
3466     public void test117_verifier() {
3467         MyValueEmpty[] arr1 = new MyValueEmpty[] { new MyValueEmpty() };
3468         MyValueEmpty res = test117(arr1, arr1);
3469         Asserts.assertEquals(res, new MyValueEmpty());
3470         Asserts.assertEquals(arr1[0], new MyValueEmpty());
3471     }
3472 
3473     // Test acmp with empty inline types
3474     @Test
3475     public boolean test118(MyValueEmpty v1, MyValueEmpty v2, Object o1) {
3476         return (v1 == v2) && (v2 == o1);
3477     }
3478 
3479     @Run(test = "test118")
3480     public void test118_verifier() {
3481         boolean res = test118(new MyValueEmpty(), new MyValueEmpty(), new MyValueEmpty());
3482         Asserts.assertTrue(res);
3483     }
3484 
3485     @ImplicitlyConstructible
3486     @LooselyConsistentValue
3487     static value class EmptyContainer {
3488         @NullRestricted
3489         private MyValueEmpty empty = new MyValueEmpty();
3490     }
3491 
3492     @ImplicitlyConstructible
3493     @LooselyConsistentValue
3494     static value class MixedContainer {
3495         public int val = 0;
3496         @NullRestricted
3497         private EmptyContainer empty = new EmptyContainer();
3498     }
3499 
3500     @NullRestricted
3501     static final MyValueEmpty empty = new MyValueEmpty();
3502 
3503     @NullRestricted
3504     static final EmptyContainer emptyC = new EmptyContainer();
3505 
3506     @NullRestricted
3507     static final MixedContainer mixedContainer = new MixedContainer();
3508 
3509     // Test re-allocation of empty inline type array during deoptimization
3510     @Test
3511     @IR(failOn = {ALLOC_G})
3512     public void test119(boolean deopt, Method m) {
3513         MyValueEmpty[]   array1 = new MyValueEmpty[] { empty };
3514         EmptyContainer[] array2 = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 1);
3515         array2[0] = emptyC;
3516         MixedContainer[] array3 = (MixedContainer[])ValueClass.newNullRestrictedArray(MixedContainer.class, 1);
3517         array3[0] = mixedContainer;
3518         if (deopt) {
3519             // uncommon trap
3520             TestFramework.deoptimize(m);
3521         }
3522         Asserts.assertEquals(array1[0], empty);
3523         Asserts.assertEquals(array2[0], emptyC);
3524         Asserts.assertEquals(array3[0], mixedContainer);
3525     }
3526 
3527     @Run(test = "test119")
3528     public void test119_verifier(RunInfo info) {
3529         test119(!info.isWarmUp(), info.getTest());
3530     }
3531 
3532     // Test removal of empty inline type field stores
3533     @Test
3534     @IR(failOn = {ALLOC_G, LOAD, STORE, FIELD_ACCESS, NULL_CHECK_TRAP, TRAP})
3535     public void test120() {
3536         fEmpty1 = empty;
3537         fEmpty3 = empty;
3538         // fEmpty2 and fEmpty4 could be null, store can't be removed
3539     }
3540 
3541     @Run(test = "test120")
3542     public void test120_verifier() {
3543         test120();
3544         Asserts.assertEquals(fEmpty1, empty);
3545         Asserts.assertEquals(fEmpty2, empty);
3546     }
3547 
3548     // Test removal of empty inline type field loads
3549     @Test
3550     @IR(failOn = {ALLOC_G, LOAD, STORE, FIELD_ACCESS, NULL_CHECK_TRAP, TRAP})
3551     public boolean test121() {
3552         return fEmpty1.equals(fEmpty3);
3553         // fEmpty2 and fEmpty4 could be null, load can't be removed
3554     }
3555 
3556     @Run(test = "test121")
3557     public void test121_verifier() {
3558         boolean res = test121();
3559         Asserts.assertTrue(res);
3560     }
3561 
3562     // Verify that empty inline type field loads check for null holder
3563     @Test
3564     @IR(failOn = {ALLOC_G})
3565     public MyValueEmpty test122(TestLWorld t) {
3566         return t.fEmpty3;
3567     }
3568 
3569     @Run(test = "test122")
3570     public void test122_verifier() {
3571         MyValueEmpty res = test122(this);
3572         Asserts.assertEquals(res, new MyValueEmpty());
3573         try {
3574             test122(null);
3575             throw new RuntimeException("No NPE thrown");
3576         } catch (NullPointerException e) {
3577             // Expected
3578         }
3579     }
3580 
3581     // Verify that empty inline type field stores check for null holder
3582     @Test
3583     @IR(failOn = {ALLOC_G})
3584     public void test123(TestLWorld t) {
3585         t.fEmpty3 = new MyValueEmpty();
3586     }
3587 
3588     @Run(test = "test123")
3589     public void test123_verifier() {
3590         test123(this);
3591         Asserts.assertEquals(fEmpty3, new MyValueEmpty());
3592         try {
3593             test123(null);
3594             throw new RuntimeException("No NPE thrown");
3595         } catch (NullPointerException e) {
3596             // Expected
3597         }
3598     }
3599 
3600     // acmp doesn't need substitutability test when one input is known
3601     // not to be a value type
3602     @Test
3603     @IR(failOn = SUBSTITUTABILITY_TEST)
3604     public boolean test124(NonValueClass o1, Object o2) {
3605         return o1 == o2;
3606     }
3607 
3608     @Run(test = "test124")
3609     public void test124_verifier() {
3610         NonValueClass obj = new NonValueClass(rI);
3611         test124(obj, obj);
3612         test124(obj, testValue1);
3613     }
3614 
3615     // acmp doesn't need substitutability test when one input is null
3616     @Test
3617     @IR(failOn = {SUBSTITUTABILITY_TEST})
3618     public boolean test125(Object o1) {
3619         Object o2 = null;
3620         return o1 == o2;
3621     }
3622 
3623     @Run(test = "test125")
3624     public void test125_verifier() {
3625         test125(testValue1);
3626         test125(null);
3627     }
3628 
3629     // Test inline type that can only be scalarized after loop opts
3630     @Test
3631     @IR(failOn = {ALLOC_G, LOAD, STORE})
3632     public long test126(boolean trap) {
3633         MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD);
3634         MyValue2 val = null;
3635 
3636         for (int i = 0; i < 4; i++) {
3637             if ((i % 2) == 0) {
3638                 val = nonNull;
3639             }
3640         }
3641         // 'val' is always non-null here but that's only known after loop opts
3642         if (trap) {
3643             // Uncommon trap with an inline input that can only be scalarized after loop opts
3644             return val.hash();
3645         }
3646         return 0;
3647     }
3648 
3649     @Run(test = "test126")
3650     @Warmup(10000)
3651     public void test126_verifier(RunInfo info) {
3652         long res = test126(false);
3653         Asserts.assertEquals(res, 0L);
3654         if (!info.isWarmUp()) {
3655             res = test126(true);
3656             Asserts.assertEquals(res, testValue2.hash());
3657         }
3658     }
3659 
3660     // Same as test126 but with interface type
3661     @Test
3662     @IR(failOn = {ALLOC_G, LOAD, STORE})
3663     public long test127(boolean trap) {
3664         MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD);
3665         MyInterface val = null;
3666 
3667         for (int i = 0; i < 4; i++) {
3668             if ((i % 2) == 0) {
3669                 val = nonNull;
3670             }
3671         }
3672         // 'val' is always non-null here but that's only known after loop opts
3673         if (trap) {
3674             // Uncommon trap with an inline input that can only be scalarized after loop opts
3675             return val.hash();
3676         }
3677         return 0;
3678     }
3679 
3680     @Run(test = "test127")
3681     @Warmup(10000)
3682     public void test127_verifier(RunInfo info) {
3683         long res = test127(false);
3684         Asserts.assertEquals(res, 0L);
3685         if (!info.isWarmUp()) {
3686             res = test127(true);
3687             Asserts.assertEquals(res, testValue2.hash());
3688         }
3689     }
3690 
3691     // Test inline type that can only be scalarized after CCP
3692     @Test
3693     @IR(failOn = {ALLOC_G, LOAD, STORE})
3694     public long test128(boolean trap) {
3695         MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD);
3696         MyValue2 val = null;
3697 
3698         int limit = 2;
3699         for (; limit < 4; limit *= 2);
3700         for (int i = 2; i < limit; i++) {
3701             val = nonNull;
3702         }
3703         // 'val' is always non-null here but that's only known after CCP
3704         if (trap) {
3705             // Uncommon trap with an inline input that can only be scalarized after CCP
3706             return val.hash();
3707         }
3708         return 0;
3709     }
3710 
3711     @Run(test = "test128")
3712     @Warmup(10000)
3713     public void test128_verifier(RunInfo info) {
3714         long res = test128(false);
3715         Asserts.assertEquals(res, 0L);
3716         if (!info.isWarmUp()) {
3717             res = test128(true);
3718             Asserts.assertEquals(res, testValue2.hash());
3719         }
3720     }
3721 
3722     // Same as test128 but with interface type
3723     @Test
3724     @IR(failOn = {ALLOC_G, LOAD, STORE})
3725     public long test129(boolean trap) {
3726         MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD);
3727         MyInterface val = null;
3728 
3729         int limit = 2;
3730         for (; limit < 4; limit *= 2);
3731         for (int i = 0; i < limit; i++) {
3732             val = nonNull;
3733         }
3734         // 'val' is always non-null here but that's only known after CCP
3735         if (trap) {
3736             // Uncommon trap with an inline input that can only be scalarized after CCP
3737             return val.hash();
3738         }
3739         return 0;
3740     }
3741 
3742     @Run(test = "test129")
3743     @Warmup(10000)
3744     public void test129_verifier(RunInfo info) {
3745         long res = test129(false);
3746         Asserts.assertEquals(res, 0L);
3747         if (!info.isWarmUp()) {
3748             res = test129(true);
3749             Asserts.assertEquals(res, testValue2.hash());
3750         }
3751     }
3752 
3753     // Lock on inline type (known after inlining)
3754     @ForceInline
3755     public Object test130_inlinee() {
3756         return MyValue1.createWithFieldsInline(rI, rL);
3757     }
3758 
3759     @Test
3760     // TODO 8325106
3761     /*
3762     @IR(failOn = {LOAD},
3763         // LockNode keeps MyValue1 allocation alive up until macro expansion which in turn keeps MyValue2
3764         // alloc alive. Although the MyValue1 allocation is removed (unused), MyValue2 is expanded first
3765         // and therefore stays.
3766         counts = {ALLOC, "<= 1", STORE, "<= 1"})
3767     */
3768     public void test130() {
3769         Object obj = test130_inlinee();
3770         synchronized (obj) {
3771             throw new RuntimeException("test130 failed: synchronization on inline type should not succeed");
3772         }
3773     }
3774 
3775     @Run(test = "test130")
3776     public void test130_verifier() {
3777         try {
3778             test130();
3779             throw new RuntimeException("test130 failed: no exception thrown");
3780         } catch (IllegalMonitorStateException ex) {
3781             // Expected
3782         }
3783     }
3784 
3785     // Same as test130 but with field load instead of allocation
3786     @ForceInline
3787     public Object test131_inlinee() {
3788         return testValue1;
3789     }
3790 
3791     @Test
3792     @IR(failOn = {ALLOC_G})
3793     public void test131() {
3794         Object obj = test131_inlinee();
3795         synchronized (obj) {
3796             throw new RuntimeException("test131 failed: synchronization on inline type should not succeed");
3797         }
3798     }
3799 
3800     @Run(test = "test131")
3801     public void test131_verifier() {
3802         try {
3803             test131();
3804             throw new RuntimeException("test131 failed: no exception thrown");
3805         } catch (IllegalMonitorStateException ex) {
3806             // Expected
3807         }
3808     }
3809 
3810     // Test locking on object that is known to be an inline type only after CCP
3811     @Test
3812     @IR(failOn = {ALLOC, LOAD, STORE})
3813     public void test132() {
3814         MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD);
3815         Object obj = new NonValueClass(42);
3816 
3817         int limit = 2;
3818         for (; limit < 4; limit *= 2);
3819         for (int i = 2; i < limit; i++) {
3820             obj = vt;
3821         }
3822         synchronized (obj) {
3823             throw new RuntimeException("test132 failed: synchronization on inline type should not succeed");
3824         }
3825     }
3826 
3827     @Run(test = "test132")
3828     @Warmup(10000)
3829     public void test132_verifier() {
3830         try {
3831             test132();
3832             throw new RuntimeException("test132 failed: no exception thrown");
3833         } catch (IllegalMonitorStateException ex) {
3834             // Expected
3835         }
3836     }
3837 
3838     // Test conditional locking on inline type and non-escaping object
3839     @Test
3840     public void test133(boolean b) {
3841         Object obj = b ? new NonValueClass(rI) : MyValue2.createWithFieldsInline(rI, rD);
3842         synchronized (obj) {
3843             if (!b) {
3844                 throw new RuntimeException("test133 failed: synchronization on inline type should not succeed");
3845             }
3846         }
3847     }
3848 
3849     @Run(test = "test133")
3850     public void test133_verifier() {
3851         test133(true);
3852         try {
3853             test133(false);
3854             throw new RuntimeException("test133 failed: no exception thrown");
3855         } catch (IllegalMonitorStateException ex) {
3856             // Expected
3857         }
3858     }
3859 
3860     // Variant with non-scalarized inline type
3861     @Test
3862     @IR(failOn = {ALLOC_G})
3863     public void test134(boolean b) {
3864         Object obj = null;
3865         if (b) {
3866             obj = MyValue2.createWithFieldsInline(rI, rD);
3867         }
3868         synchronized (obj) {
3869 
3870         }
3871     }
3872 
3873     @Run(test = "test134")
3874     public void test134_verifier() {
3875         try {
3876             test134(true);
3877             throw new RuntimeException("test134 failed: no exception thrown");
3878         } catch (IllegalMonitorStateException ex) {
3879             // Expected
3880         }
3881     }
3882 
3883     // Test that acmp of the same inline object is removed
3884     @Test
3885     @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP})
3886     public boolean test135() {
3887         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
3888         return val == val;
3889     }
3890 
3891     @Run(test = "test135")
3892     public void test135_verifier() {
3893         Asserts.assertTrue(test135());
3894     }
3895 
3896     // Same as test135 but with null
3897     @Test
3898     @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP})
3899     public boolean test136(boolean b) {
3900         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
3901         if (b) {
3902             val = null;
3903         }
3904         return val == val;
3905     }
3906 
3907     @Run(test = "test136")
3908     public void test136_verifier() {
3909         Asserts.assertTrue(test136(false));
3910         Asserts.assertTrue(test136(true));
3911     }
3912 
3913     // Test that acmp of different inline objects with same content is removed
3914     @Test
3915     // TODO 8228361
3916     // @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP})
3917     public boolean test137(int i) {
3918         MyValue2 val1 = MyValue2.createWithFieldsInline(i, rD);
3919         MyValue2 val2 = MyValue2.createWithFieldsInline(i, rD);
3920         return val1 == val2;
3921     }
3922 
3923     @Run(test = "test137")
3924     public void test137_verifier() {
3925         Asserts.assertTrue(test137(rI));
3926     }
3927 
3928     // Same as test137 but with null
3929     @Test
3930     // TODO 8228361
3931     // @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP})
3932     public boolean test138(int i, boolean b) {
3933         MyValue2 val1 = MyValue2.createWithFieldsInline(i, rD);
3934         MyValue2 val2 = MyValue2.createWithFieldsInline(i, rD);
3935         if (b) {
3936             val1 = null;
3937             val2 = null;
3938         }
3939         return val1 == val2;
3940     }
3941 
3942     @Run(test = "test138")
3943     public void test138_verifier() {
3944         Asserts.assertTrue(test138(rI, false));
3945         Asserts.assertTrue(test138(rI, true));
3946     }
3947 
3948     @ImplicitlyConstructible
3949     @LooselyConsistentValue
3950     static value class Test139Value {
3951         Object obj = null;
3952         @NullRestricted
3953         MyValueEmpty empty = new MyValueEmpty();
3954     }
3955 
3956     @ImplicitlyConstructible
3957     @LooselyConsistentValue
3958     static value class Test139Wrapper {
3959         @NullRestricted
3960         Test139Value value = new Test139Value();
3961     }
3962 
3963     @Test
3964     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
3965     public MyValueEmpty test139() {
3966         Test139Wrapper w = new Test139Wrapper();
3967         return w.value.empty;
3968     }
3969 
3970     @Run(test = "test139")
3971     public void test139_verifier() {
3972         MyValueEmpty empty = test139();
3973         Asserts.assertEquals(empty, new MyValueEmpty());
3974     }
3975 
3976     // Test calling a method on a loaded but not linked inline type
3977     @ImplicitlyConstructible
3978     @LooselyConsistentValue
3979     value class Test140Value {
3980         int x = 0;
3981 
3982         public int get() {
3983             return x;
3984         }
3985     }
3986 
3987     @Test
3988     @IR(failOn = {ALLOC_G})
3989     public int test140() {
3990         Test140Value vt = new Test140Value();
3991         return vt.get();
3992     }
3993 
3994     @Run(test = "test140")
3995     @Warmup(0)
3996     public void test140_verifier() {
3997         int result = test140();
3998         Asserts.assertEquals(result, 0);
3999     }
4000 
4001     // Test calling a method on a linked but not initialized inline type
4002     @ImplicitlyConstructible
4003     @LooselyConsistentValue
4004     value class Test141Value {
4005         int x = 0;
4006 
4007         public int get() {
4008             return x;
4009         }
4010     }
4011 
4012     @Test
4013     @IR(failOn = {ALLOC_G})
4014     public int test141() {
4015         Test141Value vt = new Test141Value();
4016         return vt.get();
4017     }
4018 
4019     @Run(test = "test141")
4020     @Warmup(0)
4021     public void test141_verifier() {
4022         int result = test141();
4023         Asserts.assertEquals(result, 0);
4024     }
4025 
4026     // Test that virtual calls on inline type receivers are properly inlined
4027     @Test
4028     @IR(failOn = {ALLOC_G, LOAD, STORE})
4029     public long test142() {
4030         MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD);
4031         MyInterface val = null;
4032 
4033         for (int i = 0; i < 4; i++) {
4034             if ((i % 2) == 0) {
4035                 val = nonNull;
4036             }
4037         }
4038         return val.hash();
4039     }
4040 
4041     @Run(test = "test142")
4042     public void test142_verifier() {
4043         long res = test142();
4044         Asserts.assertEquals(res, testValue2.hash());
4045     }
4046 
4047     // Test merging of buffered default and non-default inline types
4048     @Test
4049     // TODO 8325106 With incremental inlining, we already buffer the larval which can't use the default oop because it might be overridden.
4050     @IR(applyIf = {"AlwaysIncrementalInline", "false"},
4051         failOn = {ALLOC_G})
4052     public Object test144(int i) {
4053         if (i == 0) {
4054             return MyValue1.createDefaultInline();
4055         } else if (i == 1) {
4056             return testValue1;
4057         } else {
4058             return MyValue1.createDefaultInline();
4059         }
4060     }
4061 
4062     @Run(test = "test144")
4063     public void test144_verifier() {
4064         Asserts.assertEquals(test144(0), MyValue1.createDefaultInline());
4065         Asserts.assertEquals(test144(1), testValue1);
4066         Asserts.assertEquals(test144(2), MyValue1.createDefaultInline());
4067     }
4068 
4069     // Tests writing an array element with a (statically known) incompatible type
4070     private static final MethodHandle setArrayElementIncompatibleRef = OldInstructionHelper.loadCode(MethodHandles.lookup(),
4071         "setArrayElementIncompatibleRef",
4072         MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class),
4073         CODE -> {
4074             CODE.
4075             aload_1().
4076             iload_2().
4077             aload_3().
4078             aastore().
4079             return_();
4080         });
4081 
4082     // Test inline type connected to result node
4083     @Test
4084     @IR(failOn = {ALLOC_G})
4085     public MyValue1 test146(Object obj) {
4086         return (MyValue1)obj;
4087     }
4088 
4089     @Run(test = "test146")
4090     @Warmup(10000)
4091     public void test146_verifier() {
4092         Asserts.assertEQ(test146(testValue1), testValue1);
4093     }
4094 
4095     @ForceInline
4096     public Object test148_helper(Object obj) {
4097         return (MyValue1)obj;
4098     }
4099 
4100     // Same as test146 but with helper method
4101     @Test
4102     public Object test148(Object obj) {
4103         return test148_helper(obj);
4104     }
4105 
4106     @Run(test = "test148")
4107     @Warmup(10000)
4108     public void test148_verifier() {
4109         Asserts.assertEQ(test148(testValue1), testValue1);
4110     }
4111 
4112     @ForceInline
4113     public Object test149_helper(Object obj) {
4114         return (MyValue1)obj;
4115     }
4116 
4117     // Same as test147 but with helper method
4118     @Test
4119     public Object test149(Object obj) {
4120         return test149_helper(obj);
4121     }
4122 
4123     @Run(test = "test149")
4124     @Warmup(10000)
4125     public void test149_verifier() {
4126         Asserts.assertEQ(test149(testValue1), testValue1);
4127         Asserts.assertEQ(test149(null), null);
4128     }
4129 
4130     // Test post-parse call devirtualization with inline type receiver
4131     @Test
4132     // TODO 8325106
4133     /*
4134     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
4135         failOn = {ALLOC})
4136     */
4137     @IR(failOn = {compiler.lib.ir_framework.IRNode.DYNAMIC_CALL_OF_METHOD, "MyValue2::hash"},
4138         counts = {compiler.lib.ir_framework.IRNode.STATIC_CALL_OF_METHOD, "MyValue2::hash", "= 1"})
4139     public long test150() {
4140         MyValue2 val = MyValue2.createWithFieldsInline(rI, rD);
4141         MyInterface receiver = MyValue1.createWithFieldsInline(rI, rL);
4142 
4143         for (int i = 0; i < 4; i++) {
4144             if ((i % 2) == 0) {
4145                 receiver = val;
4146             }
4147         }
4148         // Trigger post parse call devirtualization (strength-reducing
4149         // virtual calls to direct calls).
4150         return receiver.hash();
4151     }
4152 
4153     @Run(test = "test150")
4154     public void test150_verifier() {
4155         Asserts.assertEquals(test150(), testValue2.hash());
4156     }
4157 
4158 // TODO 8325106 This triggers #  assert(false) failed: Should have been buffered
4159 /*
4160     // Same as test150 but with val not being allocated in the scope of the method
4161     @Test
4162     @IR(failOn = {compiler.lib.ir_framework.IRNode.DYNAMIC_CALL_OF_METHOD, "MyValue2::hash"},
4163         counts = {compiler.lib.ir_framework.IRNode.STATIC_CALL_OF_METHOD, "MyValue2::hash", "= 1"})
4164     public long test151(MyValue2 val) {
4165         MyAbstract receiver = MyValue1.createWithFieldsInline(rI, rL);
4166 
4167         for (int i = 0; i < 100; i++) {
4168             if ((i % 2) == 0) {
4169                 receiver = val;
4170             }
4171         }
4172         // Trigger post parse call devirtualization (strength-reducing
4173         // virtual calls to direct calls).
4174         return receiver.hash();
4175     }
4176 
4177     @Run(test = "test151")
4178     @Warmup(0) // Make sure there is no receiver type profile
4179     public void test151_verifier() {
4180         Asserts.assertEquals(test151(testValue2), testValue2.hash());
4181     }
4182 */
4183 
4184     static interface MyInterface2 {
4185         public int val();
4186     }
4187 
4188     static abstract value class MyAbstract2 implements MyInterface2 {
4189 
4190     }
4191 
4192     static class MyClass152 extends MyAbstract2 {
4193         private int val;
4194 
4195         @ForceInline
4196         public MyClass152(int val) {
4197             this.val = val;
4198         }
4199 
4200         @Override
4201         public int val() {
4202             return val;
4203         }
4204     }
4205 
4206     @ImplicitlyConstructible
4207     @LooselyConsistentValue
4208     static value class MyValue152 extends MyAbstract2 {
4209         private int unused = 0; // Make sure sub-offset of val is field non-zero
4210         private int val;
4211 
4212         @ForceInline
4213         public MyValue152(int val) {
4214             this.val = val;
4215         }
4216 
4217         @Override
4218         public int val() {
4219             return val;
4220         }
4221     }
4222 
4223     @ImplicitlyConstructible
4224     @LooselyConsistentValue
4225     static value class MyWrapper152 {
4226         private int unused = 0; // Make sure sub-offset of val field is non-zero
4227         @NullRestricted
4228         MyValue152 val;
4229 
4230         @ForceInline
4231         public MyWrapper152(MyInterface2 val) {
4232             this.val = (MyValue152)val;
4233         }
4234     }
4235 
4236     // Test that checkcast with speculative type does not break scalarization in return
4237     @Test
4238     public MyWrapper152 test152(MyInterface2 val) {
4239         return new MyWrapper152(val);
4240     }
4241 
4242     @Run(test = "test152")
4243     @Warmup(10000) // Make sure profile information is available at cast
4244     public void test152_verifier() {
4245         MyClass152 unused = new MyClass152(rI);
4246         MyValue152 val = new MyValue152(rI);
4247         Asserts.assertEquals(test152(val).val, val);
4248     }
4249 
4250     @DontInline
4251     static void test153_helper(MyWrapper152 arg) {
4252 
4253     }
4254 
4255     // Test that checkcast with speculative type does not prevent scalarization in args
4256     @Test
4257     public void test153(MyInterface2 val) {
4258         test153_helper(new MyWrapper152(val));
4259     }
4260 
4261     @Run(test = "test153")
4262     @Warmup(10000) // Make sure profile information is available at cast
4263     public void test153_verifier() {
4264         MyClass152 unused = new MyClass152(rI);
4265         MyValue152 val = new MyValue152(rI);
4266         test153(val);
4267     }
4268 
4269     // Test that checkcast with speculative type enables scalarization
4270     @Test
4271     @IR(failOn = {ALLOC_G, STORE})
4272     public int test154(Method m, MyInterface2 val, boolean b1, boolean b2) {
4273         MyInterface2 obj = new MyValue152(rI);
4274         if (b1) {
4275             // Speculative cast to MyValue152 enables scalarization
4276             obj = (MyAbstract2)val;
4277         }
4278         if (b2) {
4279             // Uncommon trap
4280             TestFramework.deoptimize(m);
4281             return obj.val();
4282         }
4283         return -1;
4284     }
4285 
4286     @Run(test = "test154")
4287     @Warmup(10000) // Make sure profile information is available at cast
4288     public void test154_verifier(RunInfo info) {
4289         MyClass152 unused = new MyClass152(rI);
4290         MyValue152 val = new MyValue152(rI);
4291         Asserts.assertEquals(test154(info.getTest(), val, false, false), -1);
4292         Asserts.assertEquals(test154(info.getTest(), val, true, false), -1);
4293         if (!info.isWarmUp()) {
4294             Asserts.assertEquals(test154(info.getTest(), val, false, true), rI);
4295         }
4296     }
4297 
4298     // Same as test154 but with null val
4299     @Test
4300     @IR(failOn = {ALLOC_G, STORE})
4301     public int test155(Method m, MyInterface2 val, boolean b1, boolean b2) {
4302         MyInterface2 obj = new MyValue152(rI);
4303         if (b1) {
4304             // Speculative cast to MyValue152 enables scalarization
4305             obj = (MyAbstract2)val;
4306         }
4307         if (b2) {
4308             // Uncommon trap
4309             TestFramework.deoptimize(m);
4310             return obj.val();
4311         }
4312         return -1;
4313     }
4314 
4315     @Run(test = "test155")
4316     @Warmup(10000) // Make sure profile information is available at cast
4317     public void test155_verifier(RunInfo info) {
4318         MyClass152 unused = new MyClass152(rI);
4319         MyValue152 val = new MyValue152(rI);
4320         Asserts.assertEquals(test155(info.getTest(), val, false, false), -1);
4321         Asserts.assertEquals(test155(info.getTest(), val, true, false), -1);
4322         Asserts.assertEquals(test155(info.getTest(), null, true, false), -1);
4323         if (!info.isWarmUp()) {
4324             Asserts.assertEquals(test155(info.getTest(), val, false, true), rI);
4325         }
4326     }
4327 
4328     @NullRestricted
4329     final static MyValue1 test157Cache = MyValue1.createWithFieldsInline(rI, 0);
4330 
4331     // Test merging buffered inline type from field load with non-buffered inline type
4332     @Test
4333     public MyValue1 test157(long val) {
4334         return (val == 0L) ? test157Cache : MyValue1.createWithFieldsInline(rI, val);
4335     }
4336 
4337     @Run(test = "test157")
4338     public void test157_verifier() {
4339         Asserts.assertEquals(test157(0), test157Cache);
4340         Asserts.assertEquals(test157(rL).hash(), testValue1.hash());
4341     }
4342 
4343     @NullRestricted
4344     static MyValue1 test158Cache = MyValue1.createWithFieldsInline(rI, 0);
4345 
4346     // Same as test157 but with non-final field load
4347     @Test
4348     public MyValue1 test158(long val) {
4349         return (val == 0L) ? test158Cache : MyValue1.createWithFieldsInline(rI, val);
4350     }
4351 
4352     @Run(test = "test158")
4353     public void test158_verifier() {
4354         Asserts.assertEquals(test158(0), test158Cache);
4355         Asserts.assertEquals(test158(rL).hash(), testValue1.hash());
4356     }
4357 
4358     // Verify that cast that with incompatible types is properly handled
4359     @Test
4360     public void test160(NonValueClass arg) {
4361         Object tmp = arg;
4362         MyValue1 res = (MyValue1)tmp;
4363     }
4364 
4365     @Run(test = "test160")
4366     @Warmup(10000)
4367     public void test160_verifier(RunInfo info) {
4368         try {
4369             test160(new NonValueClass(42));
4370             throw new RuntimeException("No CCE thrown");
4371         } catch (ClassCastException e) {
4372             // Expected
4373         }
4374         test160(null);
4375     }
4376 }