1 /*
   2  * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package compiler.valhalla.inlinetypes;
  25 
  26 import compiler.lib.ir_framework.*;
  27 import jdk.test.lib.Asserts;
  28 
  29 import jdk.internal.value.ValueClass;
  30 import jdk.internal.vm.annotation.ImplicitlyConstructible;
  31 import jdk.internal.vm.annotation.LooselyConsistentValue;
  32 import jdk.internal.vm.annotation.NullRestricted;
  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:FlatArrayElementMaxSize=-1", "-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         if (src instanceof MyInterface[] && dst instanceof MyInterface[]) {
  89             for (int i = 0; i < src.length; ++i) {
  90                 Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash());
  91             }
  92         } else {
  93             for (int i = 0; i < src.length; ++i) {
  94                 Asserts.assertEQ(src[i], dst[i]);
  95             }
  96         }
  97     }
  98 
  99     static void verify(MyValue1[] src, MyValue1[] dst) {
 100         for (int i = 0; i < src.length; ++i) {
 101             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 102         }
 103     }
 104 
 105     static void verify(MyValue1[] src, Object[] dst) {
 106         for (int i = 0; i < src.length; ++i) {
 107             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 108         }
 109     }
 110 
 111     static void verify(MyValue2[] src, MyValue2[] dst) {
 112         for (int i = 0; i < src.length; ++i) {
 113             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 114         }
 115     }
 116 
 117     static void verify(MyValue2[] src, Object[] dst) {
 118         for (int i = 0; i < src.length; ++i) {
 119             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 120         }
 121     }
 122 
 123     static boolean compile_and_run_again_if_deoptimized(RunInfo info) {
 124         if (!info.isWarmUp()) {
 125             Method m = info.getTest();
 126             if (TestFramework.isCompiled(m)) {
 127                 TestFramework.compile(m, CompLevel.C2);
 128             }
 129         }
 130         return false;
 131     }
 132 
 133     @ImplicitlyConstructible
 134     @LooselyConsistentValue
 135     static value class NotFlattenable {
 136         private final Object o1 = null;
 137         private final Object o2 = null;
 138         private final Object o3 = null;
 139         private final Object o4 = null;
 140         private final Object o5 = null;
 141         private final Object o6 = null;
 142     }
 143 
 144     // Test value class array creation and initialization
 145     @Test
 146     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
 147         counts = {ALLOCA, "= 1"})
 148     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
 149         counts = {ALLOCA, "= 1"},
 150         failOn = LOAD)
 151     public MyValue1[] test1(int len) {
 152         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 153         for (int i = 0; i < len; ++i) {
 154             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 155         }
 156         return va;
 157     }
 158 
 159     @Run(test = "test1")
 160     public void test1_verifier() {
 161         int len = Math.abs(rI % 10);
 162         MyValue1[] va = test1(len);
 163         for (int i = 0; i < len; ++i) {
 164             Asserts.assertEQ(va[i].hash(), hash());
 165         }
 166     }
 167 
 168     // Test creation of a value class array and element access
 169     @Test
 170     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP})
 171     public long test2() {
 172         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
 173         va[0] = MyValue1.createWithFieldsInline(rI, rL);
 174         return va[0].hash();
 175     }
 176 
 177     @Run(test = "test2")
 178     public void test2_verifier() {
 179         long result = test2();
 180         Asserts.assertEQ(result, hash());
 181     }
 182 
 183     // Test receiving a value class array from the interpreter,
 184     // updating its elements in a loop and computing a hash.
 185     @Test
 186     @IR(failOn = ALLOCA)
 187     public long test3(MyValue1[] va) {
 188         long result = 0;
 189         for (int i = 0; i < 10; ++i) {
 190             result += va[i].hash();
 191             va[i] = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 192         }
 193         return result;
 194     }
 195 
 196     @Run(test = "test3")
 197     public void test3_verifier() {
 198         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 10);
 199         long expected = 0;
 200         for (int i = 0; i < 10; ++i) {
 201             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 202             expected += va[i].hash();
 203         }
 204         long result = test3(va);
 205         Asserts.assertEQ(expected, result);
 206         for (int i = 0; i < 10; ++i) {
 207             if (va[i].hash() != hash(rI + 1, rL + 1)) {
 208                 Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1));
 209             }
 210         }
 211     }
 212 
 213     // Test returning a value class array received from the interpreter
 214     @Test
 215     @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP})
 216     public MyValue1[] test4(MyValue1[] va) {
 217         return va;
 218     }
 219 
 220     @Run(test = "test4")
 221     public void test4_verifier() {
 222         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 10);
 223         for (int i = 0; i < 10; ++i) {
 224             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 225         }
 226         va = test4(va);
 227         for (int i = 0; i < 10; ++i) {
 228             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 229         }
 230     }
 231 
 232     // Merge value class arrays created from two branches
 233     @Test
 234     public MyValue1[] test5(boolean b) {
 235         MyValue1[] va;
 236         if (b) {
 237             va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 5);
 238             for (int i = 0; i < 5; ++i) {
 239                 va[i] = MyValue1.createWithFieldsInline(rI, rL);
 240             }
 241         } else {
 242             va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 10);
 243             for (int i = 0; i < 10; ++i) {
 244                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
 245             }
 246         }
 247         long sum = va[0].hashInterpreted();
 248         if (b) {
 249             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
 250         } else {
 251             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
 252         }
 253         return va;
 254     }
 255 
 256     @Run(test = "test5")
 257     public void test5_verifier() {
 258         MyValue1[] va = test5(true);
 259         Asserts.assertEQ(va.length, 5);
 260         Asserts.assertEQ(va[0].hash(), hash(rI, hash()));
 261         for (int i = 1; i < 5; ++i) {
 262             Asserts.assertEQ(va[i].hash(), hash());
 263         }
 264         va = test5(false);
 265         Asserts.assertEQ(va.length, 10);
 266         Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1));
 267         for (int i = 1; i < 10; ++i) {
 268             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 269         }
 270     }
 271 
 272     // Test creation of value class array with single element
 273     @Test
 274     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP})
 275     public MyValue1 test6() {
 276         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
 277         return va[0];
 278     }
 279 
 280     @Run(test = "test6")
 281     public void test6_verifier() {
 282         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
 283         MyValue1 v = test6();
 284         Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive());
 285     }
 286 
 287     // Test default initialization of value class arrays
 288     @Test
 289     @IR(failOn = LOAD)
 290     public MyValue1[] test7(int len) {
 291         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 292     }
 293 
 294     @Run(test = "test7")
 295     public void test7_verifier() {
 296         int len = Math.abs(rI % 10);
 297         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 298         MyValue1[] var = test7(len);
 299         for (int i = 0; i < len; ++i) {
 300             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
 301         }
 302     }
 303 
 304     // Test creation of value class array with zero length
 305     @Test
 306     @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP})
 307     public MyValue1[] test8() {
 308         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0);
 309     }
 310 
 311     @Run(test = "test8")
 312     public void test8_verifier() {
 313         MyValue1[] va = test8();
 314         Asserts.assertEQ(va.length, 0);
 315     }
 316 
 317     static MyValue1[] test9_va;
 318 
 319     // Test that value class array loaded from field has correct type
 320     @Test
 321     @IR(failOn = LOOP)
 322     public long test9() {
 323         return test9_va[0].hash();
 324     }
 325 
 326     @Run(test = "test9")
 327     public void test9_verifier() {
 328         test9_va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
 329         test9_va[0] = MyValue1.createWithFieldsInline(rI, rL);
 330         long result = test9();
 331         Asserts.assertEQ(result, hash());
 332     }
 333 
 334     // Multi-dimensional arrays
 335     @Test
 336     public MyValue1[][][] test10(int len1, int len2, int len3) {
 337         MyValue1[][][] arr = new MyValue1[len1][len2][len3];
 338         for (int i = 0; i < len1; i++) {
 339             for (int j = 0; j < len2; j++) {
 340                 for (int k = 0; k < len3; k++) {
 341                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i , rL + j + k);
 342                 }
 343             }
 344         }
 345         return arr;
 346     }
 347 
 348     @Run(test = "test10")
 349     public void test10_verifier() {
 350         MyValue1[][][] arr = test10(2, 3, 4);
 351         for (int i = 0; i < 2; i++) {
 352             for (int j = 0; j < 3; j++) {
 353                 for (int k = 0; k < 4; k++) {
 354                     Asserts.assertEQ(arr[i][j][k].hash(), MyValue1.createWithFieldsDontInline(rI + i , rL + j + k).hash());
 355                 }
 356             }
 357         }
 358     }
 359 
 360     @Test
 361     public void test11(MyValue1[][][] arr, long[] res) {
 362         int l = 0;
 363         for (int i = 0; i < arr.length; i++) {
 364             for (int j = 0; j < arr[i].length; j++) {
 365                 for (int k = 0; k < arr[i][j].length; k++) {
 366                     res[l] = arr[i][j][k].hash();
 367                     l++;
 368                 }
 369             }
 370         }
 371     }
 372 
 373     @Run(test = "test11")
 374     public void test11_verifier() {
 375         MyValue1[][][] arr = new MyValue1[2][3][4];
 376         long[] res = new long[2*3*4];
 377         long[] verif = new long[2*3*4];
 378         int l = 0;
 379         for (int i = 0; i < 2; i++) {
 380             for (int j = 0; j < 3; j++) {
 381                 for (int k = 0; k < 4; k++) {
 382                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i, rL + j + k);
 383                     verif[l] = arr[i][j][k].hash();
 384                     l++;
 385                 }
 386             }
 387         }
 388         test11(arr, res);
 389         for (int i = 0; i < verif.length; i++) {
 390             Asserts.assertEQ(res[i], verif[i]);
 391         }
 392     }
 393 
 394     // Array load out of bounds (upper bound) at compile time
 395     @Test
 396     public int test12() {
 397         int arraySize = Math.abs(rI) % 10;
 398         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize);
 399 
 400         for (int i = 0; i < arraySize; i++) {
 401             va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 402         }
 403 
 404         try {
 405             return va[arraySize + 1].x;
 406         } catch (ArrayIndexOutOfBoundsException e) {
 407             return rI;
 408         }
 409     }
 410 
 411     @Run(test = "test12")
 412     public void test12_verifier() {
 413         Asserts.assertEQ(test12(), rI);
 414     }
 415 
 416     // Array load  out of bounds (lower bound) at compile time
 417     @Test
 418     public int test13() {
 419         int arraySize = Math.abs(rI) % 10;
 420         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize);
 421 
 422         for (int i = 0; i < arraySize; i++) {
 423             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL);
 424         }
 425 
 426         try {
 427             return va[-arraySize].x;
 428         } catch (ArrayIndexOutOfBoundsException e) {
 429             return rI;
 430         }
 431     }
 432 
 433     @Run(test = "test13")
 434     public void test13_verifier() {
 435         Asserts.assertEQ(test13(), rI);
 436     }
 437 
 438     // Array load out of bound not known to compiler (both lower and upper bound)
 439     @Test
 440     public int test14(MyValue1[] va, int index)  {
 441         return va[index].x;
 442     }
 443 
 444     @Run(test = "test14")
 445     public void test14_verifier() {
 446         int arraySize = Math.abs(rI) % 10;
 447         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize);
 448 
 449         for (int i = 0; i < arraySize; i++) {
 450             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 451         }
 452 
 453         int result;
 454         for (int i = -20; i < 20; i++) {
 455             try {
 456                 result = test14(va, i);
 457             } catch (ArrayIndexOutOfBoundsException e) {
 458                 result = rI;
 459             }
 460             Asserts.assertEQ(result, rI);
 461         }
 462     }
 463 
 464     // Array store out of bounds (upper bound) at compile time
 465     @Test
 466     public int test15() {
 467         int arraySize = Math.abs(rI) % 10;
 468         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize);
 469 
 470         try {
 471             for (int i = 0; i <= arraySize; i++) {
 472                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 473             }
 474             return rI - 1;
 475         } catch (ArrayIndexOutOfBoundsException e) {
 476             return rI;
 477         }
 478     }
 479 
 480     @Run(test = "test15")
 481     public void test15_verifier() {
 482         Asserts.assertEQ(test15(), rI);
 483     }
 484 
 485     // Array store out of bounds (lower bound) at compile time
 486     @Test
 487     public int test16() {
 488         int arraySize = Math.abs(rI) % 10;
 489         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize);
 490 
 491         try {
 492             for (int i = -1; i <= arraySize; i++) {
 493                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 494             }
 495             return rI - 1;
 496         } catch (ArrayIndexOutOfBoundsException e) {
 497             return rI;
 498         }
 499     }
 500 
 501     @Run(test = "test16")
 502     public void test16_verifier() {
 503         Asserts.assertEQ(test16(), rI);
 504     }
 505 
 506     // Array store out of bound not known to compiler (both lower and upper bound)
 507     @Test
 508     public int test17(MyValue1[] va, int index, MyValue1 vt)  {
 509         va[index] = vt;
 510         return va[index].x;
 511     }
 512 
 513     @Run(test = "test17")
 514     public void test17_verifier() {
 515         int arraySize = Math.abs(rI) % 10;
 516         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize);
 517 
 518         for (int i = 0; i < arraySize; i++) {
 519             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 520         }
 521 
 522         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 523         int result;
 524         for (int i = -20; i < 20; i++) {
 525             try {
 526                 result = test17(va, i, vt);
 527             } catch (ArrayIndexOutOfBoundsException e) {
 528                 result = rI + 1;
 529             }
 530             Asserts.assertEQ(result, rI + 1);
 531         }
 532 
 533         for (int i = 0; i < arraySize; i++) {
 534             Asserts.assertEQ(va[i].x, rI + 1);
 535         }
 536     }
 537 
 538     // clone() as stub call
 539     @Test
 540     public MyValue1[] test18(MyValue1[] va) {
 541         return va.clone();
 542     }
 543 
 544     @Run(test = "test18")
 545     public void test18_verifier() {
 546         int len = Math.abs(rI) % 10;
 547         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 548         for (int i = 0; i < len; ++i) {
 549             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 550         }
 551         MyValue1[] result = test18(va);
 552         for (int i = 0; i < len; ++i) {
 553             Asserts.assertEQ(result[i].hash(), va[i].hash());
 554         }
 555     }
 556 
 557     // clone() as series of loads/stores
 558     static MyValue1[] test19_orig = null;
 559 
 560     @Test
 561     public MyValue1[] test19() {
 562         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
 563         for (int i = 0; i < va.length; ++i) {
 564             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 565         }
 566         test19_orig = va;
 567 
 568         return va.clone();
 569     }
 570 
 571     @Run(test = "test19")
 572     public void test19_verifier() {
 573         MyValue1[] result = test19();
 574         for (int i = 0; i < test19_orig.length; ++i) {
 575             Asserts.assertEQ(result[i].hash(), test19_orig[i].hash());
 576         }
 577     }
 578 
 579     // arraycopy() of value class array with oop fields
 580     @Test
 581     public void test20(MyValue1[] src, MyValue1[] dst) {
 582         System.arraycopy(src, 0, dst, 0, src.length);
 583     }
 584 
 585     @Run(test = "test20")
 586     public void test20_verifier() {
 587         int len = Math.abs(rI) % 10;
 588         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 589         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 590         for (int i = 0; i < len; ++i) {
 591             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 592         }
 593         test20(src, dst);
 594         for (int i = 0; i < len; ++i) {
 595             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 596         }
 597     }
 598 
 599     // arraycopy() of value class array with no oop field
 600     @Test
 601     public void test21(MyValue2[] src, MyValue2[] dst) {
 602         System.arraycopy(src, 0, dst, 0, src.length);
 603     }
 604 
 605     @Run(test = "test21")
 606     public void test21_verifier() {
 607         int len = Math.abs(rI) % 10;
 608         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
 609         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
 610         for (int i = 0; i < len; ++i) {
 611             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 612         }
 613         test21(src, dst);
 614         for (int i = 0; i < len; ++i) {
 615             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 616         }
 617     }
 618 
 619     // arraycopy() of value class array with oop field and tightly
 620     // coupled allocation as dest
 621     @Test
 622     public MyValue1[] test22(MyValue1[] src) {
 623         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, src.length);
 624         System.arraycopy(src, 0, dst, 0, src.length);
 625         return dst;
 626     }
 627 
 628     @Run(test = "test22")
 629     public void test22_verifier() {
 630         int len = Math.abs(rI) % 10;
 631         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 632         for (int i = 0; i < len; ++i) {
 633             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 634         }
 635         MyValue1[] dst = test22(src);
 636         for (int i = 0; i < len; ++i) {
 637             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 638         }
 639     }
 640 
 641     // arraycopy() of value class array with oop fields and tightly
 642     // coupled allocation as dest
 643     @Test
 644     public MyValue1[] test23(MyValue1[] src) {
 645         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, src.length + 10);
 646         System.arraycopy(src, 0, dst, 5, src.length);
 647         return dst;
 648     }
 649 
 650     @Run(test = "test23")
 651     public void test23_verifier() {
 652         int len = Math.abs(rI) % 10;
 653         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 654         for (int i = 0; i < len; ++i) {
 655             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 656         }
 657         MyValue1[] dst = test23(src);
 658         for (int i = 5; i < len; ++i) {
 659             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 660         }
 661     }
 662 
 663     // arraycopy() of value class array passed as Object
 664     @Test
 665     public void test24(MyValue1[] src, Object dst) {
 666         System.arraycopy(src, 0, dst, 0, src.length);
 667     }
 668 
 669     @Run(test = "test24")
 670     public void test24_verifier() {
 671         int len = Math.abs(rI) % 10;
 672         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 673         MyValue1[] dst1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 674         Object[] dst2 = new Object[len];
 675         for (int i = 0; i < len; ++i) {
 676             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 677         }
 678         test24(src, dst1);
 679         for (int i = 0; i < len; ++i) {
 680             Asserts.assertEQ(src[i].hash(), dst1[i].hash());
 681         }
 682         test24(src, dst2);
 683         for (int i = 0; i < len; ++i) {
 684             Asserts.assertEQ(src[i].hash(), ((MyValue1)dst2[i]).hash());
 685         }
 686     }
 687 
 688     // short arraycopy() with no oop field
 689     @Test
 690     public void test25(MyValue2[] src, MyValue2[] dst) {
 691         System.arraycopy(src, 0, dst, 0, 8);
 692     }
 693 
 694     @Run(test = "test25")
 695     public void test25_verifier() {
 696         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
 697         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
 698         for (int i = 0; i < 8; ++i) {
 699             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 700         }
 701         test25(src, dst);
 702         for (int i = 0; i < 8; ++i) {
 703             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 704         }
 705     }
 706 
 707     // short arraycopy() with oop fields
 708     @Test
 709     public void test26(MyValue1[] src, MyValue1[] dst) {
 710         System.arraycopy(src, 0, dst, 0, 8);
 711     }
 712 
 713     @Run(test = "test26")
 714     public void test26_verifier() {
 715         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
 716         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
 717         for (int i = 0; i < 8; ++i) {
 718             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 719         }
 720         test26(src, dst);
 721         for (int i = 0; i < 8; ++i) {
 722             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 723         }
 724     }
 725 
 726     // short arraycopy() with oop fields and offsets
 727     @Test
 728     public void test27(MyValue1[] src, MyValue1[] dst) {
 729         System.arraycopy(src, 1, dst, 2, 6);
 730     }
 731 
 732     @Run(test = "test27")
 733     public void test27_verifier() {
 734         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
 735         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
 736         for (int i = 0; i < 8; ++i) {
 737             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 738         }
 739         test27(src, dst);
 740         for (int i = 2; i < 8; ++i) {
 741             Asserts.assertEQ(src[i-1].hash(), dst[i].hash());
 742         }
 743     }
 744 
 745     // non escaping allocations
 746     // TODO 8252027: Make sure this is optimized with ZGC
 747     @Test
 748     @IR(applyIf = {"UseZGC", "false"},
 749         failOn = {ALLOCA, LOOP, LOAD, TRAP})
 750     public MyValue2 test28() {
 751         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
 752         src[0] = MyValue2.createWithFieldsInline(rI, rD);
 753         MyValue2[] dst = (MyValue2[])src.clone();
 754         return dst[0];
 755     }
 756 
 757     @Run(test = "test28")
 758     public void test28_verifier() {
 759         MyValue2 v = MyValue2.createWithFieldsInline(rI, rD);
 760         MyValue2 result = test28();
 761         Asserts.assertEQ(result.hash(), v.hash());
 762     }
 763 
 764     // non escaping allocations
 765     // TODO 8227588: shouldn't this have the same IR matching rules as test6?
 766     // @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP)
 767     @Test
 768     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
 769         failOn = {ALLOCA, LOOP, LOAD, TRAP})
 770     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
 771         failOn = {ALLOCA, LOOP, TRAP})
 772     public MyValue2 test29(MyValue2[] src) {
 773         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
 774         System.arraycopy(src, 0, dst, 0, 10);
 775         return dst[0];
 776     }
 777 
 778     @Run(test = "test29")
 779     public void test29_verifier() {
 780         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
 781         for (int i = 0; i < 10; ++i) {
 782             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 783         }
 784         MyValue2 v = test29(src);
 785         Asserts.assertEQ(src[0].hash(), v.hash());
 786     }
 787 
 788     // non escaping allocation with uncommon trap that needs
 789     // eliminated value class array element as debug info
 790     @Test
 791     public MyValue2 test30(MyValue2[] src, boolean flag) {
 792         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
 793         System.arraycopy(src, 0, dst, 0, 10);
 794         if (flag) { }
 795         return dst[0];
 796     }
 797 
 798     @Run(test = "test30")
 799     @Warmup(10000)
 800     public void test30_verifier(RunInfo info) {
 801         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
 802         for (int i = 0; i < 10; ++i) {
 803             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 804         }
 805         MyValue2 v = test30(src, !info.isWarmUp());
 806         Asserts.assertEQ(src[0].hash(), v.hash());
 807     }
 808 
 809 
 810     // non escaping allocation with memory phi
 811     @Test
 812     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP})
 813     public long test31(boolean b, boolean deopt, Method m) {
 814         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1);
 815         if (b) {
 816             src[0] = MyValue2.createWithFieldsInline(rI, rD);
 817         } else {
 818             src[0] = MyValue2.createWithFieldsInline(rI+1, rD+1);
 819         }
 820         if (deopt) {
 821             // uncommon trap
 822             TestFramework.deoptimize(m);
 823         }
 824         return src[0].hash();
 825     }
 826 
 827     @Run(test = "test31")
 828     public void test31_verifier(RunInfo info) {
 829         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, rD);
 830         long result1 = test31(true, !info.isWarmUp(), info.getTest());
 831         Asserts.assertEQ(result1, v1.hash());
 832         MyValue2 v2 = MyValue2.createWithFieldsInline(rI + 1, rD + 1);
 833         long result2 = test31(false, !info.isWarmUp(), info.getTest());
 834         Asserts.assertEQ(result2, v2.hash());
 835     }
 836 
 837     // Tests with Object arrays and clone/arraycopy
 838     // clone() as stub call
 839     @Test
 840     public Object[] test32(Object[] va) {
 841         return va.clone();
 842     }
 843 
 844     @Run(test = "test32")
 845     public void test32_verifier() {
 846         int len = Math.abs(rI) % 10;
 847         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 848         for (int i = 0; i < len; ++i) {
 849             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 850         }
 851         MyValue1[] result = (MyValue1[])test32(va);
 852         for (int i = 0; i < len; ++i) {
 853             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 854         }
 855     }
 856 
 857     @Test
 858     public Object[] test33(Object[] va) {
 859         return va.clone();
 860     }
 861 
 862     @Run(test = "test33")
 863     public void test33_verifier() {
 864         int len = Math.abs(rI) % 10;
 865         Object[] va = new Object[len];
 866         for (int i = 0; i < len; ++i) {
 867             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 868         }
 869         Object[] result = test33(va);
 870         for (int i = 0; i < len; ++i) {
 871             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 872             // Check that array has correct properties (null-ok)
 873             result[i] = null;
 874         }
 875     }
 876 
 877     // clone() as series of loads/stores
 878     static Object[] test34_orig = null;
 879 
 880     @ForceInline
 881     public Object[] test34_helper(boolean flag) {
 882         Object[] va = null;
 883         if (flag) {
 884             va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
 885             for (int i = 0; i < va.length; ++i) {
 886                 va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 887             }
 888         } else {
 889             va = new Object[8];
 890         }
 891         return va;
 892     }
 893 
 894     @Test
 895     public Object[] test34(boolean flag) {
 896         Object[] va = test34_helper(flag);
 897         test34_orig = va;
 898         return va.clone();
 899     }
 900 
 901     @Run(test = "test34")
 902     public void test34_verifier(RunInfo info) {
 903         test34(false);
 904         for (int i = 0; i < 10; i++) { // make sure we do deopt
 905             Object[] result = test34(true);
 906             verify(test34_orig, result);
 907             // Check that array has correct properties (null-free)
 908             try {
 909                 result[0] = null;
 910                 throw new RuntimeException("Should throw NullPointerException");
 911             } catch (NullPointerException e) {
 912                 // Expected
 913             }
 914         }
 915         if (compile_and_run_again_if_deoptimized(info)) {
 916             Object[] result = test34(true);
 917             verify(test34_orig, result);
 918             // Check that array has correct properties (null-free)
 919             try {
 920                 result[0] = null;
 921                 throw new RuntimeException("Should throw NullPointerException");
 922             } catch (NullPointerException e) {
 923                 // Expected
 924             }
 925         }
 926     }
 927 
 928     // arraycopy() of value class array of unknown size
 929     @Test
 930     public void test35(Object src, Object dst, int len) {
 931         System.arraycopy(src, 0, dst, 0, len);
 932     }
 933 
 934     @Run(test = "test35")
 935     public void test35_verifier(RunInfo info) {
 936         int len = Math.abs(rI) % 10;
 937         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 938         MyValue1[] dst1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
 939         Object[] dst2 = new Object[len];
 940         for (int i = 0; i < len; ++i) {
 941             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 942         }
 943         test35(src, dst1, src.length);
 944         verify(src, dst1);
 945         test35(src, dst2, src.length);
 946         verify(src, dst2);
 947         if (compile_and_run_again_if_deoptimized(info)) {
 948             test35(src, dst1, src.length);
 949             verify(src, dst1);
 950         }
 951     }
 952 
 953     @Test
 954     public void test36(Object src, MyValue2[] dst) {
 955         System.arraycopy(src, 0, dst, 0, dst.length);
 956     }
 957 
 958     @Run(test = "test36")
 959     public void test36_verifier(RunInfo info) {
 960         int len = Math.abs(rI) % 10;
 961         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
 962         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
 963         for (int i = 0; i < len; ++i) {
 964             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 965         }
 966         test36(src, dst);
 967         verify(src, dst);
 968         if (compile_and_run_again_if_deoptimized(info)) {
 969             test36(src, dst);
 970             verify(src, dst);
 971         }
 972     }
 973 
 974     @Test
 975     public void test37(MyValue2[] src, Object dst) {
 976         System.arraycopy(src, 0, dst, 0, src.length);
 977     }
 978 
 979     @Run(test = "test37")
 980     public void test37_verifier(RunInfo info) {
 981         int len = Math.abs(rI) % 10;
 982         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
 983         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
 984         for (int i = 0; i < len; ++i) {
 985             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
 986         }
 987         test37(src, dst);
 988         verify(src, dst);
 989         if (compile_and_run_again_if_deoptimized(info)) {
 990             test37(src, dst);
 991             verify(src, dst);
 992         }
 993     }
 994 
 995     @Test
 996     public void test38(Object src, MyValue2[] dst) {
 997         System.arraycopy(src, 0, dst, 0, dst.length);
 998     }
 999 
1000     @Run(test = "test38")
1001     @Warmup(1) // Avoid early compilation
1002     public void test38_verifier(RunInfo info) {
1003         int len = Math.abs(rI) % 10;
1004         Object[] src = new Object[len];
1005         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1006         for (int i = 0; i < len; ++i) {
1007             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1008         }
1009         test38(src, dst);
1010         verify(dst, src);
1011         if (!info.isWarmUp()) {
1012             Method m = info.getTest();
1013             TestFramework.assertDeoptimizedByC2(m);
1014             TestFramework.compile(m, CompLevel.C2);
1015             test38(src, dst);
1016             verify(dst, src);
1017             TestFramework.assertCompiledByC2(m);
1018         }
1019     }
1020 
1021     @Test
1022     public void test39(MyValue2[] src, Object dst) {
1023         System.arraycopy(src, 0, dst, 0, src.length);
1024     }
1025 
1026     @Run(test = "test39")
1027     public void test39_verifier(RunInfo info) {
1028         int len = Math.abs(rI) % 10;
1029         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1030         Object[] dst = new Object[len];
1031         for (int i = 0; i < len; ++i) {
1032             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1033         }
1034         test39(src, dst);
1035         verify(src, dst);
1036         if (compile_and_run_again_if_deoptimized(info)) {
1037             test39(src, dst);
1038             verify(src, dst);
1039         }
1040     }
1041 
1042     @Test
1043     public void test40(Object[] src, Object dst) {
1044         System.arraycopy(src, 0, dst, 0, src.length);
1045     }
1046 
1047     @Run(test = "test40")
1048     @Warmup(1) // Avoid early compilation
1049     public void test40_verifier(RunInfo info) {
1050         int len = Math.abs(rI) % 10;
1051         Object[] src = new Object[len];
1052         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1053         for (int i = 0; i < len; ++i) {
1054             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1055         }
1056         test40(src, dst);
1057         verify(dst, src);
1058         if (!info.isWarmUp()) {
1059             Method m = info.getTest();
1060             TestFramework.assertDeoptimizedByC2(m);
1061             TestFramework.compile(m, CompLevel.C2);
1062             test40(src, dst);
1063             verify(dst, src);
1064             TestFramework.assertCompiledByC2(m);
1065         }
1066     }
1067 
1068     @Test
1069     public void test41(Object src, Object[] dst) {
1070         System.arraycopy(src, 0, dst, 0, dst.length);
1071     }
1072 
1073     @Run(test = "test41")
1074     public void test41_verifier(RunInfo info) {
1075         int len = Math.abs(rI) % 10;
1076         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1077         Object[] dst = new Object[len];
1078         for (int i = 0; i < len; ++i) {
1079             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1080         }
1081         test41(src, dst);
1082         verify(src, dst);
1083         if (compile_and_run_again_if_deoptimized(info)) {
1084             test41(src, dst);
1085             verify(src, dst);
1086         }
1087     }
1088 
1089     @Test
1090     public void test42(Object[] src, Object[] dst) {
1091         System.arraycopy(src, 0, dst, 0, src.length);
1092     }
1093 
1094     @Run(test = "test42")
1095     public void test42_verifier(RunInfo info) {
1096         int len = Math.abs(rI) % 10;
1097         Object[] src = new Object[len];
1098         Object[] dst = new Object[len];
1099         for (int i = 0; i < len; ++i) {
1100             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1101         }
1102         test42(src, dst);
1103         verify(src, dst);
1104         if (!info.isWarmUp()) {
1105             TestFramework.assertCompiledByC2(info.getTest());
1106         }
1107     }
1108 
1109     // short arraycopy()'s
1110     @Test
1111     public void test43(Object src, Object dst) {
1112         System.arraycopy(src, 0, dst, 0, 8);
1113     }
1114 
1115     @Run(test = "test43")
1116     public void test43_verifier(RunInfo info) {
1117         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
1118         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
1119         for (int i = 0; i < 8; ++i) {
1120             src[i] = MyValue1.createWithFieldsInline(rI, rL);
1121         }
1122         test43(src, dst);
1123         verify(src, dst);
1124         if (compile_and_run_again_if_deoptimized(info)) {
1125             test43(src, dst);
1126             verify(src, dst);
1127         }
1128     }
1129 
1130     @Test
1131     public void test44(Object src, MyValue2[] dst) {
1132         System.arraycopy(src, 0, dst, 0, 8);
1133     }
1134 
1135     @Run(test = "test44")
1136     public void test44_verifier(RunInfo info) {
1137         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1138         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1139         for (int i = 0; i < 8; ++i) {
1140             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1141         }
1142         test44(src, dst);
1143         verify(src, dst);
1144         if (compile_and_run_again_if_deoptimized(info)) {
1145             test44(src, dst);
1146             verify(src, dst);
1147         }
1148     }
1149 
1150     @Test
1151     public void test45(MyValue2[] src, Object dst) {
1152         System.arraycopy(src, 0, dst, 0, 8);
1153     }
1154 
1155     @Run(test = "test45")
1156     public void test45_verifier(RunInfo info) {
1157         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1158         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1159         for (int i = 0; i < 8; ++i) {
1160             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1161         }
1162         test45(src, dst);
1163         verify(src, dst);
1164         if (compile_and_run_again_if_deoptimized(info)) {
1165             test45(src, dst);
1166             verify(src, dst);
1167         }
1168     }
1169 
1170     @Test
1171     public void test46(Object[] src, MyValue2[] dst) {
1172         System.arraycopy(src, 0, dst, 0, 8);
1173     }
1174 
1175     @Run(test = "test46")
1176     @Warmup(1) // Avoid early compilation
1177     public void test46_verifier(RunInfo info) {
1178         Object[] src = new Object[8];
1179         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1180         for (int i = 0; i < 8; ++i) {
1181             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1182         }
1183         test46(src, dst);
1184         verify(dst, src);
1185         if (!info.isWarmUp()) {
1186             Method m = info.getTest();
1187             TestFramework.assertDeoptimizedByC2(m);
1188             TestFramework.compile(m, CompLevel.C2);
1189             test46(src, dst);
1190             verify(dst, src);
1191             TestFramework.assertCompiledByC2(m);
1192         }
1193     }
1194 
1195     @Test
1196     public void test47(MyValue2[] src, Object[] dst) {
1197         System.arraycopy(src, 0, dst, 0, 8);
1198     }
1199 
1200     @Run(test = "test47")
1201     public void test47_verifier(RunInfo info) {
1202         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1203         Object[] dst = new Object[8];
1204         for (int i = 0; i < 8; ++i) {
1205             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1206         }
1207         test47(src, dst);
1208         verify(src, dst);
1209         if (compile_and_run_again_if_deoptimized(info)) {
1210             test47(src, dst);
1211             verify(src, dst);
1212         }
1213     }
1214 
1215     @Test
1216     public void test48(Object[] src, Object dst) {
1217         System.arraycopy(src, 0, dst, 0, 8);
1218     }
1219 
1220     @Run(test = "test48")
1221     @Warmup(1) // Avoid early compilation
1222     public void test48_verifier(RunInfo info) {
1223         Object[] src = new Object[8];
1224         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1225         for (int i = 0; i < 8; ++i) {
1226             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1227         }
1228         test48(src, dst);
1229         verify(dst, src);
1230         if (!info.isWarmUp()) {
1231             Method m = info.getTest();
1232             TestFramework.assertDeoptimizedByC2(m);
1233             TestFramework.compile(m, CompLevel.C2);
1234             test48(src, dst);
1235             verify(dst, src);
1236             TestFramework.assertCompiledByC2(m);
1237         }
1238     }
1239 
1240     @Test
1241     public void test49(Object src, Object[] dst) {
1242         System.arraycopy(src, 0, dst, 0, 8);
1243     }
1244 
1245     @Run(test = "test49")
1246     public void test49_verifier(RunInfo info) {
1247         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
1248         Object[] dst = new Object[8];
1249         for (int i = 0; i < 8; ++i) {
1250             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1251         }
1252         test49(src, dst);
1253         verify(src, dst);
1254         if (compile_and_run_again_if_deoptimized(info)) {
1255             test49(src, dst);
1256             verify(src, dst);
1257         }
1258     }
1259 
1260     @Test
1261     public void test50(Object[] src, Object[] dst) {
1262         System.arraycopy(src, 0, dst, 0, 8);
1263     }
1264 
1265     @Run(test = "test50")
1266     public void test50_verifier(RunInfo info) {
1267         Object[] src = new Object[8];
1268         Object[] dst = new Object[8];
1269         for (int i = 0; i < 8; ++i) {
1270             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
1271         }
1272         test50(src, dst);
1273         verify(src, dst);
1274         if (!info.isWarmUp()) {
1275             Method m = info.getTest();
1276             TestFramework.assertCompiledByC2(m);
1277         }
1278     }
1279 
1280     @Test
1281     public MyValue1[] test51(MyValue1[] va) {
1282         Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class);
1283         return (MyValue1[]) res;
1284     }
1285 
1286     @Run(test = "test51")
1287     public void test51_verifier() {
1288         int len = Math.abs(rI) % 10;
1289         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1290         for (int i = 0; i < len; ++i) {
1291             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1292         }
1293         MyValue1[] result = test51(va);
1294         verify(va, result);
1295     }
1296 
1297     static final MyValue1[] test52_va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
1298 
1299     @Test
1300     public MyValue1[] test52() {
1301         Object[] res = Arrays.copyOf(test52_va, 8, MyValue1[].class);
1302         return (MyValue1[]) res;
1303     }
1304 
1305     @Run(test = "test52")
1306     public void test52_verifier() {
1307         for (int i = 0; i < 8; ++i) {
1308             test52_va[i] = MyValue1.createWithFieldsInline(rI, rL);
1309         }
1310         MyValue1[] result = test52();
1311         verify(test52_va, result);
1312     }
1313 
1314     @Test
1315     public MyValue1[] test53(Object[] va) {
1316         Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class);
1317         return (MyValue1[]) res;
1318     }
1319 
1320     @Run(test = "test53")
1321     public void test53_verifier() {
1322         int len = Math.abs(rI) % 10;
1323         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1324         for (int i = 0; i < len; ++i) {
1325             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1326         }
1327         MyValue1[] result = test53(va);
1328         verify(result, va);
1329     }
1330 
1331     @Test
1332     public Object[] test54(MyValue1[] va) {
1333         return Arrays.copyOf(va, va.length, Object[].class);
1334     }
1335 
1336     @Run(test = "test54")
1337     public void test54_verifier() {
1338         int len = Math.abs(rI) % 10;
1339         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1340         for (int i = 0; i < len; ++i) {
1341             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1342         }
1343         Object[] result = test54(va);
1344         verify(va, result);
1345     }
1346 
1347     @Test
1348     public Object[] test55(Object[] va) {
1349         return Arrays.copyOf(va, va.length, Object[].class);
1350     }
1351 
1352     @Run(test = "test55")
1353     public void test55_verifier() {
1354         int len = Math.abs(rI) % 10;
1355         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1356         for (int i = 0; i < len; ++i) {
1357             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1358         }
1359         Object[] result = test55(va);
1360         verify(va, result);
1361     }
1362 
1363     @Test
1364     public MyValue1[] test56(Object[] va) {
1365         Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class);
1366         return (MyValue1[]) res;
1367     }
1368 
1369     @Run(test = "test56")
1370     public void test56_verifier() {
1371         int len = Math.abs(rI) % 10;
1372         Object[] va = new Object[len];
1373         for (int i = 0; i < len; ++i) {
1374             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1375         }
1376         MyValue1[] result = test56(va);
1377         verify(result, va);
1378     }
1379 
1380     @Test
1381     public Object[] test57(Object[] va, Class klass) {
1382         return Arrays.copyOf(va, va.length, klass);
1383     }
1384 
1385     @Run(test = "test57")
1386     public void test57_verifier() {
1387         int len = Math.abs(rI) % 10;
1388         Object[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1389         for (int i = 0; i < len; ++i) {
1390             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1391         }
1392         Object[] result = test57(va, MyValue1[].class);
1393         verify(va, result);
1394     }
1395 
1396     @Test
1397     public Object[] test58(MyValue1[] va, Class klass) {
1398         return Arrays.copyOf(va, va.length, klass);
1399     }
1400 
1401     @Run(test = "test58")
1402     public void test58_verifier(RunInfo info) {
1403         int len = Math.abs(rI) % 10;
1404         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1405         for (int i = 0; i < len; ++i) {
1406             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1407         }
1408         for (int i = 0; i < 10; i++) {
1409             Object[] result = test58(va, MyValue1[].class);
1410             verify(va, result);
1411         }
1412         if (compile_and_run_again_if_deoptimized(info)) {
1413             Object[] result = test58(va, MyValue1[].class);
1414             verify(va, result);
1415         }
1416     }
1417 
1418     @Test
1419     public Object[] test59(MyValue1[] va) {
1420         return Arrays.copyOf(va, va.length+1, va.getClass());
1421     }
1422 
1423     @Run(test = "test59")
1424     public void test59_verifier() {
1425         int len = Math.abs(rI) % 10;
1426         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1427         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1);
1428         for (int i = 0; i < len; ++i) {
1429             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1430             verif[i] = va[i];
1431         }
1432         Object[] result = test59(va);
1433         // Result is a null-restricted array
1434         Asserts.assertEQ(result[len], ValueClass.zeroInstance(MyValue1.class));
1435         result[len] = MyValue1.createDefaultInline();
1436         verify(verif, result);
1437     }
1438 
1439     @Test
1440     public Object[] test60(Object[] va, Class klass) {
1441         return Arrays.copyOf(va, va.length+1, klass);
1442     }
1443 
1444     @Run(test = "test60")
1445     public void test60_verifier() {
1446         int len = Math.abs(rI) % 10;
1447         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1448         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1);
1449         for (int i = 0; i < len; ++i) {
1450             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1451             verif[i] = (MyValue1)va[i];
1452         }
1453         Object[] result = test60(va, va.getClass());
1454         // Result is a null-restricted array
1455         Asserts.assertEQ(result[len], ValueClass.zeroInstance(MyValue1.class));
1456         result[len] = MyValue1.createDefaultInline();
1457         verify(verif, result);
1458     }
1459 
1460     @Test
1461     public Object[] test61(Object[] va, Class klass) {
1462         return Arrays.copyOf(va, va.length+1, klass);
1463     }
1464 
1465     @Run(test = "test61")
1466     public void test61_verifier() {
1467         int len = Math.abs(rI) % 10;
1468         Object[] va = new NonValueClass[len];
1469         for (int i = 0; i < len; ++i) {
1470             va[i] = new NonValueClass(rI);
1471         }
1472         Object[] result = test61(va, NonValueClass[].class);
1473         for (int i = 0; i < va.length; ++i) {
1474             Asserts.assertEQ(va[i], result[i]);
1475         }
1476     }
1477 
1478     @ForceInline
1479     public Object[] test62_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1480         Object[] arr = null;
1481         if (i == 10) {
1482             arr = oa;
1483         } else {
1484             arr = va;
1485         }
1486         return arr;
1487     }
1488 
1489     @Test
1490     public Object[] test62(MyValue1[] va, NonValueClass[] oa) {
1491         int i = 0;
1492         for (; i < 10; i++);
1493 
1494         Object[] arr = test62_helper(i, va, oa);
1495 
1496         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1497     }
1498 
1499     @Run(test = "test62")
1500     public void test62_verifier() {
1501         int len = Math.abs(rI) % 10;
1502         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1503         NonValueClass[] oa = new NonValueClass[len];
1504         for (int i = 0; i < len; ++i) {
1505             oa[i] = new NonValueClass(rI);
1506         }
1507         test62_helper(42, va, oa);
1508         Object[] result = test62(va, oa);
1509         for (int i = 0; i < va.length; ++i) {
1510             Asserts.assertEQ(oa[i], result[i]);
1511         }
1512     }
1513 
1514     @ForceInline
1515     public Object[] test63_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1516         Object[] arr = null;
1517         if (i == 10) {
1518             arr = va;
1519         } else {
1520             arr = oa;
1521         }
1522         return arr;
1523     }
1524 
1525     @Test
1526     public Object[] test63(MyValue1[] va, NonValueClass[] oa) {
1527         int i = 0;
1528         for (; i < 10; i++);
1529 
1530         Object[] arr = test63_helper(i, va, oa);
1531 
1532         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1533     }
1534 
1535     @Run(test = "test63")
1536     public void test63_verifier() {
1537         int len = Math.abs(rI) % 10;
1538         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1539         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1);
1540         for (int i = 0; i < len; ++i) {
1541             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1542             verif[i] = va[i];
1543         }
1544         NonValueClass[] oa = new NonValueClass[len];
1545         test63_helper(42, va, oa);
1546         Object[] result = test63(va, oa);
1547         // Result is a null-restricted array
1548         Asserts.assertEQ(result[len], MyValue1.createDefaultInline());
1549         result[len] = MyValue1.createDefaultInline();
1550         verify(verif, result);
1551     }
1552 
1553     // Test default initialization of value class arrays: small array
1554     @Test
1555     public MyValue1[] test64() {
1556         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
1557     }
1558 
1559     @Run(test = "test64")
1560     public void test64_verifier() {
1561         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
1562         MyValue1[] var = test64();
1563         for (int i = 0; i < 8; ++i) {
1564             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1565         }
1566     }
1567 
1568     // Test default initialization of value class arrays: large array
1569     @Test
1570     public MyValue1[] test65() {
1571         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 32);
1572     }
1573 
1574     @Run(test = "test65")
1575     public void test65_verifier() {
1576         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 32);
1577         MyValue1[] var = test65();
1578         for (int i = 0; i < 32; ++i) {
1579             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1580         }
1581     }
1582 
1583     // Check init store elimination
1584     @Test
1585     @IR(counts = {ALLOCA, "= 1"})
1586     public MyValue1[] test66(MyValue1 vt) {
1587         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
1588         va[0] = vt;
1589         return va;
1590     }
1591 
1592     @Run(test = "test66")
1593     public void test66_verifier() {
1594         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1595         MyValue1[] va = test66(vt);
1596         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1597     }
1598 
1599     // Zeroing elimination and arraycopy
1600     @Test
1601     public MyValue1[] test67(MyValue1[] src) {
1602         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 16);
1603         System.arraycopy(src, 0, dst, 0, 13);
1604         return dst;
1605     }
1606 
1607     @Run(test = "test67")
1608     public void test67_verifier() {
1609         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 16);
1610         MyValue1[] var = test67(va);
1611         for (int i = 0; i < 16; ++i) {
1612             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1613         }
1614     }
1615 
1616     // A store with a default value can be eliminated
1617     @Test
1618     public MyValue1[] test68() {
1619         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1620         va[0] = va[1];
1621         return va;
1622     }
1623 
1624     @Run(test = "test68")
1625     public void test68_verifier() {
1626         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1627         MyValue1[] var = test68();
1628         for (int i = 0; i < 2; ++i) {
1629             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1630         }
1631     }
1632 
1633     // Requires individual stores to init array
1634     @Test
1635     public MyValue1[] test69(MyValue1 vt) {
1636         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 4);
1637         va[0] = vt;
1638         va[3] = vt;
1639         return va;
1640     }
1641 
1642     @Run(test = "test69")
1643     public void test69_verifier() {
1644         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1645         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 4);
1646         va[0] = vt;
1647         va[3] = vt;
1648         MyValue1[] var = test69(vt);
1649         for (int i = 0; i < va.length; ++i) {
1650             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1651         }
1652     }
1653 
1654     // A store with a default value can be eliminated: same as test68
1655     // but store is further away from allocation
1656     @Test
1657     public MyValue1[] test70(MyValue1[] other) {
1658         other[1] = other[0];
1659         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1660         other[0] = va[1];
1661         va[0] = va[1];
1662         return va;
1663     }
1664 
1665     @Run(test = "test70")
1666     public void test70_verifier() {
1667         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1668         MyValue1[] var = test70(va);
1669         for (int i = 0; i < 2; ++i) {
1670             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1671         }
1672     }
1673 
1674     // EA needs to consider oop fields in flattened arrays
1675     @Test
1676     public void test71() {
1677         int len = 10;
1678         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1679         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1680         for (int i = 0; i < len; ++i) {
1681             src[i] = MyValue2.createWithFieldsDontInline(rI+i, rD+i);
1682         }
1683         System.arraycopy(src, 0, dst, 0, src.length);
1684         for (int i = 0; i < len; ++i) {
1685             Asserts.assertEQ(src[i].hash(), dst[i].hash());
1686         }
1687     }
1688 
1689     @Run(test = "test71")
1690     public void test71_verifier() {
1691         test71();
1692     }
1693 
1694     // Test EA with leaf call to 'store_unknown_inline'
1695     @Test
1696     public void test72(Object[] o, boolean b, Object element) {
1697         Object[] arr1 = new Object[10];
1698         Object[] arr2 = new Object[10];
1699         if (b) {
1700             arr1 = o;
1701         }
1702         arr1[0] = element;
1703         arr2[0] = element;
1704     }
1705 
1706     @Run(test = "test72")
1707     public void test72_verifier() {
1708         Object[] arr = new Object[1];
1709         Object elem = new Object();
1710         test72(arr, true, elem);
1711         test72(arr, false, elem);
1712     }
1713 
1714     @Test
1715     public void test73(Object[] oa, MyValue1 v, Object o) {
1716         // TestLWorld.test38 use a C1 Phi node for the array. This test
1717         // adds the case where the stored value is a C1 Phi node.
1718         Object o2 = (o == null) ? v : o;
1719         oa[0] = v;  // The stored value is known to be flattenable
1720         oa[1] = o;  // The stored value may be flattenable
1721         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1722         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1723     }
1724 
1725     @Run(test = "test73")
1726     public void test73_verifier() {
1727         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1728         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1729         MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 3);
1730         try {
1731             test73(arr, v0, v1);
1732             throw new RuntimeException("ArrayStoreException expected");
1733         } catch (ArrayStoreException e) {
1734             // expected
1735         }
1736         Asserts.assertEQ(arr[0].hash(), v0.hash());
1737         Asserts.assertEQ(arr[1].hash(), v1.hash());
1738         Asserts.assertEQ(arr[2].hash(), v1.hash());
1739     }
1740 
1741     public static void test74Callee(MyValue1[] va) { }
1742 
1743     // Tests invoking unloaded method with value class array in signature
1744     @Test
1745     public void test74(MethodHandle m, MyValue1[] va) throws Throwable {
1746         m.invoke(va);
1747     }
1748 
1749     @Run(test = "test74")
1750     @Warmup(0)
1751     public void test74_verifier() throws Throwable {
1752         MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class));
1753         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0);
1754         test74(m, va);
1755     }
1756 
1757     // Some more array clone tests
1758     @ForceInline
1759     public Object[] test75_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1760         Object[] arr = null;
1761         if (i == 10) {
1762             arr = oa;
1763         } else {
1764             arr = va;
1765         }
1766         return arr;
1767     }
1768 
1769     @Test
1770     public Object[] test75(MyValue1[] va, NonValueClass[] oa) {
1771         int i = 0;
1772         for (; i < 10; i++);
1773 
1774         Object[] arr = test75_helper(i, va, oa);
1775         return arr.clone();
1776     }
1777 
1778     @Run(test = "test75")
1779     public void test75_verifier() {
1780         int len = Math.abs(rI) % 10;
1781         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1782         NonValueClass[] oa = new NonValueClass[len];
1783         for (int i = 0; i < len; ++i) {
1784             oa[i] = new NonValueClass(rI);
1785         }
1786         test75_helper(42, va, oa);
1787         Object[] result = test75(va, oa);
1788 
1789         for (int i = 0; i < va.length; ++i) {
1790             Asserts.assertEQ(oa[i], result[i]);
1791             // Check that array has correct properties (null-ok)
1792             result[i] = null;
1793         }
1794     }
1795 
1796     @ForceInline
1797     public Object[] test76_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1798         Object[] arr = null;
1799         if (i == 10) {
1800             arr = va;
1801         } else {
1802             arr = oa;
1803         }
1804         return arr;
1805     }
1806 
1807     @Test
1808     public Object[] test76(MyValue1[] va, NonValueClass[] oa) {
1809         int i = 0;
1810         for (; i < 10; i++);
1811 
1812         Object[] arr = test76_helper(i, va, oa);
1813         return arr.clone();
1814     }
1815 
1816     @Run(test = "test76")
1817     public void test76_verifier() {
1818         int len = Math.abs(rI) % 10;
1819         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1820         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1821         for (int i = 0; i < len; ++i) {
1822             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1823             verif[i] = va[i];
1824         }
1825         NonValueClass[] oa = new NonValueClass[len];
1826         test76_helper(42, va, oa);
1827         Object[] result = test76(va, oa);
1828         verify(verif, result);
1829         // Check that array has correct properties (null-free)
1830         if (len > 0) {
1831             try {
1832                 result[0] = null;
1833                 throw new RuntimeException("Should throw NullPointerException");
1834             } catch (NullPointerException e) {
1835                 // Expected
1836             }
1837         }
1838     }
1839 
1840     @Test
1841     public void test77() {
1842         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1843         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1844         MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
1845 
1846         Object[] oa = arr;
1847         Object o1 = v1;
1848         Object o = (o1 == null) ? v0 : o1;
1849 
1850         oa[0] = o; // For C1, due to IfOp optimization, the declared_type of o becomes NULL.
1851 
1852         Asserts.assertEQ(arr[0].hash(), v1.hash());
1853     }
1854 
1855 
1856     @Run(test = "test77")
1857     public void test77_verifier() {
1858         test77();
1859     }
1860 
1861     @Test
1862     public long test78(MyValue1 v, int n) {
1863         long x = 0;
1864         for (int i = 0; i < n; i++) {
1865         }
1866 
1867         MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, n);
1868         a[0] = v;
1869         for (int i = 0; i<n; i++) {
1870             x += a[i].hash(); // C1 PhiSimplifier changes "a" from a Phi node to a NewObjectArray node
1871         }
1872 
1873         return x;
1874     }
1875 
1876     @Run(test = "test78")
1877     public void test78_verifier() {
1878         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1879         Asserts.assertEQ(test78(v, 1), v.hash());
1880     }
1881 
1882     // Verify that casting an array element to a non-flattenable type marks the array as not-flat
1883     @Test
1884     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
1885         counts = {LOAD_UNKNOWN_INLINE, "= 1"})
1886     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
1887         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE})
1888     public Object test79(Object[] array, int i) {
1889         NonValueClass i1 = (NonValueClass)array[0];
1890         Object o = array[1];
1891         return array[i];
1892     }
1893 
1894     @Run(test = "test79")
1895     public void test79_verifier() {
1896         NonValueClass obj = new NonValueClass(rI);
1897         NonValueClass[] array = new NonValueClass[2];
1898         array[1] = obj;
1899         Object result = test79(array, 1);
1900         Asserts.assertEquals(result, obj);
1901     }
1902 
1903     // Same as test79 but with not-flattenable value class
1904     @Test
1905     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
1906         counts = {LOAD_UNKNOWN_INLINE, "= 1"})
1907     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
1908         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE})
1909     public Object test80(Object[] array, int i) {
1910         NotFlattenable vt = (NotFlattenable)array[0];
1911         Object o = array[1];
1912         return array[i];
1913     }
1914 
1915     @Run(test = "test80")
1916     public void test80_verifier() {
1917         NotFlattenable vt = new NotFlattenable();
1918         NotFlattenable[] array = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
1919         array[1] = vt;
1920         Object result = test80(array, 1);
1921         Asserts.assertEquals(result, vt);
1922     }
1923 
1924     // 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
1925     @Test
1926     @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1927     public Object test81(Object[] array, NonValueClass v, Object o, int i) {
1928         if (v == null) {
1929           return null;
1930         }
1931         array[0] = v;
1932         array[1] = array[0];
1933         array[2] = o;
1934         return array[i];
1935     }
1936 
1937     @Run(test = "test81")
1938     public void test81_verifier() {
1939         NonValueClass obj = new NonValueClass(rI);
1940         NonValueClass[] array1 = new NonValueClass[3];
1941         Object[] array2 = new Object[3];
1942         Object result = test81(array1, obj, obj, 0);
1943         Asserts.assertEquals(array1[0], obj);
1944         Asserts.assertEquals(array1[1], obj);
1945         Asserts.assertEquals(array1[2], obj);
1946         Asserts.assertEquals(result, obj);
1947         result = test81(array2, obj, obj, 1);
1948         Asserts.assertEquals(array2[0], obj);
1949         Asserts.assertEquals(array2[1], obj);
1950         Asserts.assertEquals(array2[2], obj);
1951         Asserts.assertEquals(result, obj);
1952     }
1953 
1954     // Verify that writing an object of a non-flattenable value class to an array marks the array as not-flat
1955     @Test
1956     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
1957         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE})
1958     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
1959         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE})
1960     public Object test82(Object[] array, NotFlattenable vt, Object o, int i) {
1961         array[0] = vt;
1962         array[1] = array[0];
1963         array[2] = o;
1964         return array[i];
1965     }
1966 
1967     @Run(test = "test82")
1968     public void test82_verifier() {
1969         NotFlattenable vt = new NotFlattenable();
1970         NotFlattenable[] array1 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 3);
1971         Object[] array2 = new Object[3];
1972         Object result = test82(array1, vt, vt, 0);
1973         Asserts.assertEquals(array1[0], vt);
1974         Asserts.assertEquals(array1[1], vt);
1975         Asserts.assertEquals(array1[2], vt);
1976         Asserts.assertEquals(result, vt);
1977         result = test82(array2, vt, vt, 1);
1978         Asserts.assertEquals(array2[0], vt);
1979         Asserts.assertEquals(array2[1], vt);
1980         Asserts.assertEquals(array2[2], vt);
1981         Asserts.assertEquals(result, vt);
1982     }
1983 
1984     // Verify that casting an array element to a non-value class type type marks the array as not-null-free and not-flat
1985     @Test
1986     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
1987         counts = {LOAD_UNKNOWN_INLINE, "= 1"},
1988         failOn = {ALLOCA_G, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1989     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
1990             failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1991     public void test83(Object[] array, Object o) {
1992         NonValueClass i = (NonValueClass)array[0];
1993         array[1] = o;
1994     }
1995 
1996     @Run(test = "test83")
1997     public void test83_verifier() {
1998         NonValueClass obj = new NonValueClass(rI);
1999         NonValueClass[] array1 = new NonValueClass[2];
2000         Object[] array2 = new Object[2];
2001         test83(array1, obj);
2002         Asserts.assertEquals(array1[1], obj);
2003         test83(array2, null);
2004         Asserts.assertEquals(array2[1], null);
2005     }
2006 
2007     // Verify that writing constant null into an array marks the array as not-null-free and not-flat
2008     @Test
2009     @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2010         counts = {INLINE_ARRAY_NULL_GUARD, "= 1"})
2011     public Object test84(Object[] array, int i) {
2012         array[0] = null;
2013         array[1] = null;
2014         return array[i];
2015     }
2016 
2017     @Run(test = "test84")
2018     public void test84_verifier(RunInfo info) {
2019         NotFlattenable[] array1 = new NotFlattenable[2];
2020         Object[] array2 = new Object[2];
2021         Object result = test84(array1, 0);
2022         Asserts.assertEquals(array1[0], null);
2023         Asserts.assertEquals(result, null);
2024         result = test84(array2, 1);
2025         Asserts.assertEquals(array2[0], null);
2026         Asserts.assertEquals(result, null);
2027         if (!info.isWarmUp()) {
2028             NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
2029             try {
2030                 test84(array3, 1);
2031                 throw new RuntimeException("Should throw NullPointerException");
2032             } catch (NullPointerException e) {
2033                 // Expected
2034             }
2035         }
2036     }
2037 
2038     // Same as test84 but with branches
2039     @Test
2040     @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2041         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2042     public void test85(Object[] array, Object o, boolean b) {
2043         if (b) {
2044             array[0] = null;
2045         } else {
2046             array[1] = null;
2047         }
2048         array[1] = o;
2049     }
2050 
2051     @Run(test = "test85")
2052     public void test85_verifier(RunInfo info) {
2053         NonValueClass obj = new NonValueClass(rI);
2054         NonValueClass[] array1 = new NonValueClass[2];
2055         Object[] array2 = new Object[2];
2056         test85(array1, obj, true);
2057         Asserts.assertEquals(array1[1], obj);
2058         test85(array1, null, false);
2059         Asserts.assertEquals(array1[1], null);
2060         test85(array2, obj, true);
2061         Asserts.assertEquals(array2[1], obj);
2062         test85(array2, null, false);
2063         Asserts.assertEquals(array2[1], null);
2064         if (!info.isWarmUp()) {
2065             NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
2066             try {
2067                 test85(array3, null, true);
2068                 throw new RuntimeException("Should throw NullPointerException");
2069             } catch (NullPointerException e) {
2070                 // Expected
2071             }
2072         }
2073     }
2074 
2075     // Same as test85 but with not-flattenable value class array
2076     @Test
2077     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2078         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2079         counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"})
2080     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2081         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2082         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2083     public void test86(NotFlattenable[] array, NotFlattenable o, boolean b) {
2084         if (b) {
2085             array[0] = null;
2086         } else {
2087             array[1] = null;
2088         }
2089         array[1] = o;
2090     }
2091 
2092     @Run(test = "test86")
2093     public void test86_verifier(RunInfo info) {
2094         NotFlattenable vt = new NotFlattenable();
2095         NotFlattenable[] array1 = new NotFlattenable[2];
2096         test86(array1, vt, true);
2097         Asserts.assertEquals(array1[1], vt);
2098         test86(array1, null, false);
2099         Asserts.assertEquals(array1[1], null);
2100         if (!info.isWarmUp()) {
2101             NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
2102             try {
2103                 test86(array2, null, true);
2104                 throw new RuntimeException("Should throw NullPointerException");
2105             } catch (NullPointerException e) {
2106                 // Expected
2107             }
2108         }
2109     }
2110 
2111     // Same as test85 but with value class array
2112     @Test
2113     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2114         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2115         counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"})
2116     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2117         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2118         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2119     public void test87(MyValue1[] array, MyValue1 o, boolean b) {
2120         if (b) {
2121             array[0] = null;
2122         } else {
2123             array[1] = null;
2124         }
2125         array[1] = o;
2126     }
2127 
2128     @Run(test = "test87")
2129     public void test87_verifier(RunInfo info) {
2130         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2131         MyValue1[] array1 = new MyValue1[2];
2132         test87(array1, vt, true);
2133         Asserts.assertEquals(array1[1], vt);
2134         test87(array1, null, false);
2135         Asserts.assertEquals(array1[1], null);
2136         if (!info.isWarmUp()) {
2137             MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
2138             try {
2139                 test87(array2, null, true);
2140                 throw new RuntimeException("Should throw NullPointerException");
2141             } catch (NullPointerException e) {
2142                 // Expected
2143             }
2144         }
2145     }
2146 
2147     // Additional correctness tests to make sure we have the required null checks
2148     @Test
2149     public void test88(Object[] array, NonValueClass v) {
2150         array[0] = v;
2151     }
2152 
2153     @Run(test = "test88")
2154     public void test88_verifier(RunInfo info) {
2155         NonValueClass[] array1 = new NonValueClass[1];
2156         Object[] array2 = new Object[1];
2157         test88(array1, null);
2158         Asserts.assertEquals(array1[0], null);
2159         test88(array2, null);
2160         Asserts.assertEquals(array2[0], null);
2161         if (!info.isWarmUp()) {
2162             MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2163             try {
2164                 test88(array3, null);
2165                 throw new RuntimeException("Should throw NullPointerException");
2166             } catch (NullPointerException e) {
2167                 // Expected
2168             }
2169         }
2170     }
2171 
2172     @Test
2173     public void test89(MyValue1[] array, NonValueClass v) {
2174         Object o = v;
2175         array[0] = (MyValue1)o;
2176     }
2177 
2178     @Run(test = "test89")
2179     public void test89_verifier(RunInfo info) {
2180         MyValue1[] array1 = new MyValue1[1];
2181         test89(array1, null);
2182         Asserts.assertEquals(array1[0], null);
2183         if (!info.isWarmUp()) {
2184             MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2185             try {
2186                 test89(array2, null);
2187                 throw new RuntimeException("Should throw NullPointerException");
2188             } catch (NullPointerException e) {
2189                 // Expected
2190             }
2191         }
2192     }
2193 
2194     @Test
2195     public boolean test90() {
2196         boolean b = true;
2197 
2198         MyValue1[] qArray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0);
2199         MyValue1[] lArray = new MyValue1[0];
2200 
2201         b = b && (qArray instanceof MyValue1[]);
2202         b = b && (lArray instanceof MyValue1[]);
2203 
2204         MyValue1[][] qArray2 = { (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0) };
2205         MyValue1[][] lArray2 = new MyValue1[0][0];
2206 
2207         b = b && (qArray2 instanceof MyValue1[][]);
2208         b = b && (lArray2 instanceof MyValue1[][]);
2209 
2210         return b;
2211     }
2212 
2213     @Run(test = "test90")
2214     public void test90_verifier() {
2215         Asserts.assertEQ(test90(), true);
2216     }
2217 
2218     @ImplicitlyConstructible
2219     @LooselyConsistentValue
2220     static value class Test91Value {
2221         public int f0;
2222         public int f1;
2223         public int f2;
2224         public int f3;
2225         public int f4;
2226         public int f5;
2227 
2228         public Test91Value(int i) {
2229             this.f0 = i;
2230             this.f1 = i;
2231             this.f2 = i;
2232             this.f3 = i;
2233             this.f4 = i;
2234             this.f5 = i;
2235         }
2236 
2237         public void verify() {
2238             if ((f0 != f1) || (f1 != f2) || (f2 != f3) || (f3 != f4) || (f4 != f5)) {
2239                 throw new RuntimeException("test91 failed");
2240             }
2241         }
2242     }
2243 
2244     // Test anti-dependencies between loads and stores from flattened array
2245     @Test
2246     public int test91(Test91Value[] array, int lo, int val) {
2247         int i = 3;
2248         while (lo < i) {
2249             Test91Value tmp = array[lo];
2250             array[lo++] = array[i];
2251             array[i--] = tmp;
2252         }
2253         return val;
2254     }
2255 
2256     @Run(test = "test91")
2257     @Warmup(0)
2258     public void test91_verifier() {
2259         Test91Value[] array = (Test91Value[])ValueClass.newNullRestrictedArray(Test91Value.class, 5);
2260         for (int i = 0; i < 5; ++i) {
2261             array[i] = new Test91Value(i);
2262             array[i].verify();
2263         }
2264         Asserts.assertEQ(test91(array, 0, 5), 5);
2265         for (int i = 0; i < 5; ++i) {
2266             array[i].verify();
2267         }
2268     }
2269 
2270     @Test
2271     public void test92(Object[] src, Object[] dst) {
2272         System.arraycopy(src, 0, dst, 0, src.length);
2273     }
2274 
2275     @Run(test = "test92")
2276     public void test92_verifier() {
2277         MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2278         MyValue1[] b = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2279         try {
2280             test92(a, null);
2281             throw new RuntimeException("Should throw NullPointerException");
2282         } catch (NullPointerException expected) {}
2283 
2284         try {
2285             test92(null, b);
2286             throw new RuntimeException("Should throw NullPointerException");
2287         } catch (NullPointerException expected) {}
2288 
2289         a[0] = MyValue1.createWithFieldsInline(rI, rL);
2290         test92(a, b);
2291         verify(a, b);
2292     }
2293 
2294     // Same as test30 but accessing all elements of the non-escaping array
2295     @Test
2296     public long test93(MyValue2[] src, boolean flag) {
2297         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2298         System.arraycopy(src, 0, dst, 0, 10);
2299         if (flag) {  }
2300         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2301                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2302     }
2303 
2304     @Run(test = "test93")
2305     @Warmup(10000)
2306     public void test93_verifier(RunInfo info) {
2307         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2308         for (int i = 0; i < 10; ++i) {
2309             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2310         }
2311         long res = test93(src, !info.isWarmUp());
2312         long expected = 0;
2313         for (int i = 0; i < 10; ++i) {
2314             expected += src[i].hash();
2315         }
2316         Asserts.assertEQ(res, expected);
2317     }
2318 
2319     // Same as test93 but with variable source array offset
2320     @Test
2321     public long test94(MyValue2[] src, int i, boolean flag) {
2322         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2323         System.arraycopy(src, i, dst, 0, 1);
2324         if (flag) {  }
2325         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2326                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2327     }
2328 
2329     @Run(test = "test94")
2330     @Warmup(10000)
2331     public void test94_verifier(RunInfo info) {
2332         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2333         for (int i = 0; i < 10; ++i) {
2334             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2335         }
2336         for (int i = 0; i < 10; ++i) {
2337             long res = test94(src, i, !info.isWarmUp());
2338             long expected = src[i].hash() + 9*MyValue2.createDefaultInline().hash();
2339             Asserts.assertEQ(res, expected);
2340         }
2341     }
2342 
2343     static final MyValue1[] nullFreeArray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2344 
2345     // Test propagation of not null-free/flat information
2346     @Test
2347     @IR(failOn = CHECKCAST_ARRAY)
2348     public MyValue1[] test95(Object[] array) {
2349         array[0] = null;
2350         // Always throws a ClassCastException because we just successfully
2351         // stored null and therefore the array can't be a null-free value class array.
2352         return nullFreeArray.getClass().cast(array);
2353     }
2354 
2355     @Run(test = "test95")
2356     public void test95_verifier() {
2357         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2358         NonValueClass[] array2 = new NonValueClass[1];
2359         try {
2360             test95(array1);
2361             throw new RuntimeException("Should throw NullPointerException");
2362         } catch (NullPointerException e) {
2363             // Expected
2364         }
2365         try {
2366             test95(array2);
2367             throw new RuntimeException("Should throw ClassCastException");
2368         } catch (ClassCastException e) {
2369             // Expected
2370         }
2371     }
2372 
2373     // Same as test95 but with cmp user of cast result
2374     @Test
2375     @IR(failOn = CHECKCAST_ARRAY)
2376     public boolean test96(Object[] array) {
2377         array[0] = null;
2378         // Always throws a ClassCastException because we just successfully
2379         // stored null and therefore the array can't be a null-free value class array.
2380         MyValue1[] casted = nullFreeArray.getClass().cast(array);
2381         return casted != null;
2382     }
2383 
2384     @Run(test = "test96")
2385     public void test96_verifier() {
2386         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2387         NonValueClass[] array2 = new NonValueClass[1];
2388         try {
2389             test96(array1);
2390             throw new RuntimeException("Should throw NullPointerException");
2391         } catch (NullPointerException e) {
2392             // Expected
2393         }
2394         try {
2395             test96(array2);
2396             throw new RuntimeException("Should throw ClassCastException");
2397         } catch (ClassCastException e) {
2398             // Expected
2399         }
2400     }
2401 
2402     // Same as test95 but with instanceof instead of cast
2403     @Test
2404     @IR(failOn = CHECKCAST_ARRAY)
2405     public boolean test97(Object[] array) {
2406         array[0] = new NonValueClass(42);
2407         // Always throws a ClassCastException because we just successfully stored
2408         // a non-value type value and therefore the array can't be a value class array.
2409         return array instanceof MyValue1[];
2410     }
2411 
2412     @Run(test = "test97")
2413     public void test97_verifier() {
2414         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2415         NonValueClass[] array2 = new NonValueClass[1];
2416         try {
2417             test97(array1);
2418             throw new RuntimeException("Should throw ArrayStoreException");
2419         } catch (ArrayStoreException e) {
2420             // Expected
2421         }
2422         boolean res = test97(array2);
2423         Asserts.assertFalse(res);
2424     }
2425 
2426     // Same as test95 but with non-flattenable store
2427     @Test
2428     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2429         failOn = CHECKCAST_ARRAY)
2430     public MyValue1[] test98(Object[] array) {
2431         array[0] = new NotFlattenable();
2432         // Always throws a ClassCastException because we just successfully stored a
2433         // non-flattenable value and therefore the array can't be a flat array.
2434         return (MyValue1[])array;
2435     }
2436 
2437     @Run(test = "test98")
2438     public void test98_verifier() {
2439         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2440         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2441         try {
2442             test98(array1);
2443             throw new RuntimeException("Should throw ArrayStoreException");
2444         } catch (ArrayStoreException e) {
2445             // Expected
2446         }
2447         try {
2448             test98(array2);
2449             throw new RuntimeException("Should throw ClassCastException");
2450         } catch (ClassCastException e) {
2451             // Expected
2452         }
2453     }
2454 
2455     // Same as test98 but with cmp user of cast result
2456     @Test
2457     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2458         failOn = CHECKCAST_ARRAY)
2459     public boolean test99(Object[] array) {
2460         array[0] = new NotFlattenable();
2461         // Always throws a ClassCastException because we just successfully stored a
2462         // non-flattenable value and therefore the array can't be a flat array.
2463         MyValue1[] casted = (MyValue1[])array;
2464         return casted != null;
2465     }
2466 
2467     @Run(test = "test99")
2468     public void test99_verifier() {
2469         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2470         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2471         try {
2472             test99(array1);
2473             throw new RuntimeException("Should throw ArrayStoreException");
2474         } catch (ArrayStoreException e) {
2475             // Expected
2476         }
2477         try {
2478             test99(array2);
2479             throw new RuntimeException("Should throw ClassCastException");
2480         } catch (ClassCastException e) {
2481             // Expected
2482         }
2483     }
2484 
2485     // Same as test98 but with instanceof instead of cast
2486     @Test
2487     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2488         failOn = CHECKCAST_ARRAY)
2489     public boolean test100(Object[] array) {
2490         array[0] = new NotFlattenable();
2491         // Always throws a ClassCastException because we just successfully stored a
2492         // non-flattenable value and therefore the array can't be a flat array.
2493         return array instanceof MyValue1[];
2494     }
2495 
2496     @Run(test = "test100")
2497     public void test100_verifier() {
2498         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2499         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2500         try {
2501             test100(array1);
2502             throw new RuntimeException("Should throw ArrayStoreException");
2503         } catch (ArrayStoreException e) {
2504             // Expected
2505         }
2506         boolean res = test100(array2);
2507         Asserts.assertFalse(res);
2508     }
2509 
2510     // Test that CHECKCAST_ARRAY matching works as expected
2511     @Test
2512     @IR(counts = { CHECKCAST_ARRAY, "= 1" })
2513     public boolean test101(Object[] array) {
2514         return array instanceof MyValue1[];
2515     }
2516 
2517     @Run(test = "test101")
2518     public void test101_verifier() {
2519         MyValue1[] array1 = new MyValue1[1];
2520         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2521         MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2522         Asserts.assertTrue(test101(array1));
2523         Asserts.assertFalse(test101(array2));
2524         Asserts.assertTrue(test101(array3));
2525     }
2526 
2527     // Test that CHECKCAST_ARRAY matching works as expected with null-free arrays
2528     @Test
2529     @IR(counts = { CHECKCAST_ARRAY, "= 1" })
2530     public Object test101NullFree(Object[] array) {
2531         return nullFreeArray.getClass().cast(array);
2532     }
2533 
2534     @Run(test = "test101NullFree")
2535     public void test101NullFree_verifier() {
2536         MyValue1[] array1 = new MyValue1[1];
2537         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2538         MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2539         try {
2540             test101NullFree(array1);
2541             throw new RuntimeException("Should throw ClassCastException");
2542         } catch (ClassCastException e) {
2543             // Expected
2544         }
2545         try {
2546             test101NullFree(array2);
2547             throw new RuntimeException("Should throw ClassCastException");
2548         } catch (ClassCastException e) {
2549             // Expected
2550         }
2551         test101NullFree(array3);
2552     }
2553 
2554     static final MyValue2[] val_src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
2555     static final MyValue2[] val_dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
2556     static final Object[]   obj_src = new Object[8];
2557     static final Object[]   obj_null_src = new Object[8];
2558     static final Object[]   obj_dst = new Object[8];
2559 
2560     @ForceInline
2561     static Object get_val_src() { return val_src; }
2562     @ForceInline
2563     static Object get_val_dst() { return val_dst; }
2564     @ForceInline
2565     static Class get_val_class() { return val_src.getClass(); }
2566     @ForceInline
2567     static Class get_non_val_class() { return NonValueClass[].class; }
2568     @ForceInline
2569     static Object get_obj_src() { return obj_src; }
2570     @ForceInline
2571     static Object get_obj_null_src() { return obj_null_src; }
2572     @ForceInline
2573     static Object get_obj_dst() { return obj_dst; }
2574     @ForceInline
2575     static Class get_obj_class() { return Object[].class; }
2576 
2577     static {
2578         for (int i = 0; i < 8; ++i) {
2579             val_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2580             obj_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2581             obj_null_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2582         }
2583         obj_null_src[0] = null;
2584     }
2585 
2586     // Arraycopy with constant source and destination arrays
2587     @Test
2588     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2589         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2590     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2591         failOn = INTRINSIC_SLOW_PATH)
2592     public void test102() {
2593         System.arraycopy(val_src, 0, obj_dst, 0, 8);
2594     }
2595 
2596     @Run(test = "test102")
2597     public void test102_verifier() {
2598         test102();
2599         verify(val_src, obj_dst);
2600     }
2601 
2602     // Same as test102 but with MyValue2[] dst
2603     @Test
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 = {"FlatArrayElementMaxSize", "= -1"},
2662         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2663     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
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 = {"FlatArrayElementMaxSize", "!= -1"},
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 = {"FlatArrayElementMaxSize", "= -1"},
2733         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2734     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
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 = {"FlatArrayElementMaxSize", "= -1"},
2803         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2804     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
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 = {"FlatArrayElementMaxSize", "!= -1"},
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 = {"FlatArrayElementMaxSize", "= -1"},
3036         counts = {JLONG_ARRAYCOPY, "= 1"},
3037         failOn = {CHECKCAST_ARRAYCOPY, CLONE_INTRINSIC_SLOW_PATH})
3038     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
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 = {"FlatArrayElementMaxSize", "= -1"},
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     @NullRestricted
3118     static final MyValueEmpty empty = new MyValueEmpty();
3119 
3120     // Empty value class array access
3121     @Test
3122     @IR(failOn = {ALLOC, ALLOCA, LOAD})
3123     public MyValueEmpty test130(MyValueEmpty[] array) {
3124         array[0] = new MyValueEmpty();
3125         return array[1];
3126     }
3127 
3128     @Run(test = "test130")
3129     public void test130_verifier() {
3130         MyValueEmpty[] array = (MyValueEmpty[])ValueClass.newNullRestrictedArray(MyValueEmpty.class, 2);
3131         MyValueEmpty res = test130(array);
3132         Asserts.assertEquals(array[0], empty);
3133         Asserts.assertEquals(res, empty);
3134     }
3135 
3136     @ImplicitlyConstructible
3137     @LooselyConsistentValue
3138     static value class EmptyContainer {
3139         @NullRestricted
3140         MyValueEmpty empty = new MyValueEmpty();
3141     }
3142 
3143     // Empty value class container array access
3144     @Test
3145     @IR(failOn = {ALLOC, ALLOCA, LOAD})
3146     public MyValueEmpty test131(EmptyContainer[] array) {
3147         array[0] = new EmptyContainer();
3148         return array[1].empty;
3149     }
3150 
3151     @Run(test = "test131")
3152     public void test131_verifier() {
3153         EmptyContainer[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 2);
3154         MyValueEmpty res = test131(array);
3155         Asserts.assertEquals(array[0], new EmptyContainer());
3156         Asserts.assertEquals(res, new MyValueEmpty());
3157     }
3158 
3159     // Empty value class array access with unknown array type
3160     @Test
3161     public Object test132(Object[] array) {
3162         array[0] = new MyValueEmpty();
3163         return array[1];
3164     }
3165 
3166     @Run(test = "test132")
3167     public void test132_verifier() {
3168         Object[] array = (MyValueEmpty[])ValueClass.newNullRestrictedArray(MyValueEmpty.class, 2);
3169         Object res = test132(array);
3170         Asserts.assertEquals(array[0], empty);
3171         Asserts.assertEquals(res, empty);
3172         array = new Object[2];
3173         res = test132(array);
3174         Asserts.assertEquals(array[0], empty);
3175         Asserts.assertEquals(res, null);
3176     }
3177 
3178     // Empty value class container array access with unknown array type
3179     @Test
3180     public Object test133(Object[] array) {
3181         array[0] = new EmptyContainer();
3182         return array[1];
3183     }
3184 
3185     @Run(test = "test133")
3186     public void test133_verifier() {
3187         EmptyContainer empty = new EmptyContainer();
3188         Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 2);
3189         Object res = test133(array);
3190         Asserts.assertEquals(array[0], empty);
3191         Asserts.assertEquals(res, empty);
3192         array = new Object[2];
3193         res = test133(array);
3194         Asserts.assertEquals(array[0], empty);
3195         Asserts.assertEquals(res, null);
3196     }
3197 
3198     // Non-escaping empty value class array access
3199     @Test
3200     @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE})
3201     public static MyValueEmpty test134() {
3202         MyValueEmpty[] array = new MyValueEmpty[1];
3203         array[0] = empty;
3204         return array[0];
3205     }
3206 
3207     @Run(test = "test134")
3208     public void test134_verifier() {
3209         MyValueEmpty res = test134();
3210         Asserts.assertEquals(res, empty);
3211     }
3212 
3213     // Test accessing a locked (value class) array
3214     @Test
3215     public Object test135(Object[] array, Object val) {
3216         array[0] = val;
3217         return array[1];
3218     }
3219 
3220     @Run(test = "test135")
3221     public void test135_verifier() {
3222         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
3223         array1[1] = MyValue1.createWithFieldsInline(rI, rL);
3224         synchronized (array1) {
3225             Object res = test135(array1, array1[1]);
3226             Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash());
3227             Asserts.assertEquals(array1[0].hash(), array1[1].hash());
3228         }
3229         NonValueClass[] array2 = new NonValueClass[2];
3230         array2[1] = new NonValueClass(rI);
3231         synchronized (array2) {
3232             Object res = test135(array2, array2[1]);
3233             Asserts.assertEquals(res, array2[1]);
3234             Asserts.assertEquals(array2[0], array2[1]);
3235         }
3236     }
3237 
3238     // Same as test135 but with locking in compiled method
3239     @Test
3240     public Object test136(Object[] array, Object val) {
3241         Object res = null;
3242         synchronized (array) {
3243             array[0] = val;
3244             res = array[1];
3245         }
3246         return res;
3247     }
3248 
3249     @Run(test = "test136")
3250     public void test136_verifier() {
3251         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
3252         array1[1] = MyValue1.createWithFieldsInline(rI, rL);
3253         Object res = test136(array1, array1[1]);
3254         Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash());
3255         Asserts.assertEquals(array1[0].hash(), array1[1].hash());
3256         NonValueClass[] array2 = new NonValueClass[2];
3257         array2[1] = new NonValueClass(rI);
3258         res = test136(array2, array2[1]);
3259         Asserts.assertEquals(res, array2[1]);
3260         Asserts.assertEquals(array2[0], array2[1]);
3261     }
3262 
3263     Object oFld1, oFld2;
3264 
3265     // Test loop unwswitching with locked (value class) array accesses
3266     @Test
3267     public void test137(Object[] array1, Object[] array2) {
3268         for (int i = 0; i < array1.length; i++) {
3269             oFld1 = array1[i];
3270             oFld2 = array2[i];
3271         }
3272     }
3273 
3274     @Run(test = "test137")
3275     public void test137_verifier() {
3276         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 100);
3277         Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL));
3278         NonValueClass[] array2 = new NonValueClass[100];
3279         Arrays.fill(array2, new NonValueClass(rI));
3280         synchronized (array1) {
3281             test137(array1, array1);
3282             Asserts.assertEquals(oFld1, array1[0]);
3283             Asserts.assertEquals(oFld2, array1[0]);
3284             test137(array1, array2);
3285             Asserts.assertEquals(oFld1, array1[0]);
3286             Asserts.assertEquals(oFld2, array2[0]);
3287             test137(array2, array1);
3288             Asserts.assertEquals(oFld1, array2[0]);
3289             Asserts.assertEquals(oFld2, array1[0]);
3290         }
3291         synchronized (array2) {
3292             test137(array2, array2);
3293             Asserts.assertEquals(oFld1, array2[0]);
3294             Asserts.assertEquals(oFld2, array2[0]);
3295             test137(array1, array2);
3296             Asserts.assertEquals(oFld1, array1[0]);
3297             Asserts.assertEquals(oFld2, array2[0]);
3298             test137(array2, array1);
3299             Asserts.assertEquals(oFld1, array2[0]);
3300             Asserts.assertEquals(oFld2, array1[0]);
3301         }
3302     }
3303 
3304     // Same as test137 but with locking in loop
3305     @Test
3306     public void test138(Object[] array1, Object[] array2) {
3307         for (int i = 0; i < array1.length; i++) {
3308             synchronized (array1) {
3309                 oFld1 = array1[i];
3310             }
3311             synchronized (array2) {
3312                 oFld2 = array2[i];
3313             }
3314         }
3315     }
3316 
3317     @Run(test = "test138")
3318     public void test138_verifier() {
3319         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 100);
3320         Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL));
3321         NonValueClass[] array2 = new NonValueClass[100];
3322         Arrays.fill(array2, new NonValueClass(rI));
3323         test138(array1, array1);
3324         Asserts.assertEquals(oFld1, array1[0]);
3325         Asserts.assertEquals(oFld2, array1[0]);
3326         test138(array1, array2);
3327         Asserts.assertEquals(oFld1, array1[0]);
3328         Asserts.assertEquals(oFld2, array2[0]);
3329         test138(array2, array1);
3330         Asserts.assertEquals(oFld1, array2[0]);
3331         Asserts.assertEquals(oFld2, array1[0]);
3332         test138(array2, array2);
3333         Asserts.assertEquals(oFld1, array2[0]);
3334         Asserts.assertEquals(oFld2, array2[0]);
3335         Asserts.assertEquals(oFld2, array2[0]);
3336     }
3337 
3338     // Test load from array that is only known to be not a value class array after parsing
3339     @Test
3340     @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE,
3341                   STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3342     public Object test139() {
3343         Object[]  array = null;
3344         Object[] oarray = new NonValueClass[1];
3345         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3346         for (int i = 0; i < 10; i++) {
3347             array = varray;
3348             varray = oarray;
3349         }
3350         return array[0];
3351     }
3352 
3353     @Run(test = "test139")
3354     public void test139_verifier() {
3355         Object res = test139();
3356         Asserts.assertEquals(res, null);
3357     }
3358 
3359     // Test store to array that is only known to be not a value class array after parsing
3360     @Test
3361     @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, TRAP,
3362                   LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3363     public Object[] test140(Object val) {
3364         Object[]  array = null;
3365         Object[] oarray = new NonValueClass[1];
3366         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3367         for (int i = 0; i < 10; i++) {
3368             array = varray;
3369             varray = oarray;
3370         }
3371         array[0] = val;
3372         return array;
3373     }
3374 
3375     @Run(test = "test140")
3376     public void test140_verifier() {
3377         NonValueClass obj = new NonValueClass(rI);
3378         Object[] res = test140(obj);
3379         Asserts.assertEquals(res[0], obj);
3380         res = test140(null);
3381         Asserts.assertEquals(res[0], null);
3382     }
3383 
3384     // Test load from array that is only known to be not a value class array after parsing
3385     // TODO 8255938
3386     @Test
3387     // @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3388     public Object test141() {
3389         Object[]  array = null;
3390         Object[] oarray = new NonValueClass[1];
3391         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3392         for (int i = 0; i < 10; i++) {
3393             array = oarray;
3394             oarray = varray;
3395         }
3396         return array[0];
3397     }
3398 
3399     @Run(test = "test141")
3400     public void test141_verifier() {
3401         Object res = test141();
3402         Asserts.assertEquals(res, MyValue1.createDefaultInline());
3403     }
3404 
3405     // Test store to array that is only known to be not a value class array after parsing
3406     // TODO 8255938
3407     @Test
3408     // @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3409     public Object[] test142(Object val) {
3410         Object[]  array = null;
3411         Object[] oarray = new NonValueClass[1];
3412         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3413         for (int i = 0; i < 10; i++) {
3414             array = oarray;
3415             oarray = varray;
3416         }
3417         array[0] = val;
3418         return array;
3419     }
3420 
3421     @Run(test = "test142")
3422     public void test142_verifier(RunInfo info) {
3423         Object[] res = test142(MyValue1.createDefaultInline());
3424         Asserts.assertEquals(res[0], MyValue1.createDefaultInline());
3425         if (!info.isWarmUp()) {
3426             try {
3427                 test142(null);
3428                 throw new RuntimeException("Should throw NullPointerException");
3429             } catch (NullPointerException e) {
3430                 // Expected
3431             }
3432         }
3433     }
3434 
3435     static interface MyInterface143 {
3436         public int hash();
3437     }
3438 
3439     static class MyObject143 implements MyInterface143 {
3440         public int hash() { return 42; }
3441     }
3442 
3443     volatile MyInterface143[] array143 = new MyObject143[1];
3444     int len143 = 0;
3445 
3446     volatile int vf = 0;
3447 
3448     // Test that triggers an anti dependency failure when array mark word is loaded from immutable memory
3449     @Test
3450     public void test143() {
3451         MyInterface143[] arr = array143;
3452         int tmp = arr.length;
3453         for (int i = 0; i < len143; i++) {
3454             if (arr[i].hash() > 0) {
3455                 return;
3456             }
3457         }
3458     }
3459 
3460     @Run(test = "test143")
3461     @Warmup(0)
3462     public void test143_verifier() {
3463         test143();
3464     }
3465 
3466     // Same as test143 but with two flat array checks that are unswitched
3467     @Test
3468     public void test144() {
3469         MyInterface143[] arr1 = array143;
3470         MyInterface143[] arr2 = array143;
3471         int tmp1 = arr1.length;
3472         int tmp2 = arr2.length;
3473         for (int i = 0; i < len143; i++) {
3474             if (arr1[i].hash() > 0 && arr2[i].hash() > 0) {
3475                 return;
3476             }
3477         }
3478     }
3479 
3480     @Run(test = "test144")
3481     @Warmup(0)
3482     public void test144_verifier() {
3483         test144();
3484     }
3485 
3486     // Test that array load slow path correctly initializes non-flattened field of empty value class
3487     @Test
3488     public Object test145(Object[] array) {
3489         return array[0];
3490     }
3491 
3492     @Run(test = "test145")
3493     public void test145_verifier() {
3494         Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 1);
3495         EmptyContainer empty = (EmptyContainer)test145(array);
3496         Asserts.assertEquals(empty, new EmptyContainer());
3497     }
3498 
3499     // Test that non-flattened array does not block scalarization
3500     @Test
3501     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE})
3502     public void test146(boolean b) {
3503         MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD);
3504         MyValue2[] array = { vt };
3505         if (b) {
3506             for (int i = 0; i < 10; ++i) {
3507                 if (array != array) {
3508                     array = null;
3509                 }
3510             }
3511         }
3512     }
3513 
3514     @Run(test = "test146")
3515     @Warmup(50000)
3516     public void test146_verifier() {
3517         test146(true);
3518     }
3519 
3520     // Test that non-flattened array does not block scalarization
3521     @Test
3522     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE})
3523     public int test147(boolean deopt) {
3524         // Both vt and array should be scalarized
3525         MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD);
3526         MyValue2[] array = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1);
3527 
3528         // Delay scalarization to after loop opts
3529         boolean store = false;
3530         for (int i = 0; i < 5; ++i) {
3531             if (i == 1) {
3532                 store = true;
3533             }
3534         }
3535         if (store) {
3536             array[0] = vt;
3537         }
3538 
3539         if (deopt) {
3540             // Uncommon trap referencing array
3541             return array[0].x + 42;
3542         }
3543         return array[0].x;
3544     }
3545 
3546     @Run(test = "test147")
3547     @Warmup(50000)
3548     public void test147_verifier(RunInfo info) {
3549         int res = test147(!info.isWarmUp());
3550         Asserts.assertEquals(res, MyValue2.createWithFieldsInline(rI, rD).x + (info.isWarmUp() ? 0 : 42));
3551     }
3552 
3553     // Test that correct basic types are used when folding field
3554     // loads from a scalar replaced array through an arraycopy.
3555     @Test
3556     public void test148(MyValue1 vt) {
3557         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3558         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3559         src[0] = vt;
3560         System.arraycopy(src, 0, dst, 0, 1);
3561         if (src[0].hash() != dst[0].hash()) {
3562           throw new RuntimeException("Unexpected hash");
3563         }
3564     }
3565 
3566     @Run(test = "test148")
3567     public void test148_verifier() {
3568         test148(MyValue1.createWithFieldsInline(rI, rL));
3569     }
3570 
3571     // Abstract class without any value class implementers
3572     static abstract class MyAbstract149 {
3573         public abstract int get();
3574     }
3575 
3576     static class TestClass149 extends MyAbstract149 {
3577         final int x;
3578 
3579         public int get() { return x; };
3580 
3581         public TestClass149(int x) {
3582             this.x = x;
3583         }
3584     }
3585 
3586     // Test OSR compilation with array known to be not null-free/flat
3587     @Test
3588     public int test149(MyAbstract149[] array) {
3589         int res = 0;
3590         // Trigger OSR compilation
3591         for (int i = 0; i < 10_000; ++i) {
3592             res += array[i % 10].get();
3593         }
3594         return res;
3595     }
3596 
3597     @Run(test = "test149")
3598     public void test149_verifier() {
3599         TestClass149[] array = new TestClass149[10];
3600         for (int i = 0; i < 10; ++i) {
3601             array[i] = new TestClass149(i);
3602         }
3603         Asserts.assertEquals(test149(array), 45000);
3604     }
3605 
3606     @ImplicitlyConstructible
3607     @LooselyConsistentValue
3608     static value class Test150Value {
3609         Object s = "test";
3610     }
3611 
3612     // Test that optimizing a checkcast of a load from a flat array works as expected
3613     @Test
3614     static String test150() {
3615         Test150Value[] array = (Test150Value[])ValueClass.newNullRestrictedArray(Test150Value.class, 1);
3616         array[0] = new Test150Value();
3617         return (String)array[0].s;
3618     }
3619 }