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 // TODO fix
 854 //    @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
 855     public MyValue2? test28() {
 856         MyValue2?[] src = new MyValue2?[10];
 857         src[0] = null;
 858         MyValue2?[] dst = (MyValue2?[])src.clone();
 859         return dst[0];
 860     }
 861 
 862     @DontCompile
 863     public void test28_verifier(boolean warmup) {
 864         MyValue2 v = MyValue2.createWithFieldsInline(rI, false);
 865         MyValue2? result = test28();
 866         Asserts.assertEQ(result, null);
 867     }
 868 
 869     // non escaping allocations
 870     @Test(failOn = ALLOCA + LOOP + TRAP)
 871     public MyValue2? test29(MyValue2?[] src) {
 872         MyValue2?[] dst = new MyValue2?[10];
 873         System.arraycopy(src, 0, dst, 0, 10);
 874         return dst[0];
 875     }
 876 
 877     @DontCompile
 878     public void test29_verifier(boolean warmup) {
 879         MyValue2?[] src = new MyValue2?[10];
 880         for (int i = 0; i < 10; ++i) {
 881             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 882         }
 883         MyValue2? v = test29(src);
 884         Asserts.assertEQ(src[0].hash(), v.hash());
 885     }
 886 
 887     // non escaping allocation with uncommon trap that needs
 888     // eliminated value type array element as debug info
 889     @Test
 890     @Warmup(10000)
 891     public MyValue2? test30(MyValue2?[] src, boolean flag) {
 892         MyValue2?[] dst = new MyValue2?[10];
 893         System.arraycopy(src, 0, dst, 0, 10);
 894         if (flag) { }
 895         return dst[0];
 896     }
 897 
 898     @DontCompile
 899     public void test30_verifier(boolean warmup) {
 900         MyValue2?[] src = new MyValue2?[10];
 901         for (int i = 0; i < 10; ++i) {
 902             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 903         }
 904         MyValue2? v = test30(src, false);
 905         Asserts.assertEQ(src[0].hash(), v.hash());
 906     }
 907 
 908     // non escaping allocation with memory phi
 909     @Test()
 910 // TODO fix
 911 //    @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + TRAP)
 912     public long test31(boolean b, boolean deopt) {
 913         MyValue2?[] src = new MyValue2?[1];
 914         if (b) {
 915             src[0] = MyValue2.createWithFieldsInline(rI, true);
 916         } else {
 917             src[0] = MyValue2.createWithFieldsInline(rI, false);
 918         }
 919         if (deopt) {
 920             // uncommon trap
 921             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31"));
 922         }
 923         return src[0].hash();
 924     }
 925 
 926     @DontCompile
 927     public void test31_verifier(boolean warmup) {
 928         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true);
 929         long result1 = test31(true, !warmup);
 930         Asserts.assertEQ(result1, v1.hash());
 931         MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false);
 932         long result2 = test31(false, !warmup);
 933         Asserts.assertEQ(result2, v2.hash());
 934     }
 935 
 936     // Tests with Object arrays and clone/arraycopy
 937     // clone() as stub call
 938     @Test
 939     public Object[] test32(Object[] va) {
 940         return va.clone();
 941     }
 942 
 943     @DontCompile
 944     public void test32_verifier(boolean warmup) {
 945         int len = Math.abs(rI) % 10;
 946         MyValue1?[] va1 = new MyValue1?[len];
 947         MyValue1[] va2 = new MyValue1[len];
 948         for (int i = 1; i < len; ++i) {
 949             va1[i] = testValue1;
 950             va2[i] = testValue1;
 951         }
 952         MyValue1?[] result1 = (MyValue1?[])test32(va1);
 953         MyValue1?[] result2 = (MyValue1?[])test32(va2);
 954         if (len > 0) {
 955             Asserts.assertEQ(result1[0], null);
 956             Asserts.assertEQ(result2[0].hash(), MyValue1.default.hash());
 957         }
 958         for (int i = 1; i < len; ++i) {
 959             Asserts.assertEQ(((MyValue1)result1[i]).hash(), ((MyValue1)va1[i]).hash());
 960             Asserts.assertEQ(((MyValue1)result2[i]).hash(), ((MyValue1)va2[i]).hash());
 961         }
 962     }
 963 
 964     @Test
 965     public Object[] test33(Object[] va) {
 966         return va.clone();
 967     }
 968 
 969     @DontCompile
 970     public void test33_verifier(boolean warmup) {
 971         int len = Math.abs(rI) % 10;
 972         Object[] va = new Object[len];
 973         for (int i = 0; i < len; ++i) {
 974             va[i] = testValue1;
 975         }
 976         Object[] result = test33(va);
 977         for (int i = 0; i < len; ++i) {
 978             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 979         }
 980     }
 981 
 982     // clone() as series of loads/stores
 983     static Object[] test34_orig = null;
 984 
 985     @ForceInline
 986     public Object[] test34_helper(boolean flag) {
 987         Object[] va = null;
 988         if (flag) {
 989             va = new MyValue1?[8];
 990             for (int i = 0; i < va.length; ++i) {
 991                 va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 992             }
 993         } else {
 994             va = new Object[8];
 995         }
 996         return va;
 997     }
 998 
 999     @Test
