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=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  38  *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI
  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         if (len > 0) {
 509             Asserts.assertEQ(result1[0], null);
 510         }
 511         for (int i = 1; i < len; ++i) {
 512             Asserts.assertEQ(result1[i].hash(), va1[i].hash());
 513         }
 514         // make sure we do deopt: GraphKit::new_array assumes an
 515         // array of references
 516         for (int j = 0; j < 10; j++) {
 517             MyValue1?[] result2 = test18(va2);
 518 
 519             for (int i = 0; i < len; ++i) {
 520                 Asserts.assertEQ(result2[i].hash(), va2[i].hash());
 521             }
 522         }
 523         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test18")) {
 524             MyValue1?[] result2 = test18(va2);
 525             for (int i = 0; i < len; ++i) {
 526                 Asserts.assertEQ(result2[i].hash(), va2[i].hash());
 527             }
 528         }
 529     }
 530 
 531     // clone() as series of loads/stores
 532     static MyValue1?[] test19_orig = null;
 533 
 534     @Test
 535     public MyValue1?[] test19() {
 536         MyValue1?[] va = new MyValue1?[8];
 537         for (int i = 1; i < va.length; ++i) {
 538             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 539         }
 540         test19_orig = va;
 541 
 542         return va.clone();
 543     }
 544 
 545     @DontCompile
 546     public void test19_verifier(boolean warmup) {
 547         MyValue1?[] result = test19();
 548         Asserts.assertEQ(result[0], null);
 549         for (int i = 1; i < test19_orig.length; ++i) {
 550             Asserts.assertEQ(result[i].hash(), test19_orig[i].hash());
 551         }
 552     }
 553 
 554     // arraycopy() of value type array with oop fields
 555     @Test
 556     public void test20(MyValue1?[] src, MyValue1?[] dst) {
 557         System.arraycopy(src, 0, dst, 0, src.length);
 558     }
 559 
 560     @DontCompile
 561     public void test20_verifier(boolean warmup) {
 562         int len = Math.abs(rI) % 10;
 563         MyValue1?[] src1 = new MyValue1?[len];
 564         MyValue1?[] src2 = new MyValue1?[len];
 565         MyValue1[]  src3 = new MyValue1[len];
 566         MyValue1[]  src4 = new MyValue1[len];
 567         MyValue1?[] dst1 = new MyValue1?[len];
 568         MyValue1[]  dst2 = new MyValue1[len];
 569         MyValue1?[] dst3 = new MyValue1?[len];
 570         MyValue1[]  dst4 = new MyValue1[len];
 571         if (len > 0) {
 572             src2[0] = testValue1;
 573         }
 574         for (int i = 1; i < len; ++i) {
 575             src1[i] = testValue1;
 576             src2[i] = testValue1;
 577             src3[i] = testValue1;
 578             src4[i] = testValue1;
 579         }
 580         test20(src1, dst1);
 581         test20(src2, dst2);
 582         test20(src3, dst3);
 583         test20(src4, dst4);
 584         if (len > 0) {
 585             Asserts.assertEQ(dst1[0], null);
 586             Asserts.assertEQ(dst2[0].hash(), src2[0].hash());
 587             Asserts.assertEQ(dst3[0].hash(), src3[0].hash());
 588             Asserts.assertEQ(dst4[0].hash(), src4[0].hash());
 589         }
 590         for (int i = 1; i < len; ++i) {
 591             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 592             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 593             Asserts.assertEQ(src3[i].hash(), dst3[i].hash());
 594             Asserts.assertEQ(src4[i].hash(), dst4[i].hash());
 595         }
 596     }
 597 
 598     // arraycopy() of value type array with no oop field
 599     @Test
 600     public void test21(MyValue2?[] src, MyValue2?[] dst) {
 601         System.arraycopy(src, 0, dst, 0, src.length);
 602     }
 603 
 604     @DontCompile
 605     public void test21_verifier(boolean warmup) {
 606         int len = Math.abs(rI) % 10;
 607         MyValue2?[] src1 = new MyValue2?[len];
 608         MyValue2?[] src2 = new MyValue2?[len];
 609         MyValue2[]  src3 = new MyValue2[len];
 610         MyValue2[]  src4 = new MyValue2[len];
 611         MyValue2?[] dst1 = new MyValue2?[len];
 612         MyValue2[]  dst2 = new MyValue2[len];
 613         MyValue2?[] dst3 = new MyValue2?[len];
 614         MyValue2[]  dst4 = new MyValue2[len];
 615         if (len > 0) {
 616             src2[0] = MyValue2.createWithFieldsInline(rI, true);
 617         }
 618         for (int i = 1; i < len; ++i) {
 619             src1[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 620             src2[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 621             src3[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 622             src4[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 623         }
 624         test21(src1, dst1);
 625         test21(src2, dst2);
 626         test21(src3, dst3);
 627         test21(src4, dst4);
 628         if (len > 0) {
 629             Asserts.assertEQ(dst1[0], null);
 630             Asserts.assertEQ(dst2[0].hash(), src2[0].hash());
 631             Asserts.assertEQ(dst3[0].hash(), src3[0].hash());
 632             Asserts.assertEQ(dst4[0].hash(), src4[0].hash());
 633         }
 634         for (int i = 1; i < len; ++i) {
 635             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 636             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 637             Asserts.assertEQ(src3[i].hash(), dst3[i].hash());
 638             Asserts.assertEQ(src4[i].hash(), dst4[i].hash());
 639         }
 640     }
 641 
 642     // arraycopy() of value type array with oop field and tightly
 643     // coupled allocation as dest
 644     @Test
 645     public MyValue1?[] test22(MyValue1?[] src) {
 646         MyValue1?[] dst = new MyValue1?[src.length];
 647         System.arraycopy(src, 0, dst, 0, src.length);
 648         return dst;
 649     }
 650 
 651     @DontCompile
 652     public void test22_verifier(boolean warmup) {
 653         int len = Math.abs(rI) % 10;
 654         MyValue1?[] src1 = new MyValue1?[len];
 655         MyValue1[]  src2 = new MyValue1[len];
 656         for (int i = 1; i < len; ++i) {
 657             src1[i] = testValue1;
 658             src2[i] = testValue1;
 659         }
 660         MyValue1?[] dst1 = test22(src1);
 661         MyValue1?[] dst2 = test22(src2);
 662         if (len > 0) {
 663             Asserts.assertEQ(dst1[0], null);
 664             Asserts.assertEQ(dst2[0].hash(), MyValue1.default.hash());
 665         }
 666         for (int i = 1; i < len; ++i) {
 667             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 668             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 669         }
 670     }
 671 
 672     // arraycopy() of value type array with oop fields and tightly
 673     // coupled allocation as dest
 674     @Test
 675     public MyValue1?[] test23(MyValue1?[] src) {
 676         MyValue1?[] dst = new MyValue1?[src.length + 10];
 677         System.arraycopy(src, 0, dst, 5, src.length);
 678         return dst;
 679     }
 680 
 681     @DontCompile
 682     public void test23_verifier(boolean warmup) {
 683         int len = Math.abs(rI) % 10;
 684         MyValue1?[] src1 = new MyValue1?[len];
 685         MyValue1[] src2 = new MyValue1[len];
 686         for (int i = 0; i < len; ++i) {
 687             src1[i] = testValue1;
 688             src2[i] = testValue1;
 689         }
 690         MyValue1?[] dst1 = test23(src1);
 691         MyValue1?[] dst2 = test23(src2);
 692         for (int i = 0; i < 5; ++i) {
 693             Asserts.assertEQ(dst1[i], null);
 694             Asserts.assertEQ(dst2[i], null);
 695         }
 696         for (int i = 5; i < len; ++i) {
 697             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 698             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 699         }
 700     }
 701 
 702     // arraycopy() of value type array passed as Object
 703     @Test
 704     public void test24(MyValue1?[] src, Object dst) {
 705         System.arraycopy(src, 0, dst, 0, src.length);
 706     }
 707 
 708     @DontCompile
 709     public void test24_verifier(boolean warmup) {
 710         int len = Math.abs(rI) % 10;
 711         MyValue1?[] src1 = new MyValue1?[len];
 712         MyValue1?[] src2 = new MyValue1?[len];
 713         MyValue1[]  src3 = new MyValue1[len];
 714         MyValue1[]  src4 = new MyValue1[len];
 715         MyValue1?[] dst1 = new MyValue1?[len];
 716         MyValue1[]  dst2 = new MyValue1[len];
 717         MyValue1?[] dst3 = new MyValue1?[len];
 718         MyValue1[]  dst4 = new MyValue1[len];
 719         if (len > 0) {
 720             src2[0] = testValue1;
 721         }
 722         for (int i = 1; i < len; ++i) {
 723             src1[i] = testValue1;
 724             src2[i] = testValue1;
 725             src3[i] = testValue1;
 726             src4[i] = testValue1;
 727         }
 728         test24(src1, dst1);
 729         test24(src2, dst2);
 730         test24(src3, dst3);
 731         test24(src4, dst4);
 732         if (len > 0) {
 733             Asserts.assertEQ(dst1[0], null);
 734             Asserts.assertEQ(dst2[0].hash(), src2[0].hash());
 735             Asserts.assertEQ(dst3[0].hash(), src3[0].hash());
 736             Asserts.assertEQ(dst4[0].hash(), src4[0].hash());
 737         }
 738         for (int i = 1; i < len; ++i) {
 739             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 740             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 741             Asserts.assertEQ(src3[i].hash(), dst3[i].hash());
 742             Asserts.assertEQ(src4[i].hash(), dst4[i].hash());
 743         }
 744     }
 745 
 746     // short arraycopy() with no oop field
 747     @Test
 748     public void test25(MyValue2?[] src, MyValue2?[] dst) {
 749         System.arraycopy(src, 0, dst, 0, 8);
 750     }
 751 
 752     @DontCompile
 753     public void test25_verifier(boolean warmup) {
 754         MyValue2?[] src1 = new MyValue2?[8];
 755         MyValue2?[] src2 = new MyValue2?[8];
 756         MyValue2[]  src3 = new MyValue2[8];
 757         MyValue2[]  src4 = new MyValue2[8];
 758         MyValue2?[] dst1 = new MyValue2?[8];
 759         MyValue2[]  dst2 = new MyValue2[8];
 760         MyValue2?[] dst3 = new MyValue2?[8];
 761         MyValue2[]  dst4 = new MyValue2[8];
 762         src2[0] = MyValue2.createWithFieldsInline(rI, true);
 763         for (int i = 1; i < 8; ++i) {
 764             src1[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 765             src2[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 766             src3[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 767             src4[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 768         }
 769         test25(src1, dst1);
 770         test25(src2, dst2);
 771         test25(src3, dst3);
 772         test25(src4, dst4);
 773         Asserts.assertEQ(dst1[0], null);
 774         Asserts.assertEQ(dst2[0].hash(), src2[0].hash());
 775         Asserts.assertEQ(dst3[0].hash(), src3[0].hash());
 776         Asserts.assertEQ(dst4[0].hash(), src4[0].hash());
 777         for (int i = 1; i < 8; ++i) {
 778             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 779             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 780             Asserts.assertEQ(src3[i].hash(), dst3[i].hash());
 781             Asserts.assertEQ(src4[i].hash(), dst4[i].hash());
 782         }
 783     }
 784 
 785     // short arraycopy() with oop fields
 786     @Test
 787     public void test26(MyValue1?[] src, MyValue1?[] dst) {
 788         System.arraycopy(src, 0, dst, 0, 8);
 789     }
 790 
 791     @DontCompile
 792     public void test26_verifier(boolean warmup) {
 793         MyValue1?[] src1 = new MyValue1?[8];
 794         MyValue1?[] src2 = new MyValue1?[8];
 795         MyValue1[]  src3 = new MyValue1[8];
 796         MyValue1[]  src4 = new MyValue1[8];
 797         MyValue1?[] dst1 = new MyValue1?[8];
 798         MyValue1[]  dst2 = new MyValue1[8];
 799         MyValue1?[] dst3 = new MyValue1?[8];
 800         MyValue1[]  dst4 = new MyValue1[8];
 801         src2[0] = testValue1;
 802         for (int i = 1; i < 8 ; ++i) {
 803             src1[i] = testValue1;
 804             src2[i] = testValue1;
 805             src3[i] = testValue1;
 806             src4[i] = testValue1;
 807         }
 808         test26(src1, dst1);
 809         test26(src2, dst2);
 810         test26(src3, dst3);
 811         test26(src4, dst4);
 812         Asserts.assertEQ(dst1[0], null);
 813         Asserts.assertEQ(dst2[0].hash(), src2[0].hash());
 814         Asserts.assertEQ(dst3[0].hash(), src3[0].hash());
 815         Asserts.assertEQ(dst4[0].hash(), src4[0].hash());
 816         for (int i = 1; i < 8; ++i) {
 817             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 818             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 819             Asserts.assertEQ(src3[i].hash(), dst3[i].hash());
 820             Asserts.assertEQ(src4[i].hash(), dst4[i].hash());
 821         }
 822     }
 823 
 824     // short arraycopy() with oop fields and offsets
 825     @Test
 826     public void test27(MyValue1?[] src, MyValue1?[] dst) {
 827         System.arraycopy(src, 1, dst, 2, 6);
 828     }
 829 
 830     @DontCompile
 831     public void test27_verifier(boolean warmup) {
 832         MyValue1?[] src1 = new MyValue1?[8];
 833         MyValue1?[] src2 = new MyValue1?[8];
 834         MyValue1[]  src3 = new MyValue1[8];
 835         MyValue1[]  src4 = new MyValue1[8];
 836         MyValue1?[] dst1 = new MyValue1?[8];
 837         MyValue1[]  dst2 = new MyValue1[8];
 838         MyValue1?[] dst3 = new MyValue1?[8];
 839         MyValue1[]  dst4 = new MyValue1[8];
 840         for (int i = 1; i < 8; ++i) {
 841             src1[i] = testValue1;
 842             src2[i] = testValue1;
 843             src3[i] = testValue1;
 844             src4[i] = testValue1;
 845         }
 846         test27(src1, dst1);
 847         test27(src2, dst2);
 848         test27(src3, dst3);
 849         test27(src4, dst4);
 850         for (int i = 0; i < 2; ++i) {
 851             Asserts.assertEQ(dst1[i], null);
 852             Asserts.assertEQ(dst2[i].hash(), MyValue1.default.hash());
 853             Asserts.assertEQ(dst3[i], null);
 854             Asserts.assertEQ(dst4[i].hash(), MyValue1.default.hash());
 855         }
 856         for (int i = 2; i < 8; ++i) {
 857             Asserts.assertEQ(src1[i].hash(), dst1[i].hash());
 858             Asserts.assertEQ(src2[i].hash(), dst2[i].hash());
 859             Asserts.assertEQ(src3[i].hash(), dst3[i].hash());
 860             Asserts.assertEQ(src4[i].hash(), dst4[i].hash());
 861         }
 862     }
 863 
 864     // non escaping allocations
 865 // TODO fix
 866 //    @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
 867     public MyValue2? test28() {
 868         MyValue2?[] src = new MyValue2?[10];
 869         src[0] = null;
 870         MyValue2?[] dst = (MyValue2?[])src.clone();
 871         return dst[0];
 872     }
 873 
 874     @DontCompile
 875     public void test28_verifier(boolean warmup) {
 876         MyValue2 v = MyValue2.createWithFieldsInline(rI, false);
 877         MyValue2? result = test28();
 878         Asserts.assertEQ(result, null);
 879     }
 880 
 881     // non escaping allocations
 882     @Test(failOn = ALLOCA + LOOP + TRAP)
 883     public MyValue2? test29(MyValue2?[] src) {
 884         MyValue2?[] dst = new MyValue2?[10];
 885         System.arraycopy(src, 0, dst, 0, 10);
 886         return dst[0];
 887     }
 888 
 889     @DontCompile
 890     public void test29_verifier(boolean warmup) {
 891         MyValue2?[] src = new MyValue2?[10];
 892         for (int i = 0; i < 10; ++i) {
 893             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 894         }
 895         MyValue2? v = test29(src);
 896         Asserts.assertEQ(src[0].hash(), v.hash());
 897     }
 898 
 899     // non escaping allocation with uncommon trap that needs
 900     // eliminated value type array element as debug info
 901     @Test
 902     @Warmup(10000)
 903     public MyValue2? test30(MyValue2?[] src, boolean flag) {
 904         MyValue2?[] dst = new MyValue2?[10];
 905         System.arraycopy(src, 0, dst, 0, 10);
 906         if (flag) { }
 907         return dst[0];
 908     }
 909 
 910     @DontCompile
 911     public void test30_verifier(boolean warmup) {
 912         MyValue2?[] src = new MyValue2?[10];
 913         for (int i = 0; i < 10; ++i) {
 914             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 915         }
 916         MyValue2? v = test30(src, false);
 917         Asserts.assertEQ(src[0].hash(), v.hash());
 918     }
 919 
 920     // non escaping allocation with memory phi
 921     @Test()
 922 // TODO fix
 923 //    @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + TRAP)
 924     public long test31(boolean b, boolean deopt) {
 925         MyValue2?[] src = new MyValue2?[1];
 926         if (b) {
 927             src[0] = MyValue2.createWithFieldsInline(rI, true);
 928         } else {
 929             src[0] = MyValue2.createWithFieldsInline(rI, false);
 930         }
 931         if (deopt) {
 932             // uncommon trap
 933             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31"));
 934         }
 935         return src[0].hash();
 936     }
 937 
 938     @DontCompile
 939     public void test31_verifier(boolean warmup) {
 940         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true);
 941         long result1 = test31(true, !warmup);
 942         Asserts.assertEQ(result1, v1.hash());
 943         MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false);
 944         long result2 = test31(false, !warmup);
 945         Asserts.assertEQ(result2, v2.hash());
 946     }
 947 
 948     // Tests with Object arrays and clone/arraycopy
 949     // clone() as stub call
 950     @Test
 951     public Object[] test32(Object[] va) {
 952         return va.clone();
 953     }
 954 
 955     @DontCompile
 956     public void test32_verifier(boolean warmup) {
 957         int len = Math.abs(rI) % 10;
 958         MyValue1?[] va1 = new MyValue1?[len];
 959         MyValue1[] va2 = new MyValue1[len];
 960         for (int i = 1; i < len; ++i) {
 961             va1[i] = testValue1;
 962             va2[i] = testValue1;
 963         }
 964         MyValue1?[] result1 = (MyValue1?[])test32(va1);
 965         MyValue1?[] result2 = (MyValue1?[])test32(va2);
 966         if (len > 0) {
 967             Asserts.assertEQ(result1[0], null);
 968             Asserts.assertEQ(result2[0].hash(), MyValue1.default.hash());
 969         }
 970         for (int i = 1; i < len; ++i) {
 971             Asserts.assertEQ(((MyValue1)result1[i]).hash(), ((MyValue1)va1[i]).hash());
 972             Asserts.assertEQ(((MyValue1)result2[i]).hash(), ((MyValue1)va2[i]).hash());
 973         }
 974     }
 975 
 976     @Test
 977     public Object[] test33(Object[] va) {
 978         return va.clone();
 979     }
 980 
 981     @DontCompile
 982     public void test33_verifier(boolean warmup) {
 983         int len = Math.abs(rI) % 10;
 984         Object[] va = new Object[len];
 985         for (int i = 0; i < len; ++i) {
 986             va[i] = testValue1;
 987         }
 988         Object[] result = test33(va);
 989         for (int i = 0; i < len; ++i) {
 990             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 991         }
 992     }
 993 
 994     // clone() as series of loads/stores
 995     static Object[] test34_orig = null;
 996 
 997     @ForceInline
 998     public Object[] test34_helper(boolean flag) {
 999         Object[] va = null;
1000         if (flag) {
1001             va = new MyValue1?[8];
1002             for (int i = 0; i < va.length; ++i) {
1003                 va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
1004             }
1005         } else {
1006             va = new Object[8];
1007         }
1008         return va;
1009     }
1010 
1011     @Test
1012     public Object[] test34(boolean flag) {
1013         Object[] va = test34_helper(flag);
1014         test34_orig = va;
1015         return va.clone();
1016     }
1017 
1018     @DontCompile
1019     public void test34_verifier(boolean warmup) {
1020         test34(false);
1021         for (int i = 0; i < 10; i++) { // make sure we do deopt
1022             Object[] result = test34(true);
1023             verify(test34_orig, result);
1024         }
1025         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test34")) {
1026             Object[] result = test34(true);
1027             verify(test34_orig, result);
1028         }
1029     }
1030 
1031     static void verify(Object[] src, Object[] dst) {
1032         for (int i = 0; i < src.length; ++i) {
1033             if (src[i] != null) {
1034                 Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash());
1035             } else {
1036                 Asserts.assertEQ(dst[i], null);
1037             }
1038         }
1039     }
1040 
1041     static void verify(MyValue1?[] src, MyValue1?[] dst) {
1042         for (int i = 0; i < src.length; ++i) {
1043             if (src[i] != null) {
1044                 Asserts.assertEQ(src[i].hash(), dst[i].hash());
1045             } else {
1046                 Asserts.assertEQ(dst[i], null);
1047             }
1048         }
1049     }
1050 
1051     static void verify(MyValue1?[] src, Object[] dst) {
1052         for (int i = 0; i < src.length; ++i) {
1053             if (src[i] != null) {
1054                 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
1055             } else {
1056                 Asserts.assertEQ(dst[i], null);
1057             }
1058         }
1059     }
1060 
1061     static void verify(MyValue2?[] src, MyValue2?[] dst) {
1062         for (int i = 0; i < src.length; ++i) {
1063             if (src[i] != null) {
1064                 Asserts.assertEQ(src[i].hash(), dst[i].hash());
1065             } else {
1066                 Asserts.assertEQ(dst[i], null);
1067             }
1068         }
1069     }
1070 
1071     static void verify(MyValue2?[] src, Object[] dst) {
1072         for (int i = 0; i < src.length; ++i) {
1073             if (src[i] != null) {
1074                 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
1075             } else {
1076                 Asserts.assertEQ(dst[i], null);
1077             }
1078         }
1079     }
1080 
1081     static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) {
1082         if (!warmup) {
1083             Method m = tests.get(test);
1084             if (USE_COMPILER &&  !WHITE_BOX.isMethodCompiled(m, false)) {
1085                 if (!ValueTypeArrayFlatten && !XCOMP) {
1086                     throw new RuntimeException("Unexpected deoptimization");
1087                 }
1088                 WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1089                 return true;
1090             }
1091         }
1092         return false;
1093     }
1094 
1095     // arraycopy() of value type array of unknown size
1096     @Test
1097     public void test35(Object src, Object dst, int len) {
1098         System.arraycopy(src, 0, dst, 0, len);
1099     }
1100 
1101     @DontCompile
1102     public void test35_verifier(boolean warmup) {
1103         int len = Math.abs(rI) % 10;
1104         MyValue1?[] src = new MyValue1?[len];
1105         MyValue1?[] dst = new MyValue1?[len];
1106         for (int i = 1; i < len; ++i) {
1107             src[i] = testValue1;
1108         }
1109         test35(src, dst, src.length);
1110         verify(src, dst);
1111         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test35")) {
1112             test35(src, dst, src.length);
1113             verify(src, dst);
1114         }
1115     }
1116 
1117     @Test
1118     public void test36(Object src, MyValue2?[] dst) {
1119         System.arraycopy(src, 0, dst, 0, dst.length);
1120     }
1121 
1122     @DontCompile
1123     public void test36_verifier(boolean warmup) {
1124         int len = Math.abs(rI) % 10;
1125         MyValue2?[] src = new MyValue2?[len];
1126         MyValue2?[] dst = new MyValue2?[len];
1127         for (int i = 1; i < len; ++i) {
1128             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1129         }
1130         test36(src, dst);
1131         verify(src, dst);
1132         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test36")) {
1133             test36(src, dst);
1134             verify(src, dst);
1135         }
1136     }
1137 
1138     @Test
1139     public void test37(MyValue2?[] src, Object dst) {
1140         System.arraycopy(src, 0, dst, 0, src.length);
1141     }
1142 
1143     @DontCompile
1144     public void test37_verifier(boolean warmup) {
1145         int len = Math.abs(rI) % 10;
1146         MyValue2?[] src = new MyValue2?[len];
1147         MyValue2?[] dst = new MyValue2?[len];
1148         for (int i = 1; i < len; ++i) {
1149             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1150         }
1151         test37(src, dst);
1152         verify(src, dst);
1153         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test37")) {
1154             test37(src, dst);
1155             verify(src, dst);
1156         }
1157     }
1158 
1159     @Test
1160     @Warmup(1) // Avoid early compilation
1161     public void test38(Object src, MyValue2?[] dst) {
1162         System.arraycopy(src, 0, dst, 0, dst.length);
1163     }
1164 
1165     @DontCompile
1166     public void test38_verifier(boolean warmup) {
1167         int len = Math.abs(rI) % 10;
1168         Object[] src = new Object[len];
1169         MyValue2?[] dst = new MyValue2?[len];
1170         for (int i = 1; i < len; ++i) {
1171             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1172         }
1173         test38(src, dst);
1174         verify(dst, src);
1175         if (!warmup) {
1176             Method m = tests.get("TestNullableArrays::test38");
1177             assertDeoptimizedByC2(m);
1178             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1179             test38(src, dst);
1180             verify(dst, src);
1181             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1182                 throw new RuntimeException("unexpected deoptimization");
1183             }
1184         }
1185     }
1186 
1187     @Test
1188     public void test39(MyValue2?[] src, Object dst) {
1189         System.arraycopy(src, 0, dst, 0, src.length);
1190     }
1191 
1192     @DontCompile
1193     public void test39_verifier(boolean warmup) {
1194         int len = Math.abs(rI) % 10;
1195         MyValue2?[] src = new MyValue2?[len];
1196         Object[] dst = new Object[len];
1197         for (int i = 1; i < len; ++i) {
1198             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1199         }
1200         test39(src, dst);
1201         verify(src, dst);
1202         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test39")) {
1203             test39(src, dst);
1204             verify(src, dst);
1205         }
1206     }
1207 
1208     @Test
1209     @Warmup(1) // Avoid early compilation
1210     public void test40(Object[] src, Object dst) {
1211         System.arraycopy(src, 0, dst, 0, src.length);
1212     }
1213 
1214     @DontCompile
1215     public void test40_verifier(boolean warmup) {
1216         int len = Math.abs(rI) % 10;
1217         Object[] src = new Object[len];
1218         MyValue2?[] dst = new MyValue2?[len];
1219         for (int i = 1; i < len; ++i) {
1220             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1221         }
1222         test40(src, dst);
1223         verify(dst, src);
1224         if (!warmup) {
1225             Method m = tests.get("TestNullableArrays::test40");
1226             assertDeoptimizedByC2(m);
1227             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1228             test40(src, dst);
1229             verify(dst, src);
1230             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1231                 throw new RuntimeException("unexpected deoptimization");
1232             }
1233         }
1234     }
1235 
1236     @Test
1237     public void test41(Object src, Object[] dst) {
1238         System.arraycopy(src, 0, dst, 0, dst.length);
1239     }
1240 
1241     @DontCompile
1242     public void test41_verifier(boolean warmup) {
1243         int len = Math.abs(rI) % 10;
1244         MyValue2?[] src = new MyValue2?[len];
1245         Object[] dst = new Object[len];
1246         for (int i = 1; i < len; ++i) {
1247             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1248         }
1249         test41(src, dst);
1250         verify(src, dst);
1251         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test41")) {
1252             test41(src, dst);
1253             verify(src, dst);
1254         }
1255     }
1256 
1257     @Test
1258     public void test42(Object[] src, Object[] dst) {
1259         System.arraycopy(src, 0, dst, 0, src.length);
1260     }
1261 
1262     @DontCompile
1263     public void test42_verifier(boolean warmup) {
1264         int len = Math.abs(rI) % 10;
1265         Object[] src = new Object[len];
1266         Object[] dst = new Object[len];
1267         for (int i = 1; i < len; ++i) {
1268             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1269         }
1270         test42(src, dst);
1271         verify(src, dst);
1272         if (!warmup) {
1273             Method m = tests.get("TestNullableArrays::test42");
1274             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1275                 throw new RuntimeException("unexpected deoptimization");
1276             }
1277         }
1278     }
1279 
1280     // short arraycopy()'s
1281     @Test
1282     public void test43(Object src, Object dst) {
1283         System.arraycopy(src, 0, dst, 0, 8);
1284     }
1285 
1286     @DontCompile
1287     public void test43_verifier(boolean warmup) {
1288         MyValue1?[] src = new MyValue1?[8];
1289         MyValue1?[] dst = new MyValue1?[8];
1290         for (int i = 1; i < 8; ++i) {
1291             src[i] = testValue1;
1292         }
1293         test43(src, dst);
1294         verify(src, dst);
1295         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test43")) {
1296             test43(src, dst);
1297             verify(src, dst);
1298         }
1299     }
1300 
1301     @Test
1302     public void test44(Object src, MyValue2?[] dst) {
1303         System.arraycopy(src, 0, dst, 0, 8);
1304     }
1305 
1306     @DontCompile
1307     public void test44_verifier(boolean warmup) {
1308         MyValue2?[] src = new MyValue2?[8];
1309         MyValue2?[] dst = new MyValue2?[8];
1310         for (int i = 1; i < 8; ++i) {
1311             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1312         }
1313         test44(src, dst);
1314         verify(src, dst);
1315         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test44")) {
1316             test44(src, dst);
1317             verify(src, dst);
1318         }
1319     }
1320 
1321     @Test
1322     public void test45(MyValue2?[] src, Object dst) {
1323         System.arraycopy(src, 0, dst, 0, 8);
1324     }
1325 
1326     @DontCompile
1327     public void test45_verifier(boolean warmup) {
1328         MyValue2?[] src = new MyValue2?[8];
1329         MyValue2?[] dst = new MyValue2?[8];
1330         for (int i = 1; i < 8; ++i) {
1331             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1332         }
1333         test45(src, dst);
1334         verify(src, dst);
1335         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test45")) {
1336             test45(src, dst);
1337             verify(src, dst);
1338         }
1339     }
1340 
1341     @Test
1342     @Warmup(1) // Avoid early compilation
1343     public void test46(Object[] src, MyValue2?[] dst) {
1344         System.arraycopy(src, 0, dst, 0, 8);
1345     }
1346 
1347     @DontCompile
1348     public void test46_verifier(boolean warmup) {
1349         Object[] src = new Object[8];
1350         MyValue2?[] dst = new MyValue2?[8];
1351         for (int i = 1; i < 8; ++i) {
1352             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1353         }
1354         test46(src, dst);
1355         verify(dst, src);
1356         if (!warmup) {
1357             Method m = tests.get("TestNullableArrays::test46");
1358             assertDeoptimizedByC2(m);
1359             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1360             test46(src, dst);
1361             verify(dst, src);
1362             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1363                 throw new RuntimeException("unexpected deoptimization");
1364             }
1365         }
1366     }
1367 
1368     @Test
1369     public void test47(MyValue2?[] src, Object[] dst) {
1370         System.arraycopy(src, 0, dst, 0, 8);
1371     }
1372 
1373     @DontCompile
1374     public void test47_verifier(boolean warmup) {
1375         MyValue2?[] src = new MyValue2?[8];
1376         Object[] dst = new Object[8];
1377         for (int i = 1; i < 8; ++i) {
1378             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1379         }
1380         test47(src, dst);
1381         verify(src, dst);
1382         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test47")) {
1383             test47(src, dst);
1384             verify(src, dst);
1385         }
1386     }
1387 
1388     @Test
1389     @Warmup(1) // Avoid early compilation
1390     public void test48(Object[] src, Object dst) {
1391         System.arraycopy(src, 0, dst, 0, 8);
1392     }
1393 
1394     @DontCompile
1395     public void test48_verifier(boolean warmup) {
1396         Object[] src = new Object[8];
1397         MyValue2?[] dst = new MyValue2?[8];
1398         for (int i = 1; i < 8; ++i) {
1399             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1400         }
1401         test48(src, dst);
1402         verify(dst, src);
1403         if (!warmup) {
1404             Method m = tests.get("TestNullableArrays::test48");
1405             assertDeoptimizedByC2(m);
1406             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1407             test48(src, dst);
1408             verify(dst, src);
1409             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1410                 throw new RuntimeException("unexpected deoptimization");
1411             }
1412         }
1413     }
1414 
1415     @Test
1416     public void test49(Object src, Object[] dst) {
1417         System.arraycopy(src, 0, dst, 0, 8);
1418     }
1419 
1420     @DontCompile
1421     public void test49_verifier(boolean warmup) {
1422         MyValue2?[] src = new MyValue2?[8];
1423         Object[] dst = new Object[8];
1424         for (int i = 1; i < 8; ++i) {
1425             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1426         }
1427         test49(src, dst);
1428         verify(src, dst);
1429         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test49")) {
1430             test49(src, dst);
1431             verify(src, dst);
1432         }
1433     }
1434 
1435     @Test
1436     public void test50(Object[] src, Object[] dst) {
1437         System.arraycopy(src, 0, dst, 0, 8);
1438     }
1439 
1440     @DontCompile
1441     public void test50_verifier(boolean warmup) {
1442         Object[] src = new Object[8];
1443         Object[] dst = new Object[8];
1444         for (int i = 1; i < 8; ++i) {
1445             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1446         }
1447         test50(src, dst);
1448         verify(src, dst);
1449         if (!warmup) {
1450             Method m = tests.get("TestNullableArrays::test50");
1451             if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1452                 throw new RuntimeException("unexpected deoptimization");
1453             }
1454         }
1455     }
1456 
1457     @Test
1458     public MyValue1?[] test51(MyValue1?[] va) {
1459         return Arrays.copyOf(va, va.length, MyValue1?[].class);
1460     }
1461 
1462     @DontCompile
1463     public void test51_verifier(boolean warmup) {
1464         int len = Math.abs(rI) % 10;
1465         MyValue1?[] va = new MyValue1?[len];
1466         for (int i = 1; i < len; ++i) {
1467             va[i] = testValue1;
1468         }
1469         MyValue1?[] result = test51(va);
1470         verify(va, result);
1471     }
1472 
1473     static final MyValue1?[] test52_va = new MyValue1?[8];
1474 
1475     @Test
1476     public MyValue1?[] test52() {
1477         return Arrays.copyOf(test52_va, 8, MyValue1?[].class);
1478     }
1479 
1480     @DontCompile
1481     public void test52_verifier(boolean warmup) {
1482         for (int i = 1; i < 8; ++i) {
1483             test52_va[i] = testValue1;
1484         }
1485         MyValue1?[] result = test52();
1486         verify(test52_va, result);
1487     }
1488 
1489     @Test
1490     public MyValue1?[] test53(Object[] va) {
1491         return Arrays.copyOf(va, va.length, MyValue1?[].class);
1492     }
1493 
1494     @DontCompile
1495     public void test53_verifier(boolean warmup) {
1496         int len = Math.abs(rI) % 10;
1497         MyValue1?[] va = new MyValue1?[len];
1498         for (int i = 1; i < len; ++i) {
1499             va[i] = testValue1;
1500         }
1501         MyValue1?[] result = test53(va);
1502         verify(result, va);
1503     }
1504 
1505     @Test
1506     public Object[] test54(MyValue1?[] va) {
1507         return Arrays.copyOf(va, va.length, Object[].class);
1508     }
1509 
1510     @DontCompile
1511     public void test54_verifier(boolean warmup) {
1512         int len = Math.abs(rI) % 10;
1513         MyValue1?[] va = new MyValue1?[len];
1514         for (int i = 1; i < len; ++i) {
1515             va[i] = testValue1;
1516         }
1517         Object[] result = test54(va);
1518         verify(va, result);
1519     }
1520 
1521     @Test
1522     public Object[] test55(Object[] va) {
1523         return Arrays.copyOf(va, va.length, Object[].class);
1524     }
1525 
1526     @DontCompile
1527     public void test55_verifier(boolean warmup) {
1528         int len = Math.abs(rI) % 10;
1529         MyValue1?[] va = new MyValue1?[len];
1530         for (int i = 1; i < len; ++i) {
1531             va[i] = testValue1;
1532         }
1533         Object[] result = test55(va);
1534         verify(va, result);
1535     }
1536 
1537     @Test
1538     public MyValue1?[] test56(Object[] va) {
1539         return Arrays.copyOf(va, va.length, MyValue1?[].class);
1540     }
1541 
1542     @DontCompile
1543     public void test56_verifier(boolean warmup) {
1544         int len = Math.abs(rI) % 10;
1545         Object[] va = new Object[len];
1546         for (int i = 1; i < len; ++i) {
1547             va[i] = testValue1;
1548         }
1549         MyValue1?[] result = test56(va);
1550         verify(result, va);
1551     }
1552 
1553    @Test
1554     public Object[] test57(Object[] va, Class klass) {
1555         return Arrays.copyOf(va, va.length, klass);
1556     }
1557 
1558     @DontCompile
1559     public void test57_verifier(boolean warmup) {
1560         int len = Math.abs(rI) % 10;
1561         Object[] va = new MyValue1?[len];
1562         for (int i = 1; i < len; ++i) {
1563             va[i] = testValue1;
1564         }
1565         Object[] result = test57(va, MyValue1?[].class);
1566         verify(va, result);
1567     }
1568 
1569     @Test
1570     public Object[] test58(MyValue1?[] va, Class klass) {
1571         return Arrays.copyOf(va, va.length, klass);
1572     }
1573 
1574     @DontCompile
1575     public void test58_verifier(boolean warmup) {
1576         int len = Math.abs(rI) % 10;
1577         MyValue1?[] va = new MyValue1?[len];
1578         for (int i = 1; i < len; ++i) {
1579             va[i] = testValue1;
1580         }
1581         for (int i = 1; i < 10; i++) {
1582             Object[] result = test58(va, MyValue1?[].class);
1583             verify(va, result);
1584         }
1585         if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test58")) {
1586             Object[] result = test58(va, MyValue1?[].class);
1587             verify(va, result);
1588         }
1589     }
1590 
1591     @Test
1592     public Object[] test59(MyValue1?[] va) {
1593         return Arrays.copyOf(va, va.length+1, MyValue1?[].class);
1594     }
1595 
1596     @DontCompile
1597     public void test59_verifier(boolean warmup) {
1598         int len = Math.abs(rI) % 10;
1599         MyValue1?[] va = new MyValue1?[len];
1600         MyValue1?[] verif = new MyValue1?[len+1];
1601         for (int i = 1; i < len; ++i) {
1602             va[i] = testValue1;
1603             verif[i] = va[i];
1604         }
1605         Object[] result = test59(va);
1606         verify(verif, result);
1607     }
1608 
1609     @Test
1610     public Object[] test60(Object[] va, Class klass) {
1611         return Arrays.copyOf(va, va.length+1, klass);
1612     }
1613 
1614     @DontCompile
1615     public void test60_verifier(boolean warmup) {
1616         int len = Math.abs(rI) % 10;
1617         MyValue1?[] va = new MyValue1?[len];
1618         MyValue1?[] verif = new MyValue1?[len+1];
1619         for (int i = 1; i < len; ++i) {
1620             va[i] = testValue1;
1621             verif[i] = (MyValue1)va[i];
1622         }
1623         Object[] result = test60(va, MyValue1?[].class);
1624         verify(verif, result);
1625     }
1626 
1627     @Test
1628     public Object[] test61(Object[] va, Class klass) {
1629         return Arrays.copyOf(va, va.length+1, klass);
1630     }
1631 
1632     @DontCompile
1633     public void test61_verifier(boolean warmup) {
1634         int len = Math.abs(rI) % 10;
1635         Object[] va = new Integer[len];
1636         for (int i = 1; i < len; ++i) {
1637             va[i] = new Integer(rI);
1638         }
1639         Object[] result = test61(va, Integer[].class);
1640         for (int i = 0; i < va.length; ++i) {
1641             Asserts.assertEQ(va[i], result[i]);
1642         }
1643     }
1644 
1645     @ForceInline
1646     public Object[] test62_helper(int i, MyValue1?[] va, Integer[] oa) {
1647         Object[] arr = null;
1648         if (i == 10) {
1649             arr = oa;
1650         } else {
1651             arr = va;
1652         }
1653         return arr;
1654     }
1655 
1656     @Test
1657     public Object[] test62(MyValue1?[] va, Integer[] oa) {
1658         int i = 0;
1659         for (; i < 10; i++);
1660 
1661         Object[] arr = test62_helper(i, va, oa);
1662 
1663         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1664     }
1665 
1666     @DontCompile
1667     public void test62_verifier(boolean warmup) {
1668         int len = Math.abs(rI) % 10;
1669         MyValue1?[] va = new MyValue1?[len];
1670         Integer[] oa = new Integer[len];
1671         for (int i = 1; i < len; ++i) {
1672             oa[i] = new Integer(rI);
1673         }
1674         test62_helper(42, va, oa);
1675         Object[] result = test62(va, oa);
1676         for (int i = 0; i < va.length; ++i) {
1677             Asserts.assertEQ(oa[i], result[i]);
1678         }
1679     }
1680 
1681     @ForceInline
1682     public Object[] test63_helper(int i, MyValue1?[] va, Integer[] oa) {
1683         Object[] arr = null;
1684         if (i == 10) {
1685             arr = va;
1686         } else {
1687             arr = oa;
1688         }
1689         return arr;
1690     }
1691 
1692     @Test
1693     public Object[] test63(MyValue1?[] va, Integer[] oa) {
1694         int i = 0;
1695         for (; i < 10; i++);
1696 
1697         Object[] arr = test63_helper(i, va, oa);
1698 
1699         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1700     }
1701 
1702     @DontCompile
1703     public void test63_verifier(boolean warmup) {
1704         int len = Math.abs(rI) % 10;
1705         MyValue1?[] va = new MyValue1?[len];
1706         MyValue1?[] verif = new MyValue1?[len+1];
1707         for (int i = 1; i < len; ++i) {
1708             va[i] = testValue1;
1709             verif[i] = va[i];
1710         }
1711         Integer[] oa = new Integer[len];
1712         test63_helper(42, va, oa);
1713         Object[] result = test63(va, oa);
1714         verify(verif, result);
1715     }
1716 
1717     // Test default initialization of value type arrays: small array
1718     @Test
1719     public MyValue1?[] test64() {
1720         return new MyValue1?[8];
1721     }
1722 
1723     @DontCompile
1724     public void test64_verifier(boolean warmup) {
1725         MyValue1?[] va = test64();
1726         for (int i = 0; i < 8; ++i) {
1727             Asserts.assertEQ(va[i], null);
1728         }
1729     }
1730 
1731     // Test default initialization of value type arrays: large array
1732     @Test
1733     public MyValue1?[] test65() {
1734         return new MyValue1?[32];
1735     }
1736 
1737     @DontCompile
1738     public void test65_verifier(boolean warmup) {
1739         MyValue1?[] va = test65();
1740         for (int i = 0; i < 32; ++i) {
1741             Asserts.assertEQ(va[i], null);
1742         }
1743     }
1744 
1745     // Check init store elimination
1746     @Test
1747     public MyValue1?[] test66(MyValue1? vt) {
1748         MyValue1?[] va = new MyValue1?[1];
1749         va[0] = vt;
1750         return va;
1751     }
1752 
1753     @DontCompile
1754     public void test66_verifier(boolean warmup) {
1755         MyValue1? vt = MyValue1.createWithFieldsDontInline(rI, rL);
1756         MyValue1?[] va = test66(vt);
1757         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1758     }
1759 
1760     // Zeroing elimination and arraycopy
1761     @Test
1762     public MyValue1?[] test67(MyValue1?[] src) {
1763         MyValue1?[] dst = new MyValue1?[16];
1764         System.arraycopy(src, 0, dst, 0, 13);
1765         return dst;
1766     }
1767 
1768     @DontCompile
1769     public void test67_verifier(boolean warmup) {
1770         MyValue1?[] va = new MyValue1?[16];
1771         MyValue1?[] var = test67(va);
1772         for (int i = 0; i < 16; ++i) {
1773             Asserts.assertEQ(var[i], null);
1774         }
1775     }
1776 
1777     // A store with a default value can be eliminated
1778     @Test
1779     public MyValue1?[] test68() {
1780         MyValue1?[] va = new MyValue1?[2];
1781         va[0] = va[1];
1782         return va;
1783     }
1784 
1785     @DontCompile
1786     public void test68_verifier(boolean warmup) {
1787         MyValue1?[] va = test68();
1788         for (int i = 0; i < 2; ++i) {
1789             Asserts.assertEQ(va[i], null);
1790         }
1791     }
1792 
1793     // Requires individual stores to init array
1794     @Test
1795     public MyValue1?[] test69(MyValue1? vt) {
1796         MyValue1?[] va = new MyValue1?[4];
1797         va[0] = vt;
1798         va[3] = vt;
1799         return va;
1800     }
1801 
1802     @DontCompile
1803     public void test69_verifier(boolean warmup) {
1804         MyValue1? vt = MyValue1.createWithFieldsDontInline(rI, rL);
1805         MyValue1?[] va = new MyValue1?[4];
1806         va[0] = vt;
1807         va[3] = vt;
1808         MyValue1?[] var = test69(vt);
1809         for (int i = 0; i < va.length; ++i) {
1810             Asserts.assertEQ(va[i], var[i]);
1811         }
1812     }
1813 
1814     // A store with a default value can be eliminated: same as test68
1815     // but store is farther away from allocation
1816     @Test
1817     public MyValue1?[] test70(MyValue1?[] other) {
1818         other[1] = other[0];
1819         MyValue1?[] va = new MyValue1?[2];
1820         other[0] = va[1];
1821         va[0] = va[1];
1822         return va;
1823     }
1824 
1825     @DontCompile
1826     public void test70_verifier(boolean warmup) {
1827         MyValue1?[] va = new MyValue1?[2];
1828         MyValue1?[] var = test70(va);
1829         for (int i = 0; i < 2; ++i) {
1830             Asserts.assertEQ(va[i], var[i]);
1831         }
1832     }
1833 
1834     // EA needs to consider oop fields in flattened arrays
1835     @Test
1836     public void test71() {
1837         int len = 10;
1838         MyValue2?[] src = new MyValue2?[len];
1839         MyValue2?[] dst = new MyValue2?[len];
1840         for (int i = 1; i < len; ++i) {
1841             src[i] = MyValue2.createWithFieldsDontInline(rI, (i % 2) == 0);
1842         }
1843         System.arraycopy(src, 0, dst, 0, src.length);
1844         for (int i = 0; i < len; ++i) {
1845             if (src[i] == null) {
1846                 Asserts.assertEQ(dst[i], null);
1847             } else {
1848                 Asserts.assertEQ(src[i].hash(), dst[i].hash());
1849             }
1850         }
1851     }
1852 
1853     @DontCompile
1854     public void test71_verifier(boolean warmup) {
1855         test71();
1856     }
1857 
1858     // Test EA with leaf call to 'store_unknown_value'
1859     @Test
1860     public void test72(Object[] o, boolean b, Object element) {
1861         Object[] arr1 = new Object[10];
1862         Object[] arr2 = new Object[10];
1863         if (b) {
1864             arr1 = o;
1865         }
1866         arr1[0] = element;
1867         arr2[0] = element;
1868     }
1869 
1870     @DontCompile
1871     public void test72_verifier(boolean warmup) {
1872         Object[] arr = new Object[1];
1873         Object elem = new Object();
1874         test72(arr, true, elem);
1875         test72(arr, false, elem);
1876     }
1877 
1878     @Test
1879     public void test73(Object[] oa, MyValue1? v, Object o) {
1880         // TestLWorld.test38 use a C1 Phi node for the array. This test
1881         // adds the case where the stored value is a C1 Phi node.
1882         Object o2 = (o == null) ? v : o;
1883         oa[0] = v;  // The stored value is known to be flattenable
1884         oa[1] = o;  // The stored value may be flattenable
1885         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1886         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1887     }
1888 
1889     @DontCompile
1890     public void test73_verifier(boolean warmup) {
1891         MyValue1? v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1892         MyValue1? v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1893         MyValue1?[] arr = new MyValue1?[3];
1894         try {
1895             test73(arr, v0, v1);
1896             throw new RuntimeException("ArrayStoreException expected");
1897         } catch (ArrayStoreException t) {
1898             // expected
1899         }
1900         Asserts.assertEQ(arr[0].hash(), v0.hash());
1901         Asserts.assertEQ(arr[1].hash(), v1.hash());
1902         Asserts.assertEQ(arr[2].hash(), v1.hash());
1903     }
1904 
1905     // Some more array clone tests
1906     @ForceInline
1907     public Object[] test74_helper(int i, MyValue1?[] va, Integer[] oa) {
1908         Object[] arr = null;
1909         if (i == 10) {
1910             arr = oa;
1911         } else {
1912             arr = va;
1913         }
1914         return arr;
1915     }
1916 
1917     @Test
1918     public Object[] test74(MyValue1?[] va, Integer[] oa) {
1919         int i = 0;
1920         for (; i < 10; i++);
1921 
1922         Object[] arr = test74_helper(i, va, oa);
1923         return arr.clone();
1924     }
1925 
1926     @DontCompile
1927     public void test74_verifier(boolean warmup) {
1928         int len = Math.abs(rI) % 10;
1929         MyValue1?[] va = new MyValue1?[len];
1930         Integer[] oa = new Integer[len];
1931         for (int i = 1; i < len; ++i) {
1932             oa[i] = new Integer(rI);
1933         }
1934         test74_helper(42, va, oa);
1935         Object[] result = test74(va, oa);
1936 
1937         for (int i = 0; i < va.length; ++i) {
1938             Asserts.assertEQ(oa[i], result[i]);
1939             // Check that array has correct storage properties (null-ok)
1940             result[i] = null;
1941         }
1942     }
1943 
1944     @ForceInline
1945     public Object[] test75_helper(int i, MyValue1?[] va, Integer[] oa) {
1946         Object[] arr = null;
1947         if (i == 10) {
1948             arr = va;
1949         } else {
1950             arr = oa;
1951         }
1952         return arr;
1953     }
1954 
1955     @Test
1956     public Object[] test75(MyValue1?[] va, Integer[] oa) {
1957         int i = 0;
1958         for (; i < 10; i++);
1959 
1960         Object[] arr = test75_helper(i, va, oa);
1961         return arr.clone();
1962     }
1963 
1964     @DontCompile
1965     public void test75_verifier(boolean warmup) {
1966         int len = Math.abs(rI) % 10;
1967         MyValue1?[] va = new MyValue1?[len];
1968         MyValue1?[] verif = new MyValue1?[len];
1969         for (int i = 1; i < len; ++i) {
1970             va[i] = testValue1;
1971             verif[i] = va[i];
1972         }
1973         Integer[] oa = new Integer[len];
1974         test75_helper(42, va, oa);
1975         Object[] result = test75(va, oa);
1976         verify(verif, result);
1977         if (len > 0) {
1978             // Check that array has correct storage properties (null-ok)
1979             result[0] = null;
1980         }
1981     }
1982 
1983     // Test mixing nullable and non-nullable arrays
1984     @Test
1985     public Object[] test76(MyValue1[] vva, MyValue1?[] vba, MyValue1 vt, Object[] out, int n) {
1986         Object[] result = null;
1987         if (n == 0) {
1988             result = vva;
1989         } else if (n == 1) {
1990             result = vba;
1991         } else if (n == 2) {
1992             result = new MyValue1[42];
1993         } else if (n == 3) {
1994             result = new MyValue1?[42];
1995         }
1996         result[0] = vt;
1997         out[0] = result[1];
1998         return result;
1999     }
2000 
2001     @DontCompile
2002     public void test76_verifier(boolean warmup) {
2003         MyValue1 vt = testValue1;
2004         Object[] out = new Object[1];
2005         MyValue1[] vva = new MyValue1[42];
2006         MyValue1[] vva_r = new MyValue1[42];
2007         vva_r[0] = vt;
2008         MyValue1?[] vba = new MyValue1?[42];
2009         MyValue1?[] vba_r = new MyValue1?[42];
2010         vba_r[0] = vt;
2011         Object[] result = test76(vva, vba, vt, out, 0);
2012         verify(result, vva_r);
2013         Asserts.assertEQ(out[0], vva_r[1]);
2014         result = test76(vva, vba, vt, out, 1);
2015         verify(result, vba_r);
2016         Asserts.assertEQ(out[0], vba_r[1]);
2017         result = test76(vva, vba, vt, out, 2);
2018         verify(result, vva_r);
2019         Asserts.assertEQ(out[0], vva_r[1]);
2020         result = test76(vva, vba, vt, out, 3);
2021         verify(result, vba_r);
2022         Asserts.assertEQ(out[0], vba_r[1]);
2023     }
2024 
2025     @Test
2026     public Object[] test77(boolean b) {
2027         Object[] va;
2028         if (b) {
2029             va = new MyValue1?[5];
2030             for (int i = 0; i < 5; ++i) {
2031                 va[i] = testValue1;
2032             }
2033         } else {
2034             va = new MyValue1[10];
2035             for (int i = 0; i < 10; ++i) {
2036                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
2037             }
2038         }
2039         long sum = ((MyValue1)va[0]).hashInterpreted();
2040         if (b) {
2041             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
2042         } else {
2043             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
2044         }
2045         return va;
2046     }
2047 
2048     @DontCompile
2049     public void test77_verifier(boolean warmup) {
2050         Object[] va = test77(true);
2051         Asserts.assertEQ(va.length, 5);
2052         Asserts.assertEQ(((MyValue1)va[0]).hash(), hash(rI, hash()));
2053         for (int i = 1; i < 5; ++i) {
2054             Asserts.assertEQ(((MyValue1)va[i]).hash(), hash());
2055         }
2056         va = test77(false);
2057         Asserts.assertEQ(va.length, 10);
2058         Asserts.assertEQ(((MyValue1)va[0]).hash(), hash(rI + 1, hash(rI, rL) + 1));
2059         for (int i = 1; i < 10; ++i) {
2060             Asserts.assertEQ(((MyValue1)va[i]).hash(), hash(rI + i, rL + i));
2061         }
2062     }
2063 
2064     // Same as test76 but with non value type array cases
2065     @Test
2066     public Object[] test78(MyValue1[] vva, MyValue1?[] vba, Object val, Object[] out, int n) {
2067         Object[] result = null;
2068         if (n == 0) {
2069             result = vva;
2070         } else if (n == 1) {
2071             result = vba;
2072         } else if (n == 2) {
2073             result = new MyValue1[42];
2074         } else if (n == 3) {
2075             result = new MyValue1?[42];
2076         } else  if (n == 4) {
2077             result = new Integer[42];
2078         }
2079         result[0] = val;
2080         out[0] = result[1];
2081         return result;
2082     }
2083 
2084     @DontCompile
2085     public void test78_verifier(boolean warmup) {
2086         MyValue1 vt = testValue1;
2087         Integer i = new Integer(42);
2088         Object[] out = new Object[1];
2089         MyValue1[] vva = new MyValue1[42];
2090         MyValue1[] vva_r = new MyValue1[42];
2091         vva_r[0] = vt;
2092         MyValue1?[] vba = new MyValue1?[42];
2093         MyValue1?[] vba_r = new MyValue1?[42];
2094         vba_r[0] = vt;
2095         Object[] result = test78(vva, vba, vt, out, 0);
2096         verify(result, vva_r);
2097         Asserts.assertEQ(out[0], vva_r[1]);
2098         result = test78(vva, vba, vt, out, 1);
2099         verify(result, vba_r);
2100         Asserts.assertEQ(out[0], vba_r[1]);
2101         result = test78(vva, vba, vt, out, 2);
2102         verify(result, vva_r);
2103         Asserts.assertEQ(out[0], vva_r[1]);
2104         result = test78(vva, vba, vt, out, 3);
2105         verify(result, vba_r);
2106         Asserts.assertEQ(out[0], vba_r[1]);
2107         result = test78(vva, vba, i, out, 4);
2108         Asserts.assertEQ(result[0], i);
2109         Asserts.assertEQ(out[0], null);
2110     }
2111 
2112     // Test widening conversions from [Q to [L
2113     @Test(failOn = ALLOC + ALLOCA + STORE)
2114     public static MyValue1?[] test79(MyValue1[] va) {
2115         return va;
2116     }
2117 
2118     @DontCompile
2119     public void test79_verifier(boolean warmup) {
2120         MyValue1[] va = new MyValue1[1];
2121         va[0] = testValue1;
2122         MyValue1?[] res = test79(va);
2123         Asserts.assertEquals(res[0].hash(), testValue1.hash());
2124         try {
2125             res[0] = null;
2126             throw new RuntimeException("NullPointerException expected");
2127         } catch (NullPointerException npe) {
2128             // Expected
2129         }
2130         res[0] = testValue1;
2131         test79(null); // Should not throw NPE
2132     }
2133 
2134     // Same as test79 but with explicit cast and Object return
2135     @Test(failOn = ALLOC + ALLOCA + STORE)
2136     public static Object[] test80(MyValue1[] va) {
2137         return (MyValue1?[])va;
2138     }
2139 
2140     @DontCompile
2141     public void test80_verifier(boolean warmup) {
2142         MyValue1[] va = new MyValue1[1];
2143         va[0] = testValue1;
2144         Object[] res = test80(va);
2145         Asserts.assertEquals(((MyValue1)res[0]).hash(), testValue1.hash());
2146         try {
2147             res[0] = null;
2148             throw new RuntimeException("NullPointerException expected");
2149         } catch (NullPointerException npe) {
2150             // Expected
2151         }
2152         res[0] = testValue1;
2153         test80(null); // Should not throw NPE
2154     }
2155 
2156     // Test mixing widened and boxed array type
2157     @Test()
2158     public static long test81(MyValue1[] va1, MyValue1?[] va2, MyValue1 vt, boolean b, boolean shouldThrow) {
2159         MyValue1?[] result = b ? va1 : va2;
2160         try {
2161             result[0] = vt;
2162         } catch (NullPointerException npe) {
2163             // Ignored
2164         }
2165         return result[1].hash();
2166     }
2167 
2168     @DontCompile
2169     public void test81_verifier(boolean warmup) {
2170         MyValue1[] va = new MyValue1[2];
2171         MyValue1?[] vaB = new MyValue1?[2];
2172         va[1] = testValue1;
2173         vaB[1] = testValue1;
2174         long res = test81(va, vaB, testValue1, true, true);
2175         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2176         Asserts.assertEquals(res, testValue1.hash());
2177         res = test81(va, vaB, testValue1, false, false);
2178         Asserts.assertEquals(vaB[0].hash(), testValue1.hash());
2179         Asserts.assertEquals(res, testValue1.hash());
2180         res = test81(va, va, testValue1, false, true);
2181         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2182         Asserts.assertEquals(res, testValue1.hash());
2183     }
2184 
2185     // Same as test81 but more cases and null writes
2186     @Test()
2187     public static long test82(MyValue1[] va1, MyValue1?[] va2, MyValue1 vt1, MyValue1? vt2, int i, boolean shouldThrow) {
2188         MyValue1?[] result = null;
2189         if (i == 0) {
2190             result = va1;
2191         } else if (i == 1) {
2192             result = va2;
2193         } else if (i == 2) {
2194             result = new MyValue1?[2];
2195             result[1] = vt1;
2196         } else if (i == 3) {
2197             result = new MyValue1[2];
2198             result[1] = vt1;
2199         }
2200         try {
2201             result[0] = (i <= 1) ? null : vt2;
2202             if (shouldThrow) {
2203                 throw new RuntimeException("NullPointerException expected");
2204             }
2205         } catch (NullPointerException npe) {
2206             Asserts.assertTrue(shouldThrow, "NullPointerException thrown");
2207         }
2208         result[0] = vt1;
2209         return result[1].hash();
2210     }
2211 
2212     @DontCompile
2213     public void test82_verifier(boolean warmup) {
2214         MyValue1[] va = new MyValue1[2];
2215         MyValue1?[] vaB = new MyValue1?[2];
2216         va[1] = testValue1;
2217         vaB[1] = testValue1;
2218         long res = test82(va, vaB, testValue1, testValue1, 0, true);
2219         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2220         Asserts.assertEquals(res, testValue1.hash());
2221         res = test82(va, vaB, testValue1, testValue1, 1, false);
2222         Asserts.assertEquals(vaB[0].hash(), testValue1.hash());
2223         Asserts.assertEquals(res, testValue1.hash());
2224         res = test82(va, va, testValue1, testValue1, 1, true);
2225         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2226         Asserts.assertEquals(res, testValue1.hash());
2227         res = test82(va, va, testValue1, null, 2, false);
2228         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2229         Asserts.assertEquals(res, testValue1.hash());
2230         res = test82(va, va, testValue1, null, 3, true);
2231         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2232         Asserts.assertEquals(res, testValue1.hash());
2233     }
2234 
2235     @Test(failOn = ALLOC + ALLOCA + STORE)
2236     public static long test83(MyValue1[] va) {
2237         MyValue1?[] result = va;
2238         return result[0].hash();
2239     }
2240 
2241     @DontCompile
2242     public void test83_verifier(boolean warmup) {
2243         MyValue1[] va = new MyValue1[42];
2244         va[0] = testValue1;
2245         long res = test83(va);
2246         Asserts.assertEquals(res, testValue1.hash());
2247     }
2248 
2249     @Test(failOn = ALLOC + ALLOCA + STORE)
2250     public static MyValue1?[] test84(MyValue1 vt1, MyValue1? vt2) {
2251         MyValue1?[] result = new MyValue1[2];
2252         result[0] = vt1;
2253         result[1] = vt2;
2254         return result;
2255     }
2256 
2257     @DontCompile
2258     public void test84_verifier(boolean warmup) {
2259         MyValue1?[] res = test84(testValue1, testValue1);
2260         Asserts.assertEquals(res[0].hash(), testValue1.hash());
2261         Asserts.assertEquals(res[1].hash(), testValue1.hash());
2262         try {
2263             test84(testValue1, null);
2264             throw new RuntimeException("NullPointerException expected");
2265         } catch (NullPointerException npe) {
2266             // Expected
2267         }
2268     }
2269 
2270     @Test()
2271     public static long test85(MyValue1?[] va, MyValue1 val) {
2272         va[0] = val;
2273         return va[1].hash();
2274     }
2275 
2276     @DontCompile
2277     public void test85_verifier(boolean warmup) {
2278         MyValue1[] va = new MyValue1[2];
2279         MyValue1?[] vab = new MyValue1?[2];
2280         va[1] = testValue1;
2281         vab[1] = testValue1;
2282         long res = test85(va, testValue1);
2283         Asserts.assertEquals(res, testValue1.hash());
2284         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2285         res = test85(vab, testValue1);
2286         Asserts.assertEquals(res, testValue1.hash());
2287         Asserts.assertEquals(vab[0].hash(), testValue1.hash());
2288     }
2289 
2290     // Same as test85 but with box value
2291     @Test()
2292     public static long test86(MyValue1?[] va, MyValue1? val) {
2293         va[0] = val;
2294         return va[1].hash();
2295     }
2296 
2297     @DontCompile
2298     public void test86_verifier(boolean warmup) {
2299         MyValue1[] va = new MyValue1[2];
2300         MyValue1?[] vab = new MyValue1?[2];
2301         va[1] = testValue1;
2302         vab[1] = testValue1;
2303         long res = test86(va, testValue1);
2304         Asserts.assertEquals(res, testValue1.hash());
2305         Asserts.assertEquals(va[0].hash(), testValue1.hash());
2306         try {
2307             test86(va, null);
2308             throw new RuntimeException("NullPointerException expected");
2309         } catch (NullPointerException npe) {
2310             // Expected
2311         }
2312         res = test86(vab, testValue1);
2313         Asserts.assertEquals(res, testValue1.hash());
2314         Asserts.assertEquals(vab[0].hash(), testValue1.hash());
2315         res = test86(vab, null);
2316         Asserts.assertEquals(res, testValue1.hash());
2317         Asserts.assertEquals(vab[0], null);
2318     }
2319 
2320     // Test initialization of nullable array with constant
2321     @Test()
2322     public long test87() {
2323         MyValue1?[] va = new MyValue1?[1];
2324         va[0] = testValue1;
2325         return va[0].hash();
2326     }
2327 
2328     @DontCompile
2329     public void test87_verifier(boolean warmup) {
2330         long result = test87();
2331         Asserts.assertEQ(result, hash());
2332     }
2333 
2334     // Test narrowing conversion from [L to [Q
2335     @Test(failOn = ALLOC + ALLOCA + STORE)
2336     public static MyValue1[] test88(MyValue1?[] va) {
2337         return (MyValue1[])va;
2338     }
2339 
2340     @DontCompile
2341     public void test88_verifier(boolean warmup) {
2342         MyValue1[] va = new MyValue1[1];
2343         va[0] = testValue1;
2344         MyValue1[] res = test88(va);
2345         Asserts.assertEquals(res[0].hash(), testValue1.hash());
2346         res[0] = testValue1;
2347         test88(null); // Should not throw NPE
2348         try {
2349             test88(new MyValue1?[1]);
2350             throw new RuntimeException("ClassCastException expected");
2351         } catch (ClassCastException cce) {
2352             // Expected
2353         }
2354     }
2355 
2356     // Same as test88 but with explicit cast and Object argument
2357     @Test(failOn = ALLOC + ALLOCA + STORE)
2358     public static MyValue1[] test89(Object[] va) {
2359         return (MyValue1[])va;
2360     }
2361 
2362     @DontCompile
2363     public void test89_verifier(boolean warmup) {
2364         MyValue1[] va = new MyValue1[1];
2365         va[0] = testValue1;
2366         MyValue1[] res = test89(va);
2367         Asserts.assertEquals(((MyValue1)res[0]).hash(), testValue1.hash());
2368         res[0] = testValue1;
2369         test89(null); // Should not throw NPE
2370         try {
2371             test89(new MyValue1?[1]);
2372             throw new RuntimeException("ClassCastException expected");
2373         } catch (ClassCastException cce) {
2374             // Expected
2375         }
2376     }
2377 
2378     // More cast tests
2379     @Test()
2380     public static MyValue1?[] test90(Object va) {
2381         return (MyValue1?[])va;
2382     }
2383 
2384     @DontCompile
2385     public void test90_verifier(boolean warmup) {
2386         MyValue1[] va = new MyValue1[1];
2387         MyValue1?[] vab = new MyValue1?[1];
2388         try {
2389           // Trigger some ClassCastExceptions so C2 does not add an uncommon trap
2390           test90(new Integer[0]);
2391         } catch (ClassCastException cce) {
2392           // Expected
2393         }
2394         test90(va);
2395         test90(vab);
2396         test90(null);
2397     }
2398 
2399     @Test()
2400     public static MyValue1?[] test91(Object[] va) {
2401         return (MyValue1?[])va;
2402     }
2403 
2404     @DontCompile
2405     public void test91_verifier(boolean warmup) {
2406         MyValue1[] va = new MyValue1[1];
2407         MyValue1?[] vab = new MyValue1?[1];
2408         try {
2409           // Trigger some ClassCastExceptions so C2 does not add an uncommon trap
2410           test91(new Integer[0]);
2411         } catch (ClassCastException cce) {
2412           // Expected
2413         }
2414         test91(va);
2415         test91(vab);
2416         test91(null);
2417     }
2418 
2419     // Test if arraycopy intrinsic correctly checks for flattened source array
2420     @Test()
2421     public static void test92(MyValue1?[] src, MyValue1?[] dst) {
2422         System.arraycopy(src, 0, dst, 0, 2);
2423     }
2424 
2425     @DontCompile
2426     public void test92_verifier(boolean warmup) {
2427         MyValue1[]  va = new MyValue1[2];
2428         MyValue1?[] vab = new MyValue1?[2];
2429         va[0] = testValue1;
2430         vab[0] = testValue1;
2431         test92(va, vab);
2432         Asserts.assertEquals(va[0], vab[0]);
2433         Asserts.assertEquals(va[1], vab[1]);
2434     }
2435 
2436     @Test()
2437     public static void test93(Object src, MyValue1?[] dst) {
2438         System.arraycopy(src, 0, dst, 0, 2);
2439     }
2440 
2441     @DontCompile
2442     public void test93_verifier(boolean warmup) {
2443         MyValue1[]  va = new MyValue1[2];
2444         MyValue1?[] vab = new MyValue1?[2];
2445         va[0] = testValue1;
2446         vab[0] = testValue1;
2447         test93(va, vab);
2448         Asserts.assertEquals(va[0], vab[0]);
2449         Asserts.assertEquals(va[1], vab[1]);
2450     }
2451 
2452     // Test non-escaping allocation with arraycopy
2453     // that does not modify loaded array element.
2454     @Test()
2455     public static long test94() {
2456         MyValue1?[] src = new MyValue1?[8];
2457         MyValue1[]  dst = new MyValue1[8];
2458         for (int i = 1; i < 8; ++i) {
2459             src[i] = testValue1;
2460         }
2461         System.arraycopy(src, 1, dst, 2, 6);
2462         return dst[0].hash();
2463     }
2464 
2465     @DontCompile
2466     public static void test94_verifier(boolean warmup) {
2467         long result = test94();
2468         Asserts.assertEquals(result, MyValue1.default.hash());
2469     }
2470 
2471     // Test meeting constant TypeInstPtr with ValueTypeNode
2472     @ForceInline
2473     public long test95_callee() {
2474         MyValue1?[] va = new MyValue1?[1];
2475         va[0] = testValue1;
2476         return va[0].hashInterpreted();
2477     }
2478 
2479     @Test()
2480     @Warmup(0)
2481     public long test95() {
2482         return test95_callee();
2483     }
2484 
2485     @DontCompile
2486     public void test95_verifier(boolean warmup) {
2487         long result = test95();
2488         Asserts.assertEQ(result, hash());
2489     }
2490 
2491     // Matrix multiplication test to exercise type flow analysis with nullable value arrays
2492     inline static class Complex {
2493         private final double re;
2494         private final double im;
2495 
2496         Complex(double re, double im) {
2497             this.re = re;
2498             this.im = im;
2499         }
2500 
2501         public Complex add(Complex that) {
2502             return new Complex(this.re + that.re, this.im + that.im);
2503         }
2504 
2505         public Complex mul(Complex that) {
2506             return new Complex(this.re * that.re - this.im * that.im,
2507                                this.re * that.im + this.im * that.re);
2508         }
2509     }
2510 
2511     @Test()
2512     public Complex?[][] test96(Complex?[][] A, Complex?[][] B) {
2513         int size = A.length;
2514         Complex?[][] R = new Complex?[size][size];
2515         for (int i = 0; i < size; i++) {
2516             for (int k = 0; k < size; k++) {
2517                 Complex? aik = A[i][k];
2518                 for (int j = 0; j < size; j++) {
2519                     R[i][j] = B[i][j].add(aik.mul((Complex)B[k][j]));
2520                 }
2521             }
2522         }
2523         return R;
2524     }
2525 
2526     static Complex?[][] test96_A = new Complex?[10][10];
2527     static Complex?[][] test96_B = new Complex?[10][10];
2528     static Complex?[][] test96_R;
2529 
2530     static {
2531         for (int i = 0; i < 10; i++) {
2532             for (int j = 0; j < 10; j++) {
2533                 test96_A[i][j] = new Complex(rI, rI);
2534                 test96_B[i][j] = new Complex(rI, rI);
2535             }
2536         }
2537     }
2538 
2539     @DontCompile
2540     public void test96_verifier(boolean warmup) {
2541         Complex?[][] result = test96(test96_A, test96_B);
2542         if (test96_R == null) {
2543             test96_R = result;
2544         }
2545         for (int i = 0; i < 10; i++) {
2546             for (int j = 0; j < 10; j++) {
2547                 Asserts.assertEQ(result[i][j], test96_R[i][j]);
2548             }
2549         }
2550     }
2551 }
--- EOF ---