1 /*
   2  * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package compiler.valhalla.valuetypes;
  25 
  26 import jdk.test.lib.Asserts;
  27 import java.lang.invoke.*;
  28 import java.lang.reflect.Method;
  29 import java.util.Arrays;
  30 
  31 /*
  32  * @test
  33  * @summary Test value type arrays
  34  * @library /testlibrary /test/lib /compiler/whitebox /
  35  * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
  36  * @compile TestArrays.java
  37  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  38  * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  39  *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI
  40  *                               compiler.valhalla.valuetypes.ValueTypeTest
  41  *                               compiler.valhalla.valuetypes.TestArrays
  42  */
  43 public class TestArrays extends ValueTypeTest {
  44     // Unlike C2, C1 intrinsics never deoptimize System.arraycopy. Instead, we fall back to
  45     // a normal method invocation when encountering flattened arrays.
  46     private static void assertDeoptimizedByC2(Method m) {
  47         int CompLevel_none              = 0,         // Interpreter
  48             CompLevel_simple            = 1,         // C1
  49             CompLevel_limited_profile   = 2,         // C1, invocation & backedge counters
  50             CompLevel_full_profile      = 3,         // C1, invocation & backedge counters + mdo
  51             CompLevel_full_optimization = 4;         // C2 or JVMCI
  52 
  53         if (USE_COMPILER && !XCOMP && WHITE_BOX.isMethodCompiled(m, false) &&
  54             WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel_full_optimization) {
  55             throw new RuntimeException("Type check should have caused it to deoptimize");
  56         }
  57     }
  58 
  59     // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters()
  60     @Override
  61     public String[] getExtraVMParameters(int scenario) {
  62         switch (scenario) {
  63         case 2: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"};
  64         case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:ValueArrayElemMaxFlatSize=-1", "-XX:-UncommonNullCast"};
  65         case 4: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"};
  66         case 5: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"};
  67         }
  68         return null;
  69     }
  70 
  71     public static void main(String[] args) throws Throwable {
  72         TestArrays test = new TestArrays();
  73         test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class);
  74     }
  75 
  76     // Helper methods
  77 
  78     protected long hash() {
  79         return hash(rI, rL);
  80     }
  81 
  82     protected long hash(int x, long y) {
  83         return MyValue1.createWithFieldsInline(x, y).hash();
  84     }
  85 
  86     // Test value type array creation and initialization
  87     @Test(valid = ValueTypeArrayFlattenOn)
  88     @Test(valid = ValueTypeArrayFlattenOff, failOn = LOAD)
  89     public MyValue1[] test1(int len) {
  90         MyValue1[] va = new MyValue1[len];
  91         for (int i = 0; i < len; ++i) {
  92             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
  93         }
  94         return va;
  95     }
  96 
  97     @DontCompile
  98     public void test1_verifier(boolean warmup) {
  99         int len = Math.abs(rI % 10);
 100         MyValue1[] va = test1(len);
 101         for (int i = 0; i < len; ++i) {
 102             Asserts.assertEQ(va[i].hash(), hash());
 103         }
 104     }
 105 
 106     // Test creation of a value type array and element access
 107     // TODO 8227588
 108     @Test(valid = ValueTypeArrayFlattenOn, failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP)
 109     @Test(valid = ValueTypeArrayFlattenOff)
 110     public long test2() {
 111         MyValue1[] va = new MyValue1[1];
 112         va[0] = MyValue1.createWithFieldsInline(rI, rL);
 113         return va[0].hash();
 114     }
 115 
 116     @DontCompile
 117     public void test2_verifier(boolean warmup) {
 118         long result = test2();
 119         Asserts.assertEQ(result, hash());
 120     }
 121 
 122     // Test receiving a value type array from the interpreter,
 123     // updating its elements in a loop and computing a hash.
 124     @Test(failOn = ALLOCA)
 125     public long test3(MyValue1[] va) {
 126         long result = 0;
 127         for (int i = 0; i < 10; ++i) {
 128             result += va[i].hash();
 129             va[i] = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 130         }
 131         return result;
 132     }
 133 
 134     @DontCompile
 135     public void test3_verifier(boolean warmup) {
 136         MyValue1[] va = new MyValue1[10];
 137         long expected = 0;
 138         for (int i = 0; i < 10; ++i) {
 139             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 140             expected += va[i].hash();
 141         }
 142         long result = test3(va);
 143         Asserts.assertEQ(expected, result);
 144         for (int i = 0; i < 10; ++i) {
 145             if (va[i].hash() != hash(rI + 1, rL + 1)) {
 146                 Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1));
 147             }
 148         }
 149     }
 150 
 151     // Test returning a value type array received from the interpreter
 152     @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP)
 153     public MyValue1[] test4(MyValue1[] va) {
 154         return va;
 155     }
 156 
 157     @DontCompile
 158     public void test4_verifier(boolean warmup) {
 159         MyValue1[] va = new MyValue1[10];
 160         for (int i = 0; i < 10; ++i) {
 161             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 162         }
 163         va = test4(va);
 164         for (int i = 0; i < 10; ++i) {
 165             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 166         }
 167     }
 168 
 169     // Merge value type arrays created from two branches
 170     @Test
 171     public MyValue1[] test5(boolean b) {
 172         MyValue1[] va;
 173         if (b) {
 174             va = new MyValue1[5];
 175             for (int i = 0; i < 5; ++i) {
 176                 va[i] = MyValue1.createWithFieldsInline(rI, rL);
 177             }
 178         } else {
 179             va = new MyValue1[10];
 180             for (int i = 0; i < 10; ++i) {
 181                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
 182             }
 183         }
 184         long sum = va[0].hashInterpreted();
 185         if (b) {
 186             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
 187         } else {
 188             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
 189         }
 190         return va;
 191     }
 192 
 193     @DontCompile
 194     public void test5_verifier(boolean warmup) {
 195         MyValue1[] va = test5(true);
 196         Asserts.assertEQ(va.length, 5);
 197         Asserts.assertEQ(va[0].hash(), hash(rI, hash()));
 198         for (int i = 1; i < 5; ++i) {
 199             Asserts.assertEQ(va[i].hash(), hash());
 200         }
 201         va = test5(false);
 202         Asserts.assertEQ(va.length, 10);
 203         Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1));
 204         for (int i = 1; i < 10; ++i) {
 205             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 206         }
 207     }
 208 
 209     // Test creation of value type array with single element
 210     @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP)
 211     public MyValue1 test6() {
 212         MyValue1[] va = new MyValue1[1];
 213         return va[0];
 214     }
 215 
 216     @DontCompile
 217     public void test6_verifier(boolean warmup) {
 218         MyValue1[] va = new MyValue1[1];
 219         MyValue1 v = test6();
 220         Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive());
 221     }
 222 
 223     // Test default initialization of value type arrays
 224     @Test(failOn = LOAD)
 225     public MyValue1[] test7(int len) {
 226         return new MyValue1[len];
 227     }
 228 
 229     @DontCompile
 230     public void test7_verifier(boolean warmup) {
 231         int len = Math.abs(rI % 10);
 232         MyValue1[] va = new MyValue1[len];
 233         MyValue1[] var = test7(len);
 234         for (int i = 0; i < len; ++i) {
 235             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
 236         }
 237     }
 238 
 239     // Test creation of value type array with zero length
 240     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
 241     public MyValue1[] test8() {
 242         return new MyValue1[0];
 243     }
 244 
 245     @DontCompile
 246     public void test8_verifier(boolean warmup) {
 247         MyValue1[] va = test8();
 248         Asserts.assertEQ(va.length, 0);
 249     }
 250 
 251     static MyValue1[] test9_va;
 252 
 253     // Test that value type array loaded from field has correct type
 254     @Test(failOn = LOOP)
 255     public long test9() {
 256         return test9_va[0].hash();
 257     }
 258 
 259     @DontCompile
 260     public void test9_verifier(boolean warmup) {
 261         test9_va = new MyValue1[1];
 262         test9_va[0] = MyValue1.createWithFieldsInline(rI, rL);
 263         long result = test9();
 264         Asserts.assertEQ(result, hash());
 265     }
 266 
 267     // Multi-dimensional arrays
 268     @Test
 269     public MyValue1[][][] test10(int len1, int len2, int len3) {
 270         MyValue1[][][] arr = new MyValue1[len1][len2][len3];
 271         for (int i = 0; i < len1; i++) {
 272             for (int j = 0; j < len2; j++) {
 273                 for (int k = 0; k < len3; k++) {
 274                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i , rL + j + k);
 275                 }
 276             }
 277         }
 278         return arr;
 279     }
 280 
 281     @DontCompile
 282     public void test10_verifier(boolean warmup) {
 283         MyValue1[][][] arr = test10(2, 3, 4);
 284         for (int i = 0; i < 2; i++) {
 285             for (int j = 0; j < 3; j++) {
 286                 for (int k = 0; k < 4; k++) {
 287                     Asserts.assertEQ(arr[i][j][k].hash(), MyValue1.createWithFieldsDontInline(rI + i , rL + j + k).hash());
 288                 }
 289             }
 290         }
 291     }
 292 
 293     @Test
 294     public void test11(MyValue1[][][] arr, long[] res) {
 295         int l = 0;
 296         for (int i = 0; i < arr.length; i++) {
 297             for (int j = 0; j < arr[i].length; j++) {
 298                 for (int k = 0; k < arr[i][j].length; k++) {
 299                     res[l] = arr[i][j][k].hash();
 300                     l++;
 301                 }
 302             }
 303         }
 304     }
 305 
 306     @DontCompile
 307     public void test11_verifier(boolean warmup) {
 308         MyValue1[][][] arr = new MyValue1[2][3][4];
 309         long[] res = new long[2*3*4];
 310         long[] verif = new long[2*3*4];
 311         int l = 0;
 312         for (int i = 0; i < 2; i++) {
 313             for (int j = 0; j < 3; j++) {
 314                 for (int k = 0; k < 4; k++) {
 315                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i, rL + j + k);
 316                     verif[l] = arr[i][j][k].hash();
 317                     l++;
 318                 }
 319             }
 320         }
 321         test11(arr, res);
 322         for (int i = 0; i < verif.length; i++) {
 323             Asserts.assertEQ(res[i], verif[i]);
 324         }
 325     }
 326 
 327     // Array load out of bounds (upper bound) at compile time
 328     @Test
 329     public int test12() {
 330         int arraySize = Math.abs(rI) % 10;;
 331         MyValue1[] va = new MyValue1[arraySize];
 332 
 333         for (int i = 0; i < arraySize; i++) {
 334             va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 335         }
 336 
 337         try {
 338             return va[arraySize + 1].x;
 339         } catch (ArrayIndexOutOfBoundsException e) {
 340             return rI;
 341         }
 342     }
 343 
 344     public void test12_verifier(boolean warmup) {
 345         Asserts.assertEQ(test12(), rI);
 346     }
 347 
 348     // Array load  out of bounds (lower bound) at compile time
 349     @Test
 350     public int test13() {
 351         int arraySize = Math.abs(rI) % 10;;
 352         MyValue1[] va = new MyValue1[arraySize];
 353 
 354         for (int i = 0; i < arraySize; i++) {
 355             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL);
 356         }
 357 
 358         try {
 359             return va[-arraySize].x;
 360         } catch (ArrayIndexOutOfBoundsException e) {
 361             return rI;
 362         }
 363     }
 364 
 365     public void test13_verifier(boolean warmup) {
 366         Asserts.assertEQ(test13(), rI);
 367     }
 368 
 369     // Array load out of bound not known to compiler (both lower and upper bound)
 370     @Test
 371     public int test14(MyValue1[] va, int index)  {
 372         return va[index].x;
 373     }
 374 
 375     public void test14_verifier(boolean warmup) {
 376         int arraySize = Math.abs(rI) % 10;
 377         MyValue1[] va = new MyValue1[arraySize];
 378 
 379         for (int i = 0; i < arraySize; i++) {
 380             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 381         }
 382 
 383         int result;
 384         for (int i = -20; i < 20; i++) {
 385             try {
 386                 result = test14(va, i);
 387             } catch (ArrayIndexOutOfBoundsException e) {
 388                 result = rI;
 389             }
 390             Asserts.assertEQ(result, rI);
 391         }
 392     }
 393 
 394     // Array store out of bounds (upper bound) at compile time
 395     @Test
 396     public int test15() {
 397         int arraySize = Math.abs(rI) % 10;;
 398         MyValue1[] va = new MyValue1[arraySize];
 399 
 400         try {
 401             for (int i = 0; i <= arraySize; i++) {
 402                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 403             }
 404             return rI - 1;
 405         } catch (ArrayIndexOutOfBoundsException e) {
 406             return rI;
 407         }
 408     }
 409 
 410     public void test15_verifier(boolean warmup) {
 411         Asserts.assertEQ(test15(), rI);
 412     }
 413 
 414     // Array store out of bounds (lower bound) at compile time
 415     @Test
 416     public int test16() {
 417         int arraySize = Math.abs(rI) % 10;;
 418         MyValue1[] va = new MyValue1[arraySize];
 419 
 420         try {
 421             for (int i = -1; i <= arraySize; i++) {
 422                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 423             }
 424             return rI - 1;
 425         } catch (ArrayIndexOutOfBoundsException e) {
 426             return rI;
 427         }
 428     }
 429 
 430     public void test16_verifier(boolean warmup) {
 431         Asserts.assertEQ(test16(), rI);
 432     }
 433 
 434     // Array store out of bound not known to compiler (both lower and upper bound)
 435     @Test
 436     public int test17(MyValue1[] va, int index, MyValue1 vt)  {
 437         va[index] = vt;
 438         return va[index].x;
 439     }
 440 
 441     @DontCompile
 442     public void test17_verifier(boolean warmup) {
 443         int arraySize = Math.abs(rI) % 10;
 444         MyValue1[] va = new MyValue1[arraySize];
 445 
 446         for (int i = 0; i < arraySize; i++) {
 447             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 448         }
 449 
 450         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 451         int result;
 452         for (int i = -20; i < 20; i++) {
 453             try {
 454                 result = test17(va, i, vt);
 455             } catch (ArrayIndexOutOfBoundsException e) {
 456                 result = rI + 1;
 457             }
 458             Asserts.assertEQ(result, rI + 1);
 459         }
 460 
 461         for (int i = 0; i < arraySize; i++) {
 462             Asserts.assertEQ(va[i].x, rI + 1);
 463         }
 464     }
 465 
 466     // clone() as stub call
 467     @Test
 468     public MyValue1[] test18(MyValue1[] va) {
 469         return va.clone();
 470     }
 471 
 472     @DontCompile
 473     public void test18_verifier(boolean warmup) {
 474         int len = Math.abs(rI) % 10;
 475         MyValue1[] va = new MyValue1[len];
 476         for (int i = 0; i < len; ++i) {
 477             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 478         }
 479         MyValue1[] result = test18(va);
 480         for (int i = 0; i < len; ++i) {
 481             Asserts.assertEQ(result[i].hash(), va[i].hash());
 482         }
 483     }
 484 
 485     // clone() as series of loads/stores
 486     static MyValue1[] test19_orig = null;
 487 
 488     @Test
 489     public MyValue1[] test19() {
 490         MyValue1[] va = new MyValue1[8];
 491         for (int i = 0; i < va.length; ++i) {
 492             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 493         }
 494         test19_orig = va;
 495 
 496         return va.clone();
 497     }
 498 
 499     @DontCompile
 500     public void test19_verifier(boolean warmup) {
 501         MyValue1[] result = test19();
 502         for (int i = 0; i < test19_orig.length; ++i) {
 503             Asserts.assertEQ(result[i].hash(), test19_orig[i].hash());
 504         }
 505     }
 506 
 507     // arraycopy() of value type array with oop fields
 508     @Test
 509     public void test20(MyValue1[] src, MyValue1[] dst) {
 510         System.arraycopy(src, 0, dst, 0, src.length);
 511     }
 512 
 513     @DontCompile
 514     public void test20_verifier(boolean warmup) {
 515         int len = Math.abs(rI) % 10;
 516         MyValue1[] src = new MyValue1[len];
 517         MyValue1[] dst = new MyValue1[len];
 518         for (int i = 0; i < len; ++i) {
 519             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 520         }
 521         test20(src, dst);
 522         for (int i = 0; i < len; ++i) {
 523             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 524         }
 525     }
 526 
 527     // arraycopy() of value type array with no oop field
 528     @Test
 529     public void test21(MyValue2[] src, MyValue2[] dst) {
 530         System.arraycopy(src, 0, dst, 0, src.length);
 531     }
 532 
 533     @DontCompile
 534     public void test21_verifier(boolean warmup) {
 535         int len = Math.abs(rI) % 10;
 536         MyValue2[] src = new MyValue2[len];
 537         MyValue2[] dst = new MyValue2[len];
 538         for (int i = 0; i < len; ++i) {
 539             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 540         }
 541         test21(src, dst);
 542         for (int i = 0; i < len; ++i) {
 543             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 544         }
 545     }
 546 
 547     // arraycopy() of value type array with oop field and tightly
 548     // coupled allocation as dest
 549     @Test
 550     public MyValue1[] test22(MyValue1[] src) {
 551         MyValue1[] dst = new MyValue1[src.length];
 552         System.arraycopy(src, 0, dst, 0, src.length);
 553         return dst;
 554     }
 555 
 556     @DontCompile
 557     public void test22_verifier(boolean warmup) {
 558         int len = Math.abs(rI) % 10;
 559         MyValue1[] src = new MyValue1[len];
 560         for (int i = 0; i < len; ++i) {
 561             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 562         }
 563         MyValue1[] dst = test22(src);
 564         for (int i = 0; i < len; ++i) {
 565             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 566         }
 567     }
 568 
 569     // arraycopy() of value type array with oop fields and tightly
 570     // coupled allocation as dest
 571     @Test
 572     public MyValue1[] test23(MyValue1[] src) {
 573         MyValue1[] dst = new MyValue1[src.length + 10];
 574         System.arraycopy(src, 0, dst, 5, src.length);
 575         return dst;
 576     }
 577 
 578     @DontCompile
 579     public void test23_verifier(boolean warmup) {
 580         int len = Math.abs(rI) % 10;
 581         MyValue1[] src = new MyValue1[len];
 582         for (int i = 0; i < len; ++i) {
 583             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 584         }
 585         MyValue1[] dst = test23(src);
 586         for (int i = 5; i < len; ++i) {
 587             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 588         }
 589     }
 590 
 591     // arraycopy() of value type array passed as Object
 592     @Test
 593     public void test24(MyValue1[] src, Object dst) {
 594         System.arraycopy(src, 0, dst, 0, src.length);
 595     }
 596 
 597     @DontCompile
 598     public void test24_verifier(boolean warmup) {
 599         int len = Math.abs(rI) % 10;
 600         MyValue1[] src = new MyValue1[len];
 601         MyValue1[] dst = new MyValue1[len];
 602         for (int i = 0; i < len; ++i) {
 603             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 604         }
 605         test24(src, dst);
 606         for (int i = 0; i < len; ++i) {
 607             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 608         }
 609     }
 610 
 611     // short arraycopy() with no oop field
 612     @Test
 613     public void test25(MyValue2[] src, MyValue2[] dst) {
 614         System.arraycopy(src, 0, dst, 0, 8);
 615     }
 616 
 617     @DontCompile
 618     public void test25_verifier(boolean warmup) {
 619         MyValue2[] src = new MyValue2[8];
 620         MyValue2[] dst = new MyValue2[8];
 621         for (int i = 0; i < 8; ++i) {
 622             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 623         }
 624         test25(src, dst);
 625         for (int i = 0; i < 8; ++i) {
 626             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 627         }
 628     }
 629 
 630     // short arraycopy() with oop fields
 631     @Test
 632     public void test26(MyValue1[] src, MyValue1[] dst) {
 633         System.arraycopy(src, 0, dst, 0, 8);
 634     }
 635 
 636     @DontCompile
 637     public void test26_verifier(boolean warmup) {
 638         MyValue1[] src = new MyValue1[8];
 639         MyValue1[] dst = new MyValue1[8];
 640         for (int i = 0; i < 8; ++i) {
 641             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 642         }
 643         test26(src, dst);
 644         for (int i = 0; i < 8; ++i) {
 645             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 646         }
 647     }
 648 
 649     // short arraycopy() with oop fields and offsets
 650     @Test
 651     public void test27(MyValue1[] src, MyValue1[] dst) {
 652         System.arraycopy(src, 1, dst, 2, 6);
 653     }
 654 
 655     @DontCompile
 656     public void test27_verifier(boolean warmup) {
 657         MyValue1[] src = new MyValue1[8];
 658         MyValue1[] dst = new MyValue1[8];
 659         for (int i = 0; i < 8; ++i) {
 660             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 661         }
 662         test27(src, dst);
 663         for (int i = 2; i < 8; ++i) {
 664             Asserts.assertEQ(src[i-1].hash(), dst[i].hash());
 665         }
 666     }
 667 
 668     // non escaping allocations
 669     @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
 670     public MyValue2 test28() {
 671         MyValue2[] src = new MyValue2[10];
 672         src[0] = MyValue2.createWithFieldsInline(rI, false);
 673         MyValue2[] dst = (MyValue2[])src.clone();
 674         return dst[0];
 675     }
 676 
 677     @DontCompile
 678     public void test28_verifier(boolean warmup) {
 679         MyValue2 v = MyValue2.createWithFieldsInline(rI, false);
 680         MyValue2 result = test28();
 681         Asserts.assertEQ(result.hash(), v.hash());
 682     }
 683 
 684     // non escaping allocations
 685     // TODO 8227588: shouldn't this have the same IR matching rules as test6?
 686     @Test(valid = ValueTypeArrayFlattenOn, failOn = ALLOCA + LOOP + LOAD + TRAP)
 687     @Test(valid = ValueTypeArrayFlattenOff)
 688     public MyValue2 test29(MyValue2[] src) {
 689         MyValue2[] dst = new MyValue2[10];
 690         System.arraycopy(src, 0, dst, 0, 10);
 691         return dst[0];
 692     }
 693 
 694     @DontCompile
 695     public void test29_verifier(boolean warmup) {
 696         MyValue2[] src = new MyValue2[10];
 697         for (int i = 0; i < 10; ++i) {
 698             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 699         }
 700         MyValue2 v = test29(src);
 701         Asserts.assertEQ(src[0].hash(), v.hash());
 702     }
 703 
 704     // non escaping allocation with uncommon trap that needs
 705     // eliminated value type array element as debug info
 706     @Test
 707     @Warmup(10000)
 708     public MyValue2 test30(MyValue2[] src, boolean flag) {
 709         MyValue2[] dst = new MyValue2[10];
 710         System.arraycopy(src, 0, dst, 0, 10);
 711         if (flag) { }
 712         return dst[0];
 713     }
 714 
 715     @DontCompile
 716     public void test30_verifier(boolean warmup) {
 717         MyValue2[] src = new MyValue2[10];
 718         for (int i = 0; i < 10; ++i) {
 719             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 720         }
 721         MyValue2 v = test30(src, !warmup);
 722         Asserts.assertEQ(src[0].hash(), v.hash());
 723     }
 724 
 725     // non escaping allocation with memory phi
 726     // TODO 8227588
 727     @Test(valid = ValueTypeArrayFlattenOn, failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP)
 728     @Test(valid = ValueTypeArrayFlattenOff)
 729     public long test31(boolean b, boolean deopt) {
 730         MyValue2[] src = new MyValue2[1];
 731         if (b) {
 732             src[0] = MyValue2.createWithFieldsInline(rI, true);
 733         } else {
 734             src[0] = MyValue2.createWithFieldsInline(rI, false);
 735         }
 736         if (deopt) {
 737             // uncommon trap
 738             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31"));
 739         }
 740         return src[0].hash();
 741     }
 742 
 743     @DontCompile
 744     public void test31_verifier(boolean warmup) {
 745         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true);
 746         long result1 = test31(true, !warmup);
 747         Asserts.assertEQ(result1, v1.hash());
 748         MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false);
 749         long result2 = test31(false, !warmup);
 750         Asserts.assertEQ(result2, v2.hash());
 751     }
 752 
 753     // Tests with Object arrays and clone/arraycopy
 754     // clone() as stub call
 755     @Test
 756     public Object[] test32(Object[] va) {
 757         return va.clone();
 758     }
 759 
 760     @DontCompile
 761     public void test32_verifier(boolean warmup) {
 762         int len = Math.abs(rI) % 10;
 763         MyValue1[] va = new MyValue1[len];
 764         for (int i = 0; i < len; ++i) {
 765             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 766         }
 767         MyValue1[] result = (MyValue1[])test32(va);
 768         for (int i = 0; i < len; ++i) {
 769             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 770         }
 771     }
 772 
 773     @Test
 774     public Object[] test33(Object[] va) {
 775         return va.clone();
 776     }
 777 
 778     @DontCompile
 779     public void test33_verifier(boolean warmup) {
 780         int len = Math.abs(rI) % 10;
 781         Object[] va = new Object[len];
 782         for (int i = 0; i < len; ++i) {
 783             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 784         }
 785         Object[] result = test33(va);
 786         for (int i = 0; i < len; ++i) {
 787             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 788             // Check that array has correct storage properties (null-ok)
 789             result[i] = null;
 790         }
 791     }
 792 
 793     // clone() as series of loads/stores
 794     static Object[] test34_orig = null;
 795 
 796     @ForceInline
 797     public Object[] test34_helper(boolean flag) {
 798         Object[] va = null;
 799         if (flag) {
 800             va = new MyValue1[8];
 801             for (int i = 0; i < va.length; ++i) {
 802                 va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 803             }
 804         } else {
 805             va = new Object[8];
 806         }
 807         return va;
 808     }
 809 
 810     @Test
 811     public Object[] test34(boolean flag) {
 812         Object[] va = test34_helper(flag);
 813         test34_orig = va;
 814         return va.clone();
 815     }
 816 
 817     @DontCompile
 818     public void test34_verifier(boolean warmup) {
 819         test34(false);
 820         for (int i = 0; i < 10; i++) { // make sure we do deopt
 821             Object[] result = test34(true);
 822             verify(test34_orig, result);
 823             // Check that array has correct storage properties (null-free)
 824             try {
 825                 result[0] = null;
 826                 throw new RuntimeException("Should throw NullPointerException");
 827             } catch (NullPointerException e) {
 828                 // Expected
 829             }
 830         }
 831         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test34")) {
 832             Object[] result = test34(true);
 833             verify(test34_orig, result);
 834             // Check that array has correct storage properties (null-free)
 835             try {
 836                 result[0] = null;
 837                 throw new RuntimeException("Should throw NullPointerException");
 838             } catch (NullPointerException e) {
 839                 // Expected
 840             }
 841         }
 842     }
 843 
 844     static void verify(Object[] src, Object[] dst) {
 845         for (int i = 0; i < src.length; ++i) {
 846             Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash());
 847         }
 848     }
 849 
 850     static void verify(MyValue1[] src, MyValue1[] dst) {
 851         for (int i = 0; i < src.length; ++i) {
 852             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 853         }
 854     }
 855 
 856     static void verify(MyValue1[] src, Object[] dst) {
 857         for (int i = 0; i < src.length; ++i) {
 858             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 859         }
 860     }
 861 
 862     static void verify(MyValue2[] src, MyValue2[] dst) {
 863         for (int i = 0; i < src.length; ++i) {
 864             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 865         }
 866     }
 867 
 868     static void verify(MyValue2[] src, Object[] dst) {
 869         for (int i = 0; i < src.length; ++i) {
 870             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 871         }
 872     }
 873 
 874     static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) {
 875         if (!warmup) {
 876             Method m = tests.get(test);
 877             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false)) {
 878                 if (!ValueTypeArrayFlatten && !XCOMP) {
 879                     throw new RuntimeException("Unexpected deoptimization");
 880                 }
 881                 enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
 882                 return true;
 883             }
 884         }
 885         return false;
 886     }
 887 
 888     // arraycopy() of value type array of unknown size
 889     @Test
 890     public void test35(Object src, Object dst, int len) {
 891         System.arraycopy(src, 0, dst, 0, len);
 892     }
 893 
 894     @DontCompile
 895     public void test35_verifier(boolean warmup) {
 896         int len = Math.abs(rI) % 10;
 897         MyValue1[] src = new MyValue1[len];
 898         MyValue1[] dst = new MyValue1[len];
 899         for (int i = 0; i < len; ++i) {
 900             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 901         }
 902         test35(src, dst, src.length);
 903         verify(src, dst);
 904         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test35")) {
 905             test35(src, dst, src.length);
 906             verify(src, dst);
 907         }
 908     }
 909 
 910     @Test
 911     public void test36(Object src, MyValue2[] dst) {
 912         System.arraycopy(src, 0, dst, 0, dst.length);
 913     }
 914 
 915     @DontCompile
 916     public void test36_verifier(boolean warmup) {
 917         int len = Math.abs(rI) % 10;
 918         MyValue2[] src = new MyValue2[len];
 919         MyValue2[] dst = new MyValue2[len];
 920         for (int i = 0; i < len; ++i) {
 921             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 922         }
 923         test36(src, dst);
 924         verify(src, dst);
 925         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test36")) {
 926             test36(src, dst);
 927             verify(src, dst);
 928         }
 929     }
 930 
 931     @Test
 932     public void test37(MyValue2[] src, Object dst) {
 933         System.arraycopy(src, 0, dst, 0, src.length);
 934     }
 935 
 936     @DontCompile
 937     public void test37_verifier(boolean warmup) {
 938         int len = Math.abs(rI) % 10;
 939         MyValue2[] src = new MyValue2[len];
 940         MyValue2[] dst = new MyValue2[len];
 941         for (int i = 0; i < len; ++i) {
 942             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 943         }
 944         test37(src, dst);
 945         verify(src, dst);
 946         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test37")) {
 947             test37(src, dst);
 948             verify(src, dst);
 949         }
 950     }
 951 
 952     @Test
 953     @Warmup(1) // Avoid early compilation
 954     public void test38(Object src, MyValue2[] dst) {
 955         System.arraycopy(src, 0, dst, 0, dst.length);
 956     }
 957 
 958     @DontCompile
 959     public void test38_verifier(boolean warmup) {
 960         int len = Math.abs(rI) % 10;
 961         Object[] src = new Object[len];
 962         MyValue2[] dst = new MyValue2[len];
 963         for (int i = 0; i < len; ++i) {
 964             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 965         }
 966         test38(src, dst);
 967         verify(dst, src);
 968         if (!warmup) {
 969             Method m = tests.get("TestArrays::test38");
 970             assertDeoptimizedByC2(m);
 971             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
 972             test38(src, dst);
 973             verify(dst, src);
 974             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
 975                 throw new RuntimeException("unexpected deoptimization");
 976             }
 977         }
 978     }
 979 
 980     @Test
 981     public void test39(MyValue2[] src, Object dst) {
 982         System.arraycopy(src, 0, dst, 0, src.length);
 983     }
 984 
 985     @DontCompile
 986     public void test39_verifier(boolean warmup) {
 987         int len = Math.abs(rI) % 10;
 988         MyValue2[] src = new MyValue2[len];
 989         Object[] dst = new Object[len];
 990         for (int i = 0; i < len; ++i) {
 991             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 992         }
 993         test39(src, dst);
 994         verify(src, dst);
 995         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test39")) {
 996             test39(src, dst);
 997             verify(src, dst);
 998         }
 999     }