1000     public Object[] test34(boolean flag) {
1001         Object[] va = test34_helper(flag);
1002         test34_orig = va;
1003         return va.clone();
1004     }
1005 
1006     @DontCompile
1007     public void test34_verifier(boolean warmup) {
1008         test34(false);
1009         for (int i = 0; i < 10; i++) { // make sure we do deopt
1010             Object[] result = test34(true);
1011             verify(test34_orig, result);
1012         }
1013         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test34")) {
1014             Object[] result = test34(true);
1015             verify(test34_orig, result);
1016         }
1017     }
1018 
1019     static void verify(Object[] src, Object[] dst) {
1020         for (int i = 0; i < src.length; ++i) {
1021             if (src[i] != null) {
1022                 Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash());
1023             } else {
1024                 Asserts.assertEQ(dst[i], null);
1025             }
1026         }
1027     }
1028 
1029     static void verify(MyValue1?[] src, MyValue1?[] dst) {
1030         for (int i = 0; i < src.length; ++i) {
1031             if (src[i] != null) {
1032                 Asserts.assertEQ(src[i].hash(), dst[i].hash());
1033             } else {
1034                 Asserts.assertEQ(dst[i], null);
1035             }
1036         }
1037     }
1038 
1039     static void verify(MyValue1?[] src, Object[] dst) {
1040         for (int i = 0; i < src.length; ++i) {
1041             if (src[i] != null) {
1042                 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
1043             } else {
1044                 Asserts.assertEQ(dst[i], null);
1045             }
1046         }
1047     }
1048 
1049     static void verify(MyValue2?[] src, MyValue2?[] dst) {
1050         for (int i = 0; i < src.length; ++i) {
1051             if (src[i] != null) {
1052                 Asserts.assertEQ(src[i].hash(), dst[i].hash());
1053             } else {
1054                 Asserts.assertEQ(dst[i], null);
1055             }
1056         }
1057     }
1058 
1059     static void verify(MyValue2?[] src, Object[] dst) {
1060         for (int i = 0; i < src.length; ++i) {
1061             if (src[i] != null) {
1062                 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
1063             } else {
1064                 Asserts.assertEQ(dst[i], null);
1065             }
1066         }
1067     }
1068 
1069     static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) {
1070         if (!warmup) {
1071             Method m = tests.get(test);
1072             if (USE_COMPILER &&  !WHITE_BOX.isMethodCompiled(m, false)) {
1073                 if (!ValueTypeArrayFlatten && !XCOMP) {
1074                     throw new RuntimeException("Unexpected deoptimization");
1075                 }
1076                 WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1077                 return true;
1078             }
1079         }
1080         return false;
1081     }
1082 
1083     // arraycopy() of value type array of unknown size
1084     @Test
1085     public void test35(Object src, Object dst, int len) {
1086         System.arraycopy(src, 0, dst, 0, len);
1087     }
1088 
1089     @DontCompile
1090     public void test35_verifier(boolean warmup) {
1091         int len = Math.abs(rI) % 10;
1092         MyValue1?[] src = new MyValue1?[len];
1093         MyValue1?[] dst = new MyValue1?[len];
1094         for (int i = 1; i < len; ++i) {
1095             src[i] = testValue1;
1096         }
1097         test35(src, dst, src.length);
1098         verify(src, dst);
1099         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test35")) {
1100             test35(src, dst, src.length);
1101             verify(src, dst);
1102         }
1103     }
1104 
1105     @Test
1106     public void test36(Object src, MyValue2?[] dst) {
1107         System.arraycopy(src, 0, dst, 0, dst.length);
1108     }
1109 
1110     @DontCompile
1111     public void test36_verifier(boolean warmup) {
1112         int len = Math.abs(rI) % 10;
1113         MyValue2?[] src = new MyValue2?[len];
1114         MyValue2?[] dst = new MyValue2?[len];
1115         for (int i = 1; i < len; ++i) {
1116             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1117         }
1118         test36(src, dst);
1119         verify(src, dst);
1120         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test36")) {
1121             test36(src, dst);
1122             verify(src, dst);
1123         }
1124     }
1125 
1126     @Test
1127     public void test37(MyValue2?[] src, Object dst) {
1128         System.arraycopy(src, 0, dst, 0, src.length);
1129     }
1130 
1131     @DontCompile
1132     public void test37_verifier(boolean warmup) {
1133         int len = Math.abs(rI) % 10;
1134         MyValue2?[] src = new MyValue2?[len];
1135         MyValue2?[] dst = new MyValue2?[len];
1136         for (int i = 1; i < len; ++i) {
1137             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1138         }
1139         test37(src, dst);
1140         verify(src, dst);
1141         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test37")) {
1142             test37(src, dst);
1143             verify(src, dst);
1144         }
1145     }
1146 
1147     @Test
1148     @Warmup(1) // Avoid early compilation
1149     public void test38(Object src, MyValue2?[] dst) {
1150         System.arraycopy(src, 0, dst, 0, dst.length);
1151     }
1152 
1153     @DontCompile
1154     public void test38_verifier(boolean warmup) {
1155         int len = Math.abs(rI) % 10;
1156         Object[] src = new Object[len];
1157         MyValue2?[] dst = new MyValue2?[len];
1158         for (int i = 1; i < len; ++i) {
1159             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1160         }
1161         test38(src, dst);
1162         verify(dst, src);
1163         if (!warmup) {
1164             Method m = tests.get("TestNullableArrays::test38");
1165             assertDeoptimizedByC2(m);
1166             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1167             test38(src, dst);
1168             verify(dst, src);
1169             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1170                 throw new RuntimeException("unexpected deoptimization");
1171             }
1172         }
1173     }
1174 
1175     @Test
1176     public void test39(MyValue2?[] src, Object dst) {
1177         System.arraycopy(src, 0, dst, 0, src.length);
1178     }
1179 
1180     @DontCompile
1181     public void test39_verifier(boolean warmup) {
1182         int len = Math.abs(rI) % 10;
1183         MyValue2?[] src = new MyValue2?[len];
1184         Object[] dst = new Object[len];
1185         for (int i = 1; i < len; ++i) {
1186             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1187         }
1188         test39(src, dst);
1189         verify(src, dst);
1190         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test39")) {
1191             test39(src, dst);
1192             verify(src, dst);
1193         }
1194     }
1195 
1196     @Test
1197     @Warmup(1) // Avoid early compilation
1198     public void test40(Object[] src, Object dst) {
1199         System.arraycopy(src, 0, dst, 0, src.length);
1200     }
1201 
1202     @DontCompile
1203     public void test40_verifier(boolean warmup) {
1204         int len = Math.abs(rI) % 10;
1205         Object[] src = new Object[len];
1206         MyValue2?[] dst = new MyValue2?[len];
1207         for (int i = 1; i < len; ++i) {
1208             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1209         }
1210         test40(src, dst);
1211         verify(dst, src);
1212         if (!warmup) {
1213             Method m = tests.get("TestNullableArrays::test40");
1214             assertDeoptimizedByC2(m);
1215             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1216             test40(src, dst);
1217             verify(dst, src);
1218             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1219                 throw new RuntimeException("unexpected deoptimization");
1220             }
1221         }
1222     }
1223 
1224     @Test
1225     public void test41(Object src, Object[] dst) {
1226         System.arraycopy(src, 0, dst, 0, dst.length);
1227     }
1228 
1229     @DontCompile
1230     public void test41_verifier(boolean warmup) {
1231         int len = Math.abs(rI) % 10;
1232         MyValue2?[] src = new MyValue2?[len];
1233         Object[] dst = new Object[len];
1234         for (int i = 1; i < len; ++i) {
1235             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1236         }
1237         test41(src, dst);
1238         verify(src, dst);
1239         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test41")) {
1240             test41(src, dst);
1241             verify(src, dst);
1242         }
1243     }
1244 
1245     @Test
1246     public void test42(Object[] src, Object[] dst) {
1247         System.arraycopy(src, 0, dst, 0, src.length);
1248     }
1249 
1250     @DontCompile
1251     public void test42_verifier(boolean warmup) {
1252         int len = Math.abs(rI) % 10;
1253         Object[] src = new Object[len];
1254         Object[] dst = new Object[len];
1255         for (int i = 1; i < len; ++i) {
1256             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1257         }
1258         test42(src, dst);
1259         verify(src, dst);
1260         if (!warmup) {
1261             Method m = tests.get("TestNullableArrays::test42");
1262             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1263                 throw new RuntimeException("unexpected deoptimization");
1264             }
1265         }
1266     }
1267 
1268     // short arraycopy()'s
1269     @Test
1270     public void test43(Object src, Object dst) {
1271         System.arraycopy(src, 0, dst, 0, 8);
1272     }
1273 
1274     @DontCompile
1275     public void test43_verifier(boolean warmup) {
1276         MyValue1?[] src = new MyValue1?[8];
1277         MyValue1?[] dst = new MyValue1?[8];
1278         for (int i = 1; i < 8; ++i) {
1279             src[i] = testValue1;
1280         }
1281         test43(src, dst);
1282         verify(src, dst);
1283         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test43")) {
1284             test43(src, dst);
1285             verify(src, dst);
1286         }
1287     }
1288 
1289     @Test
1290     public void test44(Object src, MyValue2?[] dst) {
1291         System.arraycopy(src, 0, dst, 0, 8);
1292     }
1293 
1294     @DontCompile
1295     public void test44_verifier(boolean warmup) {
1296         MyValue2?[] src = new MyValue2?[8];
1297         MyValue2?[] dst = new MyValue2?[8];
1298         for (int i = 1; i < 8; ++i) {
1299             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1300         }
1301         test44(src, dst);
1302         verify(src, dst);
1303         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test44")) {
1304             test44(src, dst);
1305             verify(src, dst);
1306         }
1307     }
1308 
1309     @Test
1310     public void test45(MyValue2?[] src, Object dst) {
1311         System.arraycopy(src, 0, dst, 0, 8);
1312     }
1313 
1314     @DontCompile
1315     public void test45_verifier(boolean warmup) {
1316         MyValue2?[] src = new MyValue2?[8];
1317         MyValue2?[] dst = new MyValue2?[8];
1318         for (int i = 1; i < 8; ++i) {
1319             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1320         }
1321         test45(src, dst);
1322         verify(src, dst);
1323         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test45")) {
1324             test45(src, dst);
1325             verify(src, dst);
1326         }
1327     }
1328 
1329     @Test
1330     @Warmup(1) // Avoid early compilation
1331     public void test46(Object[] src, MyValue2?[] dst) {
1332         System.arraycopy(src, 0, dst, 0, 8);
1333     }
1334 
1335     @DontCompile
1336     public void test46_verifier(boolean warmup) {
1337         Object[] src = new Object[8];
1338         MyValue2?[] dst = new MyValue2?[8];
1339         for (int i = 1; i < 8; ++i) {
1340             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1341         }
1342         test46(src, dst);
1343         verify(dst, src);
1344         if (!warmup) {
1345             Method m = tests.get("TestNullableArrays::test46");
1346             assertDeoptimizedByC2(m);
1347             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1348             test46(src, dst);
1349             verify(dst, src);
1350             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1351                 throw new RuntimeException("unexpected deoptimization");
1352             }
1353         }
1354     }
1355 
1356     @Test
1357     public void test47(MyValue2?[] src, Object[] dst) {
1358         System.arraycopy(src, 0, dst, 0, 8);
1359     }
1360 
1361     @DontCompile
1362     public void test47_verifier(boolean warmup) {
1363         MyValue2?[] src = new MyValue2?[8];
1364         Object[] dst = new Object[8];
1365         for (int i = 1; i < 8; ++i) {
1366             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1367         }
1368         test47(src, dst);
1369         verify(src, dst);
1370         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test47")) {
1371             test47(src, dst);
1372             verify(src, dst);
1373         }
1374     }
1375 
1376     @Test
1377     @Warmup(1) // Avoid early compilation
1378     public void test48(Object[] src, Object dst) {
1379         System.arraycopy(src, 0, dst, 0, 8);
1380     }
1381 
1382     @DontCompile
1383     public void test48_verifier(boolean warmup) {
1384         Object[] src = new Object[8];
1385         MyValue2?[] dst = new MyValue2?[8];
1386         for (int i = 1; i < 8; ++i) {
1387             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1388         }
1389         test48(src, dst);
1390         verify(dst, src);
1391         if (!warmup) {
1392             Method m = tests.get("TestNullableArrays::test48");
1393             assertDeoptimizedByC2(m);
1394             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1395             test48(src, dst);
1396             verify(dst, src);
1397             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1398                 throw new RuntimeException("unexpected deoptimization");
1399             }
1400         }
1401     }
1402 
1403     @Test
1404     public void test49(Object src, Object[] dst) {
1405         System.arraycopy(src, 0, dst, 0, 8);
1406     }
1407 
1408     @DontCompile
1409     public void test49_verifier(boolean warmup) {
1410         MyValue2?[] src = new MyValue2?[8];
1411         Object[] dst = new Object[8];
1412         for (int i = 1; i < 8; ++i) {
1413             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1414         }
1415         test49(src, dst);
1416         verify(src, dst);
1417         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test49")) {
1418             test49(src, dst);
1419             verify(src, dst);
1420         }
1421     }
1422 
1423     @Test
1424     public void test50(Object[] src, Object[] dst) {
1425         System.arraycopy(src, 0, dst, 0, 8);
1426     }
1427 
1428     @DontCompile
1429     public void test50_verifier(boolean warmup) {
1430         Object[] src = new Object[8];
1431         Object[] dst = new Object[8];
1432         for (int i = 1; i < 8; ++i) {
1433             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1434         }
1435         test50(src, dst);
1436         verify(src, dst);
1437         if (!warmup) {
1438             Method m = tests.get("TestNullableArrays::test50");
1439             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1440                 throw new RuntimeException("unexpected deoptimization");
1441             }
1442         }
1443     }
1444 
1445     @Test
1446     public MyValue1?[] test51(MyValue1?[] va) {
1447         return Arrays.copyOf(va, va.length, MyValue1?[].class);
1448     }
1449 
1450     @DontCompile
1451     public void test51_verifier(boolean warmup) {
1452         int len = Math.abs(rI) % 10;
1453         MyValue1?[] va = new MyValue1?[len];
1454         for (int i = 1; i < len; ++i) {
1455             va[i] = testValue1;
1456         }
1457         MyValue1?[] result = test51(va);
1458         verify(va, result);
1459     }
1460 
1461     static final MyValue1?[] test52_va = new MyValue1?[8];
1462 
1463     @Test
1464     public MyValue1?[] test52() {
1465         return Arrays.copyOf(test52_va, 8, MyValue1?[].class);
1466     }
1467 
1468     @DontCompile
1469     public void test52_verifier(boolean warmup) {
1470         for (int i = 1; i < 8; ++i) {
1471             test52_va[i] = testValue1;
1472         }
1473         MyValue1?[] result = test52();
1474         verify(test52_va, result);
1475     }
1476 
1477     @Test
1478     public MyValue1?[] test53(Object[] va) {
1479         return Arrays.copyOf(va, va.length, MyValue1?[].class);
1480     }
1481 
1482     @DontCompile
1483     public void test53_verifier(boolean warmup) {
1484         int len = Math.abs(rI) % 10;
1485         MyValue1?[] va = new MyValue1?[len];
1486         for (int i = 1; i < len; ++i) {
1487             va[i] = testValue1;
1488         }
1489         MyValue1?[] result = test53(va);
1490         verify(result, va);
1491     }
1492 
1493     @Test
1494     public Object[] test54(MyValue1?[] va) {
1495         return Arrays.copyOf(va, va.length, Object[].class);
1496     }
1497 
1498     @DontCompile
1499     public void test54_verifier(boolean warmup) {
1500         int len = Math.abs(rI) % 10;
1501         MyValue1?[] va = new MyValue1?[len];
1502         for (int i = 1; i < len; ++i) {
1503             va[i] = testValue1;
1504         }
1505         Object[] result = test54(va);
1506         verify(va, result);
1507     }
1508 
1509     @Test
1510     public Object[] test55(Object[] va) {
1511         return Arrays.copyOf(va, va.length, Object[].class);
1512     }
1513 
1514     @DontCompile
1515     public void test55_verifier(boolean warmup) {
1516         int len = Math.abs(rI) % 10;
1517         MyValue1?[] va = new MyValue1?[len];
1518         for (int i = 1; i < len; ++i) {
1519             va[i] = testValue1;
1520         }
1521         Object[] result = test55(va);
1522         verify(va, result);
1523     }
1524 
1525     @Test
1526     public MyValue1?[] test56(Object[] va) {
1527         return Arrays.copyOf(va, va.length, MyValue1?[].class);
1528     }
1529 
1530     @DontCompile
1531     public void test56_verifier(boolean warmup) {
1532         int len = Math.abs(rI) % 10;
1533         Object[] va = new Object[len];
1534         for (int i = 1; i < len; ++i) {
1535             va[i] = testValue1;
1536         }
1537         MyValue1?[] result = test56(va);
1538         verify(result, va);
1539     }
1540 
1541    @Test
1542     public Object[] test57(Object[] va, Class klass) {
1543         return Arrays.copyOf(va, va.length, klass);
1544     }
1545 
1546     @DontCompile
1547     public void test57_verifier(boolean warmup) {
1548         int len = Math.abs(rI) % 10;
1549         Object[] va = new MyValue1?[len];
1550         for (int i = 1; i < len; ++i) {
1551             va[i] = testValue1;
1552         }
1553         Object[] result = test57(va, MyValue1?[].class);
1554         verify(va, result);
1555     }
1556 
1557     @Test
1558     public Object[] test58(MyValue1?[] va, Class klass) {
1559         return Arrays.copyOf(va, va.length, klass);
1560     }
1561 
1562     @DontCompile
1563     public void test58_verifier(boolean warmup) {
1564         int len = Math.abs(rI) % 10;
1565         MyValue1?[] va = new MyValue1?[len];
1566         for (int i = 1; i < len; ++i) {
1567             va[i] = testValue1;
1568         }
1569         for (int i = 1; i < 10; i++) {
1570             Object[] result = test58(va, MyValue1?[].class);
1571             verify(va, result);
1572         }
1573         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test58")) {
1574             Object[] result = test58(va, MyValue1?[].class);
1575             verify(va, result);
1576         }
1577     }
1578 
1579     @Test
1580     public Object[] test59(MyValue1?[] va) {
1581         return Arrays.copyOf(va, va.length+1, MyValue1?[].class);
1582     }
1583 
1584     @DontCompile
1585     public void test59_verifier(boolean warmup) {
1586         int len = Math.abs(rI) % 10;
1587         MyValue1?[] va = new MyValue1?[len];
1588         MyValue1?[] verif = new MyValue1?[len+1];
1589         for (int i = 1; i < len; ++i) {
1590             va[i] = testValue1;
1591             verif[i] = va[i];
1592         }
1593         Object[] result = test59(va);
1594         verify(verif, result);
1595     }
1596 
1597     @Test
1598     public Object[] test60(Object[] va, Class klass) {
1599         return Arrays.copyOf(va, va.length+1, klass);
1600     }
1601 
1602     @DontCompile
1603     public void test60_verifier(boolean warmup) {
1604         int len = Math.abs(rI) % 10;
1605         MyValue1?[] va = new MyValue1?[len];
1606         MyValue1?[] verif = new MyValue1?[len+1];
1607         for (int i = 1; i < len; ++i) {
1608             va[i] = testValue1;
1609             verif[i] = (MyValue1)va[i];
1610         }
1611         Object[] result = test60(va, MyValue1?[].class);
1612         verify(verif, result);
1613     }
1614 
1615     @Test
1616     public Object[] test61(Object[] va, Class klass) {
1617         return Arrays.copyOf(va, va.length+1, klass);
1618     }
1619 
1620     @DontCompile
1621     public void test61_verifier(boolean warmup) {
1622         int len = Math.abs(rI) % 10;
1623         Object[] va = new Integer[len];
1624         for (int i = 1; i < len; ++i) {
1625             va[i] = new Integer(rI);
1626         }
1627         Object[] result = test61(va, Integer[].class);
1628         for (int i = 0; i < va.length; ++i) {
1629             Asserts.assertEQ(va[i], result[i]);
1630         }
1631     }
1632 
1633     @ForceInline
1634     public Object[] test62_helper(int i, MyValue1?[] va, Integer[] oa) {
1635         Object[] arr = null;
1636         if (i == 10) {
1637             arr = oa;
1638         } else {
1639             arr = va;
1640         }
1641         return arr;
1642     }
1643 
1644     @Test
1645     public Object[] test62(MyValue1?[] va, Integer[] oa) {
1646         int i = 0;
1647         for (; i < 10; i++);
1648 
1649         Object[] arr = test62_helper(i, va, oa);
1650 
1651         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1652     }
1653 
1654     @DontCompile
1655     public void test62_verifier(boolean warmup) {
1656         int len = Math.abs(rI) % 10;
1657         MyValue1?[] va = new MyValue1?[len];
1658         Integer[] oa = new Integer[len];
1659         for (int i = 1; i < len; ++i) {
1660             oa[i] = new Integer(rI);
1661         }
1662         test62_helper(42, va, oa);
1663         Object[] result = test62(va, oa);
1664         for (int i = 0; i < va.length; ++i) {
1665             Asserts.assertEQ(oa[i], result[i]);
1666         }
1667     }
1668 
1669     @ForceInline
1670     public Object[] test63_helper(int i, MyValue1?[] va, Integer[] oa) {
1671         Object[] arr = null;
1672         if (i == 10) {
1673             arr = va;
1674         } else {
1675             arr = oa;
1676         }
1677         return arr;
1678     }
1679 
1680     @Test
1681     public Object[] test63(MyValue1?[] va, Integer[] oa) {
1682         int i = 0;
1683         for (; i < 10; i++);
1684 
1685         Object[] arr = test63_helper(i, va, oa);
1686 
1687         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1688     }
1689 
1690     @DontCompile
1691     public void test63_verifier(boolean warmup) {
1692         int len = Math.abs(rI) % 10;
1693         MyValue1?[] va = new MyValue1?[len];
1694         MyValue1?[] verif = new MyValue1?[len+1];
1695         for (int i = 1; i < len; ++i) {
1696             va[i] = testValue1;
1697             verif[i] = va[i];
1698         }
1699         Integer[] oa = new Integer[len];
1700         test63_helper(42, va, oa);
1701         Object[] result = test63(va, oa);
1702         verify(verif, result);
1703     }
1704 
1705     // Test default initialization of value type arrays: small array
1706     @Test
1707     public MyValue1?[] test64() {
1708         return new MyValue1?[8];
1709     }
1710 
1711     @DontCompile
1712     public void test64_verifier(boolean warmup) {
1713         MyValue1?[] va = test64();
1714         for (int i = 0; i < 8; ++i) {
1715             Asserts.assertEQ(va[i], null);
1716         }
1717     }
1718 
1719     // Test default initialization of value type arrays: large array
1720     @Test
1721     public MyValue1?[] test65() {
1722         return new MyValue1?[32];
1723     }
1724 
1725     @DontCompile
1726     public void test65_verifier(boolean warmup) {
1727         MyValue1?[] va = test65();
1728         for (int i = 0; i < 32; ++i) {
1729             Asserts.assertEQ(va[i], null);
1730         }
1731     }
1732 
1733     // Check init store elimination
1734     @Test
1735     public MyValue1?[] test66(MyValue1? vt) {
1736         MyValue1?[] va = new MyValue1?[1];
1737         va[0] = vt;
1738         return va;
1739     }
1740 
1741     @DontCompile
1742     public void test66_verifier(boolean warmup) {
1743         MyValue1? vt = MyValue1.createWithFieldsDontInline(rI, rL);
1744         MyValue1?[] va = test66(vt);
1745         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1746     }
1747 
1748     // Zeroing elimination and arraycopy
1749     @Test
1750     public MyValue1?[] test67(MyValue1?[] src) {
1751         MyValue1?[] dst = new MyValue1?[16];
1752         System.arraycopy(src, 0, dst, 0, 13);
1753         return dst;
1754     }
1755 
1756     @DontCompile
1757     public void test67_verifier(boolean warmup) {
1758         MyValue1?[] va = new MyValue1?[16];
1759         MyValue1?[] var = test67(va);
1760         for (int i = 0; i < 16; ++i) {
1761             Asserts.assertEQ(var[i], null);
1762         }
1763     }
1764 
1765     // A store with a default value can be eliminated
1766     @Test
1767     public MyValue1?[] test68() {
1768         MyValue1?[] va = new MyValue1?[2];
1769         va[0] = va[1];
1770         return va;
1771     }
1772 
1773     @DontCompile
1774     public void test68_verifier(boolean warmup) {
1775         MyValue1?[] va = test68();
1776         for (int i = 0; i < 2; ++i) {
1777             Asserts.assertEQ(va[i], null);
1778         }
1779     }
1780 
1781     // Requires individual stores to init array
1782     @Test
1783     public MyValue1?[] test69(MyValue1? vt) {
1784         MyValue1?[] va = new MyValue1?[4];
1785         va[0] = vt;
1786         va[3] = vt;
1787         return va;
1788     }
1789 
1790     @DontCompile
1791     public void test69_verifier(boolean warmup) {
1792         MyValue1? vt = MyValue1.createWithFieldsDontInline(rI, rL);
1793         MyValue1?[] va = new MyValue1?[4];
1794         va[0] = vt;
1795         va[3] = vt;
1796         MyValue1?[] var = test69(vt);
1797         for (int i = 0; i < va.length; ++i) {
1798             Asserts.assertEQ(va[i], var[i]);
1799         }
1800     }
1801 
1802     // A store with a default value can be eliminated: same as test68
1803     // but store is farther away from allocation
1804     @Test
1805     public MyValue1?[] test70(MyValue1?[] other) {
1806         other[1] = other[0];
1807         MyValue1?[] va = new MyValue1?[2];
1808         other[0] = va[1];
1809         va[0] = va[1];
1810         return va;
1811     }
1812 
1813     @DontCompile
1814     public void test70_verifier(boolean warmup) {
1815         MyValue1?[] va = new MyValue1?[2];
1816         MyValue1?[] var = test70(va);
1817         for (int i = 0; i < 2; ++i) {
1818             Asserts.assertEQ(va[i], var[i]);
1819         }
1820     }
1821 
1822     // EA needs to consider oop fields in flattened arrays
1823     @Test
1824     public void test71() {
1825         int len = 10;
1826         MyValue2?[] src = new MyValue2?[len];
1827         MyValue2?[] dst = new MyValue2?[len];
1828         for (int i = 1; i < len; ++i) {
1829             src[i] = MyValue2.createWithFieldsDontInline(rI, (i % 2) == 0);
1830         }
1831         System.arraycopy(src, 0, dst, 0, src.length);
1832         for (int i = 0; i < len; ++i) {
1833             if (src[i] == null) {
1834                 Asserts.assertEQ(dst[i], null);
1835             } else {
1836                 Asserts.assertEQ(src[i].hash(), dst[i].hash());
1837             }
1838         }
1839     }
1840 
1841     @DontCompile
1842     public void test71_verifier(boolean warmup) {
1843         test71();
1844     }
1845 
1846     // Test EA with leaf call to 'store_unknown_value'
1847     @Test
1848     public void test72(Object[] o, boolean b, Object element) {
1849         Object[] arr1 = new Object[10];
1850         Object[] arr2 = new Object[10];
1851         if (b) {
1852             arr1 = o;
1853         }
1854         arr1[0] = element;
1855         arr2[0] = element;
1856     }
1857 
1858     @DontCompile
1859     public void test72_verifier(boolean warmup) {
1860         Object[] arr = new Object[1];
1861         Object elem = new Object();
1862         test72(arr, true, elem);
1863         test72(arr, false, elem);
1864     }
1865 
1866     @Test
1867     public void test73(Object[] oa, MyValue1? v, Object o) {
1868         // TestLWorld.test38 use a C1 Phi node for the array. This test
1869         // adds the case where the stored value is a C1 Phi node.
1870         Object o2 = (o == null) ? v : o;
1871         oa[0] = v;  // The stored value is known to be flattenable
1872         oa[1] = o;  // The stored value may be flattenable
1873         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1874         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1875     }
1876 
1877     @DontCompile
1878     public void test73_verifier(boolean warmup) {
1879         MyValue1? v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1880         MyValue1? v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1881         MyValue1?[] arr = new MyValue1?[3];
1882         try {
1883             test73(arr, v0, v1);
1884             throw new RuntimeException("ArrayStoreException expected");
1885         } catch (ArrayStoreException t) {
1886             // expected
1887         }
1888         Asserts.assertEQ(arr[0].hash(), v0.hash());
1889         Asserts.assertEQ(arr[1].hash(), v1.hash());
1890         Asserts.assertEQ(arr[2].hash(), v1.hash());
1891     }
1892 
1893     // Some more array clone tests
1894     @ForceInline
1895     public Object[] test74_helper(int i, MyValue1?[] va, Integer[] oa) {
1896         Object[] arr = null;
1897         if (i == 10) {
1898             arr = oa;
1899         } else {
1900             arr = va;
1901         }
1902         return arr;
1903     }
1904 
1905     @Test
1906     public Object[] test74(MyValue1?[] va, Integer[] oa) {
1907         int i = 0;
1908         for (; i < 10; i++);
1909 
1910         Object[] arr = test74_helper(i, va, oa);
1911         return arr.clone();
1912     }
1913 
1914     @DontCompile
1915     public void test74_verifier(boolean warmup) {
1916         int len = Math.abs(rI) % 10;
1917         MyValue1?[] va = new MyValue1?[len];
1918         Integer[] oa = new Integer[len];
1919         for (int i = 1; i < len; ++i) {
1920             oa[i] = new Integer(rI);
1921         }
1922         test74_helper(42, va, oa);
1923         Object[] result = test74(va, oa);
1924 
1925         for (int i = 0; i < va.length; ++i) {
1926             Asserts.assertEQ(oa[i], result[i]);
1927             // Check that array has correct storage properties (null-ok)
1928             result[i] = null;
1929         }
1930     }
1931 
1932     @ForceInline
1933     public Object[] test75_helper(int i, MyValue1?[] va, Integer[] oa) {
1934         Object[] arr = null;
1935         if (i == 10) {
1936             arr = va;
1937         } else {
1938             arr = oa;
1939         }
1940         return arr;
1941     }
1942 
1943     @Test
1944     public Object[] test75(MyValue1?[] va, Integer[] oa) {
1945         int i = 0;
1946         for (; i < 10; i++);
1947 
1948         Object[] arr = test75_helper(i, va, oa);
1949         return arr.clone();
1950     }
1951 
1952     @DontCompile
1953     public void test75_verifier(boolean warmup) {
1954         int len = Math.abs(rI) % 10;
1955         MyValue1?[] va = new MyValue1?[len];
1956         MyValue1?[] verif = new MyValue1?[len];
1957         for (int i = 1; i < len; ++i) {
1958             va[i] = testValue1;
1959             verif[i] = va[i];
1960         }
1961         Integer[] oa = new Integer[len];
1962         test75_helper(42, va, oa);
1963         Object[] result = test75(va, oa);
1964         verify(verif, result);
1965         if (len > 0) {
1966             // Check that array has correct storage properties (null-ok)
1967             result[0] = null;
1968         }
1969     }
1970 
1971     // Test mixing nullable and non-nullable arrays
1972     @Test
1973     public Object[] test76(MyValue1[] vva, MyValue1?[] vba, MyValue1 vt, Object[] out, int n) {
1974         Object[] result = null;
1975         if (n == 0) {
1976             result = vva;
1977         } else if (n == 1) {
1978             result = vba;
1979         } else if (n == 2) {
1980             result = new MyValue1[42];
1981         } else if (n == 3) {
1982             result = new MyValue1?[42];
1983         }
1984         result[0] = vt;
1985         out[0] = result[1];
1986         return result;
1987     }
1988 
1989     @DontCompile
1990     public void test76_verifier(boolean warmup) {
1991         MyValue1 vt = testValue1;
1992         Object[] out = new Object[1];
1993         MyValue1[] vva = new MyValue1[42];
1994         MyValue1[] vva_r = new MyValue1[42];
1995         vva_r[0] = vt;
1996         MyValue1?[] vba = new MyValue1?[42];
1997         MyValue1?[] vba_r = new MyValue1?[42];
1998         vba_r[0] = vt;
1999         Object[] result = test76(vva, vba, vt, out, 0);
2000         verify(result, vva_r);
2001         Asserts.assertEQ(out[0], vva_r[1]);
2002         result = test76(vva, vba, vt, out, 1);
2003         verify(result, vba_r);
2004         Asserts.assertEQ(out[0], vba_r[1]);
2005         result = test76(vva, vba, vt, out, 2);
2006         verify(result, vva_r);
2007         Asserts.assertEQ(out[0], vva_r[1]);
2008         result = test76(vva, vba, vt, out, 3);
2009         verify(result, vba_r);
2010         Asserts.assertEQ(out[0], vba_r[1]);
2011     }
2012 
2013     @Test
2014     public Object[] test77(boolean b) {
2015         Object[] va;
2016         if (b) {
2017             va = new MyValue1?[5];
2018             for (int i = 0; i < 5; ++i) {
2019                 va[i] = testValue1;
2020             }
2021         } else {
2022             va = new MyValue1[10];
2023             for (int i = 0; i < 10; ++i) {
2024                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
2025             }
2026         }
2027         long sum = ((MyValue1)va[0]).hashInterpreted();
2028         if (b) {
2029             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
2030         } else {
2031             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
2032         }
2033         return va;
2034     }
2035 
2036     @DontCompile
2037     public void test77_verifier(boolean warmup) {
2038         Object[] va = test77(true);
2039         Asserts.assertEQ(va.length, 5);
2040         Asserts.assertEQ(((MyValue1)va[0]).hash(), hash(rI, hash()));
2041         for (int i = 1; i < 5; ++i) {
2042             Asserts.assertEQ(((MyValue1)va[i]).hash(), hash());
2043         }
2044         va = test77(false);
2045         Asserts.assertEQ(va.length, 10);
2046         Asserts.assertEQ(((MyValue1)va[0]).hash(), hash(rI + 1, hash(rI, rL) + 1));
2047         for (int i = 1; i < 10; ++i) {
2048             Asserts.assertEQ(((MyValue1)va[i]).hash(), hash(rI + i, rL + i));
2049         }
2050     }
2051 
2052     // Same as test76 but with non value type array cases
2053     @Test
2054     public Object[] test78(MyValue1[] vva, MyValue1?[] vba, Object val, Object[] out, int n) {
2055         Object[] result = null;
2056         if (n == 0) {
2057             result = vva;
2058         } else if (n == 1) {
2059             result = vba;
2060         } else if (n == 2) {
2061             result = new MyValue1[42];
2062         } else if (n == 3) {
2063             result = new MyValue1?[42];
2064         } else  if (n == 4) {
2065             result = new Integer[42];
2066         }
2067         result[0] = val;
2068         out[0] = result[1];
2069         return result;
2070     }
2071 
2072     @DontCompile
2073     public void test78_verifier(boolean warmup) {
2074         MyValue1 vt = testValue1;
2075         Integer i = new Integer(42);
2076         Object[] out = new Object[1];
2077         MyValue1[] vva = new MyValue1[42];
2078         MyValue1[] vva_r = new MyValue1[42];
2079         vva_r[0] = vt;
2080         MyValue1?[] vba = new MyValue1?[42];
2081         MyValue1?[] vba_r = new MyValue1?[42];
2082         vba_r[0] = vt;
2083         Object[] result = test78(vva, vba, vt, out, 0);
2084         verify(result, vva_r);
2085         Asserts.assertEQ(out[0], vva_r[1]);
2086         result = test78(vva, vba, vt, out, 1);
2087         verify(result, vba_r);
2088         Asserts.assertEQ(out[0], vba_r[1]);
2089         result = test78(vva, vba, vt, out, 2);
2090         verify(result, vva_r);
2091         Asserts.assertEQ(out[0], vva_r[1]);
2092         result = test78(vva, vba, vt, out, 3);
2093         verify(result, vba_r);
2094         Asserts.assertEQ(out[0], vba_r[1]);
2095         result = test78(vva, vba, i, out, 4);
2096         Asserts.assertEQ(result[0], i);
2097         Asserts.assertEQ(out[0], null);
2098     }
2099 
2100     // Test widening conversions from [Q to [L
2101     @Test(failOn = ALLOC + ALLOCA + STORE)
2102     public static MyValue1?[] test79(MyValue1[] va) {
2103         return va;
2104     }
2105 
2106     @DontCompile
2107     public void test79_verifier(boolean warmup) {
2108         MyValue1[] va = new MyValue1[1];
2109         va[0] = testValue1;
2110         MyValue1?[] res = test79(va);
2111         Asserts.assertEquals(res[0].hash(), testValue1.hash());
2112         try {
2113             res[0] = null;
2114             throw new RuntimeException("NullPointerException expected");
2115         } catch (NullPointerException npe) {
2116             // Expected
2117         }
2118         res[0] = testValue1;
2119         test79(null); // Should not throw NPE
2120     }
2121 
2122     // Same as test79 but with explicit cast and Object return
2123     @Test(failOn = ALLOC + ALLOCA + STORE)
2124     public static Object[] test80(MyValue1[] va) {
2125         return (MyValue1?[])va;
2126     }
2127 
2128     @DontCompile
2129     public void test80_verifier(boolean warmup) {
2130         MyValue1[] va = new MyValue1[1];
2131         va[0] = testValue1;
2132         Object[] res = test80(va);
2133         Asserts.assertEquals(((MyValue1)res[0]).hash(), testValue1.hash());
2134         try {
2135             res[0] = null;
2136             throw new RuntimeException("NullPointerException expected");
2137         } catch (NullPointerException npe) {
2138             // Expected
2139         }
2140         res[0] = testValue1;
2141         test80(null); // Should not throw NPE
2142     }
2143 
2144     // Test mixing widened and boxed array type
2145     @Test()
2146     public static long test81(MyValue1[] va1, MyValue1?[] va2, MyValue1 vt, boolean b, boolean shouldThrow) {
2147         MyValue1?[] result = b ? va1 : va2;
2148         try {
2149             result[0] = vt;
2150         } catch (NullPointerException npe) {
2151             // Ignored
2152         }
2153         return result[1].hash();
2154     }
2155 
2156     @DontCompile
2157     public void test81_verifier(boolean warmup) {
2158         MyValue1[] va = new MyValue1[2];
2159         MyValue1?[] vaB = new MyValue1?[2];
2160         va[1] = testValue1;
2161         vaB[1] = testValue1;
2162         long res = test81(va, vaB, testValue1, true, true);
2163         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2164         Asserts.assertEquals(res, testValue1.hash());
2165         res = test81(va, vaB, testValue1, false, false);
2166         Asserts.assertEquals(vaB[0].hash(), testValue1.hash());
2167         Asserts.assertEquals(res, testValue1.hash());
2168         res = test81(va, va, testValue1, false, true);
2169         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2170         Asserts.assertEquals(res, testValue1.hash());
2171     }
2172 
2173     // Same as test81 but more cases and null writes
2174     @Test()
2175     public static long test82(MyValue1[] va1, MyValue1?[] va2, MyValue1 vt1, MyValue1? vt2, int i, boolean shouldThrow) {
2176         MyValue1?[] result = null;
2177         if (i == 0) {
2178             result = va1;
2179         } else if (i == 1) {
2180             result = va2;
2181         } else if (i == 2) {
2182             result = new MyValue1?[2];
2183             result[1] = vt1;
2184         } else if (i == 3) {
2185             result = new MyValue1[2];
2186             result[1] = vt1;
2187         }
2188         try {
2189             result[0] = (i <= 1) ? null : vt2;
2190             if (shouldThrow) {
2191                 throw new RuntimeException("NullPointerException expected");
2192             }
2193         } catch (NullPointerException npe) {
2194             Asserts.assertTrue(shouldThrow, "NullPointerException thrown");
2195         }
2196         result[0] = vt1;
2197         return result[1].hash();
2198     }
2199 
2200     @DontCompile
2201     public void test82_verifier(boolean warmup) {
2202         MyValue1[] va = new MyValue1[2];
2203         MyValue1?[] vaB = new MyValue1?[2];
2204         va[1] = testValue1;
2205         vaB[1] = testValue1;
2206         long res = test82(va, vaB, testValue1, testValue1, 0, true);
2207         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2208         Asserts.assertEquals(res, testValue1.hash());
2209         res = test82(va, vaB, testValue1, testValue1, 1, false);
2210         Asserts.assertEquals(vaB[0].hash(), testValue1.hash());
2211         Asserts.assertEquals(res, testValue1.hash());
2212         res = test82(va, va, testValue1, testValue1, 1, true);
2213         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2214         Asserts.assertEquals(res, testValue1.hash());
2215         res = test82(va, va, testValue1, null, 2, false);
2216         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2217         Asserts.assertEquals(res, testValue1.hash());
2218         res = test82(va, va, testValue1, null, 3, true);
2219         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2220         Asserts.assertEquals(res, testValue1.hash());
2221     }
2222 
2223     @Test(failOn = ALLOC + ALLOCA + STORE)
2224     public static long test83(MyValue1[] va) {
2225         MyValue1?[] result = va;
2226         return result[0].hash();
2227     }
2228 
2229     @DontCompile
2230     public void test83_verifier(boolean warmup) {
2231         MyValue1[] va = new MyValue1[42];
2232         va[0] = testValue1;
2233         long res = test83(va);
2234         Asserts.assertEquals(res, testValue1.hash());
2235     }
2236 
2237     @Test(failOn = ALLOC + ALLOCA + STORE)
2238     public static MyValue1?[] test84(MyValue1 vt1, MyValue1? vt2) {
2239         MyValue1?[] result = new MyValue1[2];
2240         result[0] = vt1;
2241         result[1] = vt2;
2242         return result;
2243     }
2244 
2245     @DontCompile
2246     public void test84_verifier(boolean warmup) {
2247         MyValue1?[] res = test84(testValue1, testValue1);
2248         Asserts.assertEquals(res[0].hash(), testValue1.hash());
2249         Asserts.assertEquals(res[1].hash(), testValue1.hash());
2250         try {
2251             test84(testValue1, null);
2252             throw new RuntimeException("NullPointerException expected");
2253         } catch (NullPointerException npe) {
2254             // Expected
2255         }
2256     }
2257 
2258     @Test()
2259     public static long test85(MyValue1?[] va, MyValue1 val) {
2260         va[0] = val;
2261         return va[1].hash();
2262     }
2263 
2264     @DontCompile
2265     public void test85_verifier(boolean warmup) {
2266         MyValue1[] va = new MyValue1[2];
2267         MyValue1?[] vab = new MyValue1?[2];
2268         va[1] = testValue1;
2269         vab[1] = testValue1;
2270         long res = test85(va, testValue1);
2271         Asserts.assertEquals(res, testValue1.hash());
2272         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2273         res = test85(vab, testValue1);
2274         Asserts.assertEquals(res, testValue1.hash());
2275         Asserts.assertEquals(vab[0].hash(), testValue1.hash());
2276     }
2277 
2278     // Same as test85 but with box value
2279     @Test()
2280     public static long test86(MyValue1?[] va, MyValue1? val) {
2281         va[0] = val;
2282         return va[1].hash();
2283     }
2284 
2285     @DontCompile
2286     public void test86_verifier(boolean warmup) {
2287         MyValue1[] va = new MyValue1[2];
2288         MyValue1?[] vab = new MyValue1?[2];
2289         va[1] = testValue1;
2290         vab[1] = testValue1;
2291         long res = test86(va, testValue1);
2292         Asserts.assertEquals(res, testValue1.hash());
2293         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2294         try {
2295             test86(va, null);
2296             throw new RuntimeException("NullPointerException expected");
2297         } catch (NullPointerException npe) {
2298             // Expected
2299         }
2300         res = test86(vab, testValue1);
2301         Asserts.assertEquals(res, testValue1.hash());
2302         Asserts.assertEquals(vab[0].hash(), testValue1.hash());
2303         res = test86(vab, null);
2304         Asserts.assertEquals(res, testValue1.hash());
2305         Asserts.assertEquals(vab[0], null);
2306     }
2307 
2308     // Test initialization of nullable array with constant
2309     @Test()
2310     public long test87() {
2311         MyValue1?[] va = new MyValue1?[1];
2312         va[0] = testValue1;
2313         return va[0].hash();
2314     }
2315 
2316     @DontCompile
2317     public void test87_verifier(boolean warmup) {
2318         long result = test87();
2319         Asserts.assertEQ(result, hash());
2320     }
2321 
2322     // Test narrowing conversion from [L to [Q
2323     @Test(failOn = ALLOC + ALLOCA + STORE)
2324     public static MyValue1[] test88(MyValue1?[] va) {
2325         return (MyValue1[])va;
2326     }
2327 
2328     @DontCompile
2329     public void test88_verifier(boolean warmup) {
2330         MyValue1[] va = new MyValue1[1];
2331         va[0] = testValue1;
2332         MyValue1[] res = test88(va);
2333         Asserts.assertEquals(res[0].hash(), testValue1.hash());
2334         res[0] = testValue1;
2335         test88(null); // Should not throw NPE
2336         try {
2337             test88(new MyValue1?[1]);
2338             throw new RuntimeException("ClassCastException expected");
2339         } catch (ClassCastException cce) {
2340             // Expected
2341         }
2342     }
2343 
2344     // Same as test88 but with explicit cast and Object argument
2345     @Test(failOn = ALLOC + ALLOCA + STORE)
2346     public static MyValue1[] test89(Object[] va) {
2347         return (MyValue1[])va;
2348     }
2349 
2350     @DontCompile
2351     public void test89_verifier(boolean warmup) {
2352         MyValue1[] va = new MyValue1[1];
2353         va[0] = testValue1;
2354         MyValue1[] res = test89(va);
2355         Asserts.assertEquals(((MyValue1)res[0]).hash(), testValue1.hash());
2356         res[0] = testValue1;
2357         test89(null); // Should not throw NPE
2358         try {
2359             test89(new MyValue1?[1]);
2360             throw new RuntimeException("ClassCastException expected");
2361         } catch (ClassCastException cce) {
2362             // Expected
2363         }
2364     }
2365 
2366     // More cast tests
2367     @Test()
2368     public static MyValue1?[] test90(Object va) {
2369         return (MyValue1?[])va;
2370     }
2371 
2372     @DontCompile
2373     public void test90_verifier(boolean warmup) {
2374         MyValue1[] va = new MyValue1[1];
2375         MyValue1?[] vab = new MyValue1?[1];
2376         try {
2377           // Trigger some ClassCastExceptions so C2 does not add an uncommon trap
2378           test90(new Integer[0]);
2379         } catch (ClassCastException cce) {
2380           // Expected
2381         }
2382         test90(va);
2383         test90(vab);
2384         test90(null);
2385     }
2386 
2387     @Test()
2388     public static MyValue1?[] test91(Object[] va) {
2389         return (MyValue1?[])va;
2390     }
2391 
2392     @DontCompile
2393     public void test91_verifier(boolean warmup) {
2394         MyValue1[] va = new MyValue1[1];
2395         MyValue1?[] vab = new MyValue1?[1];
2396         try {
2397           // Trigger some ClassCastExceptions so C2 does not add an uncommon trap
2398           test91(new Integer[0]);
2399         } catch (ClassCastException cce) {
2400           // Expected
2401         }
2402         test91(va);
2403         test91(vab);
2404         test91(null);
2405     }
2406 }