1 /*
   2  * Copyright (c) 2017, 2025, 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 
  29 import jdk.internal.value.ValueClass;
  30 import jdk.internal.vm.annotation.LooselyConsistentValue;
  31 import jdk.internal.vm.annotation.NullRestricted;
  32 import jdk.internal.vm.annotation.Strict;
  33 
  34 import java.lang.invoke.MethodHandle;
  35 import java.lang.invoke.MethodHandles;
  36 import java.lang.invoke.MethodType;
  37 import java.lang.reflect.Method;
  38 import java.util.Arrays;
  39 
  40 import static compiler.valhalla.inlinetypes.InlineTypeIRNode.*;
  41 import static compiler.valhalla.inlinetypes.InlineTypes.*;
  42 
  43 /*
  44  * @test
  45  * @key randomness
  46  * @summary Test value class arrays.
  47  * @library /test/lib /
  48  * @enablePreview
  49  * @modules java.base/jdk.internal.value
  50  *          java.base/jdk.internal.vm.annotation
  51  * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
  52  * @enablePreview
  53  * @run main/othervm/timeout=300 compiler.valhalla.inlinetypes.TestArrays
  54  */
  55 
  56 @ForceCompileClassInitializer
  57 public class TestArrays {
  58 
  59     public static void main(String[] args) {
  60         Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS;
  61         scenarios[2].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode");
  62         scenarios[3].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:+UseArrayFlattening", "-XX:-UncommonNullCast");
  63         scenarios[4].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast");
  64         scenarios[5].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode");
  65 
  66         InlineTypes.getFramework()
  67                    .addScenarios(scenarios)
  68                    .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class)
  69                    .start();
  70     }
  71 
  72     static {
  73         // Make sure RuntimeException is loaded to prevent uncommon traps in IR verified tests
  74         RuntimeException tmp = new RuntimeException("42");
  75     }
  76 
  77     // Helper methods and classes
  78 
  79     protected long hash() {
  80         return hash(rI, rL);
  81     }
  82 
  83     protected long hash(int x, long y) {
  84         return MyValue1.createWithFieldsInline(x, y).hash();
  85     }
  86 
  87     static void verify(Object[] src, Object[] dst) {
  88         for (int i = 0; i < src.length; ++i) {
  89             Asserts.assertEQ(src[i], dst[i]);
  90         }
  91     }
  92 
  93     static boolean compile_and_run_again_if_deoptimized(RunInfo info) {
  94         if (!info.isWarmUp()) {
  95             Method m = info.getTest();
  96             if (TestFramework.isCompiled(m)) {
  97                 TestFramework.compile(m, CompLevel.C2);
  98             }
  99         }
 100         return false;
 101     }
 102 
 103     @LooselyConsistentValue
 104     static value class NotFlattenable {
 105         private final Object o1 = null;
 106         private final Object o2 = null;
 107         private final Object o3 = null;
 108         private final Object o4 = null;
 109         private final Object o5 = null;
 110         private final Object o6 = null;
 111 
 112         static final NotFlattenable DEFAULT = new NotFlattenable();
 113     }
 114 
 115     // Test value class array creation and initialization
 116     @Test
 117     @IR(applyIf = {"UseArrayFlattening", "true"},
 118         counts = {ALLOCA, "= 1"})
 119     @IR(applyIf = {"UseArrayFlattening", "false"},
 120         counts = {ALLOCA, "= 1"},
 121         failOn = LOAD)
 122     public MyValue1[] test1(int len) {
 123         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 124         for (int i = 0; i < len; ++i) {
 125             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 126         }
 127         return va;
 128     }
 129 
 130     @Run(test = "test1")
 131     public void test1_verifier() {
 132         int len = Math.abs(rI % 10);
 133         MyValue1[] va = test1(len);
 134         for (int i = 0; i < len; ++i) {
 135             Asserts.assertEQ(va[i].hash(), hash());
 136         }
 137     }
 138 
 139     // Test creation of a value class array and element access
 140     @Test
 141     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP})
 142     public long test2() {
 143         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
 144         va[0] = MyValue1.createWithFieldsInline(rI, rL);
 145         return va[0].hash();
 146     }
 147 
 148     @Run(test = "test2")
 149     public void test2_verifier() {
 150         long result = test2();
 151         Asserts.assertEQ(result, hash());
 152     }
 153 
 154     // Test receiving a value class array from the interpreter,
 155     // updating its elements in a loop and computing a hash.
 156     @Test
 157     @IR(failOn = ALLOCA)
 158     public long test3(MyValue1[] va) {
 159         long result = 0;
 160         for (int i = 0; i < 10; ++i) {
 161             result += va[i].hash();
 162             va[i] = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 163         }
 164         return result;
 165     }
 166 
 167     @Run(test = "test3")
 168     public void test3_verifier() {
 169         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 10, MyValue1.DEFAULT);
 170         long expected = 0;
 171         for (int i = 0; i < 10; ++i) {
 172             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 173             expected += va[i].hash();
 174         }
 175         long result = test3(va);
 176         Asserts.assertEQ(expected, result);
 177         for (int i = 0; i < 10; ++i) {
 178             if (va[i].hash() != hash(rI + 1, rL + 1)) {
 179                 Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1));
 180             }
 181         }
 182     }
 183 
 184     // Test returning a value class array received from the interpreter
 185     @Test
 186     @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP})
 187     public MyValue1[] test4(MyValue1[] va) {
 188         return va;
 189     }
 190 
 191     @Run(test = "test4")
 192     public void test4_verifier() {
 193         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 10, MyValue1.DEFAULT);
 194         for (int i = 0; i < 10; ++i) {
 195             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 196         }
 197         va = test4(va);
 198         for (int i = 0; i < 10; ++i) {
 199             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 200         }
 201     }
 202 
 203     // Merge value class arrays created from two branches
 204     @Test
 205     public MyValue1[] test5(boolean b) {
 206         MyValue1[] va;
 207         if (b) {
 208             va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 5, MyValue1.DEFAULT);
 209             for (int i = 0; i < 5; ++i) {
 210                 va[i] = MyValue1.createWithFieldsInline(rI, rL);
 211             }
 212         } else {
 213             va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 10, MyValue1.DEFAULT);
 214             for (int i = 0; i < 10; ++i) {
 215                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
 216             }
 217         }
 218         long sum = va[0].hashInterpreted();
 219         if (b) {
 220             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
 221         } else {
 222             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
 223         }
 224         return va;
 225     }
 226 
 227     @Run(test = "test5")
 228     public void test5_verifier() {
 229         MyValue1[] va = test5(true);
 230         Asserts.assertEQ(va.length, 5);
 231         Asserts.assertEQ(va[0].hash(), hash(rI, hash()));
 232         for (int i = 1; i < 5; ++i) {
 233             Asserts.assertEQ(va[i].hash(), hash());
 234         }
 235         va = test5(false);
 236         Asserts.assertEQ(va.length, 10);
 237         Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1));
 238         for (int i = 1; i < 10; ++i) {
 239             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 240         }
 241     }
 242 
 243     // Test creation of value class array with single element
 244     @Test
 245     @IR(failOn = {ALLOCA, LOOP, LOAD, TRAP})
 246     public MyValue1 test6() {
 247         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
 248         return va[0];
 249     }
 250 
 251     @Run(test = "test6")
 252     public void test6_verifier() {
 253         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
 254         MyValue1 v = test6();
 255         Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive());
 256     }
 257 
 258     // Test initialization of value class arrays
 259     @Test
 260     @IR(failOn = LOAD)
 261     public MyValue1[] test7(int len) {
 262         return (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 263     }
 264 
 265     @Run(test = "test7")
 266     public void test7_verifier() {
 267         int len = Math.abs(rI % 10);
 268         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 269         MyValue1[] var = test7(len);
 270         for (int i = 0; i < len; ++i) {
 271             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
 272         }
 273     }
 274 
 275     // Test creation of value class array with zero length
 276     @Test
 277     @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP})
 278     public MyValue1[] test8() {
 279         return (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 0, MyValue1.DEFAULT);
 280     }
 281 
 282     @Run(test = "test8")
 283     public void test8_verifier() {
 284         MyValue1[] va = test8();
 285         Asserts.assertEQ(va.length, 0);
 286     }
 287 
 288     static MyValue1[] test9_va;
 289 
 290     // Test that value class array loaded from field has correct type
 291     @Test
 292     @IR(failOn = LOOP)
 293     public long test9() {
 294         return test9_va[0].hash();
 295     }
 296 
 297     @Run(test = "test9")
 298     public void test9_verifier() {
 299         test9_va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
 300         test9_va[0] = MyValue1.createWithFieldsInline(rI, rL);
 301         long result = test9();
 302         Asserts.assertEQ(result, hash());
 303     }
 304 
 305     // Multi-dimensional arrays
 306     @Test
 307     public MyValue1[][][] test10(int len1, int len2, int len3) {
 308         MyValue1[][][] arr = new MyValue1[len1][len2][len3];
 309         for (int i = 0; i < len1; i++) {
 310             for (int j = 0; j < len2; j++) {
 311                 for (int k = 0; k < len3; k++) {
 312                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i , rL + j + k);
 313                 }
 314             }
 315         }
 316         return arr;
 317     }
 318 
 319     @Run(test = "test10")
 320     public void test10_verifier() {
 321         MyValue1[][][] arr = test10(2, 3, 4);
 322         for (int i = 0; i < 2; i++) {
 323             for (int j = 0; j < 3; j++) {
 324                 for (int k = 0; k < 4; k++) {
 325                     Asserts.assertEQ(arr[i][j][k].hash(), MyValue1.createWithFieldsDontInline(rI + i , rL + j + k).hash());
 326                 }
 327             }
 328         }
 329     }
 330 
 331     @Test
 332     public void test11(MyValue1[][][] arr, long[] res) {
 333         int l = 0;
 334         for (int i = 0; i < arr.length; i++) {
 335             for (int j = 0; j < arr[i].length; j++) {
 336                 for (int k = 0; k < arr[i][j].length; k++) {
 337                     res[l] = arr[i][j][k].hash();
 338                     l++;
 339                 }
 340             }
 341         }
 342     }
 343 
 344     @Run(test = "test11")
 345     public void test11_verifier() {
 346         MyValue1[][][] arr = new MyValue1[2][3][4];
 347         long[] res = new long[2*3*4];
 348         long[] verif = new long[2*3*4];
 349         int l = 0;
 350         for (int i = 0; i < 2; i++) {
 351             for (int j = 0; j < 3; j++) {
 352                 for (int k = 0; k < 4; k++) {
 353                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i, rL + j + k);
 354                     verif[l] = arr[i][j][k].hash();
 355                     l++;
 356                 }
 357             }
 358         }
 359         test11(arr, res);
 360         for (int i = 0; i < verif.length; i++) {
 361             Asserts.assertEQ(res[i], verif[i]);
 362         }
 363     }
 364 
 365     // Array load out of bounds (upper bound) at compile time
 366     @Test
 367     public int test12() {
 368         int arraySize = Math.abs(rI) % 10;
 369         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, arraySize, MyValue1.DEFAULT);
 370 
 371         for (int i = 0; i < arraySize; i++) {
 372             va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 373         }
 374 
 375         try {
 376             return va[arraySize + 1].x;
 377         } catch (ArrayIndexOutOfBoundsException e) {
 378             return rI;
 379         }
 380     }
 381 
 382     @Run(test = "test12")
 383     public void test12_verifier() {
 384         Asserts.assertEQ(test12(), rI);
 385     }
 386 
 387     // Array load  out of bounds (lower bound) at compile time
 388     @Test
 389     public int test13() {
 390         int arraySize = Math.abs(rI) % 10;
 391         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, arraySize, MyValue1.DEFAULT);
 392 
 393         for (int i = 0; i < arraySize; i++) {
 394             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL);
 395         }
 396 
 397         try {
 398             return va[-arraySize].x;
 399         } catch (ArrayIndexOutOfBoundsException e) {
 400             return rI;
 401         }
 402     }
 403 
 404     @Run(test = "test13")
 405     public void test13_verifier() {
 406         Asserts.assertEQ(test13(), rI);
 407     }
 408 
 409     // Array load out of bound not known to compiler (both lower and upper bound)
 410     @Test
 411     public int test14(MyValue1[] va, int index)  {
 412         return va[index].x;
 413     }
 414 
 415     @Run(test = "test14")
 416     public void test14_verifier() {
 417         int arraySize = Math.abs(rI) % 10;
 418         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, arraySize, MyValue1.DEFAULT);
 419 
 420         for (int i = 0; i < arraySize; i++) {
 421             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 422         }
 423 
 424         int result;
 425         for (int i = -20; i < 20; i++) {
 426             try {
 427                 result = test14(va, i);
 428             } catch (ArrayIndexOutOfBoundsException e) {
 429                 result = rI;
 430             }
 431             Asserts.assertEQ(result, rI);
 432         }
 433     }
 434 
 435     // Array store out of bounds (upper bound) at compile time
 436     @Test
 437     public int test15() {
 438         int arraySize = Math.abs(rI) % 10;
 439         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, arraySize, MyValue1.DEFAULT);
 440 
 441         try {
 442             for (int i = 0; i <= arraySize; i++) {
 443                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 444             }
 445             return rI - 1;
 446         } catch (ArrayIndexOutOfBoundsException e) {
 447             return rI;
 448         }
 449     }
 450 
 451     @Run(test = "test15")
 452     public void test15_verifier() {
 453         Asserts.assertEQ(test15(), rI);
 454     }
 455 
 456     // Array store out of bounds (lower bound) at compile time
 457     @Test
 458     public int test16() {
 459         int arraySize = Math.abs(rI) % 10;
 460         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, arraySize, MyValue1.DEFAULT);
 461 
 462         try {
 463             for (int i = -1; i <= arraySize; i++) {
 464                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 465             }
 466             return rI - 1;
 467         } catch (ArrayIndexOutOfBoundsException e) {
 468             return rI;
 469         }
 470     }
 471 
 472     @Run(test = "test16")
 473     public void test16_verifier() {
 474         Asserts.assertEQ(test16(), rI);
 475     }
 476 
 477     // Array store out of bound not known to compiler (both lower and upper bound)
 478     @Test
 479     public int test17(MyValue1[] va, int index, MyValue1 vt)  {
 480         va[index] = vt;
 481         return va[index].x;
 482     }
 483 
 484     @Run(test = "test17")
 485     public void test17_verifier() {
 486         int arraySize = Math.abs(rI) % 10;
 487         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, arraySize, MyValue1.DEFAULT);
 488 
 489         for (int i = 0; i < arraySize; i++) {
 490             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 491         }
 492 
 493         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 494         int result;
 495         for (int i = -20; i < 20; i++) {
 496             try {
 497                 result = test17(va, i, vt);
 498             } catch (ArrayIndexOutOfBoundsException e) {
 499                 result = rI + 1;
 500             }
 501             Asserts.assertEQ(result, rI + 1);
 502         }
 503 
 504         for (int i = 0; i < arraySize; i++) {
 505             Asserts.assertEQ(va[i].x, rI + 1);
 506         }
 507     }
 508 
 509     // clone() as stub call
 510     @Test
 511     public MyValue1[] test18(MyValue1[] va) {
 512         return va.clone();
 513     }
 514 
 515     @Run(test = "test18")
 516     public void test18_verifier() {
 517         int len = Math.abs(rI) % 10;
 518         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 519         for (int i = 0; i < len; ++i) {
 520             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 521         }
 522         MyValue1[] result = test18(va);
 523         for (int i = 0; i < len; ++i) {
 524             Asserts.assertEQ(result[i].hash(), va[i].hash());
 525         }
 526     }
 527 
 528     // clone() as series of loads/stores
 529     static MyValue1[] test19_orig = null;
 530 
 531     @Test
 532     public MyValue1[] test19() {
 533         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
 534         for (int i = 0; i < va.length; ++i) {
 535             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 536         }
 537         test19_orig = va;
 538 
 539         return va.clone();
 540     }
 541 
 542     @Run(test = "test19")
 543     public void test19_verifier() {
 544         MyValue1[] result = test19();
 545         for (int i = 0; i < test19_orig.length; ++i) {
 546             Asserts.assertEQ(result[i].hash(), test19_orig[i].hash());
 547         }
 548     }
 549 
 550     // arraycopy() of value class array with oop fields
 551     @Test
 552     public void test20(MyValue1[] src, MyValue1[] dst) {
 553         System.arraycopy(src, 0, dst, 0, src.length);
 554     }
 555 
 556     @Run(test = "test20")
 557     public void test20_verifier() {
 558         int len = Math.abs(rI) % 10;
 559         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 560         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 561         for (int i = 0; i < len; ++i) {
 562             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 563         }
 564         test20(src, dst);
 565         for (int i = 0; i < len; ++i) {
 566             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 567         }
 568     }
 569 
 570     // arraycopy() of value class array with no oop field
 571     @Test
 572     public void test21(MyValue2[] src, MyValue2[] dst) {
 573         System.arraycopy(src, 0, dst, 0, src.length);
 574     }
 575 
 576     @Run(test = "test21")
 577     public void test21_verifier() {
 578         int len = Math.abs(rI) % 10;
 579         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
 580         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
 581         for (int i = 0; i < len; ++i) {
 582             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 583         }
 584         test21(src, dst);
 585         for (int i = 0; i < len; ++i) {
 586             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 587         }
 588     }
 589 
 590     // arraycopy() of value class array with oop field and tightly
 591     // coupled allocation as dest
 592     @Test
 593     public MyValue1[] test22(MyValue1[] src) {
 594         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, src.length, MyValue1.DEFAULT);
 595         System.arraycopy(src, 0, dst, 0, src.length);
 596         return dst;
 597     }
 598 
 599     @Run(test = "test22")
 600     public void test22_verifier() {
 601         int len = Math.abs(rI) % 10;
 602         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 603         for (int i = 0; i < len; ++i) {
 604             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 605         }
 606         MyValue1[] dst = test22(src);
 607         for (int i = 0; i < len; ++i) {
 608             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 609         }
 610     }
 611 
 612     // arraycopy() of value class array with oop fields and tightly
 613     // coupled allocation as dest
 614     @Test
 615     public MyValue1[] test23(MyValue1[] src) {
 616         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, src.length + 10, MyValue1.DEFAULT);
 617         System.arraycopy(src, 0, dst, 5, src.length);
 618         return dst;
 619     }
 620 
 621     @Run(test = "test23")
 622     public void test23_verifier() {
 623         int len = Math.abs(rI) % 10;
 624         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 625         for (int i = 0; i < len; ++i) {
 626             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 627         }
 628         MyValue1[] dst = test23(src);
 629         for (int i = 5; i < len; ++i) {
 630             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 631         }
 632     }
 633 
 634     // arraycopy() of value class array passed as Object
 635     @Test
 636     public void test24(MyValue1[] src, Object dst) {
 637         System.arraycopy(src, 0, dst, 0, src.length);
 638     }
 639 
 640     @Run(test = "test24")
 641     public void test24_verifier() {
 642         int len = Math.abs(rI) % 10;
 643         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 644         MyValue1[] dst1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 645         Object[] dst2 = new Object[len];
 646         for (int i = 0; i < len; ++i) {
 647             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 648         }
 649         test24(src, dst1);
 650         for (int i = 0; i < len; ++i) {
 651             Asserts.assertEQ(src[i].hash(), dst1[i].hash());
 652         }
 653         test24(src, dst2);
 654         for (int i = 0; i < len; ++i) {
 655             Asserts.assertEQ(src[i].hash(), ((MyValue1)dst2[i]).hash());
 656         }
 657     }
 658 
 659     // short arraycopy() with no oop field
 660     @Test
 661     public void test25(MyValue2[] src, MyValue2[] dst) {
 662         System.arraycopy(src, 0, dst, 0, 8);
 663     }
 664 
 665     @Run(test = "test25")
 666     public void test25_verifier() {
 667         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
 668         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
 669         for (int i = 0; i < 8; ++i) {
 670             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 671         }
 672         test25(src, dst);
 673         for (int i = 0; i < 8; ++i) {
 674             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 675         }
 676     }
 677 
 678     // short arraycopy() with oop fields
 679     @Test
 680     public void test26(MyValue1[] src, MyValue1[] dst) {
 681         System.arraycopy(src, 0, dst, 0, 8);
 682     }
 683 
 684     @Run(test = "test26")
 685     public void test26_verifier() {
 686         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
 687         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
 688         for (int i = 0; i < 8; ++i) {
 689             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 690         }
 691         test26(src, dst);
 692         for (int i = 0; i < 8; ++i) {
 693             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 694         }
 695     }
 696 
 697     // short arraycopy() with oop fields and offsets
 698     @Test
 699     public void test27(MyValue1[] src, MyValue1[] dst) {
 700         System.arraycopy(src, 1, dst, 2, 6);
 701     }
 702 
 703     @Run(test = "test27")
 704     public void test27_verifier() {
 705         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
 706         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
 707         for (int i = 0; i < 8; ++i) {
 708             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 709         }
 710         test27(src, dst);
 711         for (int i = 2; i < 8; ++i) {
 712             Asserts.assertEQ(src[i-1].hash(), dst[i].hash());
 713         }
 714     }
 715 
 716     // non escaping allocations
 717     // TODO 8252027: Make sure this is optimized with ZGC
 718     @Test
 719     @IR(applyIf = {"UseZGC", "false"},
 720         failOn = {ALLOCA, LOOP, LOAD, TRAP})
 721     public MyValue2 test28() {
 722         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
 723         src[0] = MyValue2.createWithFieldsInline(rI, rD);
 724         MyValue2[] dst = (MyValue2[])src.clone();
 725         return dst[0];
 726     }
 727 
 728     @Run(test = "test28")
 729     public void test28_verifier() {
 730         MyValue2 v = MyValue2.createWithFieldsInline(rI, rD);
 731         MyValue2 result = test28();
 732         Asserts.assertEQ(result.hash(), v.hash());
 733     }
 734 
 735     // non escaping allocations
 736     // TODO 8227588: shouldn't this have the same IR matching rules as test6?
 737     // @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP)
 738     @Test
 739     @IR(applyIf = {"UseArrayFlattening", "true"},
 740         failOn = {ALLOCA, LOOP, LOAD, TRAP})
 741     @IR(applyIf = {"UseArrayFlattening", "false"},
 742         failOn = {ALLOCA, LOOP, TRAP})
 743     public MyValue2 test29(MyValue2[] src) {
 744         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
 745         System.arraycopy(src, 0, dst, 0, 10);
 746         return dst[0];
 747     }
 748 
 749     @Run(test = "test29")
 750     public void test29_verifier() {
 751         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
 752         for (int i = 0; i < 10; ++i) {
 753             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 754         }
 755         MyValue2 v = test29(src);
 756         Asserts.assertEQ(src[0].hash(), v.hash());
 757     }
 758 
 759     // non escaping allocation with uncommon trap that needs
 760     // eliminated value class array element as debug info
 761     @Test
 762     public MyValue2 test30(MyValue2[] src, boolean flag) {
 763         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
 764         System.arraycopy(src, 0, dst, 0, 10);
 765         if (flag) { }
 766         return dst[0];
 767     }
 768 
 769     @Run(test = "test30")
 770     @Warmup(10000)
 771     public void test30_verifier(RunInfo info) {
 772         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
 773         for (int i = 0; i < 10; ++i) {
 774             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 775         }
 776         MyValue2 v = test30(src, !info.isWarmUp());
 777         Asserts.assertEQ(src[0].hash(), v.hash());
 778     }
 779 
 780 
 781     // non escaping allocation with memory phi
 782     @Test
 783     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP})
 784     public long test31(boolean b, boolean deopt, Method m) {
 785         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 1, MyValue2.DEFAULT);
 786         if (b) {
 787             src[0] = MyValue2.createWithFieldsInline(rI, rD);
 788         } else {
 789             src[0] = MyValue2.createWithFieldsInline(rI+1, rD+1);
 790         }
 791         if (deopt) {
 792             // uncommon trap
 793             TestFramework.deoptimize(m);
 794         }
 795         return src[0].hash();
 796     }
 797 
 798     @Run(test = "test31")
 799     public void test31_verifier(RunInfo info) {
 800         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, rD);
 801         long result1 = test31(true, !info.isWarmUp(), info.getTest());
 802         Asserts.assertEQ(result1, v1.hash());
 803         MyValue2 v2 = MyValue2.createWithFieldsInline(rI + 1, rD + 1);
 804         long result2 = test31(false, !info.isWarmUp(), info.getTest());
 805         Asserts.assertEQ(result2, v2.hash());
 806     }
 807 
 808     // Tests with Object arrays and clone/arraycopy
 809     // clone() as stub call
 810     @Test
 811     public Object[] test32(Object[] va) {
 812         return va.clone();
 813     }
 814 
 815     @Run(test = "test32")
 816     public void test32_verifier() {
 817         int len = Math.abs(rI) % 10;
 818         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 819         for (int i = 0; i < len; ++i) {
 820             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 821         }
 822         MyValue1[] result = (MyValue1[])test32(va);
 823         for (int i = 0; i < len; ++i) {
 824             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 825         }
 826     }
 827 
 828     @Test
 829     public Object[] test33(Object[] va) {
 830         return va.clone();
 831     }
 832 
 833     @Run(test = "test33")
 834     public void test33_verifier() {
 835         int len = Math.abs(rI) % 10;
 836         Object[] va = new Object[len];
 837         for (int i = 0; i < len; ++i) {
 838             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 839         }
 840         Object[] result = test33(va);
 841         for (int i = 0; i < len; ++i) {
 842             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 843             // Check that array has correct properties (null-ok)
 844             result[i] = null;
 845         }
 846     }
 847 
 848     // clone() as series of loads/stores
 849     static Object[] test34_orig = null;
 850 
 851     @ForceInline
 852     public Object[] test34_helper(boolean flag) {
 853         Object[] va = null;
 854         if (flag) {
 855             va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
 856             for (int i = 0; i < va.length; ++i) {
 857                 va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 858             }
 859         } else {
 860             va = new Object[8];
 861         }
 862         return va;
 863     }
 864 
 865     @Test
 866     public Object[] test34(boolean flag) {
 867         Object[] va = test34_helper(flag);
 868         test34_orig = va;
 869         return va.clone();
 870     }
 871 
 872     @Run(test = "test34")
 873     public void test34_verifier(RunInfo info) {
 874         test34(false);
 875         for (int i = 0; i < 10; i++) { // make sure we do deopt
 876             Object[] result = test34(true);
 877             verify(test34_orig, result);
 878             // Check that array has correct properties (null-free)
 879             try {
 880                 result[0] = null;
 881                 throw new RuntimeException("Should throw NullPointerException");
 882             } catch (NullPointerException e) {
 883                 // Expected
 884             }
 885         }
 886         if (compile_and_run_again_if_deoptimized(info)) {
 887             Object[] result = test34(true);
 888             verify(test34_orig, result);
 889             // Check that array has correct properties (null-free)
 890             try {
 891                 result[0] = null;
 892                 throw new RuntimeException("Should throw NullPointerException");
 893             } catch (NullPointerException e) {
 894                 // Expected
 895             }
 896         }
 897     }
 898 
 899     // arraycopy() of value class array of unknown size
 900     @Test
 901     public void test35(Object src, Object dst, int len) {
 902         System.arraycopy(src, 0, dst, 0, len);
 903     }
 904 
 905     @Run(test = "test35")
 906     public void test35_verifier(RunInfo info) {
 907         int len = Math.abs(rI) % 10;
 908         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 909         MyValue1[] dst1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
 910         Object[] dst2 = new Object[len];
 911         for (int i = 0; i < len; ++i) {
 912             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 913         }
 914         test35(src, dst1, src.length);
 915         verify(src, dst1);
 916         test35(src, dst2, src.length);
 917         verify(src, dst2);
 918         if (compile_and_run_again_if_deoptimized(info)) {
 919             test35(src, dst1, src.length);
 920             verify(src, dst1);
 921         }
 922     }
 923 
 924     @Test
 925     public void test36(Object src, MyValue2[] dst) {
 926         System.arraycopy(src, 0, dst, 0, dst.length);
 927     }
 928 
 929     @Run(test = "test36")
 930     public void test36_verifier(RunInfo info) {
 931         int len = Math.abs(rI) % 10;
 932         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
 933         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
 934         for (int i = 0; i < len; ++i) {
 935             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 936         }
 937         test36(src, dst);
 938         verify(src, dst);
 939         if (compile_and_run_again_if_deoptimized(info)) {
 940             test36(src, dst);
 941             verify(src, dst);
 942         }
 943     }
 944 
 945     @Test
 946     public void test37(MyValue2[] src, Object dst) {
 947         System.arraycopy(src, 0, dst, 0, src.length);
 948     }
 949 
 950     @Run(test = "test37")
 951     public void test37_verifier(RunInfo info) {
 952         int len = Math.abs(rI) % 10;
 953         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
 954         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
 955         for (int i = 0; i < len; ++i) {
 956             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 957         }
 958         test37(src, dst);
 959         verify(src, dst);
 960         if (compile_and_run_again_if_deoptimized(info)) {
 961             test37(src, dst);
 962             verify(src, dst);
 963         }
 964     }
 965 
 966     @Test
 967     public void test38(Object src, MyValue2[] dst) {
 968         System.arraycopy(src, 0, dst, 0, dst.length);
 969     }
 970 
 971     @Run(test = "test38")
 972     @Warmup(1) // Avoid early compilation
 973     public void test38_verifier(RunInfo info) {
 974         int len = Math.abs(rI) % 10;
 975         Object[] src = new Object[len];
 976         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
 977         for (int i = 0; i < len; ++i) {
 978             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 979         }
 980         test38(src, dst);
 981         verify(dst, src);
 982         if (!info.isWarmUp()) {
 983             Method m = info.getTest();
 984             TestFramework.assertDeoptimizedByC2(m);
 985             TestFramework.compile(m, CompLevel.C2);
 986             test38(src, dst);
 987             verify(dst, src);
 988             TestFramework.assertCompiledByC2(m);
 989         }
 990     }
 991 
 992     @Test
 993     public void test39(MyValue2[] src, Object dst) {
 994         System.arraycopy(src, 0, dst, 0, src.length);
 995     }
 996 
 997     @Run(test = "test39")
 998     public void test39_verifier(RunInfo info) {
 999         int len = Math.abs(rI) % 10;
1000         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
1001         Object[] dst = new Object[len];
1002         for (int i = 0; i < len; ++i) {
1003             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1004         }
1005         test39(src, dst);
1006         verify(src, dst);
1007         if (compile_and_run_again_if_deoptimized(info)) {
1008             test39(src, dst);
1009             verify(src, dst);
1010         }
1011     }
1012 
1013     @Test
1014     public void test40(Object[] src, Object dst) {
1015         System.arraycopy(src, 0, dst, 0, src.length);
1016     }
1017 
1018     @Run(test = "test40")
1019     @Warmup(1) // Avoid early compilation
1020     public void test40_verifier(RunInfo info) {
1021         int len = Math.abs(rI) % 10;
1022         Object[] src = new Object[len];
1023         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
1024         for (int i = 0; i < len; ++i) {
1025             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1026         }
1027         test40(src, dst);
1028         verify(dst, src);
1029         if (!info.isWarmUp()) {
1030             Method m = info.getTest();
1031             TestFramework.assertDeoptimizedByC2(m);
1032             TestFramework.compile(m, CompLevel.C2);
1033             test40(src, dst);
1034             verify(dst, src);
1035             TestFramework.assertCompiledByC2(m);
1036         }
1037     }
1038 
1039     @Test
1040     public void test41(Object src, Object[] dst) {
1041         System.arraycopy(src, 0, dst, 0, dst.length);
1042     }
1043 
1044     @Run(test = "test41")
1045     public void test41_verifier(RunInfo info) {
1046         int len = Math.abs(rI) % 10;
1047         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
1048         Object[] dst = new Object[len];
1049         for (int i = 0; i < len; ++i) {
1050             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1051         }
1052         test41(src, dst);
1053         verify(src, dst);
1054         if (compile_and_run_again_if_deoptimized(info)) {
1055             test41(src, dst);
1056             verify(src, dst);
1057         }
1058     }
1059 
1060     @Test
1061     public void test42(Object[] src, Object[] dst) {
1062         System.arraycopy(src, 0, dst, 0, src.length);
1063     }
1064 
1065     @Run(test = "test42")
1066     public void test42_verifier(RunInfo info) {
1067         int len = Math.abs(rI) % 10;
1068         Object[] src = new Object[len];
1069         Object[] dst = new Object[len];
1070         for (int i = 0; i < len; ++i) {
1071             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1072         }
1073         test42(src, dst);
1074         verify(src, dst);
1075         if (!info.isWarmUp()) {
1076             TestFramework.assertCompiledByC2(info.getTest());
1077         }
1078     }
1079 
1080     // short arraycopy()'s
1081     @Test
1082     public void test43(Object src, Object dst) {
1083         System.arraycopy(src, 0, dst, 0, 8);
1084     }
1085 
1086     @Run(test = "test43")
1087     public void test43_verifier(RunInfo info) {
1088         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
1089         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
1090         for (int i = 0; i < 8; ++i) {
1091             src[i] = MyValue1.createWithFieldsInline(rI, rL);
1092         }
1093         test43(src, dst);
1094         verify(src, dst);
1095         if (compile_and_run_again_if_deoptimized(info)) {
1096             test43(src, dst);
1097             verify(src, dst);
1098         }
1099     }
1100 
1101     @Test
1102     public void test44(Object src, MyValue2[] dst) {
1103         System.arraycopy(src, 0, dst, 0, 8);
1104     }
1105 
1106     @Run(test = "test44")
1107     public void test44_verifier(RunInfo info) {
1108         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1109         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1110         for (int i = 0; i < 8; ++i) {
1111             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1112         }
1113         test44(src, dst);
1114         verify(src, dst);
1115         if (compile_and_run_again_if_deoptimized(info)) {
1116             test44(src, dst);
1117             verify(src, dst);
1118         }
1119     }
1120 
1121     @Test
1122     public void test45(MyValue2[] src, Object dst) {
1123         System.arraycopy(src, 0, dst, 0, 8);
1124     }
1125 
1126     @Run(test = "test45")
1127     public void test45_verifier(RunInfo info) {
1128         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1129         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1130         for (int i = 0; i < 8; ++i) {
1131             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1132         }
1133         test45(src, dst);
1134         verify(src, dst);
1135         if (compile_and_run_again_if_deoptimized(info)) {
1136             test45(src, dst);
1137             verify(src, dst);
1138         }
1139     }
1140 
1141     @Test
1142     public void test46(Object[] src, MyValue2[] dst) {
1143         System.arraycopy(src, 0, dst, 0, 8);
1144     }
1145 
1146     @Run(test = "test46")
1147     @Warmup(1) // Avoid early compilation
1148     public void test46_verifier(RunInfo info) {
1149         Object[] src = new Object[8];
1150         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1151         for (int i = 0; i < 8; ++i) {
1152             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1153         }
1154         test46(src, dst);
1155         verify(dst, src);
1156         if (!info.isWarmUp()) {
1157             Method m = info.getTest();
1158             TestFramework.assertDeoptimizedByC2(m);
1159             TestFramework.compile(m, CompLevel.C2);
1160             test46(src, dst);
1161             verify(dst, src);
1162             TestFramework.assertCompiledByC2(m);
1163         }
1164     }
1165 
1166     @Test
1167     public void test47(MyValue2[] src, Object[] dst) {
1168         System.arraycopy(src, 0, dst, 0, 8);
1169     }
1170 
1171     @Run(test = "test47")
1172     public void test47_verifier(RunInfo info) {
1173         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1174         Object[] dst = new Object[8];
1175         for (int i = 0; i < 8; ++i) {
1176             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1177         }
1178         test47(src, dst);
1179         verify(src, dst);
1180         if (compile_and_run_again_if_deoptimized(info)) {
1181             test47(src, dst);
1182             verify(src, dst);
1183         }
1184     }
1185 
1186     @Test
1187     public void test48(Object[] src, Object dst) {
1188         System.arraycopy(src, 0, dst, 0, 8);
1189     }
1190 
1191     @Run(test = "test48")
1192     @Warmup(1) // Avoid early compilation
1193     public void test48_verifier(RunInfo info) {
1194         Object[] src = new Object[8];
1195         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1196         for (int i = 0; i < 8; ++i) {
1197             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1198         }
1199         test48(src, dst);
1200         verify(dst, src);
1201         if (!info.isWarmUp()) {
1202             Method m = info.getTest();
1203             TestFramework.assertDeoptimizedByC2(m);
1204             TestFramework.compile(m, CompLevel.C2);
1205             test48(src, dst);
1206             verify(dst, src);
1207             TestFramework.assertCompiledByC2(m);
1208         }
1209     }
1210 
1211     @Test
1212     public void test49(Object src, Object[] dst) {
1213         System.arraycopy(src, 0, dst, 0, 8);
1214     }
1215 
1216     @Run(test = "test49")
1217     public void test49_verifier(RunInfo info) {
1218         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
1219         Object[] dst = new Object[8];
1220         for (int i = 0; i < 8; ++i) {
1221             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1222         }
1223         test49(src, dst);
1224         verify(src, dst);
1225         if (compile_and_run_again_if_deoptimized(info)) {
1226             test49(src, dst);
1227             verify(src, dst);
1228         }
1229     }
1230 
1231     @Test
1232     public void test50(Object[] src, Object[] dst) {
1233         System.arraycopy(src, 0, dst, 0, 8);
1234     }
1235 
1236     @Run(test = "test50")
1237     public void test50_verifier(RunInfo info) {
1238         Object[] src = new Object[8];
1239         Object[] dst = new Object[8];
1240         for (int i = 0; i < 8; ++i) {
1241             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1242         }
1243         test50(src, dst);
1244         verify(src, dst);
1245         if (!info.isWarmUp()) {
1246             Method m = info.getTest();
1247             TestFramework.assertCompiledByC2(m);
1248         }
1249     }
1250 
1251     @Test
1252     public MyValue1[] test51(MyValue1[] va) {
1253         Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class);
1254         return (MyValue1[]) res;
1255     }
1256 
1257     @Run(test = "test51")
1258     public void test51_verifier() {
1259         int len = Math.abs(rI) % 10;
1260         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1261         for (int i = 0; i < len; ++i) {
1262             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1263         }
1264         MyValue1[] result = test51(va);
1265         verify(va, result);
1266     }
1267 
1268     static final MyValue1[] test52_va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
1269 
1270     @Test
1271     public MyValue1[] test52() {
1272         Object[] res = Arrays.copyOf(test52_va, 8, MyValue1[].class);
1273         return (MyValue1[]) res;
1274     }
1275 
1276     @Run(test = "test52")
1277     public void test52_verifier() {
1278         for (int i = 0; i < 8; ++i) {
1279             test52_va[i] = MyValue1.createWithFieldsInline(rI, rL);
1280         }
1281         MyValue1[] result = test52();
1282         verify(test52_va, result);
1283     }
1284 
1285     @Test
1286     public MyValue1[] test53(Object[] va) {
1287         Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class);
1288         return (MyValue1[]) res;
1289     }
1290 
1291     @Run(test = "test53")
1292     public void test53_verifier() {
1293         int len = Math.abs(rI) % 10;
1294         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1295         for (int i = 0; i < len; ++i) {
1296             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1297         }
1298         MyValue1[] result = test53(va);
1299         verify(result, va);
1300     }
1301 
1302     @Test
1303     public Object[] test54(MyValue1[] va) {
1304         return Arrays.copyOf(va, va.length, Object[].class);
1305     }
1306 
1307     @Run(test = "test54")
1308     public void test54_verifier() {
1309         int len = Math.abs(rI) % 10;
1310         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1311         for (int i = 0; i < len; ++i) {
1312             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1313         }
1314         Object[] result = test54(va);
1315         verify(va, result);
1316     }
1317 
1318     @Test
1319     public Object[] test55(Object[] va) {
1320         return Arrays.copyOf(va, va.length, Object[].class);
1321     }
1322 
1323     @Run(test = "test55")
1324     public void test55_verifier() {
1325         int len = Math.abs(rI) % 10;
1326         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1327         for (int i = 0; i < len; ++i) {
1328             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1329         }
1330         Object[] result = test55(va);
1331         verify(va, result);
1332     }
1333 
1334     @Test
1335     public MyValue1[] test56(Object[] va) {
1336         Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class);
1337         return (MyValue1[]) res;
1338     }
1339 
1340     @Run(test = "test56")
1341     public void test56_verifier() {
1342         int len = Math.abs(rI) % 10;
1343         Object[] va = new Object[len];
1344         for (int i = 0; i < len; ++i) {
1345             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1346         }
1347         MyValue1[] result = test56(va);
1348         verify(result, va);
1349     }
1350 
1351     @Test
1352     public Object[] test57(Object[] va, Class klass) {
1353         return Arrays.copyOf(va, va.length, klass);
1354     }
1355 
1356     @Run(test = "test57")
1357     public void test57_verifier() {
1358         int len = Math.abs(rI) % 10;
1359         Object[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1360         for (int i = 0; i < len; ++i) {
1361             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1362         }
1363         Object[] result = test57(va, MyValue1[].class);
1364         verify(va, result);
1365     }
1366 
1367     @Test
1368     public Object[] test58(MyValue1[] va, Class klass) {
1369         return Arrays.copyOf(va, va.length, klass);
1370     }
1371 
1372     @Run(test = "test58")
1373     public void test58_verifier(RunInfo info) {
1374         int len = Math.abs(rI) % 10;
1375         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1376         for (int i = 0; i < len; ++i) {
1377             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1378         }
1379         for (int i = 0; i < 10; i++) {
1380             Object[] result = test58(va, MyValue1[].class);
1381             verify(va, result);
1382         }
1383         if (compile_and_run_again_if_deoptimized(info)) {
1384             Object[] result = test58(va, MyValue1[].class);
1385             verify(va, result);
1386         }
1387     }
1388 
1389     @Test
1390     public Object[] test59(MyValue1[] va) {
1391         return Arrays.copyOf(va, va.length+1, va.getClass());
1392     }
1393 
1394     @Run(test = "test59")
1395     public void test59_verifier() {
1396         int len = Math.abs(rI) % 10;
1397         MyValue1[] va = (MyValue1[])ValueClass.newNullableAtomicArray(MyValue1.class, len);
1398         MyValue1[] verif = (MyValue1[])ValueClass.newNullableAtomicArray(MyValue1.class, len + 1);
1399         for (int i = 0; i < len; ++i) {
1400             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1401             verif[i] = va[i];
1402         }
1403         Object[] result = test59(va);
1404         verify(verif, result);
1405     }
1406 
1407     @Test
1408     public Object[] test60(Object[] va, Class klass) {
1409         return Arrays.copyOf(va, va.length+1, klass);
1410     }
1411 
1412     @Run(test = "test60")
1413     public void test60_verifier() {
1414         int len = Math.abs(rI) % 10;
1415         MyValue1[] va = (MyValue1[])ValueClass.newNullableAtomicArray(MyValue1.class, len);
1416         MyValue1[] verif = (MyValue1[])ValueClass.newNullableAtomicArray(MyValue1.class, len + 1);
1417         for (int i = 0; i < len; ++i) {
1418             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1419             verif[i] = (MyValue1)va[i];
1420         }
1421         Object[] result = test60(va, va.getClass());
1422         verify(verif, result);
1423     }
1424 
1425     @Test
1426     public Object[] test61(Object[] va, Class klass) {
1427         return Arrays.copyOf(va, va.length+1, klass);
1428     }
1429 
1430     @Run(test = "test61")
1431     public void test61_verifier() {
1432         int len = Math.abs(rI) % 10;
1433         Object[] va = new NonValueClass[len];
1434         for (int i = 0; i < len; ++i) {
1435             va[i] = new NonValueClass(rI);
1436         }
1437         Object[] result = test61(va, NonValueClass[].class);
1438         for (int i = 0; i < va.length; ++i) {
1439             Asserts.assertEQ(va[i], result[i]);
1440         }
1441     }
1442 
1443     @ForceInline
1444     public Object[] test62_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1445         Object[] arr = null;
1446         if (i == 10) {
1447             arr = oa;
1448         } else {
1449             arr = va;
1450         }
1451         return arr;
1452     }
1453 
1454     @Test
1455     public Object[] test62(MyValue1[] va, NonValueClass[] oa) {
1456         int i = 0;
1457         for (; i < 10; i++);
1458 
1459         Object[] arr = test62_helper(i, va, oa);
1460 
1461         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1462     }
1463 
1464     @Run(test = "test62")
1465     public void test62_verifier() {
1466         int len = Math.abs(rI) % 10;
1467         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1468         NonValueClass[] oa = new NonValueClass[len];
1469         for (int i = 0; i < len; ++i) {
1470             oa[i] = new NonValueClass(rI);
1471         }
1472         test62_helper(42, va, oa);
1473         Object[] result = test62(va, oa);
1474         for (int i = 0; i < va.length; ++i) {
1475             Asserts.assertEQ(oa[i], result[i]);
1476         }
1477     }
1478 
1479     @ForceInline
1480     public Object[] test63_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1481         Object[] arr = null;
1482         if (i == 10) {
1483             arr = va;
1484         } else {
1485             arr = oa;
1486         }
1487         return arr;
1488     }
1489 
1490     @Test
1491     public Object[] test63(MyValue1[] va, NonValueClass[] oa) {
1492         int i = 0;
1493         for (; i < 10; i++);
1494 
1495         Object[] arr = test63_helper(i, va, oa);
1496 
1497         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1498     }
1499 
1500     @Run(test = "test63")
1501     public void test63_verifier() {
1502         int len = Math.abs(rI) % 10;
1503         MyValue1[] va = (MyValue1[])ValueClass.newNullableAtomicArray(MyValue1.class, len);
1504         MyValue1[] verif = (MyValue1[])ValueClass.newNullableAtomicArray(MyValue1.class, len + 1);
1505         for (int i = 0; i < len; ++i) {
1506             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1507             verif[i] = va[i];
1508         }
1509         NonValueClass[] oa = new NonValueClass[len];
1510         test63_helper(42, va, oa);
1511         Object[] result = test63(va, oa);
1512         verify(verif, result);
1513     }
1514 
1515     // Test initialization of value class arrays: small array
1516     @Test
1517     public MyValue1[] test64() {
1518         return (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
1519     }
1520 
1521     @Run(test = "test64")
1522     public void test64_verifier() {
1523         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 8, MyValue1.DEFAULT);
1524         MyValue1[] var = test64();
1525         for (int i = 0; i < 8; ++i) {
1526             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1527         }
1528     }
1529 
1530     // Test initialization of value class arrays: large array
1531     @Test
1532     public MyValue1[] test65() {
1533         return (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 32, MyValue1.DEFAULT);
1534     }
1535 
1536     @Run(test = "test65")
1537     public void test65_verifier() {
1538         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 32, MyValue1.DEFAULT);
1539         MyValue1[] var = test65();
1540         for (int i = 0; i < 32; ++i) {
1541             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1542         }
1543     }
1544 
1545     // Check init store elimination
1546     @Test
1547     @IR(counts = {ALLOCA, "= 1"})
1548     public MyValue1[] test66(MyValue1 vt) {
1549         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
1550         va[0] = vt;
1551         return va;
1552     }
1553 
1554     @Run(test = "test66")
1555     public void test66_verifier() {
1556         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1557         MyValue1[] va = test66(vt);
1558         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1559     }
1560 
1561     // Zeroing elimination and arraycopy
1562     @Test
1563     public MyValue1[] test67(MyValue1[] src) {
1564         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 16, MyValue1.DEFAULT);
1565         System.arraycopy(src, 0, dst, 0, 13);
1566         return dst;
1567     }
1568 
1569     @Run(test = "test67")
1570     public void test67_verifier() {
1571         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 16, MyValue1.DEFAULT);
1572         MyValue1[] var = test67(va);
1573         for (int i = 0; i < 16; ++i) {
1574             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1575         }
1576     }
1577 
1578     // A store with an all-zero value can be eliminated
1579     @Test
1580     public MyValue1[] test68() {
1581         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 2, MyValue1.DEFAULT);
1582         va[0] = va[1];
1583         return va;
1584     }
1585 
1586     @Run(test = "test68")
1587     public void test68_verifier() {
1588         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 2, MyValue1.DEFAULT);
1589         MyValue1[] var = test68();
1590         for (int i = 0; i < 2; ++i) {
1591             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1592         }
1593     }
1594 
1595     // Requires individual stores to init array
1596     @Test
1597     public MyValue1[] test69(MyValue1 vt) {
1598         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 4, MyValue1.DEFAULT);
1599         va[0] = vt;
1600         va[3] = vt;
1601         return va;
1602     }
1603 
1604     @Run(test = "test69")
1605     public void test69_verifier() {
1606         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1607         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 4, MyValue1.DEFAULT);
1608         va[0] = vt;
1609         va[3] = vt;
1610         MyValue1[] var = test69(vt);
1611         for (int i = 0; i < va.length; ++i) {
1612             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1613         }
1614     }
1615 
1616     // Same as test68 but store is further away from allocation
1617     @Test
1618     public MyValue1[] test70(MyValue1[] other) {
1619         other[1] = other[0];
1620         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 2, MyValue1.DEFAULT);
1621         other[0] = va[1];
1622         va[0] = va[1];
1623         return va;
1624     }
1625 
1626     @Run(test = "test70")
1627     public void test70_verifier() {
1628         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 2, MyValue1.DEFAULT);
1629         MyValue1[] var = test70(va);
1630         for (int i = 0; i < 2; ++i) {
1631             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1632         }
1633     }
1634 
1635     // EA needs to consider oop fields in flattened arrays
1636     @Test
1637     public void test71() {
1638         int len = 10;
1639         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
1640         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, len, MyValue2.DEFAULT);
1641         for (int i = 0; i < len; ++i) {
1642             src[i] = MyValue2.createWithFieldsDontInline(rI+i, rD+i);
1643         }
1644         System.arraycopy(src, 0, dst, 0, src.length);
1645         for (int i = 0; i < len; ++i) {
1646             Asserts.assertEQ(src[i].hash(), dst[i].hash());
1647         }
1648     }
1649 
1650     @Run(test = "test71")
1651     public void test71_verifier() {
1652         test71();
1653     }
1654 
1655     // Test EA with leaf call to 'store_unknown_inline'
1656     @Test
1657     public void test72(Object[] o, boolean b, Object element) {
1658         Object[] arr1 = new Object[10];
1659         Object[] arr2 = new Object[10];
1660         if (b) {
1661             arr1 = o;
1662         }
1663         arr1[0] = element;
1664         arr2[0] = element;
1665     }
1666 
1667     @Run(test = "test72")
1668     public void test72_verifier() {
1669         Object[] arr = new Object[1];
1670         Object elem = new Object();
1671         test72(arr, true, elem);
1672         test72(arr, false, elem);
1673     }
1674 
1675     @Test
1676     public void test73(Object[] oa, MyValue1 v, Object o) {
1677         // TestLWorld.test38 use a C1 Phi node for the array. This test
1678         // adds the case where the stored value is a C1 Phi node.
1679         Object o2 = (o == null) ? v : o;
1680         oa[0] = v;  // The stored value is known to be flattenable
1681         oa[1] = o;  // The stored value may be flattenable
1682         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1683         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1684     }
1685 
1686     @Run(test = "test73")
1687     public void test73_verifier() {
1688         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1689         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1690         MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 3, MyValue1.DEFAULT);
1691         try {
1692             test73(arr, v0, v1);
1693             throw new RuntimeException("ArrayStoreException expected");
1694         } catch (ArrayStoreException e) {
1695             // expected
1696         }
1697         Asserts.assertEQ(arr[0].hash(), v0.hash());
1698         Asserts.assertEQ(arr[1].hash(), v1.hash());
1699         Asserts.assertEQ(arr[2].hash(), v1.hash());
1700     }
1701 
1702     public static void test74Callee(MyValue1[] va) { }
1703 
1704     // Tests invoking unloaded method with value class array in signature
1705     @Test
1706     public void test74(MethodHandle m, MyValue1[] va) throws Throwable {
1707         m.invoke(va);
1708     }
1709 
1710     @Run(test = "test74")
1711     @Warmup(0)
1712     public void test74_verifier() throws Throwable {
1713         MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class));
1714         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 0, MyValue1.DEFAULT);
1715         test74(m, va);
1716     }
1717 
1718     // Some more array clone tests
1719     @ForceInline
1720     public Object[] test75_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1721         Object[] arr = null;
1722         if (i == 10) {
1723             arr = oa;
1724         } else {
1725             arr = va;
1726         }
1727         return arr;
1728     }
1729 
1730     @Test
1731     public Object[] test75(MyValue1[] va, NonValueClass[] oa) {
1732         int i = 0;
1733         for (; i < 10; i++);
1734 
1735         Object[] arr = test75_helper(i, va, oa);
1736         return arr.clone();
1737     }
1738 
1739     @Run(test = "test75")
1740     public void test75_verifier() {
1741         int len = Math.abs(rI) % 10;
1742         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1743         NonValueClass[] oa = new NonValueClass[len];
1744         for (int i = 0; i < len; ++i) {
1745             oa[i] = new NonValueClass(rI);
1746         }
1747         test75_helper(42, va, oa);
1748         Object[] result = test75(va, oa);
1749 
1750         for (int i = 0; i < va.length; ++i) {
1751             Asserts.assertEQ(oa[i], result[i]);
1752             // Check that array has correct properties (null-ok)
1753             result[i] = null;
1754         }
1755     }
1756 
1757     @ForceInline
1758     public Object[] test76_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1759         Object[] arr = null;
1760         if (i == 10) {
1761             arr = va;
1762         } else {
1763             arr = oa;
1764         }
1765         return arr;
1766     }
1767 
1768     @Test
1769     public Object[] test76(MyValue1[] va, NonValueClass[] oa) {
1770         int i = 0;
1771         for (; i < 10; i++);
1772 
1773         Object[] arr = test76_helper(i, va, oa);
1774         return arr.clone();
1775     }
1776 
1777     @Run(test = "test76")
1778     public void test76_verifier() {
1779         int len = Math.abs(rI) % 10;
1780         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1781         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, len, MyValue1.DEFAULT);
1782         for (int i = 0; i < len; ++i) {
1783             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1784             verif[i] = va[i];
1785         }
1786         NonValueClass[] oa = new NonValueClass[len];
1787         test76_helper(42, va, oa);
1788         Object[] result = test76(va, oa);
1789         verify(verif, result);
1790         // Check that array has correct properties (null-free)
1791         if (len > 0) {
1792             try {
1793                 result[0] = null;
1794                 throw new RuntimeException("Should throw NullPointerException");
1795             } catch (NullPointerException e) {
1796                 // Expected
1797             }
1798         }
1799     }
1800 
1801     @Test
1802     public void test77() {
1803         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1804         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1805         MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
1806 
1807         Object[] oa = arr;
1808         Object o1 = v1;
1809         Object o = (o1 == null) ? v0 : o1;
1810 
1811         oa[0] = o; // For C1, due to IfOp optimization, the declared_type of o becomes NULL.
1812 
1813         Asserts.assertEQ(arr[0].hash(), v1.hash());
1814     }
1815 
1816 
1817     @Run(test = "test77")
1818     public void test77_verifier() {
1819         test77();
1820     }
1821 
1822     @Test
1823     public long test78(MyValue1 v, int n) {
1824         long x = 0;
1825         for (int i = 0; i < n; i++) {
1826         }
1827 
1828         MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, n, MyValue1.DEFAULT);
1829         a[0] = v;
1830         for (int i = 0; i<n; i++) {
1831             x += a[i].hash(); // C1 PhiSimplifier changes "a" from a Phi node to a NewObjectArray node
1832         }
1833 
1834         return x;
1835     }
1836 
1837     @Run(test = "test78")
1838     public void test78_verifier() {
1839         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1840         Asserts.assertEQ(test78(v, 1), v.hash());
1841     }
1842 
1843     // Verify that casting an array element to a non-flattenable type marks the array as not flat
1844     @Test
1845     @IR(applyIf = {"UseArrayFlattening", "true"},
1846         counts = {LOAD_UNKNOWN_INLINE, "= 1"})
1847     @IR(applyIf = {"UseArrayFlattening", "false"},
1848         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE})
1849     public Object test79(Object[] array, int i) {
1850         NonValueClass i1 = (NonValueClass)array[0];
1851         Object o = array[1];
1852         return array[i];
1853     }
1854 
1855     @Run(test = "test79")
1856     public void test79_verifier() {
1857         NonValueClass obj = new NonValueClass(rI);
1858         NonValueClass[] array = new NonValueClass[2];
1859         array[1] = obj;
1860         Object result = test79(array, 1);
1861         Asserts.assertEquals(result, obj);
1862     }
1863 
1864     // Same as test79 but with not flattenable value class
1865     @Test
1866     @IR(applyIf = {"UseArrayFlattening", "true"},
1867         counts = {LOAD_UNKNOWN_INLINE, "= 1"})
1868     @IR(applyIf = {"UseArrayFlattening", "false"},
1869         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE})
1870     public Object test80(Object[] array, int i) {
1871         NotFlattenable vt = (NotFlattenable)array[0];
1872         Object o = array[1];
1873         return array[i];
1874     }
1875 
1876     @Run(test = "test80")
1877     public void test80_verifier() {
1878         NotFlattenable vt = new NotFlattenable();
1879         NotFlattenable[] array = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 2, NotFlattenable.DEFAULT);
1880         array[1] = vt;
1881         Object result = test80(array, 1);
1882         Asserts.assertEquals(result, vt);
1883     }
1884 
1885     // Verify that writing an object of a non-inline, non-null type to an array marks the array as not null-free and not flat
1886     @Test
1887     @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1888     public Object test81(Object[] array, NonValueClass v, Object o, int i) {
1889         if (v == null) {
1890           return null;
1891         }
1892         array[0] = v;
1893         array[1] = array[0];
1894         array[2] = o;
1895         return array[i];
1896     }
1897 
1898     @Run(test = "test81")
1899     public void test81_verifier() {
1900         NonValueClass obj = new NonValueClass(rI);
1901         NonValueClass[] array1 = new NonValueClass[3];
1902         Object[] array2 = new Object[3];
1903         Object result = test81(array1, obj, obj, 0);
1904         Asserts.assertEquals(array1[0], obj);
1905         Asserts.assertEquals(array1[1], obj);
1906         Asserts.assertEquals(array1[2], obj);
1907         Asserts.assertEquals(result, obj);
1908         result = test81(array2, obj, obj, 1);
1909         Asserts.assertEquals(array2[0], obj);
1910         Asserts.assertEquals(array2[1], obj);
1911         Asserts.assertEquals(array2[2], obj);
1912         Asserts.assertEquals(result, obj);
1913     }
1914 
1915     // Verify that writing an object of a non-flattenable value class to an array marks the array as not flat
1916     @Test
1917     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
1918         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE})
1919     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
1920         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE})
1921     public Object test82(Object[] array, NotFlattenable vt, Object o, int i) {
1922         array[0] = vt;
1923         array[1] = array[0];
1924         array[2] = o;
1925         return array[i];
1926     }
1927 
1928     @Run(test = "test82")
1929     public void test82_verifier() {
1930         NotFlattenable vt = new NotFlattenable();
1931         NotFlattenable[] array1 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 3, NotFlattenable.DEFAULT);
1932         Object[] array2 = new Object[3];
1933         Object result = test82(array1, vt, vt, 0);
1934         Asserts.assertEquals(array1[0], vt);
1935         Asserts.assertEquals(array1[1], vt);
1936         Asserts.assertEquals(array1[2], vt);
1937         Asserts.assertEquals(result, vt);
1938         result = test82(array2, vt, vt, 1);
1939         Asserts.assertEquals(array2[0], vt);
1940         Asserts.assertEquals(array2[1], vt);
1941         Asserts.assertEquals(array2[2], vt);
1942         Asserts.assertEquals(result, vt);
1943     }
1944 
1945     // Verify that casting an array element to a non-value class type type marks the array as not null-free and not flat
1946     @Test
1947     @IR(applyIf = {"UseArrayFlattening", "true"},
1948         counts = {LOAD_UNKNOWN_INLINE, "= 1"},
1949         failOn = {ALLOCA_G, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1950     @IR(applyIf = {"UseArrayFlattening", "false"},
1951             failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1952     public void test83(Object[] array, Object o) {
1953         NonValueClass i = (NonValueClass)array[0];
1954         array[1] = o;
1955     }
1956 
1957     @Run(test = "test83")
1958     public void test83_verifier() {
1959         NonValueClass obj = new NonValueClass(rI);
1960         NonValueClass[] array1 = new NonValueClass[2];
1961         Object[] array2 = new Object[2];
1962         test83(array1, obj);
1963         Asserts.assertEquals(array1[1], obj);
1964         test83(array2, null);
1965         Asserts.assertEquals(array2[1], null);
1966     }
1967 
1968     // Verify that writing constant null into an array marks the array as not null-free
1969     @Test
1970     @IR(applyIf = {"UseArrayFlattening", "true"},
1971         failOn = {ALLOC_G, ALLOCA_G},
1972         counts = {INLINE_ARRAY_NULL_GUARD, "= 1", // Null check on first store, no check on second store
1973                   STORE_UNKNOWN_INLINE, "= 2",
1974                   LOAD_UNKNOWN_INLINE, "= 1"})
1975     @IR(applyIf = {"UseArrayFlattening", "false"},
1976         failOn = {ALLOC_G, ALLOCA_G, STORE_UNKNOWN_INLINE, LOAD_UNKNOWN_INLINE},
1977         counts = {INLINE_ARRAY_NULL_GUARD, "= 1"}) // Null check on first store, no check on second store
1978     public Object test84(Object[] array, int i) {
1979         array[0] = null;
1980         array[1] = null;
1981         return array[i];
1982     }
1983 
1984     @Run(test = "test84")
1985     public void test84_verifier(RunInfo info) {
1986         NotFlattenable[] array1 = new NotFlattenable[2];
1987         Object[] array2 = new Object[2];
1988         Object result = test84(array1, 0);
1989         Asserts.assertEquals(array1[0], null);
1990         Asserts.assertEquals(result, null);
1991         result = test84(array2, 1);
1992         Asserts.assertEquals(array2[0], null);
1993         Asserts.assertEquals(result, null);
1994         if (!info.isWarmUp()) {
1995             NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 2, NotFlattenable.DEFAULT);
1996             try {
1997                 test84(array3, 1);
1998                 throw new RuntimeException("Should throw NullPointerException");
1999             } catch (NullPointerException e) {
2000                 // Expected
2001             }
2002         }
2003     }
2004 
2005     // Similar to test84 but with branches
2006     @Test
2007     @IR(applyIf = {"UseArrayFlattening", "true"},
2008         failOn = {ALLOC_G, ALLOCA_G},
2009         counts = {INLINE_ARRAY_NULL_GUARD, "= 2",
2010                   STORE_UNKNOWN_INLINE, "<= 3"})
2011     @IR(applyIf = {"UseArrayFlattening", "false"},
2012         failOn = {ALLOC_G, ALLOCA_G, STORE_UNKNOWN_INLINE, LOAD_UNKNOWN_INLINE},
2013         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2014     public void test85(Object[] array, Object o, boolean b) {
2015         if (b) {
2016             array[0] = null;
2017         } else {
2018             array[1] = null;
2019         }
2020         array[1] = o;
2021     }
2022 
2023     @Run(test = "test85")
2024     public void test85_verifier(RunInfo info) {
2025         NonValueClass obj = new NonValueClass(rI);
2026         NonValueClass[] array1 = new NonValueClass[2];
2027         Object[] array2 = new Object[2];
2028         test85(array1, obj, true);
2029         Asserts.assertEquals(array1[1], obj);
2030         test85(array1, null, false);
2031         Asserts.assertEquals(array1[1], null);
2032         test85(array2, obj, true);
2033         Asserts.assertEquals(array2[1], obj);
2034         test85(array2, null, false);
2035         Asserts.assertEquals(array2[1], null);
2036         if (!info.isWarmUp()) {
2037             NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 2, NotFlattenable.DEFAULT);
2038             try {
2039                 test85(array3, null, true);
2040                 throw new RuntimeException("Should throw NullPointerException");
2041             } catch (NullPointerException e) {
2042                 // Expected
2043             }
2044         }
2045     }
2046 
2047     // Same as test85 but with not flattenable value class array
2048     @Test
2049     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2050         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2051         counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"})
2052     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2053         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2054         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2055     public void test86(NotFlattenable[] array, NotFlattenable o, boolean b) {
2056         if (b) {
2057             array[0] = null;
2058         } else {
2059             array[1] = null;
2060         }
2061         array[1] = o;
2062     }
2063 
2064     @Run(test = "test86")
2065     public void test86_verifier(RunInfo info) {
2066         NotFlattenable vt = new NotFlattenable();
2067         NotFlattenable[] array1 = new NotFlattenable[2];
2068         test86(array1, vt, true);
2069         Asserts.assertEquals(array1[1], vt);
2070         test86(array1, null, false);
2071         Asserts.assertEquals(array1[1], null);
2072         if (!info.isWarmUp()) {
2073             NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 2, NotFlattenable.DEFAULT);
2074             try {
2075                 test86(array2, null, true);
2076                 throw new RuntimeException("Should throw NullPointerException");
2077             } catch (NullPointerException e) {
2078                 // Expected
2079             }
2080         }
2081     }
2082 
2083     // Same as test85 but with value class array
2084     @Test
2085     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2086         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2087         counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"})
2088     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2089         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2090         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2091     public void test87(MyValue1[] array, MyValue1 o, boolean b) {
2092         if (b) {
2093             array[0] = null;
2094         } else {
2095             array[1] = null;
2096         }
2097         array[1] = o;
2098     }
2099 
2100     @Run(test = "test87")
2101     public void test87_verifier(RunInfo info) {
2102         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2103         MyValue1[] array1 = new MyValue1[2];
2104         test87(array1, vt, true);
2105         Asserts.assertEquals(array1[1], vt);
2106         test87(array1, null, false);
2107         Asserts.assertEquals(array1[1], null);
2108         if (!info.isWarmUp()) {
2109             MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 2, MyValue1.DEFAULT);
2110             try {
2111                 test87(array2, null, true);
2112                 throw new RuntimeException("Should throw NullPointerException");
2113             } catch (NullPointerException e) {
2114                 // Expected
2115             }
2116         }
2117     }
2118 
2119     // Additional correctness tests to make sure we have the required null checks
2120     @Test
2121     public void test88(Object[] array, NonValueClass v) {
2122         array[0] = v;
2123     }
2124 
2125     @Run(test = "test88")
2126     public void test88_verifier(RunInfo info) {
2127         NonValueClass[] array1 = new NonValueClass[1];
2128         Object[] array2 = new Object[1];
2129         test88(array1, null);
2130         Asserts.assertEquals(array1[0], null);
2131         test88(array2, null);
2132         Asserts.assertEquals(array2[0], null);
2133         if (!info.isWarmUp()) {
2134             MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2135             try {
2136                 test88(array3, null);
2137                 throw new RuntimeException("Should throw NullPointerException");
2138             } catch (NullPointerException e) {
2139                 // Expected
2140             }
2141         }
2142     }
2143 
2144     @Test
2145     public void test89(MyValue1[] array, NonValueClass v) {
2146         Object o = v;
2147         array[0] = (MyValue1)o;
2148     }
2149 
2150     @Run(test = "test89")
2151     public void test89_verifier(RunInfo info) {
2152         MyValue1[] array1 = new MyValue1[1];
2153         test89(array1, null);
2154         Asserts.assertEquals(array1[0], null);
2155         if (!info.isWarmUp()) {
2156             MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2157             try {
2158                 test89(array2, null);
2159                 throw new RuntimeException("Should throw NullPointerException");
2160             } catch (NullPointerException e) {
2161                 // Expected
2162             }
2163         }
2164     }
2165 
2166     @Test
2167     public boolean test90() {
2168         boolean b = true;
2169 
2170         MyValue1[] qArray = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 0, MyValue1.DEFAULT);
2171         MyValue1[] lArray = new MyValue1[0];
2172 
2173         b = b && (qArray instanceof MyValue1[]);
2174         b = b && (lArray instanceof MyValue1[]);
2175 
2176         MyValue1[][] qArray2 = { (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 0, MyValue1.DEFAULT) };
2177         MyValue1[][] lArray2 = new MyValue1[0][0];
2178 
2179         b = b && (qArray2 instanceof MyValue1[][]);
2180         b = b && (lArray2 instanceof MyValue1[][]);
2181 
2182         return b;
2183     }
2184 
2185     @Run(test = "test90")
2186     public void test90_verifier() {
2187         Asserts.assertEQ(test90(), true);
2188     }
2189 
2190     @LooselyConsistentValue
2191     static value class Test91Value {
2192         public int f0;
2193         public int f1;
2194         public int f2;
2195         public int f3;
2196         public int f4;
2197         public int f5;
2198 
2199         public Test91Value(int i) {
2200             this.f0 = i;
2201             this.f1 = i;
2202             this.f2 = i;
2203             this.f3 = i;
2204             this.f4 = i;
2205             this.f5 = i;
2206         }
2207 
2208         public void verify() {
2209             if ((f0 != f1) || (f1 != f2) || (f2 != f3) || (f3 != f4) || (f4 != f5)) {
2210                 throw new RuntimeException("test91 failed");
2211             }
2212         }
2213     }
2214 
2215     // Test anti-dependencies between loads and stores from flattened array
2216     @Test
2217     public int test91(Test91Value[] array, int lo, int val) {
2218         int i = 3;
2219         while (lo < i) {
2220             Test91Value tmp = array[lo];
2221             array[lo++] = array[i];
2222             array[i--] = tmp;
2223         }
2224         return val;
2225     }
2226 
2227     @Run(test = "test91")
2228     @Warmup(0)
2229     public void test91_verifier() {
2230         Test91Value[] array = (Test91Value[])ValueClass.newNullRestrictedNonAtomicArray(Test91Value.class, 5, new Test91Value(0));
2231         for (int i = 0; i < 5; ++i) {
2232             array[i] = new Test91Value(i);
2233             array[i].verify();
2234         }
2235         Asserts.assertEQ(test91(array, 0, 5), 5);
2236         for (int i = 0; i < 5; ++i) {
2237             array[i].verify();
2238         }
2239     }
2240 
2241     @Test
2242     public void test92(Object[] src, Object[] dst) {
2243         System.arraycopy(src, 0, dst, 0, src.length);
2244     }
2245 
2246     @Run(test = "test92")
2247     public void test92_verifier() {
2248         MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2249         MyValue1[] b = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2250         try {
2251             test92(a, null);
2252             throw new RuntimeException("Should throw NullPointerException");
2253         } catch (NullPointerException expected) {}
2254 
2255         try {
2256             test92(null, b);
2257             throw new RuntimeException("Should throw NullPointerException");
2258         } catch (NullPointerException expected) {}
2259 
2260         a[0] = MyValue1.createWithFieldsInline(rI, rL);
2261         test92(a, b);
2262         verify(a, b);
2263     }
2264 
2265     // Same as test30 but accessing all elements of the non-escaping array
2266     @Test
2267     public long test93(MyValue2[] src, boolean flag) {
2268         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
2269         System.arraycopy(src, 0, dst, 0, 10);
2270         if (flag) {  }
2271         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2272                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2273     }
2274 
2275     @Run(test = "test93")
2276     @Warmup(10000)
2277     public void test93_verifier(RunInfo info) {
2278         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
2279         for (int i = 0; i < 10; ++i) {
2280             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2281         }
2282         long res = test93(src, !info.isWarmUp());
2283         long expected = 0;
2284         for (int i = 0; i < 10; ++i) {
2285             expected += src[i].hash();
2286         }
2287         Asserts.assertEQ(res, expected);
2288     }
2289 
2290     // Same as test93 but with variable source array offset
2291     @Test
2292     public long test94(MyValue2[] src, int i, boolean flag) {
2293         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
2294         System.arraycopy(src, i, dst, 0, 1);
2295         if (flag) {  }
2296         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2297                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2298     }
2299 
2300     @Run(test = "test94")
2301     @Warmup(10000)
2302     public void test94_verifier(RunInfo info) {
2303         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 10, MyValue2.DEFAULT);
2304         for (int i = 0; i < 10; ++i) {
2305             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2306         }
2307         for (int i = 0; i < 10; ++i) {
2308             long res = test94(src, i, !info.isWarmUp());
2309             long expected = src[i].hash() + 9*MyValue2.createDefaultInline().hash();
2310             Asserts.assertEQ(res, expected);
2311         }
2312     }
2313 
2314     static final MyValue1[] nullFreeArray = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2315 
2316     // Test propagation of not null-free/flat information
2317     @Test
2318     @IR(failOn = IRNode.SUBTYPE_CHECK)
2319     public MyValue1[] test95(Object[] array) {
2320         array[0] = null;
2321         // Always throws a ClassCastException because we just successfully
2322         // stored null and therefore the array can't be a null-free value class array.
2323         return nullFreeArray.getClass().cast(array);
2324     }
2325 
2326     @Run(test = "test95")
2327     public void test95_verifier() {
2328         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2329         NonValueClass[] array2 = new NonValueClass[1];
2330         try {
2331             test95(array1);
2332             throw new RuntimeException("Should throw NullPointerException");
2333         } catch (NullPointerException e) {
2334             // Expected
2335         }
2336         try {
2337             test95(array2);
2338             throw new RuntimeException("Should throw ClassCastException");
2339         } catch (ClassCastException e) {
2340             // Expected
2341         }
2342     }
2343 
2344     // Same as test95 but with cmp user of cast result
2345     @Test
2346     @IR(failOn = IRNode.SUBTYPE_CHECK)
2347     public boolean test96(Object[] array) {
2348         array[0] = null;
2349         // Always throws a ClassCastException because we just successfully
2350         // stored null and therefore the array can't be a null-free value class array.
2351         MyValue1[] casted = nullFreeArray.getClass().cast(array);
2352         return casted != null;
2353     }
2354 
2355     @Run(test = "test96")
2356     public void test96_verifier() {
2357         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2358         NonValueClass[] array2 = new NonValueClass[1];
2359         try {
2360             test96(array1);
2361             throw new RuntimeException("Should throw NullPointerException");
2362         } catch (NullPointerException e) {
2363             // Expected
2364         }
2365         try {
2366             test96(array2);
2367             throw new RuntimeException("Should throw ClassCastException");
2368         } catch (ClassCastException e) {
2369             // Expected
2370         }
2371     }
2372 
2373     // Same as test95 but with instanceof instead of cast
2374     @Test
2375     @IR(applyIf = {"MonomorphicArrayCheck", "true"}, failOn = IRNode.SUBTYPE_CHECK)
2376     public boolean test97(Object[] array) {
2377         // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here.
2378         array[0] = new NonValueClass(42);
2379         // Always returns false because we just successfully stored a non-value object and therefore the array can't
2380         // be a value class array.
2381         return array instanceof MyValue1[];
2382     }
2383 
2384     @Run(test = "test97")
2385     public void test97_verifier(RunInfo runInfo) {
2386         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2387         NonValueClass[] array2 = new NonValueClass[1];
2388         // When emitting the array store check "NonValueClass <: Object[]" for "array[0] = new NonValueClass(42)" in
2389         // test97(), we speculatively assume that Object[] is exact and emit such a check with an uncommon trap before
2390         // the array store check at the same bci. We propagate that information with an additional CheckCastPP node
2391         // feeding into the array store sub type check.
2392         // At runtime, we will hit the ArrayStoreException in the first execution when array is a MyValue1[].
2393         // With the default IR framework warm-up, we will profile the ArrayStoreException in the interpreter and
2394         // pass it in the MDO to the C2 compiler which treats these exceptions as traps being hit (see
2395         // InterpreterRuntime::create_klass_exception). As a result, C2 is not able to speculatively cast the array of
2396         // type Object[] to an exact type before the first sub type check because we've seen too many traps being taken
2397         // at that bci due to the ArrayStoreException that was hit at the very same bci (see Compile::too_many_traps()
2398         // which checks that zero traps have been taken so far). Thus, neither the first sub type check for the array
2399         // check cast nor the second sub type check for the instanceof can be removed.
2400         // By not executing test97() with MyValue1[] during warm-up, which would trigger the ArrayStoreException,
2401         // we will not observe an ArrayStoreException before C2 compilation. Note that C2 also requires
2402         // MonomorphicArrayCheck in order to emit the speculative exactness check.
2403         // The same is required for test98-100().
2404         if (!runInfo.isWarmUp()) {
2405             try {
2406                 test97(array1);
2407                 throw new RuntimeException("Should throw ArrayStoreException");
2408             } catch (ArrayStoreException e) {
2409                 // Expected
2410             }
2411         }
2412         boolean res = test97(array2);
2413         Asserts.assertFalse(res);
2414     }
2415 
2416     // Same as test95 but with non-flattenable store
2417     @Test
2418     @IR(applyIfAnd = {"UseArrayFlattening", "true", "MonomorphicArrayCheck", "true"},
2419         failOn = IRNode.SUBTYPE_CHECK)
2420     public MyValue1[] test98(Object[] array) {
2421         // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here.
2422         array[0] = new NotFlattenable();
2423         // Always throws a ClassCastException because we just successfully stored a
2424         // non-flattenable value and therefore the array can't be a flat array.
2425         return (MyValue1[])array;
2426     }
2427 
2428     @Run(test = "test98")
2429     public void test98_verifier(RunInfo runInfo) {
2430         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2431         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 1, NotFlattenable.DEFAULT);
2432         if (!runInfo.isWarmUp()) { // See test97() for the reason why we need this.
2433             try {
2434                 test98(array1);
2435                 throw new RuntimeException("Should throw ArrayStoreException");
2436             } catch (ArrayStoreException e) {
2437                 // Expected
2438             }
2439         }
2440         try {
2441             test98(array2);
2442             throw new RuntimeException("Should throw ClassCastException");
2443         } catch (ClassCastException e) {
2444             // Expected
2445         }
2446     }
2447 
2448     // Same as test98 but with cmp user of cast result
2449     @Test
2450     @IR(applyIfAnd = {"UseArrayFlattening", "true", "MonomorphicArrayCheck", "true"},
2451         failOn = IRNode.SUBTYPE_CHECK)
2452     public boolean test99(Object[] array) {
2453         // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here.
2454         array[0] = new NotFlattenable();
2455         // Always throws a ClassCastException because we just successfully stored a
2456         // non-flattenable value and therefore the array can't be a flat array.
2457         MyValue1[] casted = (MyValue1[])array;
2458         return casted != null;
2459     }
2460 
2461     @Run(test = "test99")
2462     public void test99_verifier(RunInfo runInfo) {
2463         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2464         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 1, NotFlattenable.DEFAULT);
2465         if (!runInfo.isWarmUp()) { // See test97() for the reason why we need this.
2466             try {
2467                 test99(array1);
2468                 throw new RuntimeException("Should throw ArrayStoreException");
2469             } catch (ArrayStoreException e) {
2470                 // Expected
2471             }
2472         }
2473         try {
2474             test99(array2);
2475             throw new RuntimeException("Should throw ClassCastException");
2476         } catch (ClassCastException e) {
2477             // Expected
2478         }
2479     }
2480 
2481     // Same as test98 but with instanceof instead of cast
2482     @Test
2483     @IR(applyIfAnd = {"UseArrayFlattening", "true", "MonomorphicArrayCheck", "true"},
2484         failOn = IRNode.SUBTYPE_CHECK)
2485     public boolean test100(Object[] array) {
2486         // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here.
2487         array[0] = new NotFlattenable();
2488         // Always throws a ClassCastException because we just successfully stored a
2489         // non-flattenable value and therefore the array can't be a flat array.
2490         return array instanceof MyValue1[];
2491     }
2492 
2493     @Run(test = "test100")
2494     public void test100_verifier(RunInfo runInfo) {
2495         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2496         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 1, NotFlattenable.DEFAULT);
2497         if (!runInfo.isWarmUp()) { // See test97() for the reason why we need this.
2498             try {
2499                 test100(array1);
2500                 throw new RuntimeException("Should throw ArrayStoreException");
2501             } catch (ArrayStoreException e) {
2502                 // Expected
2503             }
2504         }
2505         boolean res = test100(array2);
2506         Asserts.assertFalse(res);
2507     }
2508 
2509     // Test that SUBTYPE_CHECK matching works as expected
2510     @Test
2511     @IR(counts = { IRNode.SUBTYPE_CHECK, "1" })
2512     public boolean test101(Object[] array) {
2513         return array instanceof MyValue1[];
2514     }
2515 
2516     @Run(test = "test101")
2517     public void test101_verifier() {
2518         MyValue1[] array1 = new MyValue1[1];
2519         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 1, NotFlattenable.DEFAULT);
2520         MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2521         Asserts.assertTrue(test101(array1));
2522         Asserts.assertFalse(test101(array2));
2523         Asserts.assertTrue(test101(array3));
2524     }
2525 
2526     // Test that SUBTYPE_CHECK matching works as expected with null-free arrays
2527     @Test
2528     @IR(counts = { IRNode.SUBTYPE_CHECK, "1" })
2529     public Object test101NullFree(Object[] array) {
2530         return nullFreeArray.getClass().cast(array);
2531     }
2532 
2533     @Run(test = "test101NullFree")
2534     public void test101NullFree_verifier() {
2535         MyValue1[] array1 = new MyValue1[1];
2536         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedNonAtomicArray(NotFlattenable.class, 1, NotFlattenable.DEFAULT);
2537         MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
2538         try {
2539             test101NullFree(array1);
2540             throw new RuntimeException("Should throw ClassCastException");
2541         } catch (ClassCastException e) {
2542             // Expected
2543         }
2544         try {
2545             test101NullFree(array2);
2546             throw new RuntimeException("Should throw ClassCastException");
2547         } catch (ClassCastException e) {
2548             // Expected
2549         }
2550         test101NullFree(array3);
2551     }
2552 
2553     static final MyValue2[] val_src = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
2554     static final MyValue2[] val_dst = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 8, MyValue2.DEFAULT);
2555     static final Object[]   obj_src = new Object[8];
2556     static final Object[]   obj_null_src = new Object[8];
2557     static final Object[]   obj_dst = new Object[8];
2558 
2559     @ForceInline
2560     static Object get_val_src() { return val_src; }
2561     @ForceInline
2562     static Object get_val_dst() { return val_dst; }
2563     @ForceInline
2564     static Class get_val_class() { return val_src.getClass(); }
2565     @ForceInline
2566     static Class get_non_val_class() { return NonValueClass[].class; }
2567     @ForceInline
2568     static Object get_obj_src() { return obj_src; }
2569     @ForceInline
2570     static Object get_obj_null_src() { return obj_null_src; }
2571     @ForceInline
2572     static Object get_obj_dst() { return obj_dst; }
2573     @ForceInline
2574     static Class get_obj_class() { return Object[].class; }
2575 
2576     static {
2577         for (int i = 0; i < 8; ++i) {
2578             val_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2579             obj_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2580             obj_null_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2581         }
2582         obj_null_src[0] = null;
2583     }
2584 
2585     // Arraycopy with constant source and destination arrays
2586     @Test
2587     @IR(applyIf = {"UseArrayFlattening", "true"},
2588         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2589     @IR(applyIf = {"UseArrayFlattening", "false"},
2590         failOn = INTRINSIC_SLOW_PATH)
2591     public void test102() {
2592         System.arraycopy(val_src, 0, obj_dst, 0, 8);
2593     }
2594 
2595     @Run(test = "test102")
2596     public void test102_verifier() {
2597         test102();
2598         verify(val_src, obj_dst);
2599     }
2600 
2601     // Same as test102 but with MyValue2[] dst
2602     @Test
2603     // TODO 8350865 Re-enable
2604     // @IR(failOn = INTRINSIC_SLOW_PATH)
2605     public void test103() {
2606         System.arraycopy(val_src, 0, val_dst, 0, 8);
2607     }
2608 
2609     @Run(test = "test103")
2610     public void test103_verifier() {
2611         test103();
2612         verify(val_src, val_dst);
2613     }
2614 
2615     // Same as test102 but with Object[] src
2616     @Test
2617     @IR(failOn = INTRINSIC_SLOW_PATH)
2618     public void test104() {
2619         System.arraycopy(obj_src, 0, obj_dst, 0, 8);
2620     }
2621 
2622     @Run(test = "test104")
2623     public void test104_verifier() {
2624         test104();
2625         verify(obj_src, obj_dst);
2626     }
2627 
2628     // Same as test103 but with Object[] src
2629     @Test
2630     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2631     public void test105() {
2632         System.arraycopy(obj_src, 0, val_dst, 0, 8);
2633     }
2634 
2635     @Run(test = "test105")
2636     public void test105_verifier() {
2637         test105();
2638         verify(obj_src, val_dst);
2639     }
2640 
2641     // Same as test103 but with Object[] src containing null
2642     @Test
2643     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2644     public void test105_null() {
2645         System.arraycopy(obj_null_src, 0, val_dst, 0, 8);
2646     }
2647 
2648     @Run(test = "test105_null")
2649     public void test105_null_verifier() {
2650         try {
2651             test105_null();
2652             throw new RuntimeException("NullPointerException expected");
2653         } catch (NullPointerException e) {
2654             // expected
2655         }
2656     }
2657 
2658     // Below tests are equal to test102-test105 but hide the src/dst types until
2659     // after the arraycopy intrinsic is emitted (with incremental inlining).
2660     @Test
2661     @IR(applyIf = {"UseArrayFlattening", "true"},
2662         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2663     @IR(applyIf = {"UseArrayFlattening", "false"},
2664         failOn = INTRINSIC_SLOW_PATH)
2665     public void test106() {
2666         System.arraycopy(get_val_src(), 0, get_obj_dst(), 0, 8);
2667     }
2668 
2669     @Run(test = "test106")
2670     public void test106_verifier() {
2671         test106();
2672         verify(val_src, obj_dst);
2673     }
2674 
2675     // TODO 8251971: Should be optimized but we are bailing out because
2676     // at parse time it looks as if src could be flat and dst could be not flat.
2677     @Test
2678     @IR(applyIf = {"UseArrayFlattening", "false"},
2679         failOn = INTRINSIC_SLOW_PATH)
2680     public void test107() {
2681         System.arraycopy(get_val_src(), 0, get_val_dst(), 0, 8);
2682     }
2683 
2684     @Run(test = "test107")
2685     public void test107_verifier() {
2686         test107();
2687         verify(val_src, val_dst);
2688     }
2689 
2690     @Test
2691     @IR(failOn = INTRINSIC_SLOW_PATH)
2692     public void test108() {
2693         System.arraycopy(get_obj_src(), 0, get_obj_dst(), 0, 8);
2694     }
2695 
2696     @Run(test = "test108")
2697     public void test108_verifier() {
2698         test108();
2699         verify(obj_src, obj_dst);
2700     }
2701 
2702     @Test
2703     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2704     public void test109() {
2705         System.arraycopy(get_obj_src(), 0, get_val_dst(), 0, 8);
2706     }
2707 
2708     @Run(test = "test109")
2709     public void test109_verifier() {
2710         test109();
2711         verify(obj_src, val_dst);
2712     }
2713 
2714     @Test
2715     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2716     public void test109_null() {
2717         System.arraycopy(get_obj_null_src(), 0, get_val_dst(), 0, 8);
2718     }
2719 
2720     @Run(test = "test109_null")
2721     public void test109_null_verifier() {
2722         try {
2723             test109_null();
2724             throw new RuntimeException("NullPointerException expected");
2725         } catch (NullPointerException e) {
2726             // expected
2727         }
2728     }
2729 
2730     // Arrays.copyOf with constant source and destination arrays
2731     @Test
2732     @IR(applyIf = {"UseArrayFlattening", "true"},
2733         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2734     @IR(applyIf = {"UseArrayFlattening", "false"},
2735         failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2736     public Object[] test110() {
2737         return Arrays.copyOf(val_src, 8, Object[].class);
2738     }
2739 
2740     @Run(test = "test110")
2741     public void test110_verifier() {
2742         Object[] res = test110();
2743         verify(val_src, res);
2744     }
2745 
2746     // Same as test110 but with MyValue2[] dst
2747     @Test
2748     @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2749     public Object[] test111() {
2750         return Arrays.copyOf(val_src, 8, val_src.getClass());
2751     }
2752 
2753     @Run(test = "test111")
2754     public void test111_verifier() {
2755         Object[] res = test111();
2756         verify(val_src, res);
2757     }
2758 
2759     // Same as test110 but with Object[] src
2760     @Test
2761     @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2762     public Object[] test112() {
2763         return Arrays.copyOf(obj_src, 8, Object[].class);
2764     }
2765 
2766     @Run(test = "test112")
2767     public void test112_verifier() {
2768         Object[] res = test112();
2769         verify(obj_src, res);
2770     }
2771 
2772     // Same as test111 but with Object[] src
2773     @Test
2774     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2775     public Object[] test113() {
2776         return Arrays.copyOf(obj_src, 8, MyValue2[].class);
2777     }
2778 
2779     @Run(test = "test113")
2780     public void test113_verifier() {
2781         Object[] res = test113();
2782         verify(obj_src, res);
2783     }
2784 
2785     // Same as test111 but with Object[] src containing null
2786     @Test
2787     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2788     public Object[] test113_null() {
2789         return Arrays.copyOf(obj_null_src, 8, val_src.getClass());
2790     }
2791 
2792     @Run(test = "test113_null")
2793     public void test113_null_verifier() {
2794         Object[] res = test113_null();
2795         verify(obj_null_src, res);
2796     }
2797 
2798     // Below tests are equal to test110-test113 but hide the src/dst types until
2799     // after the arraycopy intrinsic is emitted (with incremental inlining).
2800 
2801     @Test
2802     @IR(applyIf = {"UseArrayFlattening", "true"},
2803         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2804     @IR(applyIf = {"UseArrayFlattening", "false"},
2805         failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2806     public Object[] test114() {
2807         return Arrays.copyOf((Object[])get_val_src(), 8, get_obj_class());
2808     }
2809 
2810     @Run(test = "test114")
2811     public void test114_verifier() {
2812         Object[] res = test114();
2813         verify(val_src, res);
2814     }
2815 
2816     // TODO 8251971: Should be optimized but we are bailing out because
2817     // at parse time it looks as if src could be flat and dst could be not flat
2818     @Test
2819     @IR(applyIf = {"UseArrayFlattening", "false"},
2820         failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2821     public Object[] test115() {
2822         return Arrays.copyOf((Object[])get_val_src(), 8, get_val_class());
2823     }
2824 
2825     @Run(test = "test115")
2826     public void test115_verifier() {
2827         Object[] res = test115();
2828         verify(val_src, res);
2829     }
2830 
2831     @Test
2832     @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2833     public Object[] test116() {
2834         return Arrays.copyOf((Object[])get_obj_src(), 8, get_obj_class());
2835     }
2836 
2837     @Run(test = "test116")
2838     public void test116_verifier() {
2839         Object[] res = test116();
2840         verify(obj_src, res);
2841     }
2842 
2843     @Test
2844     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2845     public Object[] test117() {
2846         return Arrays.copyOf((Object[])get_obj_src(), 8, get_val_class());
2847     }
2848 
2849     @Run(test = "test117")
2850     public void test117_verifier() {
2851         Object[] res = test117();
2852         verify(obj_src, res);
2853     }
2854 
2855     @Test
2856     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2857     public Object[] test117_null() {
2858         return Arrays.copyOf((Object[])get_obj_null_src(), 8, get_val_class());
2859     }
2860 
2861     @Run(test = "test117_null")
2862     public void test117_null_verifier() {
2863         Object[] res = test117_null();
2864         verify((Object[])get_obj_null_src(), res);
2865     }
2866 
2867     // Some more Arrays.copyOf tests with only constant class
2868 
2869     @Test
2870     @IR(counts = {CLASS_CHECK_TRAP, "= 1"})
2871     // TODO JDK-8329224
2872     // failOn = INTRINSIC_SLOW_PATH)
2873     public Object[] test118(Object[] src) {
2874         return Arrays.copyOf(src, 8, val_src.getClass());
2875     }
2876 
2877     @Run(test = "test118")
2878     public void test118_verifier() {
2879         Object[] res = test118(obj_src);
2880         verify(obj_src, res);
2881         res = test118(val_src);
2882         verify(val_src, res);
2883         res = test118(obj_null_src);
2884         verify(obj_null_src, res);
2885     }
2886 
2887     @Test
2888     public Object[] test119(Object[] src) {
2889         return Arrays.copyOf(src, 8, Object[].class);
2890     }
2891 
2892     @Run(test = "test119")
2893     public void test119_verifier() {
2894         Object[] res = test119(obj_src);
2895         verify(obj_src, res);
2896         res = test119(val_src);
2897         verify(val_src, res);
2898     }
2899 
2900     @Test
2901     @IR(counts = {CLASS_CHECK_TRAP, "= 1"})
2902     // TODO JDK-8329224
2903     // failOn = INTRINSIC_SLOW_PATH)
2904     public Object[] test120(Object[] src) {
2905         return Arrays.copyOf(src, 8, NonValueClass[].class);
2906     }
2907 
2908     @Run(test = "test120")
2909     public void test120_verifier() {
2910         NonValueClass[] arr = new NonValueClass[8];
2911         for (int i = 0; i < 8; ++i) {
2912             arr[i] = new NonValueClass(rI + i);
2913         }
2914         Object[] res = test120(arr);
2915         verify(arr, res);
2916         try {
2917             test120(val_src);
2918             throw new RuntimeException("ArrayStoreException expected");
2919         } catch (ArrayStoreException e) {
2920             // expected
2921         }
2922     }
2923 
2924     @Test
2925     public Object[] test121(Object[] src) {
2926         return Arrays.copyOf(src, 8, val_src.getClass());
2927     }
2928 
2929     @Run(test = "test121")
2930     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2931     public void test121_verifier() {
2932         Object[] res = test121(obj_src);
2933         verify(obj_src, res);
2934         res = test121(val_src);
2935         verify(val_src, res);
2936         res = test121(obj_null_src);
2937         verify(obj_null_src, res);
2938     }
2939     @Test
2940     public Object[] test122(Object[] src) {
2941         return Arrays.copyOf(src, 8, get_val_class());
2942     }
2943 
2944     @Run(test = "test122")
2945     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2946     public void test122_verifier() {
2947         Object[] res = test122(obj_src);
2948         verify(obj_src, res);
2949         res = test122(val_src);
2950         verify(val_src, res);
2951         res = test122(obj_null_src);
2952         verify(obj_null_src, res);
2953     }
2954 
2955     @Test
2956     public Object[] test123(Object[] src) {
2957         return Arrays.copyOf(src, 8, NonValueClass[].class);
2958     }
2959 
2960     @Run(test = "test123")
2961     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2962     public void test123_verifier() {
2963         NonValueClass[] arr = new NonValueClass[8];
2964         for (int i = 0; i < 8; ++i) {
2965             arr[i] = new NonValueClass(rI + i);
2966         }
2967         Object[] res = test123(arr);
2968         verify(arr, res);
2969         try {
2970             test123(val_src);
2971             throw new RuntimeException("ArrayStoreException expected");
2972         } catch (ArrayStoreException e) {
2973             // expected
2974         }
2975     }
2976 
2977     @Test
2978     public Object[] test124(Object[] src) {
2979         return Arrays.copyOf(src, 8, get_non_val_class());
2980     }
2981 
2982     @Run(test = "test124")
2983     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2984     public void test124_verifier() {
2985         NonValueClass[] arr = new NonValueClass[8];
2986         for (int i = 0; i < 8; ++i) {
2987             arr[i] = new NonValueClass(rI + i);
2988         }
2989         Object[] res = test124(arr);
2990         verify(arr, res);
2991         try {
2992             test124(val_src);
2993             throw new RuntimeException("ArrayStoreException expected");
2994         } catch (ArrayStoreException e) {
2995             // expected
2996         }
2997     }
2998 
2999     @Test
3000     public Object[] test125(Object[] src, Class klass) {
3001         return Arrays.copyOf(src, 8, klass);
3002     }
3003 
3004     @Run(test = "test125")
3005     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
3006     public void test125_verifier() {
3007         NonValueClass[] arr = new NonValueClass[8];
3008         for (int i = 0; i < 8; ++i) {
3009             arr[i] = new NonValueClass(rI + i);
3010         }
3011         Object[] res = test125(arr, NonValueClass[].class);
3012         verify((Object[])arr, res);
3013         res = test125(val_src, val_src.getClass());
3014         verify(val_src, res);
3015         res = test125(obj_src, val_src.getClass());
3016         verify(obj_src, res);
3017         res = test125(obj_null_src, val_src.getClass());
3018         verify(obj_null_src, res);
3019         try {
3020             test125(arr, val_src.getClass());
3021             throw new RuntimeException("ArrayStoreException expected");
3022         } catch (ArrayStoreException e) {
3023             // expected
3024         }
3025         try {
3026             test125(val_src, MyValue1[].class);
3027             throw new RuntimeException("ArrayStoreException expected");
3028         } catch (ArrayStoreException e) {
3029             // expected
3030         }
3031     }
3032 
3033     // Verify that clone from (flat) value class array not containing oops is always optimized.
3034     @Test
3035     @IR(applyIf = {"UseArrayFlattening", "true"},
3036         counts = {JLONG_ARRAYCOPY, "= 1"},
3037         failOn = {CHECKCAST_ARRAYCOPY, CLONE_INTRINSIC_SLOW_PATH})
3038     @IR(applyIf = {"UseArrayFlattening", "false"},
3039         failOn = CLONE_INTRINSIC_SLOW_PATH)
3040     public Object[] test126() {
3041         return val_src.clone();
3042     }
3043 
3044     @Run(test = "test126")
3045     public void test126_verifier() {
3046         Object[] res = test126();
3047         verify(val_src, res);
3048     }
3049 
3050     // Verify correctness of generic_copy stub
3051     @Test
3052     public void test127(Object src, Object dst, int len) {
3053         System.arraycopy(src, 0, dst, 0, len);
3054     }
3055 
3056     @Run(test = "test127")
3057     public void test127_verifier() {
3058         test127(val_src, obj_dst, 8);
3059         verify(val_src, obj_dst);
3060         test127(val_src, val_dst, 8);
3061         verify(val_src, val_dst);
3062         test127(obj_src, val_dst, 8);
3063         verify(obj_src, val_dst);
3064         try {
3065             test127(obj_null_src, val_dst, 8);
3066             throw new RuntimeException("NullPointerException expected");
3067         } catch (NullPointerException e) {
3068             // expected
3069         }
3070     }
3071 
3072     // Verify that copyOf with known source and unknown destination class is optimized
3073     @Test
3074     @IR(applyIf = {"UseArrayFlattening", "true"},
3075         counts = {JLONG_ARRAYCOPY, "= 1"},
3076         failOn = CHECKCAST_ARRAYCOPY)
3077     public Object[] test128(Class klass) {
3078         return Arrays.copyOf(val_src, 8, klass);
3079     }
3080 
3081     @Run(test = "test128")
3082     public void test128_verifier() {
3083         Object[] res = test128(MyValue2[].class);
3084         verify(val_src, res);
3085         res = test128(Object[].class);
3086         verify(val_src, res);
3087         try {
3088             test128(MyValue1[].class);
3089             throw new RuntimeException("ArrayStoreException expected");
3090         } catch (ArrayStoreException e) {
3091             // expected
3092         }
3093     }
3094 
3095     // Arraycopy with non-array src/dst
3096     @Test
3097     public void test129(Object src, Object dst, int len) {
3098         System.arraycopy(src, 0, dst, 0, len);
3099     }
3100 
3101     @Run(test = "test129")
3102     public void test129_verifier() {
3103         try {
3104             test129(new Object(), new Object[0], 0);
3105             throw new RuntimeException("ArrayStoreException expected");
3106         } catch (ArrayStoreException e) {
3107             // expected
3108         }
3109         try {
3110             test129(new Object[0], new Object(), 0);
3111             throw new RuntimeException("ArrayStoreException expected");
3112         } catch (ArrayStoreException e) {
3113             // expected
3114         }
3115     }
3116 
3117     @Strict
3118     @NullRestricted
3119     static final MyValueEmpty empty = new MyValueEmpty();
3120 
3121     // Empty value class array access
3122     @Test
3123     @IR(failOn = {LOAD})
3124     public MyValueEmpty test130(MyValueEmpty[] array) {
3125         array[0] = new MyValueEmpty();
3126         return array[1];
3127     }
3128 
3129     @Run(test = "test130")
3130     public void test130_verifier() {
3131         MyValueEmpty[] array = (MyValueEmpty[])ValueClass.newNullRestrictedNonAtomicArray(MyValueEmpty.class, 2, empty);
3132         MyValueEmpty res = test130(array);
3133         Asserts.assertEquals(array[0], empty);
3134         Asserts.assertEquals(res, empty);
3135     }
3136 
3137     @LooselyConsistentValue
3138     static value class EmptyContainer {
3139         @Strict
3140         @NullRestricted
3141         MyValueEmpty empty = new MyValueEmpty();
3142     }
3143 
3144     // Empty value class container array access
3145     @Test
3146     @IR(failOn = {LOAD})
3147     public MyValueEmpty test131(EmptyContainer[] array) {
3148         array[0] = new EmptyContainer();
3149         return array[1].empty;
3150     }
3151 
3152     @Run(test = "test131")
3153     public void test131_verifier() {
3154         EmptyContainer[] array = (EmptyContainer[])ValueClass.newNullRestrictedNonAtomicArray(EmptyContainer.class, 2, new EmptyContainer());
3155         MyValueEmpty res = test131(array);
3156         Asserts.assertEquals(array[0], new EmptyContainer());
3157         Asserts.assertEquals(res, new MyValueEmpty());
3158     }
3159 
3160     // Empty value class array access with unknown array type
3161     @Test
3162     public Object test132(Object[] array) {
3163         array[0] = new MyValueEmpty();
3164         return array[1];
3165     }
3166 
3167     @Run(test = "test132")
3168     public void test132_verifier() {
3169         Object[] array = (MyValueEmpty[])ValueClass.newNullRestrictedNonAtomicArray(MyValueEmpty.class, 2, empty);
3170         Object res = test132(array);
3171         Asserts.assertEquals(array[0], empty);
3172         Asserts.assertEquals(res, empty);
3173         array = new Object[2];
3174         res = test132(array);
3175         Asserts.assertEquals(array[0], empty);
3176         Asserts.assertEquals(res, null);
3177     }
3178 
3179     // Empty value class container array access with unknown array type
3180     @Test
3181     public Object test133(Object[] array) {
3182         array[0] = new EmptyContainer();
3183         return array[1];
3184     }
3185 
3186     @Run(test = "test133")
3187     public void test133_verifier() {
3188         EmptyContainer empty = new EmptyContainer();
3189         Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedNonAtomicArray(EmptyContainer.class, 2, new EmptyContainer());
3190         Object res = test133(array);
3191         Asserts.assertEquals(array[0], empty);
3192         Asserts.assertEquals(res, empty);
3193         array = new Object[2];
3194         res = test133(array);
3195         Asserts.assertEquals(array[0], empty);
3196         Asserts.assertEquals(res, null);
3197     }
3198 
3199     // Non-escaping empty value class array access
3200     @Test
3201     @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE})
3202     public static MyValueEmpty test134() {
3203         MyValueEmpty[] array = new MyValueEmpty[1];
3204         array[0] = empty;
3205         return array[0];
3206     }
3207 
3208     @Run(test = "test134")
3209     public void test134_verifier() {
3210         MyValueEmpty res = test134();
3211         Asserts.assertEquals(res, empty);
3212     }
3213 
3214     // Test accessing a locked (value class) array
3215     @Test
3216     public Object test135(Object[] array, Object val) {
3217         array[0] = val;
3218         return array[1];
3219     }
3220 
3221     @Run(test = "test135")
3222     public void test135_verifier() {
3223         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 2, MyValue1.DEFAULT);
3224         array1[1] = MyValue1.createWithFieldsInline(rI, rL);
3225         synchronized (array1) {
3226             Object res = test135(array1, array1[1]);
3227             Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash());
3228             Asserts.assertEquals(array1[0].hash(), array1[1].hash());
3229         }
3230         NonValueClass[] array2 = new NonValueClass[2];
3231         array2[1] = new NonValueClass(rI);
3232         synchronized (array2) {
3233             Object res = test135(array2, array2[1]);
3234             Asserts.assertEquals(res, array2[1]);
3235             Asserts.assertEquals(array2[0], array2[1]);
3236         }
3237     }
3238 
3239     // Same as test135 but with locking in compiled method
3240     @Test
3241     public Object test136(Object[] array, Object val) {
3242         Object res = null;
3243         synchronized (array) {
3244             array[0] = val;
3245             res = array[1];
3246         }
3247         return res;
3248     }
3249 
3250     @Run(test = "test136")
3251     public void test136_verifier() {
3252         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 2, MyValue1.DEFAULT);
3253         array1[1] = MyValue1.createWithFieldsInline(rI, rL);
3254         Object res = test136(array1, array1[1]);
3255         Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash());
3256         Asserts.assertEquals(array1[0].hash(), array1[1].hash());
3257         NonValueClass[] array2 = new NonValueClass[2];
3258         array2[1] = new NonValueClass(rI);
3259         res = test136(array2, array2[1]);
3260         Asserts.assertEquals(res, array2[1]);
3261         Asserts.assertEquals(array2[0], array2[1]);
3262     }
3263 
3264     Object oFld1, oFld2;
3265 
3266     // Test loop unwswitching with locked (value class) array accesses
3267     @Test
3268     public void test137(Object[] array1, Object[] array2) {
3269         for (int i = 0; i < array1.length; i++) {
3270             oFld1 = array1[i];
3271             oFld2 = array2[i];
3272         }
3273     }
3274 
3275     @Run(test = "test137")
3276     public void test137_verifier() {
3277         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 100, MyValue1.DEFAULT);
3278         Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL));
3279         NonValueClass[] array2 = new NonValueClass[100];
3280         Arrays.fill(array2, new NonValueClass(rI));
3281         synchronized (array1) {
3282             test137(array1, array1);
3283             Asserts.assertEquals(oFld1, array1[0]);
3284             Asserts.assertEquals(oFld2, array1[0]);
3285             test137(array1, array2);
3286             Asserts.assertEquals(oFld1, array1[0]);
3287             Asserts.assertEquals(oFld2, array2[0]);
3288             test137(array2, array1);
3289             Asserts.assertEquals(oFld1, array2[0]);
3290             Asserts.assertEquals(oFld2, array1[0]);
3291         }
3292         synchronized (array2) {
3293             test137(array2, array2);
3294             Asserts.assertEquals(oFld1, array2[0]);
3295             Asserts.assertEquals(oFld2, array2[0]);
3296             test137(array1, array2);
3297             Asserts.assertEquals(oFld1, array1[0]);
3298             Asserts.assertEquals(oFld2, array2[0]);
3299             test137(array2, array1);
3300             Asserts.assertEquals(oFld1, array2[0]);
3301             Asserts.assertEquals(oFld2, array1[0]);
3302         }
3303     }
3304 
3305     // Same as test137 but with locking in loop
3306     @Test
3307     public void test138(Object[] array1, Object[] array2) {
3308         for (int i = 0; i < array1.length; i++) {
3309             synchronized (array1) {
3310                 oFld1 = array1[i];
3311             }
3312             synchronized (array2) {
3313                 oFld2 = array2[i];
3314             }
3315         }
3316     }
3317 
3318     @Run(test = "test138")
3319     public void test138_verifier() {
3320         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 100, MyValue1.DEFAULT);
3321         Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL));
3322         NonValueClass[] array2 = new NonValueClass[100];
3323         Arrays.fill(array2, new NonValueClass(rI));
3324         test138(array1, array1);
3325         Asserts.assertEquals(oFld1, array1[0]);
3326         Asserts.assertEquals(oFld2, array1[0]);
3327         test138(array1, array2);
3328         Asserts.assertEquals(oFld1, array1[0]);
3329         Asserts.assertEquals(oFld2, array2[0]);
3330         test138(array2, array1);
3331         Asserts.assertEquals(oFld1, array2[0]);
3332         Asserts.assertEquals(oFld2, array1[0]);
3333         test138(array2, array2);
3334         Asserts.assertEquals(oFld1, array2[0]);
3335         Asserts.assertEquals(oFld2, array2[0]);
3336         Asserts.assertEquals(oFld2, array2[0]);
3337     }
3338 
3339     // Test load from array that is only known to be not a value class array after parsing
3340     @Test
3341     @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE,
3342                   STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3343     public Object test139() {
3344         Object[]  array = null;
3345         Object[] oarray = new NonValueClass[1];
3346         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
3347         for (int i = 0; i < 10; i++) {
3348             array = varray;
3349             varray = oarray;
3350         }
3351         return array[0];
3352     }
3353 
3354     @Run(test = "test139")
3355     public void test139_verifier() {
3356         Object res = test139();
3357         Asserts.assertEquals(res, null);
3358     }
3359 
3360     // Test store to array that is only known to be not a value class array after parsing
3361     @Test
3362     @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, TRAP,
3363                   LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3364     public Object[] test140(Object val) {
3365         Object[]  array = null;
3366         Object[] oarray = new NonValueClass[1];
3367         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
3368         for (int i = 0; i < 10; i++) {
3369             array = varray;
3370             varray = oarray;
3371         }
3372         array[0] = val;
3373         return array;
3374     }
3375 
3376     @Run(test = "test140")
3377     public void test140_verifier() {
3378         NonValueClass obj = new NonValueClass(rI);
3379         Object[] res = test140(obj);
3380         Asserts.assertEquals(res[0], obj);
3381         res = test140(null);
3382         Asserts.assertEquals(res[0], null);
3383     }
3384 
3385     // Test load from array that is only known to be not a value class array after parsing
3386     // TODO 8255938
3387     @Test
3388     // @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3389     public Object test141() {
3390         Object[]  array = null;
3391         Object[] oarray = new NonValueClass[1];
3392         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
3393         for (int i = 0; i < 10; i++) {
3394             array = oarray;
3395             oarray = varray;
3396         }
3397         return array[0];
3398     }
3399 
3400     @Run(test = "test141")
3401     public void test141_verifier() {
3402         Object res = test141();
3403         Asserts.assertEquals(res, MyValue1.createDefaultInline());
3404     }
3405 
3406     // Test store to array that is only known to be not a value class array after parsing
3407     // TODO 8255938
3408     @Test
3409     // @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3410     public Object[] test142(Object val) {
3411         Object[]  array = null;
3412         Object[] oarray = new NonValueClass[1];
3413         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
3414         for (int i = 0; i < 10; i++) {
3415             array = oarray;
3416             oarray = varray;
3417         }
3418         array[0] = val;
3419         return array;
3420     }
3421 
3422     @Run(test = "test142")
3423     public void test142_verifier(RunInfo info) {
3424         Object[] res = test142(MyValue1.createDefaultInline());
3425         Asserts.assertEquals(res[0], MyValue1.createDefaultInline());
3426         if (!info.isWarmUp()) {
3427             try {
3428                 test142(null);
3429                 throw new RuntimeException("Should throw NullPointerException");
3430             } catch (NullPointerException e) {
3431                 // Expected
3432             }
3433         }
3434     }
3435 
3436     static interface MyInterface143 {
3437         public int hash();
3438     }
3439 
3440     static class MyObject143 implements MyInterface143 {
3441         public int hash() { return 42; }
3442     }
3443 
3444     volatile MyInterface143[] array143 = new MyObject143[1];
3445     int len143 = 0;
3446 
3447     volatile int vf = 0;
3448 
3449     // Test that triggers an anti dependency failure when array mark word is loaded from immutable memory
3450     @Test
3451     public void test143() {
3452         MyInterface143[] arr = array143;
3453         int tmp = arr.length;
3454         for (int i = 0; i < len143; i++) {
3455             if (arr[i].hash() > 0) {
3456                 return;
3457             }
3458         }
3459     }
3460 
3461     @Run(test = "test143")
3462     @Warmup(0)
3463     public void test143_verifier() {
3464         test143();
3465     }
3466 
3467     // Same as test143 but with two flat array checks that are unswitched
3468     @Test
3469     public void test144() {
3470         MyInterface143[] arr1 = array143;
3471         MyInterface143[] arr2 = array143;
3472         int tmp1 = arr1.length;
3473         int tmp2 = arr2.length;
3474         for (int i = 0; i < len143; i++) {
3475             if (arr1[i].hash() > 0 && arr2[i].hash() > 0) {
3476                 return;
3477             }
3478         }
3479     }
3480 
3481     @Run(test = "test144")
3482     @Warmup(0)
3483     public void test144_verifier() {
3484         test144();
3485     }
3486 
3487     // Test that array load slow path correctly initializes non-flattened field of empty value class
3488     @Test
3489     public Object test145(Object[] array) {
3490         return array[0];
3491     }
3492 
3493     @Run(test = "test145")
3494     public void test145_verifier() {
3495         Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedNonAtomicArray(EmptyContainer.class, 1, new EmptyContainer());
3496         EmptyContainer empty = (EmptyContainer)test145(array);
3497         Asserts.assertEquals(empty, new EmptyContainer());
3498     }
3499 
3500     // Test that non-flattened array does not block scalarization
3501     @Test
3502     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE})
3503     public void test146(boolean b) {
3504         MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD);
3505         MyValue2[] array = { vt };
3506         if (b) {
3507             for (int i = 0; i < 10; ++i) {
3508                 if (array != array) {
3509                     array = null;
3510                 }
3511             }
3512         }
3513     }
3514 
3515     @Run(test = "test146")
3516     @Warmup(50000)
3517     public void test146_verifier() {
3518         test146(true);
3519     }
3520 
3521     // Test that non-flattened array does not block scalarization
3522     @Test
3523     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE})
3524     public int test147(boolean deopt) {
3525         // Both vt and array should be scalarized
3526         MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD);
3527         MyValue2[] array = (MyValue2[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2.class, 1, MyValue2.DEFAULT);
3528 
3529         // Delay scalarization to after loop opts
3530         boolean store = false;
3531         for (int i = 0; i < 5; ++i) {
3532             if (i == 1) {
3533                 store = true;
3534             }
3535         }
3536         if (store) {
3537             array[0] = vt;
3538         }
3539 
3540         if (deopt) {
3541             // Uncommon trap referencing array
3542             return array[0].x + 42;
3543         }
3544         return array[0].x;
3545     }
3546 
3547     @Run(test = "test147")
3548     @Warmup(50000)
3549     public void test147_verifier(RunInfo info) {
3550         int res = test147(!info.isWarmUp());
3551         Asserts.assertEquals(res, MyValue2.createWithFieldsInline(rI, rD).x + (info.isWarmUp() ? 0 : 42));
3552     }
3553 
3554     // Test that correct basic types are used when folding field
3555     // loads from a scalar replaced array through an arraycopy.
3556     @Test
3557     public void test148(MyValue1 vt) {
3558         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
3559         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1.class, 1, MyValue1.DEFAULT);
3560         src[0] = vt;
3561         System.arraycopy(src, 0, dst, 0, 1);
3562         if (src[0].hash() != dst[0].hash()) {
3563           throw new RuntimeException("Unexpected hash");
3564         }
3565     }
3566 
3567     @Run(test = "test148")
3568     public void test148_verifier() {
3569         test148(MyValue1.createWithFieldsInline(rI, rL));
3570     }
3571 
3572     // Abstract class without any value class implementers
3573     static abstract class MyAbstract149 {
3574         public abstract int get();
3575     }
3576 
3577     static class TestClass149 extends MyAbstract149 {
3578         final int x;
3579 
3580         public int get() { return x; };
3581 
3582         public TestClass149(int x) {
3583             this.x = x;
3584         }
3585     }
3586 
3587     // Test OSR compilation with array known to be not null-free/flat
3588     @Test
3589     public int test149(MyAbstract149[] array) {
3590         int res = 0;
3591         // Trigger OSR compilation
3592         for (int i = 0; i < 10_000; ++i) {
3593             res += array[i % 10].get();
3594         }
3595         return res;
3596     }
3597 
3598     @Run(test = "test149")
3599     public void test149_verifier() {
3600         TestClass149[] array = new TestClass149[10];
3601         for (int i = 0; i < 10; ++i) {
3602             array[i] = new TestClass149(i);
3603         }
3604         Asserts.assertEquals(test149(array), 45000);
3605     }
3606 
3607     @LooselyConsistentValue
3608     static value class Test150Value {
3609         Object s;
3610 
3611         public Test150Value(String s) {
3612             this.s = s;
3613         }
3614     }
3615 
3616     // Test that optimizing a checkcast of a load from a flat array works as expected
3617     @Test
3618     static String test150(String s) {
3619         Test150Value[] array = (Test150Value[])ValueClass.newNullRestrictedNonAtomicArray(Test150Value.class, 1, new Test150Value("test"));
3620         array[0] = new Test150Value(s);
3621         return (String)array[0].s;
3622     }
3623 
3624     @Run(test = "test150")
3625     public void test150_verifier() {
3626         Asserts.assertEquals(test150("bla"), "bla");
3627     }
3628 
3629     static value class Test151Value {
3630         byte b;
3631         String s;
3632 
3633         Test151Value(byte b, String s) {
3634             this.b = b;
3635             this.s = s;
3636         }
3637 
3638         static final Test151Value DEFAULT = new Test151Value((byte) 1, "hello");
3639 
3640         static final Test151Value[] ARRAY = (Test151Value[]) ValueClass.newNullRestrictedAtomicArray(Test151Value.class, 100, DEFAULT);
3641     }
3642 
3643     @Test
3644     @IR(applyIf = {"InlineTypeReturnedAsFields", "true"},
3645         failOn = {ALLOC})
3646     static Test151Value test151(int i) {
3647         return Test151Value.ARRAY[i];
3648     }
3649 
3650     @Run(test = "test151")
3651     public void test151_verifier() {
3652         Asserts.assertEquals(Test151Value.DEFAULT, test151(rI & 15));
3653     }
3654 
3655     // Make sure this can't be flattened
3656     static value class MyValue152Inline {
3657         long l1 = rL;
3658         long l2 = rL;
3659     }
3660 
3661     @LooselyConsistentValue
3662     static value class MyValue152 {
3663         double d = rD;
3664 
3665         @Strict
3666         @NullRestricted
3667         MyValue152Inline val = new MyValue152Inline(); // Not flat
3668     }
3669 
3670     // Test that EA works for null-free arrays
3671     @Test
3672     // TODO 8350865 Scalar replacement does not work well for flat arrays
3673     //@IR(applyIf = {"InlineTypeReturnedAsFields", "true"},
3674     //    failOn = {ALLOC, ALLOCA})
3675     public MyValue152 test152() {
3676         MyValue152[] array = (MyValue152[])ValueClass.newNullRestrictedNonAtomicArray(MyValue152.class, 1, new MyValue152());
3677         return array[0];
3678     }
3679 
3680     @Run(test = "test152")
3681     public void test152_verifier() {
3682         Asserts.assertEquals(test152(), new MyValue152());
3683     }
3684 
3685     @LooselyConsistentValue
3686     static value class MyValue153 {
3687         @Strict
3688         @NullRestricted
3689         MyValue152Inline val = new MyValue152Inline(); // Not flat
3690     }
3691 
3692     // Same as test152 but triggers a slightly different asserts
3693     @Test
3694     // TODO 8350865 Scalar replacement does not work well for flat arrays
3695     //@IR(applyIf = {"InlineTypeReturnedAsFields", "true"},
3696     //    failOn = {ALLOC, ALLOCA})
3697     public MyValue153 test153() {
3698         MyValue153[] array = (MyValue153[])ValueClass.newNullRestrictedNonAtomicArray(MyValue153.class, 1, new MyValue153());
3699         return array[0];
3700     }
3701 
3702     @Run(test = "test153")
3703     public void test153_verifier() {
3704         Asserts.assertEquals(test153(), new MyValue153());
3705     }
3706 
3707     // Same as test152 but triggers an incorrect result
3708     @Test
3709     // TODO 8350865 Scalar replacement does not work well for flat arrays
3710     //@IR(failOn = {ALLOC, ALLOCA_G, LOAD, STORE, TRAP})
3711     public double test154() {
3712         MyValue152[] array = (MyValue152[])ValueClass.newNullRestrictedNonAtomicArray(MyValue152.class, 1, new MyValue152());
3713         return array[0].d;
3714     }
3715 
3716     @Run(test = "test154")
3717     public void test154_verifier() {
3718         Asserts.assertEquals(test154(), rD);
3719     }
3720 }