1000 
1001     @Test
1002     @Warmup(1) // Avoid early compilation
1003     public void test40(Object[] src, Object dst) {
1004         System.arraycopy(src, 0, dst, 0, src.length);
1005     }
1006 
1007     @DontCompile
1008     public void test40_verifier(boolean warmup) {
1009         int len = Math.abs(rI) % 10;
1010         Object[] src = new Object[len];
1011         MyValue2[] dst = new MyValue2[len];
1012         for (int i = 0; i < len; ++i) {
1013             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1014         }
1015         test40(src, dst);
1016         verify(dst, src);
1017         if (!warmup) {
1018             Method m = tests.get("TestArrays::test40");
1019             assertDeoptimizedByC2(m);
1020             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1021             test40(src, dst);
1022             verify(dst, src);
1023             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1024                 throw new RuntimeException("unexpected deoptimization");
1025             }
1026         }
1027     }
1028 
1029     @Test
1030     public void test41(Object src, Object[] dst) {
1031         System.arraycopy(src, 0, dst, 0, dst.length);
1032     }
1033 
1034     @DontCompile
1035     public void test41_verifier(boolean warmup) {
1036         int len = Math.abs(rI) % 10;
1037         MyValue2[] src = new MyValue2[len];
1038         Object[] dst = new Object[len];
1039         for (int i = 0; i < len; ++i) {
1040             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1041         }
1042         test41(src, dst);
1043         verify(src, dst);
1044         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test41")) {
1045             test41(src, dst);
1046             verify(src, dst);
1047         }
1048     }
1049 
1050     @Test
1051     public void test42(Object[] src, Object[] dst) {
1052         System.arraycopy(src, 0, dst, 0, src.length);
1053     }
1054 
1055     @DontCompile
1056     public void test42_verifier(boolean warmup) {
1057         int len = Math.abs(rI) % 10;
1058         Object[] src = new Object[len];
1059         Object[] dst = new Object[len];
1060         for (int i = 0; i < len; ++i) {
1061             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1062         }
1063         test42(src, dst);
1064         verify(src, dst);
1065         if (!warmup) {
1066             Method m = tests.get("TestArrays::test42");
1067             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1068                 throw new RuntimeException("unexpected deoptimization");
1069             }
1070         }
1071     }
1072 
1073     // short arraycopy()'s
1074     @Test
1075     public void test43(Object src, Object dst) {
1076         System.arraycopy(src, 0, dst, 0, 8);
1077     }
1078 
1079     @DontCompile
1080     public void test43_verifier(boolean warmup) {
1081         MyValue1[] src = new MyValue1[8];
1082         MyValue1[] dst = new MyValue1[8];
1083         for (int i = 0; i < 8; ++i) {
1084             src[i] = MyValue1.createWithFieldsInline(rI, rL);
1085         }
1086         test43(src, dst);
1087         verify(src, dst);
1088         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test43")) {
1089             test43(src, dst);
1090             verify(src, dst);
1091         }
1092     }
1093 
1094     @Test
1095     public void test44(Object src, MyValue2[] dst) {
1096         System.arraycopy(src, 0, dst, 0, 8);
1097     }
1098 
1099     @DontCompile
1100     public void test44_verifier(boolean warmup) {
1101         MyValue2[] src = new MyValue2[8];
1102         MyValue2[] dst = new MyValue2[8];
1103         for (int i = 0; i < 8; ++i) {
1104             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1105         }
1106         test44(src, dst);
1107         verify(src, dst);
1108         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test44")) {
1109             test44(src, dst);
1110             verify(src, dst);
1111         }
1112     }
1113 
1114     @Test
1115     public void test45(MyValue2[] src, Object dst) {
1116         System.arraycopy(src, 0, dst, 0, 8);
1117     }
1118 
1119     @DontCompile
1120     public void test45_verifier(boolean warmup) {
1121         MyValue2[] src = new MyValue2[8];
1122         MyValue2[] dst = new MyValue2[8];
1123         for (int i = 0; i < 8; ++i) {
1124             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1125         }
1126         test45(src, dst);
1127         verify(src, dst);
1128         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test45")) {
1129             test45(src, dst);
1130             verify(src, dst);
1131         }
1132     }
1133 
1134     @Test
1135     @Warmup(1) // Avoid early compilation
1136     public void test46(Object[] src, MyValue2[] dst) {
1137         System.arraycopy(src, 0, dst, 0, 8);
1138     }
1139 
1140     @DontCompile
1141     public void test46_verifier(boolean warmup) {
1142         Object[] src = new Object[8];
1143         MyValue2[] dst = new MyValue2[8];
1144         for (int i = 0; i < 8; ++i) {
1145             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1146         }
1147         test46(src, dst);
1148         verify(dst, src);
1149         if (!warmup) {
1150             Method m = tests.get("TestArrays::test46");
1151             assertDeoptimizedByC2(m);
1152             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1153             test46(src, dst);
1154             verify(dst, src);
1155             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1156                 throw new RuntimeException("unexpected deoptimization");
1157             }
1158         }
1159     }
1160 
1161     @Test
1162     public void test47(MyValue2[] src, Object[] dst) {
1163         System.arraycopy(src, 0, dst, 0, 8);
1164     }
1165 
1166     @DontCompile
1167     public void test47_verifier(boolean warmup) {
1168         MyValue2[] src = new MyValue2[8];
1169         Object[] dst = new Object[8];
1170         for (int i = 0; i < 8; ++i) {
1171             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1172         }
1173         test47(src, dst);
1174         verify(src, dst);
1175         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test47")) {
1176             test47(src, dst);
1177             verify(src, dst);
1178         }
1179     }
1180 
1181     @Test
1182     @Warmup(1) // Avoid early compilation
1183     public void test48(Object[] src, Object dst) {
1184         System.arraycopy(src, 0, dst, 0, 8);
1185     }
1186 
1187     @DontCompile
1188     public void test48_verifier(boolean warmup) {
1189         Object[] src = new Object[8];
1190         MyValue2[] dst = new MyValue2[8];
1191         for (int i = 0; i < 8; ++i) {
1192             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1193         }
1194         test48(src, dst);
1195         verify(dst, src);
1196         if (!warmup) {
1197             Method m = tests.get("TestArrays::test48");
1198             assertDeoptimizedByC2(m);
1199             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1200             test48(src, dst);
1201             verify(dst, src);
1202             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1203                 throw new RuntimeException("unexpected deoptimization");
1204             }
1205         }
1206     }
1207 
1208     @Test
1209     public void test49(Object src, Object[] dst) {
1210         System.arraycopy(src, 0, dst, 0, 8);
1211     }
1212 
1213     @DontCompile
1214     public void test49_verifier(boolean warmup) {
1215         MyValue2[] src = new MyValue2[8];
1216         Object[] dst = new Object[8];
1217         for (int i = 0; i < 8; ++i) {
1218             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1219         }
1220         test49(src, dst);
1221         verify(src, dst);
1222         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test49")) {
1223             test49(src, dst);
1224             verify(src, dst);
1225         }
1226     }
1227 
1228     @Test
1229     public void test50(Object[] src, Object[] dst) {
1230         System.arraycopy(src, 0, dst, 0, 8);
1231     }
1232 
1233     @DontCompile
1234     public void test50_verifier(boolean warmup) {
1235         Object[] src = new Object[8];
1236         Object[] dst = new Object[8];
1237         for (int i = 0; i < 8; ++i) {
1238             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1239         }
1240         test50(src, dst);
1241         verify(src, dst);
1242         if (!warmup) {
1243             Method m = tests.get("TestArrays::test50");
1244             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1245                 throw new RuntimeException("unexpected deoptimization");
1246             }
1247         }
1248     }
1249 
1250     @Test
1251     public MyValue1[] test51(MyValue1[] va) {
1252         return Arrays.copyOf(va, va.length, MyValue1[].class);
1253     }
1254 
1255     @DontCompile
1256     public void test51_verifier(boolean warmup) {
1257         int len = Math.abs(rI) % 10;
1258         MyValue1[] va = new MyValue1[len];
1259         for (int i = 0; i < len; ++i) {
1260             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1261         }
1262         MyValue1[] result = test51(va);
1263         verify(va, result);
1264     }
1265 
1266     static final MyValue1[] test52_va = new MyValue1[8];
1267 
1268     @Test
1269     public MyValue1[] test52() {
1270         return Arrays.copyOf(test52_va, 8, MyValue1[].class);
1271     }
1272 
1273     @DontCompile
1274     public void test52_verifier(boolean warmup) {
1275         for (int i = 0; i < 8; ++i) {
1276             test52_va[i] = MyValue1.createWithFieldsInline(rI, rL);
1277         }
1278         MyValue1[] result = test52();
1279         verify(test52_va, result);
1280     }
1281 
1282     @Test
1283     public MyValue1[] test53(Object[] va) {
1284         return Arrays.copyOf(va, va.length, MyValue1[].class);
1285     }
1286 
1287     @DontCompile
1288     public void test53_verifier(boolean warmup) {
1289         int len = Math.abs(rI) % 10;
1290         MyValue1[] va = new MyValue1[len];
1291         for (int i = 0; i < len; ++i) {
1292             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1293         }
1294         MyValue1[] result = test53(va);
1295         verify(result, va);
1296     }
1297 
1298     @Test
1299     public Object[] test54(MyValue1[] va) {
1300         return Arrays.copyOf(va, va.length, Object[].class);
1301     }
1302 
1303     @DontCompile
1304     public void test54_verifier(boolean warmup) {
1305         int len = Math.abs(rI) % 10;
1306         MyValue1[] va = new MyValue1[len];
1307         for (int i = 0; i < len; ++i) {
1308             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1309         }
1310         Object[] result = test54(va);
1311         verify(va, result);
1312     }
1313 
1314     @Test
1315     public Object[] test55(Object[] va) {
1316         return Arrays.copyOf(va, va.length, Object[].class);
1317     }
1318 
1319     @DontCompile
1320     public void test55_verifier(boolean warmup) {
1321         int len = Math.abs(rI) % 10;
1322         MyValue1[] va = new MyValue1[len];
1323         for (int i = 0; i < len; ++i) {
1324             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1325         }
1326         Object[] result = test55(va);
1327         verify(va, result);
1328     }
1329 
1330     @Test
1331     public MyValue1[] test56(Object[] va) {
1332         return Arrays.copyOf(va, va.length, MyValue1[].class);
1333     }
1334 
1335     @DontCompile
1336     public void test56_verifier(boolean warmup) {
1337         int len = Math.abs(rI) % 10;
1338         Object[] va = new Object[len];
1339         for (int i = 0; i < len; ++i) {
1340             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1341         }
1342         MyValue1[] result = test56(va);
1343         verify(result, va);
1344     }
1345 
1346    @Test
1347     public Object[] test57(Object[] va, Class klass) {
1348         return Arrays.copyOf(va, va.length, klass);
1349     }
1350 
1351     @DontCompile
1352     public void test57_verifier(boolean warmup) {
1353         int len = Math.abs(rI) % 10;
1354         Object[] va = new MyValue1[len];
1355         for (int i = 0; i < len; ++i) {
1356             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1357         }
1358         Object[] result = test57(va, MyValue1[].class);
1359         verify(va, result);
1360     }
1361 
1362     @Test
1363     public Object[] test58(MyValue1[] va, Class klass) {
1364         return Arrays.copyOf(va, va.length, klass);
1365     }
1366 
1367     @DontCompile
1368     public void test58_verifier(boolean warmup) {
1369         int len = Math.abs(rI) % 10;
1370         MyValue1[] va = new MyValue1[len];
1371         for (int i = 0; i < len; ++i) {
1372             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1373         }
1374         for (int i = 0; i < 10; i++) {
1375             Object[] result = test58(va, MyValue1[].class);
1376             verify(va, result);
1377         }
1378         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test58")) {
1379             Object[] result = test58(va, MyValue1[].class);
1380             verify(va, result);
1381         }
1382     }
1383 
1384     @Test
1385     public Object[] test59(MyValue1[] va) {
1386         return Arrays.copyOf(va, va.length+1, MyValue1[].class);
1387     }
1388 
1389     @DontCompile
1390     public void test59_verifier(boolean warmup) {
1391         int len = Math.abs(rI) % 10;
1392         MyValue1[] va = new MyValue1[len];
1393         MyValue1[] verif = new MyValue1[len+1];
1394         for (int i = 0; i < len; ++i) {
1395             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1396             verif[i] = va[i];
1397         }
1398         Object[] result = test59(va);
1399         verify(verif, result);
1400     }
1401 
1402     @Test
1403     public Object[] test60(Object[] va, Class klass) {
1404         return Arrays.copyOf(va, va.length+1, klass);
1405     }
1406 
1407     @DontCompile
1408     public void test60_verifier(boolean warmup) {
1409         int len = Math.abs(rI) % 10;
1410         MyValue1[] va = new MyValue1[len];
1411         MyValue1[] verif = new MyValue1[len+1];
1412         for (int i = 0; i < len; ++i) {
1413             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1414             verif[i] = (MyValue1)va[i];
1415         }
1416         Object[] result = test60(va, MyValue1[].class);
1417         verify(verif, result);
1418     }
1419 
1420     @Test
1421     public Object[] test61(Object[] va, Class klass) {
1422         return Arrays.copyOf(va, va.length+1, klass);
1423     }
1424 
1425     @DontCompile
1426     public void test61_verifier(boolean warmup) {
1427         int len = Math.abs(rI) % 10;
1428         Object[] va = new Integer[len];
1429         for (int i = 0; i < len; ++i) {
1430             va[i] = new Integer(rI);
1431         }
1432         Object[] result = test61(va, Integer[].class);
1433         for (int i = 0; i < va.length; ++i) {
1434             Asserts.assertEQ(va[i], result[i]);
1435         }
1436     }
1437 
1438     @ForceInline
1439     public Object[] test62_helper(int i, MyValue1[] va, Integer[] oa) {
1440         Object[] arr = null;
1441         if (i == 10) {
1442             arr = oa;
1443         } else {
1444             arr = va;
1445         }
1446         return arr;
1447     }
1448 
1449     @Test
1450     public Object[] test62(MyValue1[] va, Integer[] oa) {
1451         int i = 0;
1452         for (; i < 10; i++);
1453 
1454         Object[] arr = test62_helper(i, va, oa);
1455 
1456         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1457     }
1458 
1459     @DontCompile
1460     public void test62_verifier(boolean warmup) {
1461         int len = Math.abs(rI) % 10;
1462         MyValue1[] va = new MyValue1[len];
1463         Integer[] oa = new Integer[len];
1464         for (int i = 0; i < len; ++i) {
1465             oa[i] = new Integer(rI);
1466         }
1467         test62_helper(42, va, oa);
1468         Object[] result = test62(va, oa);
1469         for (int i = 0; i < va.length; ++i) {
1470             Asserts.assertEQ(oa[i], result[i]);
1471         }
1472     }
1473 
1474     @ForceInline
1475     public Object[] test63_helper(int i, MyValue1[] va, Integer[] oa) {
1476         Object[] arr = null;
1477         if (i == 10) {
1478             arr = va;
1479         } else {
1480             arr = oa;
1481         }
1482         return arr;
1483     }
1484 
1485     @Test
1486     public Object[] test63(MyValue1[] va, Integer[] oa) {
1487         int i = 0;
1488         for (; i < 10; i++);
1489 
1490         Object[] arr = test63_helper(i, va, oa);
1491 
1492         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1493     }
1494 
1495     @DontCompile
1496     public void test63_verifier(boolean warmup) {
1497         int len = Math.abs(rI) % 10;
1498         MyValue1[] va = new MyValue1[len];
1499         MyValue1[] verif = new MyValue1[len+1];
1500         for (int i = 0; i < len; ++i) {
1501             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1502             verif[i] = va[i];
1503         }
1504         Integer[] oa = new Integer[len];
1505         test63_helper(42, va, oa);
1506         Object[] result = test63(va, oa);
1507         verify(verif, result);
1508     }
1509 
1510     // Test default initialization of value type arrays: small array
1511     @Test
1512     public MyValue1[] test64() {
1513         return new MyValue1[8];
1514     }
1515 
1516     @DontCompile
1517     public void test64_verifier(boolean warmup) {
1518         MyValue1[] va = new MyValue1[8];
1519         MyValue1[] var = test64();
1520         for (int i = 0; i < 8; ++i) {
1521             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1522         }
1523     }
1524 
1525     // Test default initialization of value type arrays: large array
1526     @Test
1527     public MyValue1[] test65() {
1528         return new MyValue1[32];
1529     }
1530 
1531     @DontCompile
1532     public void test65_verifier(boolean warmup) {
1533         MyValue1[] va = new MyValue1[32];
1534         MyValue1[] var = test65();
1535         for (int i = 0; i < 32; ++i) {
1536             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1537         }
1538     }
1539 
1540     // Check init store elimination
1541     @Test
1542     public MyValue1[] test66(MyValue1 vt) {
1543         MyValue1[] va = new MyValue1[1];
1544         va[0] = vt;
1545         return va;
1546     }
1547 
1548     @DontCompile
1549     public void test66_verifier(boolean warmup) {
1550         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1551         MyValue1[] va = test66(vt);
1552         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1553     }
1554 
1555     // Zeroing elimination and arraycopy
1556     @Test
1557     public MyValue1[] test67(MyValue1[] src) {
1558         MyValue1[] dst = new MyValue1[16];
1559         System.arraycopy(src, 0, dst, 0, 13);
1560         return dst;
1561     }
1562 
1563     @DontCompile
1564     public void test67_verifier(boolean warmup) {
1565         MyValue1[] va = new MyValue1[16];
1566         MyValue1[] var = test67(va);
1567         for (int i = 0; i < 16; ++i) {
1568             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1569         }
1570     }
1571 
1572     // A store with a default value can be eliminated
1573     @Test
1574     public MyValue1[] test68() {
1575         MyValue1[] va = new MyValue1[2];
1576         va[0] = va[1];
1577         return va;
1578     }
1579 
1580     @DontCompile
1581     public void test68_verifier(boolean warmup) {
1582         MyValue1[] va = new MyValue1[2];
1583         MyValue1[] var = test68();
1584         for (int i = 0; i < 2; ++i) {
1585             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1586         }
1587     }
1588 
1589     // Requires individual stores to init array
1590     @Test
1591     public MyValue1[] test69(MyValue1 vt) {
1592         MyValue1[] va = new MyValue1[4];
1593         va[0] = vt;
1594         va[3] = vt;
1595         return va;
1596     }
1597 
1598     @DontCompile
1599     public void test69_verifier(boolean warmup) {
1600         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1601         MyValue1[] va = new MyValue1[4];
1602         va[0] = vt;
1603         va[3] = vt;
1604         MyValue1[] var = test69(vt);
1605         for (int i = 0; i < va.length; ++i) {
1606             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1607         }
1608     }
1609 
1610     // A store with a default value can be eliminated: same as test68
1611     // but store is farther away from allocation
1612     @Test
1613     public MyValue1[] test70(MyValue1[] other) {
1614         other[1] = other[0];
1615         MyValue1[] va = new MyValue1[2];
1616         other[0] = va[1];
1617         va[0] = va[1];
1618         return va;
1619     }
1620 
1621     @DontCompile
1622     public void test70_verifier(boolean warmup) {
1623         MyValue1[] va = new MyValue1[2];
1624         MyValue1[] var = test70(va);
1625         for (int i = 0; i < 2; ++i) {
1626             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1627         }
1628     }
1629 
1630     // EA needs to consider oop fields in flattened arrays
1631     @Test
1632     public void test71() {
1633         int len = 10;
1634         MyValue2[] src = new MyValue2[len];
1635         MyValue2[] dst = new MyValue2[len];
1636         for (int i = 0; i < len; ++i) {
1637             src[i] = MyValue2.createWithFieldsDontInline(rI, (i % 2) == 0);
1638         }
1639         System.arraycopy(src, 0, dst, 0, src.length);
1640         for (int i = 0; i < len; ++i) {
1641             Asserts.assertEQ(src[i].hash(), dst[i].hash());
1642         }
1643     }
1644 
1645     @DontCompile
1646     public void test71_verifier(boolean warmup) {
1647         test71();
1648     }
1649 
1650     // Test EA with leaf call to 'store_unknown_value'
1651     @Test
1652     public void test72(Object[] o, boolean b, Object element) {
1653         Object[] arr1 = new Object[10];
1654         Object[] arr2 = new Object[10];
1655         if (b) {
1656             arr1 = o;
1657         }
1658         arr1[0] = element;
1659         arr2[0] = element;
1660     }
1661 
1662     @DontCompile
1663     public void test72_verifier(boolean warmup) {
1664         Object[] arr = new Object[1];
1665         Object elem = new Object();
1666         test72(arr, true, elem);
1667         test72(arr, false, elem);
1668     }
1669 
1670     @Test
1671     public void test73(Object[] oa, MyValue1 v, Object o) {
1672         // TestLWorld.test38 use a C1 Phi node for the array. This test
1673         // adds the case where the stored value is a C1 Phi node.
1674         Object o2 = (o == null) ? v : o;
1675         oa[0] = v;  // The stored value is known to be flattenable
1676         oa[1] = o;  // The stored value may be flattenable
1677         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1678         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1679     }
1680 
1681     @DontCompile
1682     public void test73_verifier(boolean warmup) {
1683         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1684         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1685         MyValue1[] arr = new MyValue1[3];
1686         try {
1687             test73(arr, v0, v1);
1688             throw new RuntimeException("ArrayStoreException expected");
1689         } catch (ArrayStoreException t) {
1690             // expected
1691         }
1692         Asserts.assertEQ(arr[0].hash(), v0.hash());
1693         Asserts.assertEQ(arr[1].hash(), v1.hash());
1694         Asserts.assertEQ(arr[2].hash(), v1.hash());
1695     }
1696 
1697     public static void test74Callee(MyValue1[] va) { }
1698 
1699     // Tests invoking unloaded method with value array in signature
1700     @Test
1701     @Warmup(0)
1702     public void test74(MethodHandle m, MyValue1[] va) throws Throwable {
1703         m.invoke(va);
1704     }
1705 
1706     @DontCompile
1707     public void test74_verifier(boolean warmup) throws Throwable {
1708         MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class));
1709         MyValue1[] va = new MyValue1[0];
1710         test74(m, va);
1711     }
1712 
1713     // Some more array clone tests
1714     @ForceInline
1715     public Object[] test75_helper(int i, MyValue1[] va, Integer[] oa) {
1716         Object[] arr = null;
1717         if (i == 10) {
1718             arr = oa;
1719         } else {
1720             arr = va;
1721         }
1722         return arr;
1723     }
1724 
1725     @Test
1726     public Object[] test75(MyValue1[] va, Integer[] oa) {
1727         int i = 0;
1728         for (; i < 10; i++);
1729 
1730         Object[] arr = test75_helper(i, va, oa);
1731         return arr.clone();
1732     }
1733 
1734     @DontCompile
1735     public void test75_verifier(boolean warmup) {
1736         int len = Math.abs(rI) % 10;
1737         MyValue1[] va = new MyValue1[len];
1738         Integer[] oa = new Integer[len];
1739         for (int i = 0; i < len; ++i) {
1740             oa[i] = new Integer(rI);
1741         }
1742         test75_helper(42, va, oa);
1743         Object[] result = test75(va, oa);
1744 
1745         for (int i = 0; i < va.length; ++i) {
1746             Asserts.assertEQ(oa[i], result[i]);
1747             // Check that array has correct storage properties (null-ok)
1748             result[i] = null;
1749         }
1750     }
1751 
1752     @ForceInline
1753     public Object[] test76_helper(int i, MyValue1[] va, Integer[] oa) {
1754         Object[] arr = null;
1755         if (i == 10) {
1756             arr = va;
1757         } else {
1758             arr = oa;
1759         }
1760         return arr;
1761     }
1762 
1763     @Test
1764     public Object[] test76(MyValue1[] va, Integer[] oa) {
1765         int i = 0;
1766         for (; i < 10; i++);
1767 
1768         Object[] arr = test76_helper(i, va, oa);
1769         return arr.clone();
1770     }
1771 
1772     @DontCompile
1773     public void test76_verifier(boolean warmup) {
1774         int len = Math.abs(rI) % 10;
1775         MyValue1[] va = new MyValue1[len];
1776         MyValue1[] verif = new MyValue1[len];
1777         for (int i = 0; i < len; ++i) {
1778             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1779             verif[i] = va[i];
1780         }
1781         Integer[] oa = new Integer[len];
1782         test76_helper(42, va, oa);
1783         Object[] result = test76(va, oa);
1784         verify(verif, result);
1785         // Check that array has correct storage properties (null-free)
1786         if (len > 0) {
1787             try {
1788                 result[0] = null;
1789                 throw new RuntimeException("Should throw NullPointerException");
1790             } catch (NullPointerException e) {
1791                 // Expected
1792             }
1793         }
1794     }
1795 
1796     @Test
1797     public void test77() {
1798         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1799         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1800         MyValue1[] arr = new MyValue1[1];
1801 
1802         Object[] oa = arr;
1803         Object o1 = v1;
1804         Object o = (o1 == null) ? v0 : o1;
1805 
1806         oa[0] = o; // For C1, due to IfOp optimization, the declared_type of o becomes NULL.
1807 
1808         Asserts.assertEQ(arr[0].hash(), v1.hash());
1809     }
1810 
1811 
1812     @DontCompile
1813     public void test77_verifier(boolean warmup) {
1814         test77();
1815     }
1816 
1817     @Test
1818     public long test78(MyValue1 v, int n) {
1819         long x = 0;
1820         for (int i = 0; i<n; i++) {
1821         }
1822 
1823         MyValue1[] a = new MyValue1[n];
1824         a[0] = v;
1825         for (int i = 0; i<n; i++) {
1826             x += a[i].hash(); // C1 PhiSimplifier changes "a" from a Phi node to a NewObjectArray node
1827         }
1828 
1829         return x;
1830     }
1831 
1832     @DontCompile
1833     public void test78_verifier(boolean warmup) {
1834         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1835         Asserts.assertEQ(test78(v, 1), v.hash());
1836     }
1837 
1838     // Verify that casting an array element to a non-flattenable type marks the array as not-flat
1839     @Test(valid = ValueTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_VALUE }, matchCount = { 1, 1 })
1840     @Test(valid = ValueTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE)
1841     public Object test79(Object[] array, int i) {
1842         Integer i1 = (Integer)array[0];
1843         Object o = array[1];
1844         return array[i];
1845     }
1846 
1847     @DontCompile
1848     public void test79_verifier(boolean warmup) {
1849         Integer i = new Integer(rI);
1850         Integer[] array = new Integer[2];
1851         array[1] = i;
1852         Object result = test79(array, 1);
1853         Asserts.assertEquals(result, i);
1854     }
1855 
1856     inline static class NotFlattenable {
1857         private final Object o1 = null;
1858         private final Object o2 = null;
1859         private final Object o3 = null;
1860         private final Object o4 = null;
1861         private final Object o5 = null;
1862         private final Object o6 = null;
1863     }
1864 
1865     // Same as test80 but with not-flattenable inline type
1866     @Test(valid = ValueTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_VALUE }, matchCount = { 1, 1 })
1867     @Test(valid = ValueTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE)
1868     public Object test80(Object[] array, int i) {
1869         NotFlattenable vt = (NotFlattenable)array[0];
1870         Object o = array[1];
1871         return array[i];
1872     }
1873 
1874     @DontCompile
1875     public void test80_verifier(boolean warmup) {
1876         NotFlattenable vt = new NotFlattenable();
1877         NotFlattenable[] array = new NotFlattenable[2];
1878         array[1] = vt;
1879         Object result = test80(array, 1);
1880         Asserts.assertEquals(result, vt);
1881     }
1882 
1883     // 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
1884     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE + VALUE_ARRAY_NULL_GUARD)
1885     public Object test81(Object[] array, Integer v, Object o, int i) {
1886         if (v == null) {
1887           return null;
1888         }
1889         array[0] = v;
1890         array[1] = array[0];
1891         array[2] = o;
1892         return array[i];
1893     }
1894 
1895     @DontCompile
1896     public void test81_verifier(boolean warmup) {
1897         Integer i = new Integer(rI);
1898         Integer[] array1 = new Integer[3];
1899         Object[] array2 = new Object[3];
1900         Object result = test81(array1, i, i, 0);
1901         Asserts.assertEquals(array1[0], i);
1902         Asserts.assertEquals(array1[1], i);
1903         Asserts.assertEquals(array1[2], i);
1904         Asserts.assertEquals(result, i);
1905         result = test81(array2, i, i, 1);
1906         Asserts.assertEquals(array2[0], i);
1907         Asserts.assertEquals(array2[1], i);
1908         Asserts.assertEquals(array2[2], i);
1909         Asserts.assertEquals(result, i);
1910     }
1911 
1912     // Verify that writing an object of a non-flattenable inline type to an array marks the array as not-flat
1913     @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE)
1914     @Test(valid = ValueTypePassFieldsAsArgsOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE)
1915     public Object test82(Object[] array, NotFlattenable vt, Object o, int i) {
1916         array[0] = vt;
1917         array[1] = array[0];
1918         array[2] = o;
1919         return array[i];
1920     }
1921 
1922     @DontCompile
1923     public void test82_verifier(boolean warmup) {
1924         NotFlattenable vt = new NotFlattenable();
1925         NotFlattenable[] array1 = new NotFlattenable[3];
1926         Object[] array2 = new Object[3];
1927         Object result = test82(array1, vt, vt, 0);
1928         Asserts.assertEquals(array1[0], vt);
1929         Asserts.assertEquals(array1[1], vt);
1930         Asserts.assertEquals(array1[2], vt);
1931         Asserts.assertEquals(result, vt);
1932         result = test82(array2, vt, vt, 1);
1933         Asserts.assertEquals(array2[0], vt);
1934         Asserts.assertEquals(array2[1], vt);
1935         Asserts.assertEquals(array2[2], vt);
1936         Asserts.assertEquals(result, vt);
1937     }
1938 
1939     // Verify that casting an array element to a non-inline type type marks the array as not-null-free and not-flat
1940     @Test(valid = ValueTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_VALUE }, matchCount = { 1, 1 }, failOn = ALLOCA_G + STORE_UNKNOWN_VALUE + VALUE_ARRAY_NULL_GUARD)
1941     @Test(valid = ValueTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE + VALUE_ARRAY_NULL_GUARD)
1942     public void test83(Object[] array, Object o) {
1943         Integer i = (Integer)array[0];
1944         array[1] = o;
1945     }
1946 
1947     @DontCompile
1948     public void test83_verifier(boolean warmup) {
1949         Integer i = new Integer(rI);
1950         Integer[] array1 = new Integer[2];
1951         Object[] array2 = new Object[2];
1952         test83(array1, i);
1953         Asserts.assertEquals(array1[1], i);
1954         test83(array2, null);
1955         Asserts.assertEquals(array2[1], null);
1956     }
1957 
1958     // Verify that writing constant null into an array marks the array as not-null-free and not-flat
1959     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 1 })
1960     public Object test84(Object[] array, int i) {
1961         array[0] = null;
1962         array[1] = null;
1963         return array[i];
1964     }
1965 
1966     @DontCompile
1967     public void test84_verifier(boolean warmup) {
1968         NotFlattenable?[] array1 = new NotFlattenable?[2];
1969         Object[] array2 = new Object[2];
1970         Object result = test84(array1, 0);
1971         Asserts.assertEquals(array1[0], null);
1972         Asserts.assertEquals(result, null);
1973         result = test84(array2, 1);
1974         Asserts.assertEquals(array2[0], null);
1975         Asserts.assertEquals(result, null);
1976         if (!warmup) {
1977             NotFlattenable[] array3 = new NotFlattenable[2];
1978             try {
1979                 test84(array3, 1);
1980                 throw new RuntimeException("Should throw NullPointerException");
1981             } catch (NullPointerException e) {
1982                 // Expected
1983             }
1984         }
1985     }
1986 
1987     // Same as test84 but with branches
1988     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 2 })
1989     public void test85(Object[] array, Object o, boolean b) {
1990         if (b) {
1991             array[0] = null;
1992         } else {
1993             array[1] = null;
1994         }
1995         array[1] = o;
1996     }
1997 
1998     @DontCompile
1999     public void test85_verifier(boolean warmup) {
2000         Integer i = new Integer(rI);
2001         Integer[] array1 = new Integer[2];
2002         Object[] array2 = new Object[2];
2003         test85(array1, i, true);
2004         Asserts.assertEquals(array1[1], i);
2005         test85(array1, null, false);
2006         Asserts.assertEquals(array1[1], null);
2007         test85(array2, i, true);
2008         Asserts.assertEquals(array2[1], i);
2009         test85(array2, null, false);
2010         Asserts.assertEquals(array2[1], null);
2011         if (!warmup) {
2012             NotFlattenable[] array3 = new NotFlattenable[2];
2013             try {
2014                 test85(array3, null, true);
2015                 throw new RuntimeException("Should throw NullPointerException");
2016             } catch (NullPointerException e) {
2017                 // Expected
2018             }
2019         }
2020     }
2021 
2022     // Same as test85 but with not-flattenable inline type array
2023     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 2 })
2024     public void test86(NotFlattenable?[] array, NotFlattenable? o, boolean b) {
2025         if (b) {
2026             array[0] = null;
2027         } else {
2028             array[1] = null;
2029         }
2030         array[1] = o;
2031     }
2032 
2033     @DontCompile
2034     public void test86_verifier(boolean warmup) {
2035         NotFlattenable vt = new NotFlattenable();
2036         NotFlattenable?[] array1 = new NotFlattenable?[2];
2037         test86(array1, vt, true);
2038         Asserts.assertEquals(array1[1], vt);
2039         test86(array1, null, false);
2040         Asserts.assertEquals(array1[1], null);
2041         if (!warmup) {
2042             NotFlattenable[] array2 = new NotFlattenable[2];
2043             try {
2044                 test86(array2, null, true);
2045                 throw new RuntimeException("Should throw NullPointerException");
2046             } catch (NullPointerException e) {
2047                 // Expected
2048             }
2049         }
2050     }
2051 
2052     // Same as test85 but with inline type array
2053     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 2 })
2054     public void test87(MyValue1?[] array, MyValue1? o, boolean b) {
2055         if (b) {
2056             array[0] = null;
2057         } else {
2058             array[1] = null;
2059         }
2060         array[1] = o;
2061     }
2062 
2063     @DontCompile
2064     public void test87_verifier(boolean warmup) {
2065         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2066         MyValue1?[] array1 = new MyValue1?[2];
2067         test87(array1, vt, true);
2068         Asserts.assertEquals(array1[1], vt);
2069         test87(array1, null, false);
2070         Asserts.assertEquals(array1[1], null);
2071         if (!warmup) {
2072             MyValue1[] array2 = new MyValue1[2];
2073             try {
2074                 test87(array2, null, true);
2075                 throw new RuntimeException("Should throw NullPointerException");
2076             } catch (NullPointerException e) {
2077                 // Expected
2078             }
2079         }
2080     }
2081 
2082     // Additional correcntess tests to make sure we have the required null checks
2083     @Test()
2084     public void test88(Object[] array, Integer v) {
2085         array[0] = v;
2086     }
2087 
2088     @DontCompile
2089     public void test88_verifier(boolean warmup) {
2090         Integer[] array1 = new Integer[1];
2091         Object[] array2 = new Object[1];
2092         test88(array1, null);
2093         Asserts.assertEquals(array1[0], null);
2094         test88(array2, null);
2095         Asserts.assertEquals(array2[0], null);
2096         if (!warmup) {
2097             MyValue1[] array3 = new MyValue1[1];
2098             try {
2099                 test88(array3, null);
2100                 throw new RuntimeException("Should throw NullPointerException");
2101             } catch (NullPointerException e) {
2102                 // Expected
2103             }
2104         }
2105     }
2106 
2107     @Test()
2108     public void test89(MyValue1?[] array, Integer v) {
2109         Object o = v;
2110         array[0] = (MyValue1?)o;
2111     }
2112 
2113     @DontCompile
2114     public void test89_verifier(boolean warmup) {
2115         MyValue1?[] array1 = new MyValue1?[1];
2116         test89(array1, null);
2117         Asserts.assertEquals(array1[0], null);
2118         if (!warmup) {
2119             MyValue1[] array2 = new MyValue1[1];
2120             try {
2121                 test89(array2, null);
2122                 throw new RuntimeException("Should throw NullPointerException");
2123             } catch (NullPointerException e) {
2124                 // Expected
2125             }
2126         }
2127     }
2128 
2129     @Test
2130     public boolean test90() {
2131         boolean b = true;
2132 
2133         MyValue1[] qArray = new MyValue1[0];
2134         MyValue1?[] lArray = new MyValue1?[0];
2135 
2136         b = b && (qArray instanceof MyValue1[]);
2137         b = b && (lArray instanceof MyValue1?[]);
2138 
2139         MyValue1[][] qArray2 = new MyValue1[0][0];
2140         MyValue1?[][] lArray2 = new MyValue1?[0][0];
2141 
2142         b = b && (qArray2 instanceof MyValue1[][]);
2143         b = b && (lArray2 instanceof MyValue1?[][]);
2144 
2145         return b;
2146     }
2147 
2148     @DontCompile
2149     public void test90_verifier(boolean warmup) {
2150         Asserts.assertEQ(test90(), true);
2151     }
2152 
2153     inline static final class Test91Value {
2154         public final int f0;
2155         public final int f1;
2156         public final int f2;
2157         public final int f3;
2158         public final int f4;
2159         public final int f5;
2160 
2161         public Test91Value(int i) {
2162             this.f0 = i;
2163             this.f1 = i;
2164             this.f2 = i;
2165             this.f3 = i;
2166             this.f4 = i;
2167             this.f5 = i;
2168         }
2169 
2170         public void verify() {
2171             if ((f0 != f1) || (f1 != f2) || (f2 != f3) || (f3 != f4) || (f4 != f5)) {
2172                 throw new RuntimeException("test91 failed");
2173             }
2174         }
2175     }
2176 
2177     // Test anti-dependencies between loads and stores from flattened array
2178     @Test
2179     @Warmup(0)
2180     public int test91(Test91Value[] array, int lo, int val) {
2181         int i = 3;
2182         while (lo < i) {
2183             Test91Value tmp = array[lo];
2184             array[lo++] = array[i];
2185             array[i--] = tmp;
2186         }
2187         return val;
2188     }
2189 
2190     @DontCompile
2191     public void test91_verifier(boolean warmup) {
2192         Test91Value[] array = new Test91Value[5];
2193         for (int i = 0; i < 5; ++i) {
2194             array[i] = new Test91Value(i);
2195             array[i].verify();
2196         }
2197         Asserts.assertEQ(test91(array, 0, 5), 5);
2198         for (int i = 0; i < 5; ++i) {
2199             array[i].verify();
2200         }
2201     }
2202 
2203     @Test
2204     public void test92(Object[] src, Object[] dst) {
2205         System.arraycopy(src, 0, dst, 0, src.length);
2206     }
2207 
2208     @DontCompile
2209     public void test92_verifier(boolean warmup) {
2210         MyValue1[] a = new MyValue1[1];
2211         MyValue1[] b = new MyValue1[1];
2212         try {
2213             test92(a, null);
2214             throw new RuntimeException("Should throw NullPointerException");
2215         } catch (NullPointerException expected) {}
2216 
2217         try {
2218             test92(null, b);
2219             throw new RuntimeException("Should throw NullPointerException");
2220         } catch (NullPointerException expected) {}
2221 
2222         a[0] = MyValue1.createWithFieldsInline(rI, rL);
2223         test92(a, b);
2224         verify(a, b);
2225     }
2226 
2227     // Same as test30 but accessing all elements of the non-escaping array
2228     @Test
2229     public long test93(MyValue2[] src, boolean flag) {
2230         MyValue2[] dst = new MyValue2[10];
2231         System.arraycopy(src, 0, dst, 0, 10);
2232         if (flag) {  }
2233         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2234                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2235     }
2236 
2237     @DontCompile
2238     public void test93_verifier(boolean warmup) {
2239         MyValue2[] src = new MyValue2[10];
2240         for (int i = 0; i < 10; ++i) {
2241             src[i] = MyValue2.createWithFieldsInline(rI, (rI % 2) == 0);
2242         }
2243         long res = test93(src, !warmup);
2244         long expected = 0;
2245         for (int i = 0; i < 10; ++i) {
2246             expected += src[i].hash();
2247         }
2248         Asserts.assertEQ(res, expected);
2249     }
2250 
2251     // Same as test93 but with variable source array offset
2252     @Test
2253     public long test94(MyValue2[] src, int i, boolean flag) {
2254         MyValue2[] dst = new MyValue2[10];
2255         System.arraycopy(src, i, dst, 0, 1);
2256         if (flag) {  }
2257         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2258                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2259     }
2260 
2261     @DontCompile
2262     public void test94_verifier(boolean warmup) {
2263         MyValue2[] src = new MyValue2[10];
2264         for (int i = 0; i < 10; ++i) {
2265             src[i] = MyValue2.createWithFieldsInline(i, (i % 2) == 0);
2266         }
2267         for (int i = 0; i < 10; ++i) {
2268             long res = test94(src, i, !warmup);
2269             long expected = src[i].hash() + 9*MyValue2.default.hash();
2270             Asserts.assertEQ(res, expected);
2271         }
2272     }
2273 }