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     // Ignore: JDK-8329224
1419     // @Test
1420     public Object[] test59(MyValue1[] va) {
1421         return Arrays.copyOf(va, va.length+1, va.getClass());
1422     }
1423 
1424     // @Run(test = "test59")
1425     public void test59_verifier() {
1426         int len = Math.abs(rI) % 10;
1427         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1428         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1);
1429         for (int i = 0; i < len; ++i) {
1430             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1431             verif[i] = va[i];
1432         }
1433         Object[] result = test59(va);
1434         // Result is a null-restricted array
1435         Asserts.assertEQ(result[len], ValueClass.zeroInstance(MyValue1.class));
1436         result[len] = MyValue1.createDefaultInline();
1437         verify(verif, result);
1438     }
1439 
1440     // Ignore: JDK-8329224
1441     // @Test
1442     public Object[] test60(Object[] va, Class klass) {
1443         return Arrays.copyOf(va, va.length+1, klass);
1444     }
1445 
1446     // @Run(test = "test60")
1447     public void test60_verifier() {
1448         int len = Math.abs(rI) % 10;
1449         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1450         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1);
1451         for (int i = 0; i < len; ++i) {
1452             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1453             verif[i] = (MyValue1)va[i];
1454         }
1455         Object[] result = test60(va, va.getClass());
1456         // Result is a null-restricted array
1457         Asserts.assertEQ(result[len], ValueClass.zeroInstance(MyValue1.class));
1458         result[len] = MyValue1.createDefaultInline();
1459         verify(verif, result);
1460     }
1461 
1462     @Test
1463     public Object[] test61(Object[] va, Class klass) {
1464         return Arrays.copyOf(va, va.length+1, klass);
1465     }
1466 
1467     @Run(test = "test61")
1468     public void test61_verifier() {
1469         int len = Math.abs(rI) % 10;
1470         Object[] va = new NonValueClass[len];
1471         for (int i = 0; i < len; ++i) {
1472             va[i] = new NonValueClass(rI);
1473         }
1474         Object[] result = test61(va, NonValueClass[].class);
1475         for (int i = 0; i < va.length; ++i) {
1476             Asserts.assertEQ(va[i], result[i]);
1477         }
1478     }
1479 
1480     @ForceInline
1481     public Object[] test62_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1482         Object[] arr = null;
1483         if (i == 10) {
1484             arr = oa;
1485         } else {
1486             arr = va;
1487         }
1488         return arr;
1489     }
1490 
1491     @Test
1492     public Object[] test62(MyValue1[] va, NonValueClass[] oa) {
1493         int i = 0;
1494         for (; i < 10; i++);
1495 
1496         Object[] arr = test62_helper(i, va, oa);
1497 
1498         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1499     }
1500 
1501     @Run(test = "test62")
1502     public void test62_verifier() {
1503         int len = Math.abs(rI) % 10;
1504         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1505         NonValueClass[] oa = new NonValueClass[len];
1506         for (int i = 0; i < len; ++i) {
1507             oa[i] = new NonValueClass(rI);
1508         }
1509         test62_helper(42, va, oa);
1510         Object[] result = test62(va, oa);
1511         for (int i = 0; i < va.length; ++i) {
1512             Asserts.assertEQ(oa[i], result[i]);
1513         }
1514     }
1515 
1516     @ForceInline
1517     public Object[] test63_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1518         Object[] arr = null;
1519         if (i == 10) {
1520             arr = va;
1521         } else {
1522             arr = oa;
1523         }
1524         return arr;
1525     }
1526 
1527     // Ignore: JDK-8329224
1528     // @Test
1529     public Object[] test63(MyValue1[] va, NonValueClass[] oa) {
1530         int i = 0;
1531         for (; i < 10; i++);
1532 
1533         Object[] arr = test63_helper(i, va, oa);
1534 
1535         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1536     }
1537 
1538     // @Run(test = "test63")
1539     public void test63_verifier() {
1540         int len = Math.abs(rI) % 10;
1541         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1542         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1);
1543         for (int i = 0; i < len; ++i) {
1544             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1545             verif[i] = va[i];
1546         }
1547         NonValueClass[] oa = new NonValueClass[len];
1548         test63_helper(42, va, oa);
1549         Object[] result = test63(va, oa);
1550         // Result is not a null-restricted array
1551         Asserts.assertEQ(result[len], null);
1552         result[len] = MyValue1.createDefaultInline();
1553         verify(verif, result);
1554     }
1555 
1556     // Test default initialization of value class arrays: small array
1557     @Test
1558     public MyValue1[] test64() {
1559         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
1560     }
1561 
1562     @Run(test = "test64")
1563     public void test64_verifier() {
1564         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8);
1565         MyValue1[] var = test64();
1566         for (int i = 0; i < 8; ++i) {
1567             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1568         }
1569     }
1570 
1571     // Test default initialization of value class arrays: large array
1572     @Test
1573     public MyValue1[] test65() {
1574         return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 32);
1575     }
1576 
1577     @Run(test = "test65")
1578     public void test65_verifier() {
1579         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 32);
1580         MyValue1[] var = test65();
1581         for (int i = 0; i < 32; ++i) {
1582             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1583         }
1584     }
1585 
1586     // Check init store elimination
1587     @Test
1588     @IR(counts = {ALLOCA, "= 1"})
1589     public MyValue1[] test66(MyValue1 vt) {
1590         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
1591         va[0] = vt;
1592         return va;
1593     }
1594 
1595     @Run(test = "test66")
1596     public void test66_verifier() {
1597         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1598         MyValue1[] va = test66(vt);
1599         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1600     }
1601 
1602     // Zeroing elimination and arraycopy
1603     @Test
1604     public MyValue1[] test67(MyValue1[] src) {
1605         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 16);
1606         System.arraycopy(src, 0, dst, 0, 13);
1607         return dst;
1608     }
1609 
1610     @Run(test = "test67")
1611     public void test67_verifier() {
1612         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 16);
1613         MyValue1[] var = test67(va);
1614         for (int i = 0; i < 16; ++i) {
1615             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1616         }
1617     }
1618 
1619     // A store with a default value can be eliminated
1620     @Test
1621     public MyValue1[] test68() {
1622         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1623         va[0] = va[1];
1624         return va;
1625     }
1626 
1627     @Run(test = "test68")
1628     public void test68_verifier() {
1629         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1630         MyValue1[] var = test68();
1631         for (int i = 0; i < 2; ++i) {
1632             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1633         }
1634     }
1635 
1636     // Requires individual stores to init array
1637     @Test
1638     public MyValue1[] test69(MyValue1 vt) {
1639         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 4);
1640         va[0] = vt;
1641         va[3] = vt;
1642         return va;
1643     }
1644 
1645     @Run(test = "test69")
1646     public void test69_verifier() {
1647         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1648         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 4);
1649         va[0] = vt;
1650         va[3] = vt;
1651         MyValue1[] var = test69(vt);
1652         for (int i = 0; i < va.length; ++i) {
1653             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1654         }
1655     }
1656 
1657     // A store with a default value can be eliminated: same as test68
1658     // but store is further away from allocation
1659     @Test
1660     public MyValue1[] test70(MyValue1[] other) {
1661         other[1] = other[0];
1662         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1663         other[0] = va[1];
1664         va[0] = va[1];
1665         return va;
1666     }
1667 
1668     @Run(test = "test70")
1669     public void test70_verifier() {
1670         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
1671         MyValue1[] var = test70(va);
1672         for (int i = 0; i < 2; ++i) {
1673             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1674         }
1675     }
1676 
1677     // EA needs to consider oop fields in flattened arrays
1678     @Test
1679     public void test71() {
1680         int len = 10;
1681         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1682         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len);
1683         for (int i = 0; i < len; ++i) {
1684             src[i] = MyValue2.createWithFieldsDontInline(rI+i, rD+i);
1685         }
1686         System.arraycopy(src, 0, dst, 0, src.length);
1687         for (int i = 0; i < len; ++i) {
1688             Asserts.assertEQ(src[i].hash(), dst[i].hash());
1689         }
1690     }
1691 
1692     @Run(test = "test71")
1693     public void test71_verifier() {
1694         test71();
1695     }
1696 
1697     // Test EA with leaf call to 'store_unknown_inline'
1698     @Test
1699     public void test72(Object[] o, boolean b, Object element) {
1700         Object[] arr1 = new Object[10];
1701         Object[] arr2 = new Object[10];
1702         if (b) {
1703             arr1 = o;
1704         }
1705         arr1[0] = element;
1706         arr2[0] = element;
1707     }
1708 
1709     @Run(test = "test72")
1710     public void test72_verifier() {
1711         Object[] arr = new Object[1];
1712         Object elem = new Object();
1713         test72(arr, true, elem);
1714         test72(arr, false, elem);
1715     }
1716 
1717     @Test
1718     public void test73(Object[] oa, MyValue1 v, Object o) {
1719         // TestLWorld.test38 use a C1 Phi node for the array. This test
1720         // adds the case where the stored value is a C1 Phi node.
1721         Object o2 = (o == null) ? v : o;
1722         oa[0] = v;  // The stored value is known to be flattenable
1723         oa[1] = o;  // The stored value may be flattenable
1724         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1725         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1726     }
1727 
1728     @Run(test = "test73")
1729     public void test73_verifier() {
1730         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1731         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1732         MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 3);
1733         try {
1734             test73(arr, v0, v1);
1735             throw new RuntimeException("ArrayStoreException expected");
1736         } catch (ArrayStoreException e) {
1737             // expected
1738         }
1739         Asserts.assertEQ(arr[0].hash(), v0.hash());
1740         Asserts.assertEQ(arr[1].hash(), v1.hash());
1741         Asserts.assertEQ(arr[2].hash(), v1.hash());
1742     }
1743 
1744     public static void test74Callee(MyValue1[] va) { }
1745 
1746     // Tests invoking unloaded method with value class array in signature
1747     @Test
1748     public void test74(MethodHandle m, MyValue1[] va) throws Throwable {
1749         m.invoke(va);
1750     }
1751 
1752     @Run(test = "test74")
1753     @Warmup(0)
1754     public void test74_verifier() throws Throwable {
1755         MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class));
1756         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0);
1757         test74(m, va);
1758     }
1759 
1760     // Some more array clone tests
1761     @ForceInline
1762     public Object[] test75_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1763         Object[] arr = null;
1764         if (i == 10) {
1765             arr = oa;
1766         } else {
1767             arr = va;
1768         }
1769         return arr;
1770     }
1771 
1772     @Test
1773     public Object[] test75(MyValue1[] va, NonValueClass[] oa) {
1774         int i = 0;
1775         for (; i < 10; i++);
1776 
1777         Object[] arr = test75_helper(i, va, oa);
1778         return arr.clone();
1779     }
1780 
1781     @Run(test = "test75")
1782     public void test75_verifier() {
1783         int len = Math.abs(rI) % 10;
1784         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1785         NonValueClass[] oa = new NonValueClass[len];
1786         for (int i = 0; i < len; ++i) {
1787             oa[i] = new NonValueClass(rI);
1788         }
1789         test75_helper(42, va, oa);
1790         Object[] result = test75(va, oa);
1791 
1792         for (int i = 0; i < va.length; ++i) {
1793             Asserts.assertEQ(oa[i], result[i]);
1794             // Check that array has correct properties (null-ok)
1795             result[i] = null;
1796         }
1797     }
1798 
1799     @ForceInline
1800     public Object[] test76_helper(int i, MyValue1[] va, NonValueClass[] oa) {
1801         Object[] arr = null;
1802         if (i == 10) {
1803             arr = va;
1804         } else {
1805             arr = oa;
1806         }
1807         return arr;
1808     }
1809 
1810     @Test
1811     public Object[] test76(MyValue1[] va, NonValueClass[] oa) {
1812         int i = 0;
1813         for (; i < 10; i++);
1814 
1815         Object[] arr = test76_helper(i, va, oa);
1816         return arr.clone();
1817     }
1818 
1819     @Run(test = "test76")
1820     public void test76_verifier() {
1821         int len = Math.abs(rI) % 10;
1822         MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1823         MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len);
1824         for (int i = 0; i < len; ++i) {
1825             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1826             verif[i] = va[i];
1827         }
1828         NonValueClass[] oa = new NonValueClass[len];
1829         test76_helper(42, va, oa);
1830         Object[] result = test76(va, oa);
1831         verify(verif, result);
1832         // Check that array has correct properties (null-free)
1833         if (len > 0) {
1834             try {
1835                 result[0] = null;
1836                 throw new RuntimeException("Should throw NullPointerException");
1837             } catch (NullPointerException e) {
1838                 // Expected
1839             }
1840         }
1841     }
1842 
1843     @Test
1844     public void test77() {
1845         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1846         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1847         MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
1848 
1849         Object[] oa = arr;
1850         Object o1 = v1;
1851         Object o = (o1 == null) ? v0 : o1;
1852 
1853         oa[0] = o; // For C1, due to IfOp optimization, the declared_type of o becomes NULL.
1854 
1855         Asserts.assertEQ(arr[0].hash(), v1.hash());
1856     }
1857 
1858 
1859     @Run(test = "test77")
1860     public void test77_verifier() {
1861         test77();
1862     }
1863 
1864     @Test
1865     public long test78(MyValue1 v, int n) {
1866         long x = 0;
1867         for (int i = 0; i < n; i++) {
1868         }
1869 
1870         MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, n);
1871         a[0] = v;
1872         for (int i = 0; i<n; i++) {
1873             x += a[i].hash(); // C1 PhiSimplifier changes "a" from a Phi node to a NewObjectArray node
1874         }
1875 
1876         return x;
1877     }
1878 
1879     @Run(test = "test78")
1880     public void test78_verifier() {
1881         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1882         Asserts.assertEQ(test78(v, 1), v.hash());
1883     }
1884 
1885     // Verify that casting an array element to a non-flattenable type marks the array as not-flat
1886     @Test
1887     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
1888         counts = {LOAD_UNKNOWN_INLINE, "= 1"})
1889     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
1890         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE})
1891     public Object test79(Object[] array, int i) {
1892         NonValueClass i1 = (NonValueClass)array[0];
1893         Object o = array[1];
1894         return array[i];
1895     }
1896 
1897     @Run(test = "test79")
1898     public void test79_verifier() {
1899         NonValueClass obj = new NonValueClass(rI);
1900         NonValueClass[] array = new NonValueClass[2];
1901         array[1] = obj;
1902         Object result = test79(array, 1);
1903         Asserts.assertEquals(result, obj);
1904     }
1905 
1906     // Same as test79 but with not-flattenable value class
1907     @Test
1908     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
1909         counts = {LOAD_UNKNOWN_INLINE, "= 1"})
1910     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
1911         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE})
1912     public Object test80(Object[] array, int i) {
1913         NotFlattenable vt = (NotFlattenable)array[0];
1914         Object o = array[1];
1915         return array[i];
1916     }
1917 
1918     @Run(test = "test80")
1919     public void test80_verifier() {
1920         NotFlattenable vt = new NotFlattenable();
1921         NotFlattenable[] array = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
1922         array[1] = vt;
1923         Object result = test80(array, 1);
1924         Asserts.assertEquals(result, vt);
1925     }
1926 
1927     // 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
1928     @Test
1929     @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1930     public Object test81(Object[] array, NonValueClass v, Object o, int i) {
1931         if (v == null) {
1932           return null;
1933         }
1934         array[0] = v;
1935         array[1] = array[0];
1936         array[2] = o;
1937         return array[i];
1938     }
1939 
1940     @Run(test = "test81")
1941     public void test81_verifier() {
1942         NonValueClass obj = new NonValueClass(rI);
1943         NonValueClass[] array1 = new NonValueClass[3];
1944         Object[] array2 = new Object[3];
1945         Object result = test81(array1, obj, obj, 0);
1946         Asserts.assertEquals(array1[0], obj);
1947         Asserts.assertEquals(array1[1], obj);
1948         Asserts.assertEquals(array1[2], obj);
1949         Asserts.assertEquals(result, obj);
1950         result = test81(array2, obj, obj, 1);
1951         Asserts.assertEquals(array2[0], obj);
1952         Asserts.assertEquals(array2[1], obj);
1953         Asserts.assertEquals(array2[2], obj);
1954         Asserts.assertEquals(result, obj);
1955     }
1956 
1957     // Verify that writing an object of a non-flattenable value class to an array marks the array as not-flat
1958     @Test
1959     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
1960         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE})
1961     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
1962         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE})
1963     public Object test82(Object[] array, NotFlattenable vt, Object o, int i) {
1964         array[0] = vt;
1965         array[1] = array[0];
1966         array[2] = o;
1967         return array[i];
1968     }
1969 
1970     @Run(test = "test82")
1971     public void test82_verifier() {
1972         NotFlattenable vt = new NotFlattenable();
1973         NotFlattenable[] array1 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 3);
1974         Object[] array2 = new Object[3];
1975         Object result = test82(array1, vt, vt, 0);
1976         Asserts.assertEquals(array1[0], vt);
1977         Asserts.assertEquals(array1[1], vt);
1978         Asserts.assertEquals(array1[2], vt);
1979         Asserts.assertEquals(result, vt);
1980         result = test82(array2, vt, vt, 1);
1981         Asserts.assertEquals(array2[0], vt);
1982         Asserts.assertEquals(array2[1], vt);
1983         Asserts.assertEquals(array2[2], vt);
1984         Asserts.assertEquals(result, vt);
1985     }
1986 
1987     // Verify that casting an array element to a non-value class type type marks the array as not-null-free and not-flat
1988     @Test
1989     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
1990         counts = {LOAD_UNKNOWN_INLINE, "= 1"},
1991         failOn = {ALLOCA_G, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1992     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
1993             failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
1994     public void test83(Object[] array, Object o) {
1995         NonValueClass i = (NonValueClass)array[0];
1996         array[1] = o;
1997     }
1998 
1999     @Run(test = "test83")
2000     public void test83_verifier() {
2001         NonValueClass obj = new NonValueClass(rI);
2002         NonValueClass[] array1 = new NonValueClass[2];
2003         Object[] array2 = new Object[2];
2004         test83(array1, obj);
2005         Asserts.assertEquals(array1[1], obj);
2006         test83(array2, null);
2007         Asserts.assertEquals(array2[1], null);
2008     }
2009 
2010     // Verify that writing constant null into an array marks the array as not-null-free and not-flat
2011     @Test
2012     @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2013         counts = {INLINE_ARRAY_NULL_GUARD, "= 1"})
2014     public Object test84(Object[] array, int i) {
2015         array[0] = null;
2016         array[1] = null;
2017         return array[i];
2018     }
2019 
2020     @Run(test = "test84")
2021     public void test84_verifier(RunInfo info) {
2022         NotFlattenable[] array1 = new NotFlattenable[2];
2023         Object[] array2 = new Object[2];
2024         Object result = test84(array1, 0);
2025         Asserts.assertEquals(array1[0], null);
2026         Asserts.assertEquals(result, null);
2027         result = test84(array2, 1);
2028         Asserts.assertEquals(array2[0], null);
2029         Asserts.assertEquals(result, null);
2030         if (!info.isWarmUp()) {
2031             NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
2032             try {
2033                 test84(array3, 1);
2034                 throw new RuntimeException("Should throw NullPointerException");
2035             } catch (NullPointerException e) {
2036                 // Expected
2037             }
2038         }
2039     }
2040 
2041     // Same as test84 but with branches
2042     @Test
2043     @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2044         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2045     public void test85(Object[] array, Object o, boolean b) {
2046         if (b) {
2047             array[0] = null;
2048         } else {
2049             array[1] = null;
2050         }
2051         array[1] = o;
2052     }
2053 
2054     @Run(test = "test85")
2055     public void test85_verifier(RunInfo info) {
2056         NonValueClass obj = new NonValueClass(rI);
2057         NonValueClass[] array1 = new NonValueClass[2];
2058         Object[] array2 = new Object[2];
2059         test85(array1, obj, true);
2060         Asserts.assertEquals(array1[1], obj);
2061         test85(array1, null, false);
2062         Asserts.assertEquals(array1[1], null);
2063         test85(array2, obj, true);
2064         Asserts.assertEquals(array2[1], obj);
2065         test85(array2, null, false);
2066         Asserts.assertEquals(array2[1], null);
2067         if (!info.isWarmUp()) {
2068             NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
2069             try {
2070                 test85(array3, null, true);
2071                 throw new RuntimeException("Should throw NullPointerException");
2072             } catch (NullPointerException e) {
2073                 // Expected
2074             }
2075         }
2076     }
2077 
2078     // Same as test85 but with not-flattenable value class array
2079     @Test
2080     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2081         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2082         counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"})
2083     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2084         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2085         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2086     public void test86(NotFlattenable[] array, NotFlattenable o, boolean b) {
2087         if (b) {
2088             array[0] = null;
2089         } else {
2090             array[1] = null;
2091         }
2092         array[1] = o;
2093     }
2094 
2095     @Run(test = "test86")
2096     public void test86_verifier(RunInfo info) {
2097         NotFlattenable vt = new NotFlattenable();
2098         NotFlattenable[] array1 = new NotFlattenable[2];
2099         test86(array1, vt, true);
2100         Asserts.assertEquals(array1[1], vt);
2101         test86(array1, null, false);
2102         Asserts.assertEquals(array1[1], null);
2103         if (!info.isWarmUp()) {
2104             NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2);
2105             try {
2106                 test86(array2, null, true);
2107                 throw new RuntimeException("Should throw NullPointerException");
2108             } catch (NullPointerException e) {
2109                 // Expected
2110             }
2111         }
2112     }
2113 
2114     // Same as test85 but with value class array
2115     @Test
2116     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2117         failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2118         counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"})
2119     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2120         failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE},
2121         counts = {INLINE_ARRAY_NULL_GUARD, "= 2"})
2122     public void test87(MyValue1[] array, MyValue1 o, boolean b) {
2123         if (b) {
2124             array[0] = null;
2125         } else {
2126             array[1] = null;
2127         }
2128         array[1] = o;
2129     }
2130 
2131     @Run(test = "test87")
2132     public void test87_verifier(RunInfo info) {
2133         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2134         MyValue1[] array1 = new MyValue1[2];
2135         test87(array1, vt, true);
2136         Asserts.assertEquals(array1[1], vt);
2137         test87(array1, null, false);
2138         Asserts.assertEquals(array1[1], null);
2139         if (!info.isWarmUp()) {
2140             MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
2141             try {
2142                 test87(array2, null, true);
2143                 throw new RuntimeException("Should throw NullPointerException");
2144             } catch (NullPointerException e) {
2145                 // Expected
2146             }
2147         }
2148     }
2149 
2150     // Additional correctness tests to make sure we have the required null checks
2151     @Test
2152     public void test88(Object[] array, NonValueClass v) {
2153         array[0] = v;
2154     }
2155 
2156     @Run(test = "test88")
2157     public void test88_verifier(RunInfo info) {
2158         NonValueClass[] array1 = new NonValueClass[1];
2159         Object[] array2 = new Object[1];
2160         test88(array1, null);
2161         Asserts.assertEquals(array1[0], null);
2162         test88(array2, null);
2163         Asserts.assertEquals(array2[0], null);
2164         if (!info.isWarmUp()) {
2165             MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2166             try {
2167                 test88(array3, null);
2168                 throw new RuntimeException("Should throw NullPointerException");
2169             } catch (NullPointerException e) {
2170                 // Expected
2171             }
2172         }
2173     }
2174 
2175     @Test
2176     public void test89(MyValue1[] array, NonValueClass v) {
2177         Object o = v;
2178         array[0] = (MyValue1)o;
2179     }
2180 
2181     @Run(test = "test89")
2182     public void test89_verifier(RunInfo info) {
2183         MyValue1[] array1 = new MyValue1[1];
2184         test89(array1, null);
2185         Asserts.assertEquals(array1[0], null);
2186         if (!info.isWarmUp()) {
2187             MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2188             try {
2189                 test89(array2, null);
2190                 throw new RuntimeException("Should throw NullPointerException");
2191             } catch (NullPointerException e) {
2192                 // Expected
2193             }
2194         }
2195     }
2196 
2197     @Test
2198     public boolean test90() {
2199         boolean b = true;
2200 
2201         MyValue1[] qArray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0);
2202         MyValue1[] lArray = new MyValue1[0];
2203 
2204         b = b && (qArray instanceof MyValue1[]);
2205         b = b && (lArray instanceof MyValue1[]);
2206 
2207         MyValue1[][] qArray2 = { (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0) };
2208         MyValue1[][] lArray2 = new MyValue1[0][0];
2209 
2210         b = b && (qArray2 instanceof MyValue1[][]);
2211         b = b && (lArray2 instanceof MyValue1[][]);
2212 
2213         return b;
2214     }
2215 
2216     @Run(test = "test90")
2217     public void test90_verifier() {
2218         Asserts.assertEQ(test90(), true);
2219     }
2220 
2221     @ImplicitlyConstructible
2222     @LooselyConsistentValue
2223     static value class Test91Value {
2224         public int f0;
2225         public int f1;
2226         public int f2;
2227         public int f3;
2228         public int f4;
2229         public int f5;
2230 
2231         public Test91Value(int i) {
2232             this.f0 = i;
2233             this.f1 = i;
2234             this.f2 = i;
2235             this.f3 = i;
2236             this.f4 = i;
2237             this.f5 = i;
2238         }
2239 
2240         public void verify() {
2241             if ((f0 != f1) || (f1 != f2) || (f2 != f3) || (f3 != f4) || (f4 != f5)) {
2242                 throw new RuntimeException("test91 failed");
2243             }
2244         }
2245     }
2246 
2247     // Test anti-dependencies between loads and stores from flattened array
2248     @Test
2249     public int test91(Test91Value[] array, int lo, int val) {
2250         int i = 3;
2251         while (lo < i) {
2252             Test91Value tmp = array[lo];
2253             array[lo++] = array[i];
2254             array[i--] = tmp;
2255         }
2256         return val;
2257     }
2258 
2259     @Run(test = "test91")
2260     @Warmup(0)
2261     public void test91_verifier() {
2262         Test91Value[] array = (Test91Value[])ValueClass.newNullRestrictedArray(Test91Value.class, 5);
2263         for (int i = 0; i < 5; ++i) {
2264             array[i] = new Test91Value(i);
2265             array[i].verify();
2266         }
2267         Asserts.assertEQ(test91(array, 0, 5), 5);
2268         for (int i = 0; i < 5; ++i) {
2269             array[i].verify();
2270         }
2271     }
2272 
2273     @Test
2274     public void test92(Object[] src, Object[] dst) {
2275         System.arraycopy(src, 0, dst, 0, src.length);
2276     }
2277 
2278     @Run(test = "test92")
2279     public void test92_verifier() {
2280         MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2281         MyValue1[] b = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2282         try {
2283             test92(a, null);
2284             throw new RuntimeException("Should throw NullPointerException");
2285         } catch (NullPointerException expected) {}
2286 
2287         try {
2288             test92(null, b);
2289             throw new RuntimeException("Should throw NullPointerException");
2290         } catch (NullPointerException expected) {}
2291 
2292         a[0] = MyValue1.createWithFieldsInline(rI, rL);
2293         test92(a, b);
2294         verify(a, b);
2295     }
2296 
2297     // Same as test30 but accessing all elements of the non-escaping array
2298     @Test
2299     public long test93(MyValue2[] src, boolean flag) {
2300         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2301         System.arraycopy(src, 0, dst, 0, 10);
2302         if (flag) {  }
2303         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2304                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2305     }
2306 
2307     @Run(test = "test93")
2308     @Warmup(10000)
2309     public void test93_verifier(RunInfo info) {
2310         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2311         for (int i = 0; i < 10; ++i) {
2312             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2313         }
2314         long res = test93(src, !info.isWarmUp());
2315         long expected = 0;
2316         for (int i = 0; i < 10; ++i) {
2317             expected += src[i].hash();
2318         }
2319         Asserts.assertEQ(res, expected);
2320     }
2321 
2322     // Same as test93 but with variable source array offset
2323     @Test
2324     public long test94(MyValue2[] src, int i, boolean flag) {
2325         MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2326         System.arraycopy(src, i, dst, 0, 1);
2327         if (flag) {  }
2328         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2329                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2330     }
2331 
2332     @Run(test = "test94")
2333     @Warmup(10000)
2334     public void test94_verifier(RunInfo info) {
2335         MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10);
2336         for (int i = 0; i < 10; ++i) {
2337             src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2338         }
2339         for (int i = 0; i < 10; ++i) {
2340             long res = test94(src, i, !info.isWarmUp());
2341             long expected = src[i].hash() + 9*MyValue2.createDefaultInline().hash();
2342             Asserts.assertEQ(res, expected);
2343         }
2344     }
2345 
2346     // Test propagation of not null-free/flat information
2347     @Test
2348     @IR(failOn = CHECKCAST_ARRAY)
2349     public MyValue1[] test95(Object[] array) {
2350         array[0] = null;
2351         // Always throws a ClassCastException because we just successfully
2352         // stored null and therefore the array can't be an value class array.
2353         return (MyValue1[])array;
2354     }
2355 
2356     @Run(test = "test95")
2357     public void test95_verifier() {
2358         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2359         NonValueClass[] array2 = new NonValueClass[1];
2360         try {
2361             test95(array1);
2362             throw new RuntimeException("Should throw NullPointerException");
2363         } catch (NullPointerException e) {
2364             // Expected
2365         }
2366         try {
2367             test95(array2);
2368             throw new RuntimeException("Should throw ClassCastException");
2369         } catch (ClassCastException e) {
2370             // Expected
2371         }
2372     }
2373 
2374     // Same as test95 but with cmp user of cast result
2375     @Test
2376     @IR(failOn = CHECKCAST_ARRAY)
2377     public boolean test96(Object[] array) {
2378         array[0] = null;
2379         // Always throws a ClassCastException because we just successfully
2380         // stored null and therefore the array can't be an value class array.
2381         MyValue1[] casted = (MyValue1[])array;
2382         return casted != null;
2383     }
2384 
2385     @Run(test = "test96")
2386     public void test96_verifier() {
2387         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2388         NonValueClass[] array2 = new NonValueClass[1];
2389         try {
2390             test96(array1);
2391             throw new RuntimeException("Should throw NullPointerException");
2392         } catch (NullPointerException e) {
2393             // Expected
2394         }
2395         try {
2396             test96(array2);
2397             throw new RuntimeException("Should throw ClassCastException");
2398         } catch (ClassCastException e) {
2399             // Expected
2400         }
2401     }
2402 
2403     // Same as test95 but with instanceof instead of cast
2404     @Test
2405     @IR(failOn = CHECKCAST_ARRAY)
2406     public boolean test97(Object[] array) {
2407         array[0] = new NonValueClass(42);
2408         // Always throws a ClassCastException because we just successfully stored
2409         // a non-value type value and therefore the array can't be a value class array.
2410         return array instanceof MyValue1[];
2411     }
2412 
2413     @Run(test = "test97")
2414     public void test97_verifier() {
2415         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2416         NonValueClass[] array2 = new NonValueClass[1];
2417         try {
2418             test97(array1);
2419             throw new RuntimeException("Should throw ArrayStoreException");
2420         } catch (ArrayStoreException e) {
2421             // Expected
2422         }
2423         boolean res = test97(array2);
2424         Asserts.assertFalse(res);
2425     }
2426 
2427     // Same as test95 but with non-flattenable store
2428     @Test
2429     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2430         failOn = CHECKCAST_ARRAY)
2431     public MyValue1[] test98(Object[] array) {
2432         array[0] = new NotFlattenable();
2433         // Always throws a ClassCastException because we just successfully stored a
2434         // non-flattenable value and therefore the array can't be a flat array.
2435         return (MyValue1[])array;
2436     }
2437 
2438     @Run(test = "test98")
2439     public void test98_verifier() {
2440         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2441         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2442         try {
2443             test98(array1);
2444             throw new RuntimeException("Should throw ArrayStoreException");
2445         } catch (ArrayStoreException e) {
2446             // Expected
2447         }
2448         try {
2449             test98(array2);
2450             throw new RuntimeException("Should throw ClassCastException");
2451         } catch (ClassCastException e) {
2452             // Expected
2453         }
2454     }
2455 
2456     // Same as test98 but with cmp user of cast result
2457     @Test
2458     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2459         failOn = CHECKCAST_ARRAY)
2460     public boolean test99(Object[] array) {
2461         array[0] = new NotFlattenable();
2462         // Always throws a ClassCastException because we just successfully stored a
2463         // non-flattenable value and therefore the array can't be a flat array.
2464         MyValue1[] casted = (MyValue1[])array;
2465         return casted != null;
2466     }
2467 
2468     @Run(test = "test99")
2469     public void test99_verifier() {
2470         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2471         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2472         try {
2473             test99(array1);
2474             throw new RuntimeException("Should throw ArrayStoreException");
2475         } catch (ArrayStoreException e) {
2476             // Expected
2477         }
2478         try {
2479             test99(array2);
2480             throw new RuntimeException("Should throw ClassCastException");
2481         } catch (ClassCastException e) {
2482             // Expected
2483         }
2484     }
2485 
2486     // Same as test98 but with instanceof instead of cast
2487     @Test
2488     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2489         failOn = CHECKCAST_ARRAY)
2490     public boolean test100(Object[] array) {
2491         array[0] = new NotFlattenable();
2492         // Always throws a ClassCastException because we just successfully stored a
2493         // non-flattenable value and therefore the array can't be a flat array.
2494         return array instanceof MyValue1[];
2495     }
2496 
2497     @Run(test = "test100")
2498     public void test100_verifier() {
2499         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
2500         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2501         try {
2502             test100(array1);
2503             throw new RuntimeException("Should throw ArrayStoreException");
2504         } catch (ArrayStoreException e) {
2505             // Expected
2506         }
2507         boolean res = test100(array2);
2508         Asserts.assertFalse(res);
2509     }
2510 
2511     // Test that CHECKCAST_ARRAY matching works as expected
2512     @Test
2513     // TODO 8325106 This fails to detect the "movq    R10, precise [compiler/valhalla/inlinetypes/MyValue1" shape, also affects mainline
2514     // @IR(counts = { IRNode.CHECKCAST_ARRAY, "= 1" })
2515     public boolean test101(Object[] array) {
2516         return array instanceof MyValue1[];
2517     }
2518 
2519     @Run(test = "test101")
2520     public void test101_verifier() {
2521         MyValue1[] array1 = new MyValue1[1];
2522         NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1);
2523         Asserts.assertTrue(test101(array1));
2524         Asserts.assertFalse(test101(array2));
2525     }
2526 
2527     static final MyValue2[] val_src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
2528     static final MyValue2[] val_dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8);
2529     static final Object[]   obj_src = new Object[8];
2530     static final Object[]   obj_null_src = new Object[8];
2531     static final Object[]   obj_dst = new Object[8];
2532 
2533     @ForceInline
2534     static Object get_val_src() { return val_src; }
2535     @ForceInline
2536     static Object get_val_dst() { return val_dst; }
2537     @ForceInline
2538     static Class get_val_class() { return val_src.getClass(); }
2539     @ForceInline
2540     static Class get_non_val_class() { return NonValueClass[].class; }
2541     @ForceInline
2542     static Object get_obj_src() { return obj_src; }
2543     @ForceInline
2544     static Object get_obj_null_src() { return obj_null_src; }
2545     @ForceInline
2546     static Object get_obj_dst() { return obj_dst; }
2547     @ForceInline
2548     static Class get_obj_class() { return Object[].class; }
2549 
2550     static {
2551         for (int i = 0; i < 8; ++i) {
2552             val_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2553             obj_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2554             obj_null_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i);
2555         }
2556         obj_null_src[0] = null;
2557     }
2558 
2559     // Arraycopy with constant source and destination arrays
2560     @Test
2561     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2562         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2563     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2564         failOn = INTRINSIC_SLOW_PATH)
2565     public void test102() {
2566         System.arraycopy(val_src, 0, obj_dst, 0, 8);
2567     }
2568 
2569     @Run(test = "test102")
2570     public void test102_verifier() {
2571         test102();
2572         verify(val_src, obj_dst);
2573     }
2574 
2575     // Same as test102 but with MyValue2[] dst
2576     @Test
2577     @IR(failOn = INTRINSIC_SLOW_PATH)
2578     public void test103() {
2579         System.arraycopy(val_src, 0, val_dst, 0, 8);
2580     }
2581 
2582     @Run(test = "test103")
2583     public void test103_verifier() {
2584         test103();
2585         verify(val_src, val_dst);
2586     }
2587 
2588     // Same as test102 but with Object[] src
2589     @Test
2590     @IR(failOn = INTRINSIC_SLOW_PATH)
2591     public void test104() {
2592         System.arraycopy(obj_src, 0, obj_dst, 0, 8);
2593     }
2594 
2595     @Run(test = "test104")
2596     public void test104_verifier() {
2597         test104();
2598         verify(obj_src, obj_dst);
2599     }
2600 
2601     // Same as test103 but with Object[] src
2602     @Test
2603     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2604     public void test105() {
2605         System.arraycopy(obj_src, 0, val_dst, 0, 8);
2606     }
2607 
2608     @Run(test = "test105")
2609     public void test105_verifier() {
2610         test105();
2611         verify(obj_src, val_dst);
2612     }
2613 
2614     // Same as test103 but with Object[] src containing null
2615     @Test
2616     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2617     public void test105_null() {
2618         System.arraycopy(obj_null_src, 0, val_dst, 0, 8);
2619     }
2620 
2621     @Run(test = "test105_null")
2622     public void test105_null_verifier() {
2623         try {
2624             test105_null();
2625             throw new RuntimeException("NullPointerException expected");
2626         } catch (NullPointerException e) {
2627             // expected
2628         }
2629     }
2630 
2631     // Below tests are equal to test102-test105 but hide the src/dst types until
2632     // after the arraycopy intrinsic is emitted (with incremental inlining).
2633     @Test
2634     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2635         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2636     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2637         failOn = INTRINSIC_SLOW_PATH)
2638     public void test106() {
2639         System.arraycopy(get_val_src(), 0, get_obj_dst(), 0, 8);
2640     }
2641 
2642     @Run(test = "test106")
2643     public void test106_verifier() {
2644         test106();
2645         verify(val_src, obj_dst);
2646     }
2647 
2648     // TODO 8251971: Should be optimized but we are bailing out because
2649     // at parse time it looks as if src could be flat and dst could be not flat.
2650     @Test
2651     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2652         failOn = INTRINSIC_SLOW_PATH)
2653     public void test107() {
2654         System.arraycopy(get_val_src(), 0, get_val_dst(), 0, 8);
2655     }
2656 
2657     @Run(test = "test107")
2658     public void test107_verifier() {
2659         test107();
2660         verify(val_src, val_dst);
2661     }
2662 
2663     @Test
2664     @IR(failOn = INTRINSIC_SLOW_PATH)
2665     public void test108() {
2666         System.arraycopy(get_obj_src(), 0, get_obj_dst(), 0, 8);
2667     }
2668 
2669     @Run(test = "test108")
2670     public void test108_verifier() {
2671         test108();
2672         verify(obj_src, obj_dst);
2673     }
2674 
2675     @Test
2676     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2677     public void test109() {
2678         System.arraycopy(get_obj_src(), 0, get_val_dst(), 0, 8);
2679     }
2680 
2681     @Run(test = "test109")
2682     public void test109_verifier() {
2683         test109();
2684         verify(obj_src, val_dst);
2685     }
2686 
2687     @Test
2688     @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"})
2689     public void test109_null() {
2690         System.arraycopy(get_obj_null_src(), 0, get_val_dst(), 0, 8);
2691     }
2692 
2693     @Run(test = "test109_null")
2694     public void test109_null_verifier() {
2695         try {
2696             test109_null();
2697             throw new RuntimeException("NullPointerException expected");
2698         } catch (NullPointerException e) {
2699             // expected
2700         }
2701     }
2702 
2703     // Arrays.copyOf with constant source and destination arrays
2704     @Test
2705     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2706         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2707     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2708         failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2709     public Object[] test110() {
2710         return Arrays.copyOf(val_src, 8, Object[].class);
2711     }
2712 
2713     @Run(test = "test110")
2714     public void test110_verifier() {
2715         Object[] res = test110();
2716         verify(val_src, res);
2717     }
2718 
2719     // Same as test110 but with MyValue2[] dst
2720     @Test
2721     @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2722     public Object[] test111() {
2723         return Arrays.copyOf(val_src, 8, val_src.getClass());
2724     }
2725 
2726     @Run(test = "test111")
2727     public void test111_verifier() {
2728         Object[] res = test111();
2729         verify(val_src, res);
2730     }
2731 
2732     // Same as test110 but with Object[] src
2733     @Test
2734     @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2735     public Object[] test112() {
2736         return Arrays.copyOf(obj_src, 8, Object[].class);
2737     }
2738 
2739     @Run(test = "test112")
2740     public void test112_verifier() {
2741         Object[] res = test112();
2742         verify(obj_src, res);
2743     }
2744 
2745     // Same as test111 but with Object[] src
2746     @Test
2747     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2748     public Object[] test113() {
2749         return Arrays.copyOf(obj_src, 8, MyValue2[].class);
2750     }
2751 
2752     @Run(test = "test113")
2753     public void test113_verifier() {
2754         Object[] res = test113();
2755         verify(obj_src, res);
2756     }
2757 
2758     // Same as test111 but with Object[] src containing null
2759     @Test
2760     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2761     public Object[] test113_null() {
2762         return Arrays.copyOf(obj_null_src, 8, val_src.getClass());
2763     }
2764 
2765     @Run(test = "test113_null")
2766     public void test113_null_verifier() {
2767         Object[] res = test113_null();
2768         verify(obj_null_src, res);
2769     }
2770 
2771     // Below tests are equal to test110-test113 but hide the src/dst types until
2772     // after the arraycopy intrinsic is emitted (with incremental inlining).
2773 
2774     @Test
2775     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
2776         counts = {INTRINSIC_SLOW_PATH, "= 1"})
2777     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2778         failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2779     public Object[] test114() {
2780         return Arrays.copyOf((Object[])get_val_src(), 8, get_obj_class());
2781     }
2782 
2783     @Run(test = "test114")
2784     public void test114_verifier() {
2785         Object[] res = test114();
2786         verify(val_src, res);
2787     }
2788 
2789     // TODO 8251971: Should be optimized but we are bailing out because
2790     // at parse time it looks as if src could be flat and dst could be not flat
2791     @Test
2792     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
2793         failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2794     public Object[] test115() {
2795         return Arrays.copyOf((Object[])get_val_src(), 8, get_val_class());
2796     }
2797 
2798     @Run(test = "test115")
2799     public void test115_verifier() {
2800         Object[] res = test115();
2801         verify(val_src, res);
2802     }
2803 
2804     @Test
2805     @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP})
2806     public Object[] test116() {
2807         return Arrays.copyOf((Object[])get_obj_src(), 8, get_obj_class());
2808     }
2809 
2810     @Run(test = "test116")
2811     public void test116_verifier() {
2812         Object[] res = test116();
2813         verify(obj_src, res);
2814     }
2815 
2816     @Test
2817     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2818     public Object[] test117() {
2819         return Arrays.copyOf((Object[])get_obj_src(), 8, get_val_class());
2820     }
2821 
2822     @Run(test = "test117")
2823     public void test117_verifier() {
2824         Object[] res = test117();
2825         verify(obj_src, res);
2826     }
2827 
2828     @Test
2829     @IR(counts = {CLASS_CHECK_TRAP, " = 1"})
2830     public Object[] test117_null() {
2831         return Arrays.copyOf((Object[])get_obj_null_src(), 8, get_val_class());
2832     }
2833 
2834     @Run(test = "test117_null")
2835     public void test117_null_verifier() {
2836         Object[] res = test117_null();
2837         verify((Object[])get_obj_null_src(), res);
2838     }
2839 
2840     // Some more Arrays.copyOf tests with only constant class
2841 
2842     @Test
2843     @IR(counts = {CLASS_CHECK_TRAP, "= 1"},
2844         failOn = INTRINSIC_SLOW_PATH)
2845     public Object[] test118(Object[] src) {
2846         return Arrays.copyOf(src, 8, val_src.getClass());
2847     }
2848 
2849     @Run(test = "test118")
2850     public void test118_verifier() {
2851         Object[] res = test118(obj_src);
2852         verify(obj_src, res);
2853         res = test118(val_src);
2854         verify(val_src, res);
2855         res = test118(obj_null_src);
2856         verify(obj_null_src, res);
2857     }
2858 
2859     @Test
2860     public Object[] test119(Object[] src) {
2861         return Arrays.copyOf(src, 8, Object[].class);
2862     }
2863 
2864     @Run(test = "test119")
2865     public void test119_verifier() {
2866         Object[] res = test119(obj_src);
2867         verify(obj_src, res);
2868         res = test119(val_src);
2869         verify(val_src, res);
2870     }
2871 
2872     @Test
2873     @IR(counts = {CLASS_CHECK_TRAP, "= 1"},
2874         failOn = INTRINSIC_SLOW_PATH)
2875     public Object[] test120(Object[] src) {
2876         return Arrays.copyOf(src, 8, NonValueClass[].class);
2877     }
2878 
2879     @Run(test = "test120")
2880     public void test120_verifier() {
2881         NonValueClass[] arr = new NonValueClass[8];
2882         for (int i = 0; i < 8; ++i) {
2883             arr[i] = new NonValueClass(rI + i);
2884         }
2885         Object[] res = test120(arr);
2886         verify(arr, res);
2887         try {
2888             test120(val_src);
2889             throw new RuntimeException("ArrayStoreException expected");
2890         } catch (ArrayStoreException e) {
2891             // expected
2892         }
2893     }
2894 
2895     @Test
2896     public Object[] test121(Object[] src) {
2897         return Arrays.copyOf(src, 8, val_src.getClass());
2898     }
2899 
2900     @Run(test = "test121")
2901     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2902     public void test121_verifier() {
2903         Object[] res = test121(obj_src);
2904         verify(obj_src, res);
2905         res = test121(val_src);
2906         verify(val_src, res);
2907         res = test121(obj_null_src);
2908         verify(obj_null_src, res);
2909     }
2910     @Test
2911     public Object[] test122(Object[] src) {
2912         return Arrays.copyOf(src, 8, get_val_class());
2913     }
2914 
2915     @Run(test = "test122")
2916     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2917     public void test122_verifier() {
2918         Object[] res = test122(obj_src);
2919         verify(obj_src, res);
2920         res = test122(val_src);
2921         verify(val_src, res);
2922         res = test122(obj_null_src);
2923         verify(obj_null_src, res);
2924     }
2925 
2926     @Test
2927     public Object[] test123(Object[] src) {
2928         return Arrays.copyOf(src, 8, NonValueClass[].class);
2929     }
2930 
2931     @Run(test = "test123")
2932     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2933     public void test123_verifier() {
2934         NonValueClass[] arr = new NonValueClass[8];
2935         for (int i = 0; i < 8; ++i) {
2936             arr[i] = new NonValueClass(rI + i);
2937         }
2938         Object[] res = test123(arr);
2939         verify(arr, res);
2940         try {
2941             test123(val_src);
2942             throw new RuntimeException("ArrayStoreException expected");
2943         } catch (ArrayStoreException e) {
2944             // expected
2945         }
2946     }
2947 
2948     @Test
2949     public Object[] test124(Object[] src) {
2950         return Arrays.copyOf(src, 8, get_non_val_class());
2951     }
2952 
2953     @Run(test = "test124")
2954     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2955     public void test124_verifier() {
2956         NonValueClass[] arr = new NonValueClass[8];
2957         for (int i = 0; i < 8; ++i) {
2958             arr[i] = new NonValueClass(rI + i);
2959         }
2960         Object[] res = test124(arr);
2961         verify(arr, res);
2962         try {
2963             test124(val_src);
2964             throw new RuntimeException("ArrayStoreException expected");
2965         } catch (ArrayStoreException e) {
2966             // expected
2967         }
2968     }
2969 
2970     @Test
2971     public Object[] test125(Object[] src, Class klass) {
2972         return Arrays.copyOf(src, 8, klass);
2973     }
2974 
2975     @Run(test = "test125")
2976     @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check
2977     public void test125_verifier() {
2978         NonValueClass[] arr = new NonValueClass[8];
2979         for (int i = 0; i < 8; ++i) {
2980             arr[i] = new NonValueClass(rI + i);
2981         }
2982         Object[] res = test125(arr, NonValueClass[].class);
2983         verify((Object[])arr, res);
2984         res = test125(val_src, val_src.getClass());
2985         verify(val_src, res);
2986         res = test125(obj_src, val_src.getClass());
2987         verify(val_src, res);
2988         try {
2989             test125(obj_null_src, val_src.getClass());
2990 // TODO 8325106 Remove
2991 //            throw new RuntimeException("NullPointerException expected");
2992         } catch (NullPointerException e) {
2993             // expected
2994         }
2995         try {
2996             test125(arr, val_src.getClass());
2997             throw new RuntimeException("ArrayStoreException expected");
2998         } catch (ArrayStoreException e) {
2999             // expected
3000         }
3001         try {
3002             test125(val_src, MyValue1[].class);
3003             throw new RuntimeException("ArrayStoreException expected");
3004         } catch (ArrayStoreException e) {
3005             // expected
3006         }
3007     }
3008 
3009     // Verify that clone from (flat) value class array not containing oops is always optimized.
3010     @Test
3011     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
3012         counts = {JLONG_ARRAYCOPY, "= 1"},
3013         failOn = {CHECKCAST_ARRAYCOPY, CLONE_INTRINSIC_SLOW_PATH})
3014     @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"},
3015         failOn = CLONE_INTRINSIC_SLOW_PATH)
3016     public Object[] test126() {
3017         return val_src.clone();
3018     }
3019 
3020     @Run(test = "test126")
3021     public void test126_verifier() {
3022         Object[] res = test126();
3023         verify(val_src, res);
3024     }
3025 
3026     // Verify correctness of generic_copy stub
3027     @Test
3028     public void test127(Object src, Object dst, int len) {
3029         System.arraycopy(src, 0, dst, 0, len);
3030     }
3031 
3032     @Run(test = "test127")
3033     public void test127_verifier() {
3034         test127(val_src, obj_dst, 8);
3035         verify(val_src, obj_dst);
3036         test127(val_src, val_dst, 8);
3037         verify(val_src, val_dst);
3038         test127(obj_src, val_dst, 8);
3039         verify(obj_src, val_dst);
3040         try {
3041             test127(obj_null_src, val_dst, 8);
3042             throw new RuntimeException("NullPointerException expected");
3043         } catch (NullPointerException e) {
3044             // expected
3045         }
3046     }
3047 
3048     // Verify that copyOf with known source and unknown destination class is optimized
3049     @Test
3050     @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"},
3051         counts = {JLONG_ARRAYCOPY, "= 1"},
3052         failOn = CHECKCAST_ARRAYCOPY)
3053     public Object[] test128(Class klass) {
3054         return Arrays.copyOf(val_src, 8, klass);
3055     }
3056 
3057     @Run(test = "test128")
3058     public void test128_verifier() {
3059         Object[] res = test128(MyValue2[].class);
3060         verify(val_src, res);
3061         res = test128(Object[].class);
3062         verify(val_src, res);
3063         try {
3064             test128(MyValue1[].class);
3065             throw new RuntimeException("ArrayStoreException expected");
3066         } catch (ArrayStoreException e) {
3067             // expected
3068         }
3069     }
3070 
3071     // Arraycopy with non-array src/dst
3072     @Test
3073     public void test129(Object src, Object dst, int len) {
3074         System.arraycopy(src, 0, dst, 0, len);
3075     }
3076 
3077     @Run(test = "test129")
3078     public void test129_verifier() {
3079         try {
3080             test129(new Object(), new Object[0], 0);
3081             throw new RuntimeException("ArrayStoreException expected");
3082         } catch (ArrayStoreException e) {
3083             // expected
3084         }
3085         try {
3086             test129(new Object[0], new Object(), 0);
3087             throw new RuntimeException("ArrayStoreException expected");
3088         } catch (ArrayStoreException e) {
3089             // expected
3090         }
3091     }
3092 
3093     @NullRestricted
3094     static final MyValueEmpty empty = new MyValueEmpty();
3095 
3096     // Empty value class array access
3097     @Test
3098     // TODO 8325106 Shouldn't profiling determine that the array is null restricted?
3099     //@IR(failOn = {ALLOC, ALLOCA, LOAD, STORE})
3100     public MyValueEmpty test130(MyValueEmpty[] array) {
3101         array[0] = new MyValueEmpty();
3102         return array[1];
3103     }
3104 
3105     @Run(test = "test130")
3106     public void test130_verifier() {
3107         MyValueEmpty[] array = (MyValueEmpty[])ValueClass.newNullRestrictedArray(MyValueEmpty.class, 2);
3108         MyValueEmpty res = test130(array);
3109         Asserts.assertEquals(array[0], empty);
3110         Asserts.assertEquals(res, empty);
3111     }
3112 
3113     @ImplicitlyConstructible
3114     @LooselyConsistentValue
3115     static value class EmptyContainer {
3116         @NullRestricted
3117         MyValueEmpty empty = new MyValueEmpty();
3118     }
3119 
3120     // Empty value class container array access
3121     @Test
3122     // TODO 8325106 Shouldn't profiling determine that the array is null restricted?
3123     //@IR(failOn = {ALLOC, ALLOCA, LOAD, STORE})
3124     public MyValueEmpty test131(EmptyContainer[] array) {
3125         array[0] = new EmptyContainer();
3126         return array[1].empty;
3127     }
3128 
3129     @Run(test = "test131")
3130     public void test131_verifier() {
3131         EmptyContainer[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 2);
3132         MyValueEmpty res = test131(array);
3133         Asserts.assertEquals(array[0], new EmptyContainer());
3134         Asserts.assertEquals(res, new MyValueEmpty());
3135     }
3136 
3137     // Empty value class array access with unknown array type
3138     @Test
3139     public Object test132(Object[] array) {
3140         array[0] = new MyValueEmpty();
3141         return array[1];
3142     }
3143 
3144     @Run(test = "test132")
3145     public void test132_verifier() {
3146         Object[] array = (MyValueEmpty[])ValueClass.newNullRestrictedArray(MyValueEmpty.class, 2);
3147         Object res = test132(array);
3148         Asserts.assertEquals(array[0], empty);
3149         Asserts.assertEquals(res, empty);
3150         array = new Object[2];
3151         res = test132(array);
3152         Asserts.assertEquals(array[0], empty);
3153         Asserts.assertEquals(res, null);
3154     }
3155 
3156     // Empty value class container array access with unknown array type
3157     @Test
3158     public Object test133(Object[] array) {
3159         array[0] = new EmptyContainer();
3160         return array[1];
3161     }
3162 
3163     @Run(test = "test133")
3164     public void test133_verifier() {
3165         EmptyContainer empty = new EmptyContainer();
3166         Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 2);
3167         Object res = test133(array);
3168         Asserts.assertEquals(array[0], empty);
3169         Asserts.assertEquals(res, empty);
3170         array = new Object[2];
3171         res = test133(array);
3172         Asserts.assertEquals(array[0], empty);
3173         Asserts.assertEquals(res, null);
3174     }
3175 
3176     // Non-escaping empty value class array access
3177     @Test
3178     @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE})
3179     public static MyValueEmpty test134() {
3180         MyValueEmpty[] array = new MyValueEmpty[1];
3181         array[0] = empty;
3182         return array[0];
3183     }
3184 
3185     @Run(test = "test134")
3186     public void test134_verifier() {
3187         MyValueEmpty res = test134();
3188         Asserts.assertEquals(res, empty);
3189     }
3190 
3191     // Test accessing a locked (value class) array
3192     @Test
3193     public Object test135(Object[] array, Object val) {
3194         array[0] = val;
3195         return array[1];
3196     }
3197 
3198     @Run(test = "test135")
3199     public void test135_verifier() {
3200         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
3201         array1[1] = MyValue1.createWithFieldsInline(rI, rL);
3202         synchronized (array1) {
3203             Object res = test135(array1, array1[1]);
3204             Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash());
3205             Asserts.assertEquals(array1[0].hash(), array1[1].hash());
3206         }
3207         NonValueClass[] array2 = new NonValueClass[2];
3208         array2[1] = new NonValueClass(rI);
3209         synchronized (array2) {
3210             Object res = test135(array2, array2[1]);
3211             Asserts.assertEquals(res, array2[1]);
3212             Asserts.assertEquals(array2[0], array2[1]);
3213         }
3214     }
3215 
3216     // Same as test135 but with locking in compiled method
3217     @Test
3218     public Object test136(Object[] array, Object val) {
3219         Object res = null;
3220         synchronized (array) {
3221             array[0] = val;
3222             res = array[1];
3223         }
3224         return res;
3225     }
3226 
3227     @Run(test = "test136")
3228     public void test136_verifier() {
3229         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
3230         array1[1] = MyValue1.createWithFieldsInline(rI, rL);
3231         Object res = test136(array1, array1[1]);
3232         Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash());
3233         Asserts.assertEquals(array1[0].hash(), array1[1].hash());
3234         NonValueClass[] array2 = new NonValueClass[2];
3235         array2[1] = new NonValueClass(rI);
3236         res = test136(array2, array2[1]);
3237         Asserts.assertEquals(res, array2[1]);
3238         Asserts.assertEquals(array2[0], array2[1]);
3239     }
3240 
3241     Object oFld1, oFld2;
3242 
3243     // Test loop unwswitching with locked (value class) array accesses
3244     @Test
3245     public void test137(Object[] array1, Object[] array2) {
3246         for (int i = 0; i < array1.length; i++) {
3247             oFld1 = array1[i];
3248             oFld2 = array2[i];
3249         }
3250     }
3251 
3252     @Run(test = "test137")
3253     public void test137_verifier() {
3254         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 100);
3255         Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL));
3256         NonValueClass[] array2 = new NonValueClass[100];
3257         Arrays.fill(array2, new NonValueClass(rI));
3258         synchronized (array1) {
3259             test137(array1, array1);
3260             Asserts.assertEquals(oFld1, array1[0]);
3261             Asserts.assertEquals(oFld2, array1[0]);
3262             test137(array1, array2);
3263             Asserts.assertEquals(oFld1, array1[0]);
3264             Asserts.assertEquals(oFld2, array2[0]);
3265             test137(array2, array1);
3266             Asserts.assertEquals(oFld1, array2[0]);
3267             Asserts.assertEquals(oFld2, array1[0]);
3268         }
3269         synchronized (array2) {
3270             test137(array2, array2);
3271             Asserts.assertEquals(oFld1, array2[0]);
3272             Asserts.assertEquals(oFld2, array2[0]);
3273             test137(array1, array2);
3274             Asserts.assertEquals(oFld1, array1[0]);
3275             Asserts.assertEquals(oFld2, array2[0]);
3276             test137(array2, array1);
3277             Asserts.assertEquals(oFld1, array2[0]);
3278             Asserts.assertEquals(oFld2, array1[0]);
3279         }
3280     }
3281 
3282     // Same as test137 but with locking in loop
3283     @Test
3284     public void test138(Object[] array1, Object[] array2) {
3285         for (int i = 0; i < array1.length; i++) {
3286             synchronized (array1) {
3287                 oFld1 = array1[i];
3288             }
3289             synchronized (array2) {
3290                 oFld2 = array2[i];
3291             }
3292         }
3293     }
3294 
3295     @Run(test = "test138")
3296     public void test138_verifier() {
3297         MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 100);
3298         Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL));
3299         NonValueClass[] array2 = new NonValueClass[100];
3300         Arrays.fill(array2, new NonValueClass(rI));
3301         test138(array1, array1);
3302         Asserts.assertEquals(oFld1, array1[0]);
3303         Asserts.assertEquals(oFld2, array1[0]);
3304         test138(array1, array2);
3305         Asserts.assertEquals(oFld1, array1[0]);
3306         Asserts.assertEquals(oFld2, array2[0]);
3307         test138(array2, array1);
3308         Asserts.assertEquals(oFld1, array2[0]);
3309         Asserts.assertEquals(oFld2, array1[0]);
3310         test138(array2, array2);
3311         Asserts.assertEquals(oFld1, array2[0]);
3312         Asserts.assertEquals(oFld2, array2[0]);
3313         Asserts.assertEquals(oFld2, array2[0]);
3314     }
3315 
3316     // Test load from array that is only known to be not a value class array after parsing
3317     @Test
3318     @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE,
3319                   STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3320     public Object test139() {
3321         Object[]  array = null;
3322         Object[] oarray = new NonValueClass[1];
3323         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3324         for (int i = 0; i < 10; i++) {
3325             array = varray;
3326             varray = oarray;
3327         }
3328         return array[0];
3329     }
3330 
3331     @Run(test = "test139")
3332     public void test139_verifier() {
3333         Object res = test139();
3334         Asserts.assertEquals(res, null);
3335     }
3336 
3337     // Test store to array that is only known to be not a value class array after parsing
3338     @Test
3339     @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, TRAP,
3340                   LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3341     public Object[] test140(Object val) {
3342         Object[]  array = null;
3343         Object[] oarray = new NonValueClass[1];
3344         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3345         for (int i = 0; i < 10; i++) {
3346             array = varray;
3347             varray = oarray;
3348         }
3349         array[0] = val;
3350         return array;
3351     }
3352 
3353     @Run(test = "test140")
3354     public void test140_verifier() {
3355         NonValueClass obj = new NonValueClass(rI);
3356         Object[] res = test140(obj);
3357         Asserts.assertEquals(res[0], obj);
3358         res = test140(null);
3359         Asserts.assertEquals(res[0], null);
3360     }
3361 
3362     // Test load from array that is only known to be not a value class array after parsing
3363     // TODO 8255938
3364     @Test
3365     // @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3366     public Object test141() {
3367         Object[]  array = null;
3368         Object[] oarray = new NonValueClass[1];
3369         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3370         for (int i = 0; i < 10; i++) {
3371             array = oarray;
3372             oarray = varray;
3373         }
3374         return array[0];
3375     }
3376 
3377     @Run(test = "test141")
3378     public void test141_verifier() {
3379         Object res = test141();
3380         Asserts.assertEquals(res, MyValue1.createDefaultInline());
3381     }
3382 
3383     // Test store to array that is only known to be not a value class array after parsing
3384     // TODO 8255938
3385     @Test
3386     // @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD})
3387     public Object[] test142(Object val) {
3388         Object[]  array = null;
3389         Object[] oarray = new NonValueClass[1];
3390         Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3391         for (int i = 0; i < 10; i++) {
3392             array = oarray;
3393             oarray = varray;
3394         }
3395         array[0] = val;
3396         return array;
3397     }
3398 
3399     @Run(test = "test142")
3400     public void test142_verifier(RunInfo info) {
3401         Object[] res = test142(MyValue1.createDefaultInline());
3402         Asserts.assertEquals(res[0], MyValue1.createDefaultInline());
3403         if (!info.isWarmUp()) {
3404             try {
3405                 test142(null);
3406                 throw new RuntimeException("Should throw NullPointerException");
3407             } catch (NullPointerException e) {
3408                 // Expected
3409             }
3410         }
3411     }
3412 
3413     static interface MyInterface143 {
3414         public int hash();
3415     }
3416 
3417     static class MyObject143 implements MyInterface143 {
3418         public int hash() { return 42; }
3419     }
3420 
3421     volatile MyInterface143[] array143 = new MyObject143[1];
3422     int len143 = 0;
3423 
3424     volatile int vf = 0;
3425 
3426     // Test that triggers an anti dependency failure when array mark word is loaded from immutable memory
3427     @Test
3428     public void test143() {
3429         MyInterface143[] arr = array143;
3430         int tmp = arr.length;
3431         for (int i = 0; i < len143; i++) {
3432             if (arr[i].hash() > 0) {
3433                 return;
3434             }
3435         }
3436     }
3437 
3438     @Run(test = "test143")
3439     @Warmup(0)
3440     public void test143_verifier() {
3441         test143();
3442     }
3443 
3444     // Same as test143 but with two flat array checks that are unswitched
3445     @Test
3446     public void test144() {
3447         MyInterface143[] arr1 = array143;
3448         MyInterface143[] arr2 = array143;
3449         int tmp1 = arr1.length;
3450         int tmp2 = arr2.length;
3451         for (int i = 0; i < len143; i++) {
3452             if (arr1[i].hash() > 0 && arr2[i].hash() > 0) {
3453                 return;
3454             }
3455         }
3456     }
3457 
3458     @Run(test = "test144")
3459     @Warmup(0)
3460     public void test144_verifier() {
3461         test144();
3462     }
3463 
3464     // Test that array load slow path correctly initializes non-flattened field of empty value class
3465     @Test
3466     public Object test145(Object[] array) {
3467         return array[0];
3468     }
3469 
3470     @Run(test = "test145")
3471     public void test145_verifier() {
3472         Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 1);
3473         EmptyContainer empty = (EmptyContainer)test145(array);
3474         Asserts.assertEquals(empty, new EmptyContainer());
3475     }
3476 
3477     // Test that non-flattened array does not block scalarization
3478     @Test
3479     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE})
3480     public void test146(boolean b) {
3481         MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD);
3482         MyValue2[] array = { vt };
3483         if (b) {
3484             for (int i = 0; i < 10; ++i) {
3485                 if (array != array) {
3486                     array = null;
3487                 }
3488             }
3489         }
3490     }
3491 
3492     @Run(test = "test146")
3493     @Warmup(50000)
3494     public void test146_verifier() {
3495         test146(true);
3496     }
3497 
3498     // Test that non-flattened array does not block scalarization
3499     @Test
3500     @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE})
3501     public int test147(boolean deopt) {
3502         // Both vt and array should be scalarized
3503         MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD);
3504         MyValue2[] array = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1);
3505 
3506         // Delay scalarization to after loop opts
3507         boolean store = false;
3508         for (int i = 0; i < 5; ++i) {
3509             if (i == 1) {
3510                 store = true;
3511             }
3512         }
3513         if (store) {
3514             array[0] = vt;
3515         }
3516 
3517         if (deopt) {
3518             // Uncommon trap referencing array
3519             return array[0].x + 42;
3520         }
3521         return array[0].x;
3522     }
3523 
3524     @Run(test = "test147")
3525     @Warmup(50000)
3526     public void test147_verifier(RunInfo info) {
3527         int res = test147(!info.isWarmUp());
3528         Asserts.assertEquals(res, MyValue2.createWithFieldsInline(rI, rD).x + (info.isWarmUp() ? 0 : 42));
3529     }
3530 
3531     // Test that correct basic types are used when folding field
3532     // loads from a scalar replaced array through an arraycopy.
3533     @Test
3534     public void test148(MyValue1 vt) {
3535         MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3536         MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1);
3537         src[0] = vt;
3538         System.arraycopy(src, 0, dst, 0, 1);
3539         if (src[0].hash() != dst[0].hash()) {
3540           throw new RuntimeException("Unexpected hash");
3541         }
3542     }
3543 
3544     @Run(test = "test148")
3545     public void test148_verifier() {
3546         test148(MyValue1.createWithFieldsInline(rI, rL));
3547     }
3548 
3549     // Abstract class without any value class implementers
3550     static abstract class MyAbstract149 {
3551         public abstract int get();
3552     }
3553 
3554     static class TestClass149 extends MyAbstract149 {
3555         final int x;
3556 
3557         public int get() { return x; };
3558 
3559         public TestClass149(int x) {
3560             this.x = x;
3561         }
3562     }
3563 
3564     // Test OSR compilation with array known to be not null-free/flat
3565     @Test
3566     public int test149(MyAbstract149[] array) {
3567         int res = 0;
3568         // Trigger OSR compilation
3569         for (int i = 0; i < 10_000; ++i) {
3570             res += array[i % 10].get();
3571         }
3572         return res;
3573     }
3574 
3575     @Run(test = "test149")
3576     public void test149_verifier() {
3577         TestClass149[] array = new TestClass149[10];
3578         for (int i = 0; i < 10; ++i) {
3579             array[i] = new TestClass149(i);
3580         }
3581         Asserts.assertEquals(test149(array), 45000);
3582     }
3583 
3584     @ImplicitlyConstructible
3585     @LooselyConsistentValue
3586     static value class Test150Value {
3587         Object s = "test";
3588     }
3589 
3590     // Test that optimizing a checkcast of a load from a flat array works as expected
3591     @Test
3592     static String test150() {
3593         Test150Value[] array = (Test150Value[])ValueClass.newNullRestrictedArray(Test150Value.class, 1);
3594         array[0] = new Test150Value();
3595         return (String)array[0].s;
3596     }
3597 }