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