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", "-XX:+StressArrayCopyMacroNode"};
  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", "-XX:+StressArrayCopyMacroNode"};
  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, match = { ALLOCA }, matchCount = { 1 })
  88     @Test(valid = ValueTypeArrayFlattenOff, match = { ALLOCA }, matchCount = { 1 }, 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     // TODO ZGC does not support the clone intrinsic, remove this once JDK-8232896 is fixed
 670     @Test(valid = ZGCOff, failOn = ALLOCA + LOOP + LOAD + TRAP)
 671     @Test(valid = ZGCOn)
 672     public MyValue2 test28() {
 673         MyValue2[] src = new MyValue2[10];
 674         src[0] = MyValue2.createWithFieldsInline(rI, false);
 675         MyValue2[] dst = (MyValue2[])src.clone();
 676         return dst[0];
 677     }
 678 
 679     @DontCompile
 680     public void test28_verifier(boolean warmup) {
 681         MyValue2 v = MyValue2.createWithFieldsInline(rI, false);
 682         MyValue2 result = test28();
 683         Asserts.assertEQ(result.hash(), v.hash());
 684     }
 685 
 686     // non escaping allocations
 687     // TODO 8227588: shouldn't this have the same IR matching rules as test6?
 688     @Test(valid = ValueTypeArrayFlattenOn, failOn = ALLOCA + LOOP + LOAD + TRAP)
 689     @Test(valid = ValueTypeArrayFlattenOff)
 690     public MyValue2 test29(MyValue2[] src) {
 691         MyValue2[] dst = new MyValue2[10];
 692         System.arraycopy(src, 0, dst, 0, 10);
 693         return dst[0];
 694     }
 695 
 696     @DontCompile
 697     public void test29_verifier(boolean warmup) {
 698         MyValue2[] src = new MyValue2[10];
 699         for (int i = 0; i < 10; ++i) {
 700             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 701         }
 702         MyValue2 v = test29(src);
 703         Asserts.assertEQ(src[0].hash(), v.hash());
 704     }
 705 
 706     // non escaping allocation with uncommon trap that needs
 707     // eliminated value type array element as debug info
 708     @Test
 709     @Warmup(10000)
 710     public MyValue2 test30(MyValue2[] src, boolean flag) {
 711         MyValue2[] dst = new MyValue2[10];
 712         System.arraycopy(src, 0, dst, 0, 10);
 713         if (flag) { }
 714         return dst[0];
 715     }
 716 
 717     @DontCompile
 718     public void test30_verifier(boolean warmup) {
 719         MyValue2[] src = new MyValue2[10];
 720         for (int i = 0; i < 10; ++i) {
 721             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 722         }
 723         MyValue2 v = test30(src, !warmup);
 724         Asserts.assertEQ(src[0].hash(), v.hash());
 725     }
 726 
 727     // non escaping allocation with memory phi
 728     // TODO 8227588
 729     @Test(valid = ValueTypeArrayFlattenOn, failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP)
 730     @Test(valid = ValueTypeArrayFlattenOff)
 731     public long test31(boolean b, boolean deopt) {
 732         MyValue2[] src = new MyValue2[1];
 733         if (b) {
 734             src[0] = MyValue2.createWithFieldsInline(rI, true);
 735         } else {
 736             src[0] = MyValue2.createWithFieldsInline(rI, false);
 737         }
 738         if (deopt) {
 739             // uncommon trap
 740             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31"));
 741         }
 742         return src[0].hash();
 743     }
 744 
 745     @DontCompile
 746     public void test31_verifier(boolean warmup) {
 747         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true);
 748         long result1 = test31(true, !warmup);
 749         Asserts.assertEQ(result1, v1.hash());
 750         MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false);
 751         long result2 = test31(false, !warmup);
 752         Asserts.assertEQ(result2, v2.hash());
 753     }
 754 
 755     // Tests with Object arrays and clone/arraycopy
 756     // clone() as stub call
 757     @Test
 758     public Object[] test32(Object[] va) {
 759         return va.clone();
 760     }
 761 
 762     @DontCompile
 763     public void test32_verifier(boolean warmup) {
 764         int len = Math.abs(rI) % 10;
 765         MyValue1[] va = new MyValue1[len];
 766         for (int i = 0; i < len; ++i) {
 767             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 768         }
 769         MyValue1[] result = (MyValue1[])test32(va);
 770         for (int i = 0; i < len; ++i) {
 771             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 772         }
 773     }
 774 
 775     @Test
 776     public Object[] test33(Object[] va) {
 777         return va.clone();
 778     }
 779 
 780     @DontCompile
 781     public void test33_verifier(boolean warmup) {
 782         int len = Math.abs(rI) % 10;
 783         Object[] va = new Object[len];
 784         for (int i = 0; i < len; ++i) {
 785             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 786         }
 787         Object[] result = test33(va);
 788         for (int i = 0; i < len; ++i) {
 789             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 790             // Check that array has correct storage properties (null-ok)
 791             result[i] = null;
 792         }
 793     }
 794 
 795     // clone() as series of loads/stores
 796     static Object[] test34_orig = null;
 797 
 798     @ForceInline
 799     public Object[] test34_helper(boolean flag) {
 800         Object[] va = null;
 801         if (flag) {
 802             va = new MyValue1[8];
 803             for (int i = 0; i < va.length; ++i) {
 804                 va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 805             }
 806         } else {
 807             va = new Object[8];
 808         }
 809         return va;
 810     }
 811 
 812     @Test
 813     public Object[] test34(boolean flag) {
 814         Object[] va = test34_helper(flag);
 815         test34_orig = va;
 816         return va.clone();
 817     }
 818 
 819     @DontCompile
 820     public void test34_verifier(boolean warmup) {
 821         test34(false);
 822         for (int i = 0; i < 10; i++) { // make sure we do deopt
 823             Object[] result = test34(true);
 824             verify(test34_orig, result);
 825             // Check that array has correct storage properties (null-free)
 826             try {
 827                 result[0] = null;
 828                 throw new RuntimeException("Should throw NullPointerException");
 829             } catch (NullPointerException e) {
 830                 // Expected
 831             }
 832         }
 833         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test34")) {
 834             Object[] result = test34(true);
 835             verify(test34_orig, result);
 836             // Check that array has correct storage properties (null-free)
 837             try {
 838                 result[0] = null;
 839                 throw new RuntimeException("Should throw NullPointerException");
 840             } catch (NullPointerException e) {
 841                 // Expected
 842             }
 843         }
 844     }
 845 
 846     static void verify(Object[] src, Object[] dst) {
 847         for (int i = 0; i < src.length; ++i) {
 848             Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash());
 849         }
 850     }
 851 
 852     static void verify(MyValue1[] src, MyValue1[] dst) {
 853         for (int i = 0; i < src.length; ++i) {
 854             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 855         }
 856     }
 857 
 858     static void verify(MyValue1[] src, Object[] dst) {
 859         for (int i = 0; i < src.length; ++i) {
 860             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 861         }
 862     }
 863 
 864     static void verify(MyValue2[] src, MyValue2[] dst) {
 865         for (int i = 0; i < src.length; ++i) {
 866             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 867         }
 868     }
 869 
 870     static void verify(MyValue2[] src, Object[] dst) {
 871         for (int i = 0; i < src.length; ++i) {
 872             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 873         }
 874     }
 875 
 876     static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) {
 877         if (!warmup) {
 878             Method m = tests.get(test);
 879             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false)) {
 880                 if (!ValueTypeArrayFlatten && !XCOMP) {
 881                     throw new RuntimeException("Unexpected deoptimization");
 882                 }
 883                 enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
 884                 return true;
 885             }
 886         }
 887         return false;
 888     }
 889 
 890     // arraycopy() of value type array of unknown size
 891     @Test
 892     public void test35(Object src, Object dst, int len) {
 893         System.arraycopy(src, 0, dst, 0, len);
 894     }
 895 
 896     @DontCompile
 897     public void test35_verifier(boolean warmup) {
 898         int len = Math.abs(rI) % 10;
 899         MyValue1[] src = new MyValue1[len];
 900         MyValue1[] dst = new MyValue1[len];
 901         for (int i = 0; i < len; ++i) {
 902             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 903         }
 904         test35(src, dst, src.length);
 905         verify(src, dst);
 906         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test35")) {
 907             test35(src, dst, src.length);
 908             verify(src, dst);
 909         }
 910     }
 911 
 912     @Test
 913     public void test36(Object src, MyValue2[] dst) {
 914         System.arraycopy(src, 0, dst, 0, dst.length);
 915     }
 916 
 917     @DontCompile
 918     public void test36_verifier(boolean warmup) {
 919         int len = Math.abs(rI) % 10;
 920         MyValue2[] src = new MyValue2[len];
 921         MyValue2[] dst = new MyValue2[len];
 922         for (int i = 0; i < len; ++i) {
 923             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 924         }
 925         test36(src, dst);
 926         verify(src, dst);
 927         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test36")) {
 928             test36(src, dst);
 929             verify(src, dst);
 930         }
 931     }
 932 
 933     @Test
 934     public void test37(MyValue2[] src, Object dst) {
 935         System.arraycopy(src, 0, dst, 0, src.length);
 936     }
 937 
 938     @DontCompile
 939     public void test37_verifier(boolean warmup) {
 940         int len = Math.abs(rI) % 10;
 941         MyValue2[] src = new MyValue2[len];
 942         MyValue2[] dst = new MyValue2[len];
 943         for (int i = 0; i < len; ++i) {
 944             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 945         }
 946         test37(src, dst);
 947         verify(src, dst);
 948         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test37")) {
 949             test37(src, dst);
 950             verify(src, dst);
 951         }
 952     }
 953 
 954     @Test
 955     @Warmup(1) // Avoid early compilation
 956     public void test38(Object src, MyValue2[] dst) {
 957         System.arraycopy(src, 0, dst, 0, dst.length);
 958     }
 959 
 960     @DontCompile
 961     public void test38_verifier(boolean warmup) {
 962         int len = Math.abs(rI) % 10;
 963         Object[] src = new Object[len];
 964         MyValue2[] dst = new MyValue2[len];
 965         for (int i = 0; i < len; ++i) {
 966             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 967         }
 968         test38(src, dst);
 969         verify(dst, src);
 970         if (!warmup) {
 971             Method m = tests.get("TestArrays::test38");
 972             assertDeoptimizedByC2(m);
 973             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
 974             test38(src, dst);
 975             verify(dst, src);
 976             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
 977                 throw new RuntimeException("unexpected deoptimization");
 978             }
 979         }
 980     }
 981 
 982     @Test
 983     public void test39(MyValue2[] src, Object dst) {
 984         System.arraycopy(src, 0, dst, 0, src.length);
 985     }
 986 
 987     @DontCompile
 988     public void test39_verifier(boolean warmup) {
 989         int len = Math.abs(rI) % 10;
 990         MyValue2[] src = new MyValue2[len];
 991         Object[] dst = new Object[len];
 992         for (int i = 0; i < len; ++i) {
 993             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 994         }
 995         test39(src, dst);
 996         verify(src, dst);
 997         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test39")) {
 998             test39(src, dst);
 999             verify(src, dst);
1000         }
1001     }
1002 
1003     @Test
1004     @Warmup(1) // Avoid early compilation
1005     public void test40(Object[] src, Object dst) {
1006         System.arraycopy(src, 0, dst, 0, src.length);
1007     }
1008 
1009     @DontCompile
1010     public void test40_verifier(boolean warmup) {
1011         int len = Math.abs(rI) % 10;
1012         Object[] src = new Object[len];
1013         MyValue2[] dst = new MyValue2[len];
1014         for (int i = 0; i < len; ++i) {
1015             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1016         }
1017         test40(src, dst);
1018         verify(dst, src);
1019         if (!warmup) {
1020             Method m = tests.get("TestArrays::test40");
1021             assertDeoptimizedByC2(m);
1022             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1023             test40(src, dst);
1024             verify(dst, src);
1025             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1026                 throw new RuntimeException("unexpected deoptimization");
1027             }
1028         }
1029     }
1030 
1031     @Test
1032     public void test41(Object src, Object[] dst) {
1033         System.arraycopy(src, 0, dst, 0, dst.length);
1034     }
1035 
1036     @DontCompile
1037     public void test41_verifier(boolean warmup) {
1038         int len = Math.abs(rI) % 10;
1039         MyValue2[] src = new MyValue2[len];
1040         Object[] dst = new Object[len];
1041         for (int i = 0; i < len; ++i) {
1042             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1043         }
1044         test41(src, dst);
1045         verify(src, dst);
1046         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test41")) {
1047             test41(src, dst);
1048             verify(src, dst);
1049         }
1050     }
1051 
1052     @Test
1053     public void test42(Object[] src, Object[] dst) {
1054         System.arraycopy(src, 0, dst, 0, src.length);
1055     }
1056 
1057     @DontCompile
1058     public void test42_verifier(boolean warmup) {
1059         int len = Math.abs(rI) % 10;
1060         Object[] src = new Object[len];
1061         Object[] dst = new Object[len];
1062         for (int i = 0; i < len; ++i) {
1063             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1064         }
1065         test42(src, dst);
1066         verify(src, dst);
1067         if (!warmup) {
1068             Method m = tests.get("TestArrays::test42");
1069             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1070                 throw new RuntimeException("unexpected deoptimization");
1071             }
1072         }
1073     }
1074 
1075     // short arraycopy()'s
1076     @Test
1077     public void test43(Object src, Object dst) {
1078         System.arraycopy(src, 0, dst, 0, 8);
1079     }
1080 
1081     @DontCompile
1082     public void test43_verifier(boolean warmup) {
1083         MyValue1[] src = new MyValue1[8];
1084         MyValue1[] dst = new MyValue1[8];
1085         for (int i = 0; i < 8; ++i) {
1086             src[i] = MyValue1.createWithFieldsInline(rI, rL);
1087         }
1088         test43(src, dst);
1089         verify(src, dst);
1090         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test43")) {
1091             test43(src, dst);
1092             verify(src, dst);
1093         }
1094     }
1095 
1096     @Test
1097     public void test44(Object src, MyValue2[] dst) {
1098         System.arraycopy(src, 0, dst, 0, 8);
1099     }
1100 
1101     @DontCompile
1102     public void test44_verifier(boolean warmup) {
1103         MyValue2[] src = new MyValue2[8];
1104         MyValue2[] dst = new MyValue2[8];
1105         for (int i = 0; i < 8; ++i) {
1106             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1107         }
1108         test44(src, dst);
1109         verify(src, dst);
1110         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test44")) {
1111             test44(src, dst);
1112             verify(src, dst);
1113         }
1114     }
1115 
1116     @Test
1117     public void test45(MyValue2[] src, Object dst) {
1118         System.arraycopy(src, 0, dst, 0, 8);
1119     }
1120 
1121     @DontCompile
1122     public void test45_verifier(boolean warmup) {
1123         MyValue2[] src = new MyValue2[8];
1124         MyValue2[] dst = new MyValue2[8];
1125         for (int i = 0; i < 8; ++i) {
1126             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1127         }
1128         test45(src, dst);
1129         verify(src, dst);
1130         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test45")) {
1131             test45(src, dst);
1132             verify(src, dst);
1133         }
1134     }
1135 
1136     @Test
1137     @Warmup(1) // Avoid early compilation
1138     public void test46(Object[] src, MyValue2[] dst) {
1139         System.arraycopy(src, 0, dst, 0, 8);
1140     }
1141 
1142     @DontCompile
1143     public void test46_verifier(boolean warmup) {
1144         Object[] src = new Object[8];
1145         MyValue2[] dst = new MyValue2[8];
1146         for (int i = 0; i < 8; ++i) {
1147             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1148         }
1149         test46(src, dst);
1150         verify(dst, src);
1151         if (!warmup) {
1152             Method m = tests.get("TestArrays::test46");
1153             assertDeoptimizedByC2(m);
1154             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1155             test46(src, dst);
1156             verify(dst, src);
1157             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1158                 throw new RuntimeException("unexpected deoptimization");
1159             }
1160         }
1161     }
1162 
1163     @Test
1164     public void test47(MyValue2[] src, Object[] dst) {
1165         System.arraycopy(src, 0, dst, 0, 8);
1166     }
1167 
1168     @DontCompile
1169     public void test47_verifier(boolean warmup) {
1170         MyValue2[] src = new MyValue2[8];
1171         Object[] dst = new Object[8];
1172         for (int i = 0; i < 8; ++i) {
1173             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1174         }
1175         test47(src, dst);
1176         verify(src, dst);
1177         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test47")) {
1178             test47(src, dst);
1179             verify(src, dst);
1180         }
1181     }
1182 
1183     @Test
1184     @Warmup(1) // Avoid early compilation
1185     public void test48(Object[] src, Object dst) {
1186         System.arraycopy(src, 0, dst, 0, 8);
1187     }
1188 
1189     @DontCompile
1190     public void test48_verifier(boolean warmup) {
1191         Object[] src = new Object[8];
1192         MyValue2[] dst = new MyValue2[8];
1193         for (int i = 0; i < 8; ++i) {
1194             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1195         }
1196         test48(src, dst);
1197         verify(dst, src);
1198         if (!warmup) {
1199             Method m = tests.get("TestArrays::test48");
1200             assertDeoptimizedByC2(m);
1201             enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1202             test48(src, dst);
1203             verify(dst, src);
1204             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1205                 throw new RuntimeException("unexpected deoptimization");
1206             }
1207         }
1208     }
1209 
1210     @Test
1211     public void test49(Object src, Object[] dst) {
1212         System.arraycopy(src, 0, dst, 0, 8);
1213     }
1214 
1215     @DontCompile
1216     public void test49_verifier(boolean warmup) {
1217         MyValue2[] src = new MyValue2[8];
1218         Object[] dst = new Object[8];
1219         for (int i = 0; i < 8; ++i) {
1220             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1221         }
1222         test49(src, dst);
1223         verify(src, dst);
1224         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test49")) {
1225             test49(src, dst);
1226             verify(src, dst);
1227         }
1228     }
1229 
1230     @Test
1231     public void test50(Object[] src, Object[] dst) {
1232         System.arraycopy(src, 0, dst, 0, 8);
1233     }
1234 
1235     @DontCompile
1236     public void test50_verifier(boolean warmup) {
1237         Object[] src = new Object[8];
1238         Object[] dst = new Object[8];
1239         for (int i = 0; i < 8; ++i) {
1240             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1241         }
1242         test50(src, dst);
1243         verify(src, dst);
1244         if (!warmup) {
1245             Method m = tests.get("TestArrays::test50");
1246             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1247                 throw new RuntimeException("unexpected deoptimization");
1248             }
1249         }
1250     }
1251 
1252     @Test
1253     public MyValue1[] test51(MyValue1[] va) {
1254         return Arrays.copyOf(va, va.length, MyValue1[].class);
1255     }
1256 
1257     @DontCompile
1258     public void test51_verifier(boolean warmup) {
1259         int len = Math.abs(rI) % 10;
1260         MyValue1[] va = new MyValue1[len];
1261         for (int i = 0; i < len; ++i) {
1262             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1263         }
1264         MyValue1[] result = test51(va);
1265         verify(va, result);
1266     }
1267 
1268     static final MyValue1[] test52_va = new MyValue1[8];
1269 
1270     @Test
1271     public MyValue1[] test52() {
1272         return Arrays.copyOf(test52_va, 8, MyValue1[].class);
1273     }
1274 
1275     @DontCompile
1276     public void test52_verifier(boolean warmup) {
1277         for (int i = 0; i < 8; ++i) {
1278             test52_va[i] = MyValue1.createWithFieldsInline(rI, rL);
1279         }
1280         MyValue1[] result = test52();
1281         verify(test52_va, result);
1282     }
1283 
1284     @Test
1285     public MyValue1[] test53(Object[] va) {
1286         return Arrays.copyOf(va, va.length, MyValue1[].class);
1287     }
1288 
1289     @DontCompile
1290     public void test53_verifier(boolean warmup) {
1291         int len = Math.abs(rI) % 10;
1292         MyValue1[] va = new MyValue1[len];
1293         for (int i = 0; i < len; ++i) {
1294             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1295         }
1296         MyValue1[] result = test53(va);
1297         verify(result, va);
1298     }
1299 
1300     @Test
1301     public Object[] test54(MyValue1[] va) {
1302         return Arrays.copyOf(va, va.length, Object[].class);
1303     }
1304 
1305     @DontCompile
1306     public void test54_verifier(boolean warmup) {
1307         int len = Math.abs(rI) % 10;
1308         MyValue1[] va = new MyValue1[len];
1309         for (int i = 0; i < len; ++i) {
1310             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1311         }
1312         Object[] result = test54(va);
1313         verify(va, result);
1314     }
1315 
1316     @Test
1317     public Object[] test55(Object[] va) {
1318         return Arrays.copyOf(va, va.length, Object[].class);
1319     }
1320 
1321     @DontCompile
1322     public void test55_verifier(boolean warmup) {
1323         int len = Math.abs(rI) % 10;
1324         MyValue1[] va = new MyValue1[len];
1325         for (int i = 0; i < len; ++i) {
1326             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1327         }
1328         Object[] result = test55(va);
1329         verify(va, result);
1330     }
1331 
1332     @Test
1333     public MyValue1[] test56(Object[] va) {
1334         return Arrays.copyOf(va, va.length, MyValue1[].class);
1335     }
1336 
1337     @DontCompile
1338     public void test56_verifier(boolean warmup) {
1339         int len = Math.abs(rI) % 10;
1340         Object[] va = new Object[len];
1341         for (int i = 0; i < len; ++i) {
1342             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1343         }
1344         MyValue1[] result = test56(va);
1345         verify(result, va);
1346     }
1347 
1348    @Test
1349     public Object[] test57(Object[] va, Class klass) {
1350         return Arrays.copyOf(va, va.length, klass);
1351     }
1352 
1353     @DontCompile
1354     public void test57_verifier(boolean warmup) {
1355         int len = Math.abs(rI) % 10;
1356         Object[] va = new MyValue1[len];
1357         for (int i = 0; i < len; ++i) {
1358             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1359         }
1360         Object[] result = test57(va, MyValue1[].class);
1361         verify(va, result);
1362     }
1363 
1364     @Test
1365     public Object[] test58(MyValue1[] va, Class klass) {
1366         return Arrays.copyOf(va, va.length, klass);
1367     }
1368 
1369     @DontCompile
1370     public void test58_verifier(boolean warmup) {
1371         int len = Math.abs(rI) % 10;
1372         MyValue1[] va = new MyValue1[len];
1373         for (int i = 0; i < len; ++i) {
1374             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1375         }
1376         for (int i = 0; i < 10; i++) {
1377             Object[] result = test58(va, MyValue1[].class);
1378             verify(va, result);
1379         }
1380         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test58")) {
1381             Object[] result = test58(va, MyValue1[].class);
1382             verify(va, result);
1383         }
1384     }
1385 
1386     @Test
1387     public Object[] test59(MyValue1[] va) {
1388         return Arrays.copyOf(va, va.length+1, MyValue1[].class);
1389     }
1390 
1391     @DontCompile
1392     public void test59_verifier(boolean warmup) {
1393         int len = Math.abs(rI) % 10;
1394         MyValue1[] va = new MyValue1[len];
1395         MyValue1[] verif = new MyValue1[len+1];
1396         for (int i = 0; i < len; ++i) {
1397             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1398             verif[i] = va[i];
1399         }
1400         Object[] result = test59(va);
1401         verify(verif, result);
1402     }
1403 
1404     @Test
1405     public Object[] test60(Object[] va, Class klass) {
1406         return Arrays.copyOf(va, va.length+1, klass);
1407     }
1408 
1409     @DontCompile
1410     public void test60_verifier(boolean warmup) {
1411         int len = Math.abs(rI) % 10;
1412         MyValue1[] va = new MyValue1[len];
1413         MyValue1[] verif = new MyValue1[len+1];
1414         for (int i = 0; i < len; ++i) {
1415             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1416             verif[i] = (MyValue1)va[i];
1417         }
1418         Object[] result = test60(va, MyValue1[].class);
1419         verify(verif, result);
1420     }
1421 
1422     @Test
1423     public Object[] test61(Object[] va, Class klass) {
1424         return Arrays.copyOf(va, va.length+1, klass);
1425     }
1426 
1427     @DontCompile
1428     public void test61_verifier(boolean warmup) {
1429         int len = Math.abs(rI) % 10;
1430         Object[] va = new Integer[len];
1431         for (int i = 0; i < len; ++i) {
1432             va[i] = new Integer(rI);
1433         }
1434         Object[] result = test61(va, Integer[].class);
1435         for (int i = 0; i < va.length; ++i) {
1436             Asserts.assertEQ(va[i], result[i]);
1437         }
1438     }
1439 
1440     @ForceInline
1441     public Object[] test62_helper(int i, MyValue1[] va, Integer[] oa) {
1442         Object[] arr = null;
1443         if (i == 10) {
1444             arr = oa;
1445         } else {
1446             arr = va;
1447         }
1448         return arr;
1449     }
1450 
1451     @Test
1452     public Object[] test62(MyValue1[] va, Integer[] oa) {
1453         int i = 0;
1454         for (; i < 10; i++);
1455 
1456         Object[] arr = test62_helper(i, va, oa);
1457 
1458         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1459     }
1460 
1461     @DontCompile
1462     public void test62_verifier(boolean warmup) {
1463         int len = Math.abs(rI) % 10;
1464         MyValue1[] va = new MyValue1[len];
1465         Integer[] oa = new Integer[len];
1466         for (int i = 0; i < len; ++i) {
1467             oa[i] = new Integer(rI);
1468         }
1469         test62_helper(42, va, oa);
1470         Object[] result = test62(va, oa);
1471         for (int i = 0; i < va.length; ++i) {
1472             Asserts.assertEQ(oa[i], result[i]);
1473         }
1474     }
1475 
1476     @ForceInline
1477     public Object[] test63_helper(int i, MyValue1[] va, Integer[] oa) {
1478         Object[] arr = null;
1479         if (i == 10) {
1480             arr = va;
1481         } else {
1482             arr = oa;
1483         }
1484         return arr;
1485     }
1486 
1487     @Test
1488     public Object[] test63(MyValue1[] va, Integer[] oa) {
1489         int i = 0;
1490         for (; i < 10; i++);
1491 
1492         Object[] arr = test63_helper(i, va, oa);
1493 
1494         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1495     }
1496 
1497     @DontCompile
1498     public void test63_verifier(boolean warmup) {
1499         int len = Math.abs(rI) % 10;
1500         MyValue1[] va = new MyValue1[len];
1501         MyValue1[] verif = new MyValue1[len+1];
1502         for (int i = 0; i < len; ++i) {
1503             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1504             verif[i] = va[i];
1505         }
1506         Integer[] oa = new Integer[len];
1507         test63_helper(42, va, oa);
1508         Object[] result = test63(va, oa);
1509         verify(verif, result);
1510     }
1511 
1512     // Test default initialization of value type arrays: small array
1513     @Test
1514     public MyValue1[] test64() {
1515         return new MyValue1[8];
1516     }
1517 
1518     @DontCompile
1519     public void test64_verifier(boolean warmup) {
1520         MyValue1[] va = new MyValue1[8];
1521         MyValue1[] var = test64();
1522         for (int i = 0; i < 8; ++i) {
1523             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1524         }
1525     }
1526 
1527     // Test default initialization of value type arrays: large array
1528     @Test
1529     public MyValue1[] test65() {
1530         return new MyValue1[32];
1531     }
1532 
1533     @DontCompile
1534     public void test65_verifier(boolean warmup) {
1535         MyValue1[] va = new MyValue1[32];
1536         MyValue1[] var = test65();
1537         for (int i = 0; i < 32; ++i) {
1538             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1539         }
1540     }
1541 
1542     // Check init store elimination
1543     @Test(match = { ALLOCA }, matchCount = { 1 })
1544     public MyValue1[] test66(MyValue1 vt) {
1545         MyValue1[] va = new MyValue1[1];
1546         va[0] = vt;
1547         return va;
1548     }
1549 
1550     @DontCompile
1551     public void test66_verifier(boolean warmup) {
1552         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1553         MyValue1[] va = test66(vt);
1554         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1555     }
1556 
1557     // Zeroing elimination and arraycopy
1558     @Test
1559     public MyValue1[] test67(MyValue1[] src) {
1560         MyValue1[] dst = new MyValue1[16];
1561         System.arraycopy(src, 0, dst, 0, 13);
1562         return dst;
1563     }
1564 
1565     @DontCompile
1566     public void test67_verifier(boolean warmup) {
1567         MyValue1[] va = new MyValue1[16];
1568         MyValue1[] var = test67(va);
1569         for (int i = 0; i < 16; ++i) {
1570             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1571         }
1572     }
1573 
1574     // A store with a default value can be eliminated
1575     @Test
1576     public MyValue1[] test68() {
1577         MyValue1[] va = new MyValue1[2];
1578         va[0] = va[1];
1579         return va;
1580     }
1581 
1582     @DontCompile
1583     public void test68_verifier(boolean warmup) {
1584         MyValue1[] va = new MyValue1[2];
1585         MyValue1[] var = test68();
1586         for (int i = 0; i < 2; ++i) {
1587             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1588         }
1589     }
1590 
1591     // Requires individual stores to init array
1592     @Test
1593     public MyValue1[] test69(MyValue1 vt) {
1594         MyValue1[] va = new MyValue1[4];
1595         va[0] = vt;
1596         va[3] = vt;
1597         return va;
1598     }
1599 
1600     @DontCompile
1601     public void test69_verifier(boolean warmup) {
1602         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1603         MyValue1[] va = new MyValue1[4];
1604         va[0] = vt;
1605         va[3] = vt;
1606         MyValue1[] var = test69(vt);
1607         for (int i = 0; i < va.length; ++i) {
1608             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1609         }
1610     }
1611 
1612     // A store with a default value can be eliminated: same as test68
1613     // but store is farther away from allocation
1614     @Test
1615     public MyValue1[] test70(MyValue1[] other) {
1616         other[1] = other[0];
1617         MyValue1[] va = new MyValue1[2];
1618         other[0] = va[1];
1619         va[0] = va[1];
1620         return va;
1621     }
1622 
1623     @DontCompile
1624     public void test70_verifier(boolean warmup) {
1625         MyValue1[] va = new MyValue1[2];
1626         MyValue1[] var = test70(va);
1627         for (int i = 0; i < 2; ++i) {
1628             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1629         }
1630     }
1631 
1632     // EA needs to consider oop fields in flattened arrays
1633     @Test
1634     public void test71() {
1635         int len = 10;
1636         MyValue2[] src = new MyValue2[len];
1637         MyValue2[] dst = new MyValue2[len];
1638         for (int i = 0; i < len; ++i) {
1639             src[i] = MyValue2.createWithFieldsDontInline(rI, (i % 2) == 0);
1640         }
1641         System.arraycopy(src, 0, dst, 0, src.length);
1642         for (int i = 0; i < len; ++i) {
1643             Asserts.assertEQ(src[i].hash(), dst[i].hash());
1644         }
1645     }
1646 
1647     @DontCompile
1648     public void test71_verifier(boolean warmup) {
1649         test71();
1650     }
1651 
1652     // Test EA with leaf call to 'store_unknown_value'
1653     @Test
1654     public void test72(Object[] o, boolean b, Object element) {
1655         Object[] arr1 = new Object[10];
1656         Object[] arr2 = new Object[10];
1657         if (b) {
1658             arr1 = o;
1659         }
1660         arr1[0] = element;
1661         arr2[0] = element;
1662     }
1663 
1664     @DontCompile
1665     public void test72_verifier(boolean warmup) {
1666         Object[] arr = new Object[1];
1667         Object elem = new Object();
1668         test72(arr, true, elem);
1669         test72(arr, false, elem);
1670     }
1671 
1672     @Test
1673     public void test73(Object[] oa, MyValue1 v, Object o) {
1674         // TestLWorld.test38 use a C1 Phi node for the array. This test
1675         // adds the case where the stored value is a C1 Phi node.
1676         Object o2 = (o == null) ? v : o;
1677         oa[0] = v;  // The stored value is known to be flattenable
1678         oa[1] = o;  // The stored value may be flattenable
1679         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1680         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1681     }
1682 
1683     @DontCompile
1684     public void test73_verifier(boolean warmup) {
1685         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1686         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1687         MyValue1[] arr = new MyValue1[3];
1688         try {
1689             test73(arr, v0, v1);
1690             throw new RuntimeException("ArrayStoreException expected");
1691         } catch (ArrayStoreException t) {
1692             // expected
1693         }
1694         Asserts.assertEQ(arr[0].hash(), v0.hash());
1695         Asserts.assertEQ(arr[1].hash(), v1.hash());
1696         Asserts.assertEQ(arr[2].hash(), v1.hash());
1697     }
1698 
1699     public static void test74Callee(MyValue1[] va) { }
1700 
1701     // Tests invoking unloaded method with value array in signature
1702     @Test
1703     @Warmup(0)
1704     public void test74(MethodHandle m, MyValue1[] va) throws Throwable {
1705         m.invoke(va);
1706     }
1707 
1708     @DontCompile
1709     public void test74_verifier(boolean warmup) throws Throwable {
1710         MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class));
1711         MyValue1[] va = new MyValue1[0];
1712         test74(m, va);
1713     }
1714 
1715     // Some more array clone tests
1716     @ForceInline
1717     public Object[] test75_helper(int i, MyValue1[] va, Integer[] oa) {
1718         Object[] arr = null;
1719         if (i == 10) {
1720             arr = oa;
1721         } else {
1722             arr = va;
1723         }
1724         return arr;
1725     }
1726 
1727     @Test
1728     public Object[] test75(MyValue1[] va, Integer[] oa) {
1729         int i = 0;
1730         for (; i < 10; i++);
1731 
1732         Object[] arr = test75_helper(i, va, oa);
1733         return arr.clone();
1734     }
1735 
1736     @DontCompile
1737     public void test75_verifier(boolean warmup) {
1738         int len = Math.abs(rI) % 10;
1739         MyValue1[] va = new MyValue1[len];
1740         Integer[] oa = new Integer[len];
1741         for (int i = 0; i < len; ++i) {
1742             oa[i] = new Integer(rI);
1743         }
1744         test75_helper(42, va, oa);
1745         Object[] result = test75(va, oa);
1746 
1747         for (int i = 0; i < va.length; ++i) {
1748             Asserts.assertEQ(oa[i], result[i]);
1749             // Check that array has correct storage properties (null-ok)
1750             result[i] = null;
1751         }
1752     }
1753 
1754     @ForceInline
1755     public Object[] test76_helper(int i, MyValue1[] va, Integer[] oa) {
1756         Object[] arr = null;
1757         if (i == 10) {
1758             arr = va;
1759         } else {
1760             arr = oa;
1761         }
1762         return arr;
1763     }
1764 
1765     @Test
1766     public Object[] test76(MyValue1[] va, Integer[] oa) {
1767         int i = 0;
1768         for (; i < 10; i++);
1769 
1770         Object[] arr = test76_helper(i, va, oa);
1771         return arr.clone();
1772     }
1773 
1774     @DontCompile
1775     public void test76_verifier(boolean warmup) {
1776         int len = Math.abs(rI) % 10;
1777         MyValue1[] va = new MyValue1[len];
1778         MyValue1[] verif = new MyValue1[len];
1779         for (int i = 0; i < len; ++i) {
1780             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1781             verif[i] = va[i];
1782         }
1783         Integer[] oa = new Integer[len];
1784         test76_helper(42, va, oa);
1785         Object[] result = test76(va, oa);
1786         verify(verif, result);
1787         // Check that array has correct storage properties (null-free)
1788         if (len > 0) {
1789             try {
1790                 result[0] = null;
1791                 throw new RuntimeException("Should throw NullPointerException");
1792             } catch (NullPointerException e) {
1793                 // Expected
1794             }
1795         }
1796     }
1797 
1798     @Test
1799     public void test77() {
1800         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1801         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1802         MyValue1[] arr = new MyValue1[1];
1803 
1804         Object[] oa = arr;
1805         Object o1 = v1;
1806         Object o = (o1 == null) ? v0 : o1;
1807 
1808         oa[0] = o; // For C1, due to IfOp optimization, the declared_type of o becomes NULL.
1809 
1810         Asserts.assertEQ(arr[0].hash(), v1.hash());
1811     }
1812 
1813 
1814     @DontCompile
1815     public void test77_verifier(boolean warmup) {
1816         test77();
1817     }
1818 
1819     @Test
1820     public long test78(MyValue1 v, int n) {
1821         long x = 0;
1822         for (int i = 0; i<n; i++) {
1823         }
1824 
1825         MyValue1[] a = new MyValue1[n];
1826         a[0] = v;
1827         for (int i = 0; i<n; i++) {
1828             x += a[i].hash(); // C1 PhiSimplifier changes "a" from a Phi node to a NewObjectArray node
1829         }
1830 
1831         return x;
1832     }
1833 
1834     @DontCompile
1835     public void test78_verifier(boolean warmup) {
1836         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
1837         Asserts.assertEQ(test78(v, 1), v.hash());
1838     }
1839 
1840     // Verify that casting an array element to a non-flattenable type marks the array as not-flat
1841     @Test(valid = ValueTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_VALUE }, matchCount = { 1, 1 })
1842     @Test(valid = ValueTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE)
1843     public Object test79(Object[] array, int i) {
1844         Integer i1 = (Integer)array[0];
1845         Object o = array[1];
1846         return array[i];
1847     }
1848 
1849     @DontCompile
1850     public void test79_verifier(boolean warmup) {
1851         Integer i = new Integer(rI);
1852         Integer[] array = new Integer[2];
1853         array[1] = i;
1854         Object result = test79(array, 1);
1855         Asserts.assertEquals(result, i);
1856     }
1857 
1858     inline static class NotFlattenable {
1859         private final Object o1 = null;
1860         private final Object o2 = null;
1861         private final Object o3 = null;
1862         private final Object o4 = null;
1863         private final Object o5 = null;
1864         private final Object o6 = null;
1865     }
1866 
1867     // Same as test80 but with not-flattenable inline type
1868     @Test(valid = ValueTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_VALUE }, matchCount = { 1, 1 })
1869     @Test(valid = ValueTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE)
1870     public Object test80(Object[] array, int i) {
1871         NotFlattenable vt = (NotFlattenable)array[0];
1872         Object o = array[1];
1873         return array[i];
1874     }
1875 
1876     @DontCompile
1877     public void test80_verifier(boolean warmup) {
1878         NotFlattenable vt = new NotFlattenable();
1879         NotFlattenable[] array = new NotFlattenable[2];
1880         array[1] = vt;
1881         Object result = test80(array, 1);
1882         Asserts.assertEquals(result, vt);
1883     }
1884 
1885     // Verify that writing an object of a non-inline, non-null type to an array marks the array as not-null-free and not-flat
1886     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE + VALUE_ARRAY_NULL_GUARD)
1887     public Object test81(Object[] array, Integer v, Object o, int i) {
1888         if (v == null) {
1889           return null;
1890         }
1891         array[0] = v;
1892         array[1] = array[0];
1893         array[2] = o;
1894         return array[i];
1895     }
1896 
1897     @DontCompile
1898     public void test81_verifier(boolean warmup) {
1899         Integer i = new Integer(rI);
1900         Integer[] array1 = new Integer[3];
1901         Object[] array2 = new Object[3];
1902         Object result = test81(array1, i, i, 0);
1903         Asserts.assertEquals(array1[0], i);
1904         Asserts.assertEquals(array1[1], i);
1905         Asserts.assertEquals(array1[2], i);
1906         Asserts.assertEquals(result, i);
1907         result = test81(array2, i, i, 1);
1908         Asserts.assertEquals(array2[0], i);
1909         Asserts.assertEquals(array2[1], i);
1910         Asserts.assertEquals(array2[2], i);
1911         Asserts.assertEquals(result, i);
1912     }
1913 
1914     // Verify that writing an object of a non-flattenable inline type to an array marks the array as not-flat
1915     @Test(valid = ValueTypePassFieldsAsArgsOn, failOn = ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE)
1916     @Test(valid = ValueTypePassFieldsAsArgsOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE)
1917     public Object test82(Object[] array, NotFlattenable vt, Object o, int i) {
1918         array[0] = vt;
1919         array[1] = array[0];
1920         array[2] = o;
1921         return array[i];
1922     }
1923 
1924     @DontCompile
1925     public void test82_verifier(boolean warmup) {
1926         NotFlattenable vt = new NotFlattenable();
1927         NotFlattenable[] array1 = new NotFlattenable[3];
1928         Object[] array2 = new Object[3];
1929         Object result = test82(array1, vt, vt, 0);
1930         Asserts.assertEquals(array1[0], vt);
1931         Asserts.assertEquals(array1[1], vt);
1932         Asserts.assertEquals(array1[2], vt);
1933         Asserts.assertEquals(result, vt);
1934         result = test82(array2, vt, vt, 1);
1935         Asserts.assertEquals(array2[0], vt);
1936         Asserts.assertEquals(array2[1], vt);
1937         Asserts.assertEquals(array2[2], vt);
1938         Asserts.assertEquals(result, vt);
1939     }
1940 
1941     // Verify that casting an array element to a non-inline type type marks the array as not-null-free and not-flat
1942     @Test(valid = ValueTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_VALUE }, matchCount = { 1, 1 }, failOn = ALLOCA_G + STORE_UNKNOWN_VALUE + VALUE_ARRAY_NULL_GUARD)
1943     @Test(valid = ValueTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE + VALUE_ARRAY_NULL_GUARD)
1944     public void test83(Object[] array, Object o) {
1945         Integer i = (Integer)array[0];
1946         array[1] = o;
1947     }
1948 
1949     @DontCompile
1950     public void test83_verifier(boolean warmup) {
1951         Integer i = new Integer(rI);
1952         Integer[] array1 = new Integer[2];
1953         Object[] array2 = new Object[2];
1954         test83(array1, i);
1955         Asserts.assertEquals(array1[1], i);
1956         test83(array2, null);
1957         Asserts.assertEquals(array2[1], null);
1958     }
1959 
1960     // Verify that writing constant null into an array marks the array as not-null-free and not-flat
1961     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 1 })
1962     public Object test84(Object[] array, int i) {
1963         array[0] = null;
1964         array[1] = null;
1965         return array[i];
1966     }
1967 
1968     @DontCompile
1969     public void test84_verifier(boolean warmup) {
1970         NotFlattenable?[] array1 = new NotFlattenable?[2];
1971         Object[] array2 = new Object[2];
1972         Object result = test84(array1, 0);
1973         Asserts.assertEquals(array1[0], null);
1974         Asserts.assertEquals(result, null);
1975         result = test84(array2, 1);
1976         Asserts.assertEquals(array2[0], null);
1977         Asserts.assertEquals(result, null);
1978         if (!warmup) {
1979             NotFlattenable[] array3 = new NotFlattenable[2];
1980             try {
1981                 test84(array3, 1);
1982                 throw new RuntimeException("Should throw NullPointerException");
1983             } catch (NullPointerException e) {
1984                 // Expected
1985             }
1986         }
1987     }
1988 
1989     // Same as test84 but with branches
1990     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 2 })
1991     public void test85(Object[] array, Object o, boolean b) {
1992         if (b) {
1993             array[0] = null;
1994         } else {
1995             array[1] = null;
1996         }
1997         array[1] = o;
1998     }
1999 
2000     @DontCompile
2001     public void test85_verifier(boolean warmup) {
2002         Integer i = new Integer(rI);
2003         Integer[] array1 = new Integer[2];
2004         Object[] array2 = new Object[2];
2005         test85(array1, i, true);
2006         Asserts.assertEquals(array1[1], i);
2007         test85(array1, null, false);
2008         Asserts.assertEquals(array1[1], null);
2009         test85(array2, i, true);
2010         Asserts.assertEquals(array2[1], i);
2011         test85(array2, null, false);
2012         Asserts.assertEquals(array2[1], null);
2013         if (!warmup) {
2014             NotFlattenable[] array3 = new NotFlattenable[2];
2015             try {
2016                 test85(array3, null, true);
2017                 throw new RuntimeException("Should throw NullPointerException");
2018             } catch (NullPointerException e) {
2019                 // Expected
2020             }
2021         }
2022     }
2023 
2024     // Same as test85 but with not-flattenable inline type array
2025     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 2 })
2026     public void test86(NotFlattenable?[] array, NotFlattenable? o, boolean b) {
2027         if (b) {
2028             array[0] = null;
2029         } else {
2030             array[1] = null;
2031         }
2032         array[1] = o;
2033     }
2034 
2035     @DontCompile
2036     public void test86_verifier(boolean warmup) {
2037         NotFlattenable vt = new NotFlattenable();
2038         NotFlattenable?[] array1 = new NotFlattenable?[2];
2039         test86(array1, vt, true);
2040         Asserts.assertEquals(array1[1], vt);
2041         test86(array1, null, false);
2042         Asserts.assertEquals(array1[1], null);
2043         if (!warmup) {
2044             NotFlattenable[] array2 = new NotFlattenable[2];
2045             try {
2046                 test86(array2, null, true);
2047                 throw new RuntimeException("Should throw NullPointerException");
2048             } catch (NullPointerException e) {
2049                 // Expected
2050             }
2051         }
2052     }
2053 
2054     // Same as test85 but with inline type array
2055     @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_VALUE + STORE_UNKNOWN_VALUE, match = { VALUE_ARRAY_NULL_GUARD }, matchCount = { 2 })
2056     public void test87(MyValue1?[] array, MyValue1? o, boolean b) {
2057         if (b) {
2058             array[0] = null;
2059         } else {
2060             array[1] = null;
2061         }
2062         array[1] = o;
2063     }
2064 
2065     @DontCompile
2066     public void test87_verifier(boolean warmup) {
2067         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
2068         MyValue1?[] array1 = new MyValue1?[2];
2069         test87(array1, vt, true);
2070         Asserts.assertEquals(array1[1], vt);
2071         test87(array1, null, false);
2072         Asserts.assertEquals(array1[1], null);
2073         if (!warmup) {
2074             MyValue1[] array2 = new MyValue1[2];
2075             try {
2076                 test87(array2, null, true);
2077                 throw new RuntimeException("Should throw NullPointerException");
2078             } catch (NullPointerException e) {
2079                 // Expected
2080             }
2081         }
2082     }
2083 
2084     // Additional correcntess tests to make sure we have the required null checks
2085     @Test()
2086     public void test88(Object[] array, Integer v) {
2087         array[0] = v;
2088     }
2089 
2090     @DontCompile
2091     public void test88_verifier(boolean warmup) {
2092         Integer[] array1 = new Integer[1];
2093         Object[] array2 = new Object[1];
2094         test88(array1, null);
2095         Asserts.assertEquals(array1[0], null);
2096         test88(array2, null);
2097         Asserts.assertEquals(array2[0], null);
2098         if (!warmup) {
2099             MyValue1[] array3 = new MyValue1[1];
2100             try {
2101                 test88(array3, null);
2102                 throw new RuntimeException("Should throw NullPointerException");
2103             } catch (NullPointerException e) {
2104                 // Expected
2105             }
2106         }
2107     }
2108 
2109     @Test()
2110     public void test89(MyValue1?[] array, Integer v) {
2111         Object o = v;
2112         array[0] = (MyValue1?)o;
2113     }
2114 
2115     @DontCompile
2116     public void test89_verifier(boolean warmup) {
2117         MyValue1?[] array1 = new MyValue1?[1];
2118         test89(array1, null);
2119         Asserts.assertEquals(array1[0], null);
2120         if (!warmup) {
2121             MyValue1[] array2 = new MyValue1[1];
2122             try {
2123                 test89(array2, null);
2124                 throw new RuntimeException("Should throw NullPointerException");
2125             } catch (NullPointerException e) {
2126                 // Expected
2127             }
2128         }
2129     }
2130 
2131     @Test
2132     public boolean test90() {
2133         boolean b = true;
2134 
2135         MyValue1[] qArray = new MyValue1[0];
2136         MyValue1?[] lArray = new MyValue1?[0];
2137 
2138         b = b && (qArray instanceof MyValue1[]);
2139         b = b && (lArray instanceof MyValue1?[]);
2140 
2141         MyValue1[][] qArray2 = new MyValue1[0][0];
2142         MyValue1?[][] lArray2 = new MyValue1?[0][0];
2143 
2144         b = b && (qArray2 instanceof MyValue1[][]);
2145         b = b && (lArray2 instanceof MyValue1?[][]);
2146 
2147         return b;
2148     }
2149 
2150     @DontCompile
2151     public void test90_verifier(boolean warmup) {
2152         Asserts.assertEQ(test90(), true);
2153     }
2154 
2155     inline static final class Test91Value {
2156         public final int f0;
2157         public final int f1;
2158         public final int f2;
2159         public final int f3;
2160         public final int f4;
2161         public final int f5;
2162 
2163         public Test91Value(int i) {
2164             this.f0 = i;
2165             this.f1 = i;
2166             this.f2 = i;
2167             this.f3 = i;
2168             this.f4 = i;
2169             this.f5 = i;
2170         }
2171 
2172         public void verify() {
2173             if ((f0 != f1) || (f1 != f2) || (f2 != f3) || (f3 != f4) || (f4 != f5)) {
2174                 throw new RuntimeException("test91 failed");
2175             }
2176         }
2177     }
2178 
2179     // Test anti-dependencies between loads and stores from flattened array
2180     @Test
2181     @Warmup(0)
2182     public int test91(Test91Value[] array, int lo, int val) {
2183         int i = 3;
2184         while (lo < i) {
2185             Test91Value tmp = array[lo];
2186             array[lo++] = array[i];
2187             array[i--] = tmp;
2188         }
2189         return val;
2190     }
2191 
2192     @DontCompile
2193     public void test91_verifier(boolean warmup) {
2194         Test91Value[] array = new Test91Value[5];
2195         for (int i = 0; i < 5; ++i) {
2196             array[i] = new Test91Value(i);
2197             array[i].verify();
2198         }
2199         Asserts.assertEQ(test91(array, 0, 5), 5);
2200         for (int i = 0; i < 5; ++i) {
2201             array[i].verify();
2202         }
2203     }
2204 
2205     @Test
2206     public void test92(Object[] src, Object[] dst) {
2207         System.arraycopy(src, 0, dst, 0, src.length);
2208     }
2209 
2210     @DontCompile
2211     public void test92_verifier(boolean warmup) {
2212         MyValue1[] a = new MyValue1[1];
2213         MyValue1[] b = new MyValue1[1];
2214         try {
2215             test92(a, null);
2216             throw new RuntimeException("Should throw NullPointerException");
2217         } catch (NullPointerException expected) {}
2218 
2219         try {
2220             test92(null, b);
2221             throw new RuntimeException("Should throw NullPointerException");
2222         } catch (NullPointerException expected) {}
2223 
2224         a[0] = MyValue1.createWithFieldsInline(rI, rL);
2225         test92(a, b);
2226         verify(a, b);
2227     }
2228 
2229     // Same as test30 but accessing all elements of the non-escaping array
2230     @Test
2231     public long test93(MyValue2[] src, boolean flag) {
2232         MyValue2[] dst = new MyValue2[10];
2233         System.arraycopy(src, 0, dst, 0, 10);
2234         if (flag) {  }
2235         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2236                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2237     }
2238 
2239     @DontCompile
2240     public void test93_verifier(boolean warmup) {
2241         MyValue2[] src = new MyValue2[10];
2242         for (int i = 0; i < 10; ++i) {
2243             src[i] = MyValue2.createWithFieldsInline(rI, (rI % 2) == 0);
2244         }
2245         long res = test93(src, !warmup);
2246         long expected = 0;
2247         for (int i = 0; i < 10; ++i) {
2248             expected += src[i].hash();
2249         }
2250         Asserts.assertEQ(res, expected);
2251     }
2252 
2253     // Same as test93 but with variable source array offset
2254     @Test
2255     public long test94(MyValue2[] src, int i, boolean flag) {
2256         MyValue2[] dst = new MyValue2[10];
2257         System.arraycopy(src, i, dst, 0, 1);
2258         if (flag) {  }
2259         return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
2260                dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
2261     }
2262 
2263     @DontCompile
2264     public void test94_verifier(boolean warmup) {
2265         MyValue2[] src = new MyValue2[10];
2266         for (int i = 0; i < 10; ++i) {
2267             src[i] = MyValue2.createWithFieldsInline(i, (i % 2) == 0);
2268         }
2269         for (int i = 0; i < 10; ++i) {
2270             long res = test94(src, i, !warmup);
2271             long expected = src[i].hash() + 9*MyValue2.default.hash();
2272             Asserts.assertEQ(res, expected);
2273         }
2274     }
2275 }