1 /*
   2  * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package compiler.valhalla.valuetypes;
  25 
  26 import jdk.test.lib.Asserts;
  27 import java.lang.reflect.Method;
  28 import java.util.Arrays;
  29 
  30 /*
  31  * @test
  32  * @summary Test value type arrays
  33  * @library /testlibrary /test/lib /compiler/whitebox /
  34  * @compile -XDallowWithFieldOperator TestArrays.java
  35  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  36  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  37  *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla
  38  *                               compiler.valhalla.valuetypes.ValueTypeTest
  39  *                               compiler.valhalla.valuetypes.TestArrays
  40  */
  41 public class TestArrays extends ValueTypeTest {
  42     // Unlike C2, C1 intrinsics never deoptimize System.arraycopy. Instead, we fall back to
  43     // a normal method invocation when encountering flattened arrays.
  44     private static void assertDeoptimizedByC2(Method m) {
  45         int CompLevel_none              = 0,         // Interpreter
  46             CompLevel_simple            = 1,         // C1
  47             CompLevel_limited_profile   = 2,         // C1, invocation & backedge counters
  48             CompLevel_full_profile      = 3,         // C1, invocation & backedge counters + mdo
  49             CompLevel_full_optimization = 4;         // C2 or JVMCI
  50 
  51         if (!XCOMP && WHITE_BOX.isMethodCompiled(m, false) &&
  52             WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel_full_optimization) {
  53             throw new RuntimeException("Type check should have caused it to deoptimize");
  54         }
  55     }
  56 
  57     // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters()
  58     @Override
  59     public String[] getExtraVMParameters(int scenario) {
  60         switch (scenario) {
  61         case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:ValueArrayElemMaxFlatSize=-1"};
  62         case 4: return new String[] {"-XX:-MonomorphicArrayCheck"};
  63         }
  64         return null;
  65     }
  66 
  67     public static void main(String[] args) throws Throwable {
  68         TestArrays test = new TestArrays();
  69         test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class);
  70     }
  71 
  72     // Helper methods
  73 
  74     protected long hash() {
  75         return hash(rI, rL);
  76     }
  77 
  78     protected long hash(int x, long y) {
  79         return MyValue1.createWithFieldsInline(x, y).hash();
  80     }
  81 
  82     // Test value type array creation and initialization
  83     @Test(valid = ValueTypeArrayFlattenOff, failOn = LOAD)
  84     @Test(valid = ValueTypeArrayFlattenOn)
  85     public MyValue1[] test1(int len) {
  86         MyValue1[] va = new MyValue1[len];
  87         for (int i = 0; i < len; ++i) {
  88             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
  89         }
  90         return va;
  91     }
  92 
  93     @DontCompile
  94     public void test1_verifier(boolean warmup) {
  95         int len = Math.abs(rI % 10);
  96         MyValue1[] va = test1(len);
  97         for (int i = 0; i < len; ++i) {
  98             Asserts.assertEQ(va[i].hash(), hash());
  99         }
 100     }
 101 
 102     // Test creation of a value type array and element access
 103     @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP)
 104     public long test2() {
 105         MyValue1[] va = new MyValue1[1];
 106         va[0] = MyValue1.createWithFieldsInline(rI, rL);
 107         return va[0].hash();
 108     }
 109 
 110     @DontCompile
 111     public void test2_verifier(boolean warmup) {
 112         long result = test2();
 113         Asserts.assertEQ(result, hash());
 114     }
 115 
 116     // Test receiving a value type array from the interpreter,
 117     // updating its elements in a loop and computing a hash.
 118     @Test(failOn = ALLOCA)
 119     public long test3(MyValue1[] va) {
 120         long result = 0;
 121         for (int i = 0; i < 10; ++i) {
 122             result += va[i].hash();
 123             va[i] = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 124         }
 125         return result;
 126     }
 127 
 128     @DontCompile
 129     public void test3_verifier(boolean warmup) {
 130         MyValue1[] va = new MyValue1[10];
 131         long expected = 0;
 132         for (int i = 0; i < 10; ++i) {
 133             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 134             expected += va[i].hash();
 135         }
 136         long result = test3(va);
 137         Asserts.assertEQ(expected, result);
 138         for (int i = 0; i < 10; ++i) {
 139             if (va[i].hash() != hash(rI + 1, rL + 1)) {
 140                 Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1));
 141             }
 142         }
 143     }
 144 
 145     // Test returning a value type array received from the interpreter
 146     @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP)
 147     public MyValue1[] test4(MyValue1[] va) {
 148         return va;
 149     }
 150 
 151     @DontCompile
 152     public void test4_verifier(boolean warmup) {
 153         MyValue1[] va = new MyValue1[10];
 154         for (int i = 0; i < 10; ++i) {
 155             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 156         }
 157         va = test4(va);
 158         for (int i = 0; i < 10; ++i) {
 159             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 160         }
 161     }
 162 
 163     // Merge value type arrays created from two branches
 164     @Test
 165     public MyValue1[] test5(boolean b) {
 166         MyValue1[] va;
 167         if (b) {
 168             va = new MyValue1[5];
 169             for (int i = 0; i < 5; ++i) {
 170                 va[i] = MyValue1.createWithFieldsInline(rI, rL);
 171             }
 172         } else {
 173             va = new MyValue1[10];
 174             for (int i = 0; i < 10; ++i) {
 175                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
 176             }
 177         }
 178         long sum = va[0].hashInterpreted();
 179         if (b) {
 180             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
 181         } else {
 182             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
 183         }
 184         return va;
 185     }
 186 
 187     @DontCompile
 188     public void test5_verifier(boolean warmup) {
 189         MyValue1[] va = test5(true);
 190         Asserts.assertEQ(va.length, 5);
 191         Asserts.assertEQ(va[0].hash(), hash(rI, hash()));
 192         for (int i = 1; i < 5; ++i) {
 193             Asserts.assertEQ(va[i].hash(), hash());
 194         }
 195         va = test5(false);
 196         Asserts.assertEQ(va.length, 10);
 197         Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1));
 198         for (int i = 1; i < 10; ++i) {
 199             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 200         }
 201     }
 202 
 203     // Test creation of value type array with single element
 204     @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
 205     public MyValue1 test6() {
 206         MyValue1[] va = new MyValue1[1];
 207         return va[0];
 208     }
 209 
 210     @DontCompile
 211     public void test6_verifier(boolean warmup) {
 212         MyValue1[] va = new MyValue1[1];
 213         MyValue1 v = test6();
 214         Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive());
 215     }
 216 
 217     // Test default initialization of value type arrays
 218     @Test(failOn = LOAD)
 219     public MyValue1[] test7(int len) {
 220         return new MyValue1[len];
 221     }
 222 
 223     @DontCompile
 224     public void test7_verifier(boolean warmup) {
 225         int len = Math.abs(rI % 10);
 226         MyValue1[] va = new MyValue1[len];
 227         MyValue1[] var = test7(len);
 228         for (int i = 0; i < len; ++i) {
 229             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
 230         }
 231     }
 232 
 233     // Test creation of value type array with zero length
 234     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
 235     public MyValue1[] test8() {
 236         return new MyValue1[0];
 237     }
 238 
 239     @DontCompile
 240     public void test8_verifier(boolean warmup) {
 241         MyValue1[] va = test8();
 242         Asserts.assertEQ(va.length, 0);
 243     }
 244 
 245     static MyValue1[] test9_va;
 246 
 247     // Test that value type array loaded from field has correct type
 248     @Test(failOn = LOOP)
 249     public long test9() {
 250         return test9_va[0].hash();
 251     }
 252 
 253     @DontCompile
 254     public void test9_verifier(boolean warmup) {
 255         test9_va = new MyValue1[1];
 256         test9_va[0] = MyValue1.createWithFieldsInline(rI, rL);
 257         long result = test9();
 258         Asserts.assertEQ(result, hash());
 259     }
 260 
 261     // Multi-dimensional arrays
 262     @Test
 263     public MyValue1[][][] test10(int len1, int len2, int len3) {
 264         MyValue1[][][] arr = new MyValue1[len1][len2][len3];
 265         for (int i = 0; i < len1; i++) {
 266             for (int j = 0; j < len2; j++) {
 267                 for (int k = 0; k < len3; k++) {
 268                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i , rL + j + k);
 269                 }
 270             }
 271         }
 272         return arr;
 273     }
 274 
 275     @DontCompile
 276     public void test10_verifier(boolean warmup) {
 277         MyValue1[][][] arr = test10(2, 3, 4);
 278         for (int i = 0; i < 2; i++) {
 279             for (int j = 0; j < 3; j++) {
 280                 for (int k = 0; k < 4; k++) {
 281                     Asserts.assertEQ(arr[i][j][k].hash(), MyValue1.createWithFieldsDontInline(rI + i , rL + j + k).hash());
 282                 }
 283             }
 284         }
 285     }
 286 
 287     @Test
 288     public void test11(MyValue1[][][] arr, long[] res) {
 289         int l = 0;
 290         for (int i = 0; i < arr.length; i++) {
 291             for (int j = 0; j < arr[i].length; j++) {
 292                 for (int k = 0; k < arr[i][j].length; k++) {
 293                     res[l] = arr[i][j][k].hash();
 294                     l++;
 295                 }
 296             }
 297         }
 298     }
 299 
 300     @DontCompile
 301     public void test11_verifier(boolean warmup) {
 302         MyValue1[][][] arr = new MyValue1[2][3][4];
 303         long[] res = new long[2*3*4];
 304         long[] verif = new long[2*3*4];
 305         int l = 0;
 306         for (int i = 0; i < 2; i++) {
 307             for (int j = 0; j < 3; j++) {
 308                 for (int k = 0; k < 4; k++) {
 309                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i, rL + j + k);
 310                     verif[l] = arr[i][j][k].hash();
 311                     l++;
 312                 }
 313             }
 314         }
 315         test11(arr, res);
 316         for (int i = 0; i < verif.length; i++) {
 317             Asserts.assertEQ(res[i], verif[i]);
 318         }
 319     }
 320 
 321     // Array load out of bounds (upper bound) at compile time
 322     @Test
 323     public int test12() {
 324         int arraySize = Math.abs(rI) % 10;;
 325         MyValue1[] va = new MyValue1[arraySize];
 326 
 327         for (int i = 0; i < arraySize; i++) {
 328             va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 329         }
 330 
 331         try {
 332             return va[arraySize + 1].x;
 333         } catch (ArrayIndexOutOfBoundsException e) {
 334             return rI;
 335         }
 336     }
 337 
 338     public void test12_verifier(boolean warmup) {
 339         Asserts.assertEQ(test12(), rI);
 340     }
 341 
 342     // Array load  out of bounds (lower bound) at compile time
 343     @Test
 344     public int test13() {
 345         int arraySize = Math.abs(rI) % 10;;
 346         MyValue1[] va = new MyValue1[arraySize];
 347 
 348         for (int i = 0; i < arraySize; i++) {
 349             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL);
 350         }
 351 
 352         try {
 353             return va[-arraySize].x;
 354         } catch (ArrayIndexOutOfBoundsException e) {
 355             return rI;
 356         }
 357     }
 358 
 359     public void test13_verifier(boolean warmup) {
 360         Asserts.assertEQ(test13(), rI);
 361     }
 362 
 363     // Array load out of bound not known to compiler (both lower and upper bound)
 364     @Test
 365     public int test14(MyValue1[] va, int index)  {
 366         return va[index].x;
 367     }
 368 
 369     public void test14_verifier(boolean warmup) {
 370         int arraySize = Math.abs(rI) % 10;
 371         MyValue1[] va = new MyValue1[arraySize];
 372 
 373         for (int i = 0; i < arraySize; i++) {
 374             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 375         }
 376 
 377         int result;
 378         for (int i = -20; i < 20; i++) {
 379             try {
 380                 result = test14(va, i);
 381             } catch (ArrayIndexOutOfBoundsException e) {
 382                 result = rI;
 383             }
 384             Asserts.assertEQ(result, rI);
 385         }
 386     }
 387 
 388     // Array store out of bounds (upper bound) at compile time
 389     @Test
 390     public int test15() {
 391         int arraySize = Math.abs(rI) % 10;;
 392         MyValue1[] va = new MyValue1[arraySize];
 393 
 394         try {
 395             for (int i = 0; i <= arraySize; i++) {
 396                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 397             }
 398             return rI - 1;
 399         } catch (ArrayIndexOutOfBoundsException e) {
 400             return rI;
 401         }
 402     }
 403 
 404     public void test15_verifier(boolean warmup) {
 405         Asserts.assertEQ(test15(), rI);
 406     }
 407 
 408     // Array store out of bounds (lower bound) at compile time
 409     @Test
 410     public int test16() {
 411         int arraySize = Math.abs(rI) % 10;;
 412         MyValue1[] va = new MyValue1[arraySize];
 413 
 414         try {
 415             for (int i = -1; i <= arraySize; i++) {
 416                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 417             }
 418             return rI - 1;
 419         } catch (ArrayIndexOutOfBoundsException e) {
 420             return rI;
 421         }
 422     }
 423 
 424     public void test16_verifier(boolean warmup) {
 425         Asserts.assertEQ(test16(), rI);
 426     }
 427 
 428     // Array store out of bound not known to compiler (both lower and upper bound)
 429     @Test
 430     public int test17(MyValue1[] va, int index, MyValue1 vt)  {
 431         va[index] = vt;
 432         return va[index].x;
 433     }
 434 
 435     @DontCompile
 436     public void test17_verifier(boolean warmup) {
 437         int arraySize = Math.abs(rI) % 10;
 438         MyValue1[] va = new MyValue1[arraySize];
 439 
 440         for (int i = 0; i < arraySize; i++) {
 441             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 442         }
 443 
 444         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 445         int result;
 446         for (int i = -20; i < 20; i++) {
 447             try {
 448                 result = test17(va, i, vt);
 449             } catch (ArrayIndexOutOfBoundsException e) {
 450                 result = rI + 1;
 451             }
 452             Asserts.assertEQ(result, rI + 1);
 453         }
 454 
 455         for (int i = 0; i < arraySize; i++) {
 456             Asserts.assertEQ(va[i].x, rI + 1);
 457         }
 458     }
 459 
 460     // clone() as stub call
 461     @Test
 462     public MyValue1[] test18(MyValue1[] va) {
 463         return va.clone();
 464     }
 465 
 466     @DontCompile
 467     public void test18_verifier(boolean warmup) {
 468         int len = Math.abs(rI) % 10;
 469         MyValue1[] va = new MyValue1[len];
 470         for (int i = 0; i < len; ++i) {
 471             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 472         }
 473         MyValue1[] result = test18(va);
 474         for (int i = 0; i < len; ++i) {
 475             Asserts.assertEQ(result[i].hash(), va[i].hash());
 476         }
 477     }
 478 
 479     // clone() as series of loads/stores
 480     static MyValue1[] test19_orig = null;
 481 
 482     @Test
 483     public MyValue1[] test19() {
 484         MyValue1[] va = new MyValue1[8];
 485         for (int i = 0; i < va.length; ++i) {
 486             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 487         }
 488         test19_orig = va;
 489 
 490         return va.clone();
 491     }
 492 
 493     @DontCompile
 494     public void test19_verifier(boolean warmup) {
 495         MyValue1[] result = test19();
 496         for (int i = 0; i < test19_orig.length; ++i) {
 497             Asserts.assertEQ(result[i].hash(), test19_orig[i].hash());
 498         }
 499     }
 500 
 501     // arraycopy() of value type array with oop fields
 502     @Test
 503     public void test20(MyValue1[] src, MyValue1[] dst) {
 504         System.arraycopy(src, 0, dst, 0, src.length);
 505     }
 506 
 507     @DontCompile
 508     public void test20_verifier(boolean warmup) {
 509         int len = Math.abs(rI) % 10;
 510         MyValue1[] src = new MyValue1[len];
 511         MyValue1[] dst = new MyValue1[len];
 512         for (int i = 0; i < len; ++i) {
 513             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 514         }
 515         test20(src, dst);
 516         for (int i = 0; i < len; ++i) {
 517             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 518         }
 519     }
 520 
 521     // arraycopy() of value type array with no oop field
 522     @Test
 523     public void test21(MyValue2[] src, MyValue2[] dst) {
 524         System.arraycopy(src, 0, dst, 0, src.length);
 525     }
 526 
 527     @DontCompile
 528     public void test21_verifier(boolean warmup) {
 529         int len = Math.abs(rI) % 10;
 530         MyValue2[] src = new MyValue2[len];
 531         MyValue2[] dst = new MyValue2[len];
 532         for (int i = 0; i < len; ++i) {
 533             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 534         }
 535         test21(src, dst);
 536         for (int i = 0; i < len; ++i) {
 537             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 538         }
 539     }
 540 
 541     // arraycopy() of value type array with oop field and tightly
 542     // coupled allocation as dest
 543     @Test
 544     public MyValue1[] test22(MyValue1[] src) {
 545         MyValue1[] dst = new MyValue1[src.length];
 546         System.arraycopy(src, 0, dst, 0, src.length);
 547         return dst;
 548     }
 549 
 550     @DontCompile
 551     public void test22_verifier(boolean warmup) {
 552         int len = Math.abs(rI) % 10;
 553         MyValue1[] src = new MyValue1[len];
 554         for (int i = 0; i < len; ++i) {
 555             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 556         }
 557         MyValue1[] dst = test22(src);
 558         for (int i = 0; i < len; ++i) {
 559             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 560         }
 561     }
 562 
 563     // arraycopy() of value type array with oop fields and tightly
 564     // coupled allocation as dest
 565     @Test
 566     public MyValue1[] test23(MyValue1[] src) {
 567         MyValue1[] dst = new MyValue1[src.length + 10];
 568         System.arraycopy(src, 0, dst, 5, src.length);
 569         return dst;
 570     }
 571 
 572     @DontCompile
 573     public void test23_verifier(boolean warmup) {
 574         int len = Math.abs(rI) % 10;
 575         MyValue1[] src = new MyValue1[len];
 576         for (int i = 0; i < len; ++i) {
 577             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 578         }
 579         MyValue1[] dst = test23(src);
 580         for (int i = 5; i < len; ++i) {
 581             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 582         }
 583     }
 584 
 585     // arraycopy() of value type array passed as Object
 586     @Test
 587     public void test24(MyValue1[] src, Object dst) {
 588         System.arraycopy(src, 0, dst, 0, src.length);
 589     }
 590 
 591     @DontCompile
 592     public void test24_verifier(boolean warmup) {
 593         int len = Math.abs(rI) % 10;
 594         MyValue1[] src = new MyValue1[len];
 595         MyValue1[] dst = new MyValue1[len];
 596         for (int i = 0; i < len; ++i) {
 597             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 598         }
 599         test24(src, dst);
 600         for (int i = 0; i < len; ++i) {
 601             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 602         }
 603     }
 604 
 605     // short arraycopy() with no oop field
 606     @Test
 607     public void test25(MyValue2[] src, MyValue2[] dst) {
 608         System.arraycopy(src, 0, dst, 0, 8);
 609     }
 610 
 611     @DontCompile
 612     public void test25_verifier(boolean warmup) {
 613         MyValue2[] src = new MyValue2[8];
 614         MyValue2[] dst = new MyValue2[8];
 615         for (int i = 0; i < 8; ++i) {
 616             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 617         }
 618         test25(src, dst);
 619         for (int i = 0; i < 8; ++i) {
 620             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 621         }
 622     }
 623 
 624     // short arraycopy() with oop fields
 625     @Test
 626     public void test26(MyValue1[] src, MyValue1[] dst) {
 627         System.arraycopy(src, 0, dst, 0, 8);
 628     }
 629 
 630     @DontCompile
 631     public void test26_verifier(boolean warmup) {
 632         MyValue1[] src = new MyValue1[8];
 633         MyValue1[] dst = new MyValue1[8];
 634         for (int i = 0; i < 8; ++i) {
 635             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 636         }
 637         test26(src, dst);
 638         for (int i = 0; i < 8; ++i) {
 639             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 640         }
 641     }
 642 
 643     // short arraycopy() with oop fields and offsets
 644     @Test
 645     public void test27(MyValue1[] src, MyValue1[] dst) {
 646         System.arraycopy(src, 1, dst, 2, 6);
 647     }
 648 
 649     @DontCompile
 650     public void test27_verifier(boolean warmup) {
 651         MyValue1[] src = new MyValue1[8];
 652         MyValue1[] dst = new MyValue1[8];
 653         for (int i = 0; i < 8; ++i) {
 654             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 655         }
 656         test27(src, dst);
 657         for (int i = 2; i < 8; ++i) {
 658             Asserts.assertEQ(src[i-1].hash(), dst[i].hash());
 659         }
 660     }
 661 
 662     // non escaping allocations
 663     @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
 664     public MyValue2 test28() {
 665         MyValue2[] src = new MyValue2[10];
 666         src[0] = MyValue2.createWithFieldsInline(rI, false);
 667         MyValue2[] dst = (MyValue2[])src.clone();
 668         return dst[0];
 669     }
 670 
 671     @DontCompile
 672     public void test28_verifier(boolean warmup) {
 673         MyValue2 v = MyValue2.createWithFieldsInline(rI, false);
 674         MyValue2 result = test28();
 675         Asserts.assertEQ(result.hash(), v.hash());
 676     }
 677 
 678     // non escaping allocations
 679     @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
 680     public MyValue2 test29(MyValue2[] src) {
 681         MyValue2[] dst = new MyValue2[10];
 682         System.arraycopy(src, 0, dst, 0, 10);
 683         return dst[0];
 684     }
 685 
 686     @DontCompile
 687     public void test29_verifier(boolean warmup) {
 688         MyValue2[] src = new MyValue2[10];
 689         for (int i = 0; i < 10; ++i) {
 690             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 691         }
 692         MyValue2 v = test29(src);
 693         Asserts.assertEQ(src[0].hash(), v.hash());
 694     }
 695 
 696     // non escaping allocation with uncommon trap that needs
 697     // eliminated value type array element as debug info
 698     @Test
 699     @Warmup(10000)
 700     public MyValue2 test30(MyValue2[] src, boolean flag) {
 701         MyValue2[] dst = new MyValue2[10];
 702         System.arraycopy(src, 0, dst, 0, 10);
 703         if (flag) { }
 704         return dst[0];
 705     }
 706 
 707     @DontCompile
 708     public void test30_verifier(boolean warmup) {
 709         MyValue2[] src = new MyValue2[10];
 710         for (int i = 0; i < 10; ++i) {
 711             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 712         }
 713         MyValue2 v = test30(src, false);
 714         Asserts.assertEQ(src[0].hash(), v.hash());
 715     }
 716 
 717     // non escaping allocation with memory phi
 718     @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + TRAP)
 719     public long test31(boolean b, boolean deopt) {
 720         MyValue2[] src = new MyValue2[1];
 721         if (b) {
 722             src[0] = MyValue2.createWithFieldsInline(rI, true);
 723         } else {
 724             src[0] = MyValue2.createWithFieldsInline(rI, false);
 725         }
 726         if (deopt) {
 727             // uncommon trap
 728             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31"));
 729         }
 730         return src[0].hash();
 731     }
 732 
 733     @DontCompile
 734     public void test31_verifier(boolean warmup) {
 735         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true);
 736         long result1 = test31(true, !warmup);
 737         Asserts.assertEQ(result1, v1.hash());
 738         MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false);
 739         long result2 = test31(false, !warmup);
 740         Asserts.assertEQ(result2, v2.hash());
 741     }
 742 
 743     // Tests with Object arrays and clone/arraycopy
 744     // clone() as stub call
 745     @Test
 746     public Object[] test32(Object[] va) {
 747         return va.clone();
 748     }
 749 
 750     @DontCompile
 751     public void test32_verifier(boolean warmup) {
 752         int len = Math.abs(rI) % 10;
 753         MyValue1[] va = new MyValue1[len];
 754         for (int i = 0; i < len; ++i) {
 755             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 756         }
 757         MyValue1[] result = (MyValue1[])test32(va);
 758         for (int i = 0; i < len; ++i) {
 759             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 760         }
 761     }
 762 
 763     @Test
 764     public Object[] test33(Object[] va) {
 765         return va.clone();
 766     }
 767 
 768     @DontCompile
 769     public void test33_verifier(boolean warmup) {
 770         int len = Math.abs(rI) % 10;
 771         Object[] va = new Object[len];
 772         for (int i = 0; i < len; ++i) {
 773             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 774         }
 775         Object[] result = test33(va);
 776         for (int i = 0; i < len; ++i) {
 777             Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash());
 778         }
 779     }
 780 
 781     // clone() as series of loads/stores
 782     static Object[] test34_orig = null;
 783 
 784     @ForceInline
 785     public Object[] test34_helper(boolean flag) {
 786         Object[] va = null;
 787         if (flag) {
 788             va = new MyValue1[8];
 789             for (int i = 0; i < va.length; ++i) {
 790                 va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 791             }
 792         } else {
 793             va = new Object[8];
 794         }
 795         return va;
 796     }
 797 
 798     @Test
 799     public Object[] test34(boolean flag) {
 800         Object[] va = test34_helper(flag);
 801         test34_orig = va;
 802         return va.clone();
 803     }
 804 
 805     @DontCompile
 806     public void test34_verifier(boolean warmup) {
 807         test34(false);
 808         for (int i = 0; i < 10; i++) { // make sure we do deopt
 809             Object[] result = test34(true);
 810             verify(test34_orig, result);
 811         }
 812         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test34")) {
 813             Object[] result = test34(true);
 814             verify(test34_orig, result);
 815         }
 816     }
 817 
 818     static void verify(Object[] src, Object[] dst) {
 819         for (int i = 0; i < src.length; ++i) {
 820             Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash());
 821         }
 822     }
 823 
 824     static void verify(MyValue1[] src, MyValue1[] dst) {
 825         for (int i = 0; i < src.length; ++i) {
 826             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 827         }
 828     }
 829 
 830     static void verify(MyValue1[] src, Object[] dst) {
 831         for (int i = 0; i < src.length; ++i) {
 832             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 833         }
 834     }
 835 
 836     static void verify(MyValue2[] src, MyValue2[] dst) {
 837         for (int i = 0; i < src.length; ++i) {
 838             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 839         }
 840     }
 841 
 842     static void verify(MyValue2[] src, Object[] dst) {
 843         for (int i = 0; i < src.length; ++i) {
 844             Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash());
 845         }
 846     }
 847 
 848     static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) {
 849         if (!warmup) {
 850             Method m = tests.get(test);
 851             if (!WHITE_BOX.isMethodCompiled(m, false)) {
 852                 if (!ValueTypeArrayFlatten && !XCOMP) {
 853                     throw new RuntimeException("Unexpected deoptimization");
 854                 }
 855                 WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
 856                 return true;
 857             }
 858         }
 859         return false;
 860     }
 861 
 862     // arraycopy() of value type array of unknown size
 863     @Test
 864     public void test35(Object src, Object dst, int len) {
 865         System.arraycopy(src, 0, dst, 0, len);
 866     }
 867 
 868     @DontCompile
 869     public void test35_verifier(boolean warmup) {
 870         int len = Math.abs(rI) % 10;
 871         MyValue1[] src = new MyValue1[len];
 872         MyValue1[] dst = new MyValue1[len];
 873         for (int i = 0; i < len; ++i) {
 874             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 875         }
 876         test35(src, dst, src.length);
 877         verify(src, dst);
 878         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test35")) {
 879             test35(src, dst, src.length);
 880             verify(src, dst);
 881         }
 882     }
 883 
 884     @Test
 885     public void test36(Object src, MyValue2[] dst) {
 886         System.arraycopy(src, 0, dst, 0, dst.length);
 887     }
 888 
 889     @DontCompile
 890     public void test36_verifier(boolean warmup) {
 891         int len = Math.abs(rI) % 10;
 892         MyValue2[] src = new MyValue2[len];
 893         MyValue2[] dst = new MyValue2[len];
 894         for (int i = 0; i < len; ++i) {
 895             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 896         }
 897         test36(src, dst);
 898         verify(src, dst);
 899         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test36")) {
 900             test36(src, dst);
 901             verify(src, dst);
 902         }
 903     }
 904 
 905     @Test
 906     public void test37(MyValue2[] src, Object dst) {
 907         System.arraycopy(src, 0, dst, 0, src.length);
 908     }
 909 
 910     @DontCompile
 911     public void test37_verifier(boolean warmup) {
 912         int len = Math.abs(rI) % 10;
 913         MyValue2[] src = new MyValue2[len];
 914         MyValue2[] dst = new MyValue2[len];
 915         for (int i = 0; i < len; ++i) {
 916             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 917         }
 918         test37(src, dst);
 919         verify(src, dst);
 920         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test37")) {
 921             test37(src, dst);
 922             verify(src, dst);
 923         }
 924     }
 925 
 926     @Test
 927     @Warmup(1) // Avoid early compilation
 928     public void test38(Object src, MyValue2[] dst) {
 929         System.arraycopy(src, 0, dst, 0, dst.length);
 930     }
 931 
 932     @DontCompile
 933     public void test38_verifier(boolean warmup) {
 934         int len = Math.abs(rI) % 10;
 935         Object[] src = new Object[len];
 936         MyValue2[] dst = new MyValue2[len];
 937         for (int i = 0; i < len; ++i) {
 938             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 939         }
 940         test38(src, dst);
 941         verify(dst, src);
 942         if (!warmup) {
 943             Method m = tests.get("TestArrays::test38");
 944             assertDeoptimizedByC2(m);
 945             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
 946             test38(src, dst);
 947             verify(dst, src);
 948             if (!WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
 949                 throw new RuntimeException("unexpected deoptimization");
 950             }
 951         }
 952     }
 953 
 954     @Test
 955     public void test39(MyValue2[] src, Object dst) {
 956         System.arraycopy(src, 0, dst, 0, src.length);
 957     }
 958 
 959     @DontCompile
 960     public void test39_verifier(boolean warmup) {
 961         int len = Math.abs(rI) % 10;
 962         MyValue2[] src = new MyValue2[len];
 963         Object[] dst = new Object[len];
 964         for (int i = 0; i < len; ++i) {
 965             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 966         }
 967         test39(src, dst);
 968         verify(src, dst);
 969         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test39")) {
 970             test39(src, dst);
 971             verify(src, dst);
 972         }
 973     }
 974 
 975     @Test
 976     @Warmup(1) // Avoid early compilation
 977     public void test40(Object[] src, Object dst) {
 978         System.arraycopy(src, 0, dst, 0, src.length);
 979     }
 980 
 981     @DontCompile
 982     public void test40_verifier(boolean warmup) {
 983         int len = Math.abs(rI) % 10;
 984         Object[] src = new Object[len];
 985         MyValue2[] dst = new MyValue2[len];
 986         for (int i = 0; i < len; ++i) {
 987             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 988         }
 989         test40(src, dst);
 990         verify(dst, src);
 991         if (!warmup) {
 992             Method m = tests.get("TestArrays::test40");
 993             assertDeoptimizedByC2(m);
 994             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
 995             test40(src, dst);
 996             verify(dst, src);
 997             if (!WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
 998                 throw new RuntimeException("unexpected deoptimization");
 999             }
1000         }
1001     }
1002 
1003     @Test
1004     public void test41(Object src, Object[] dst) {
1005         System.arraycopy(src, 0, dst, 0, dst.length);
1006     }
1007 
1008     @DontCompile
1009     public void test41_verifier(boolean warmup) {
1010         int len = Math.abs(rI) % 10;
1011         MyValue2[] src = new MyValue2[len];
1012         Object[] dst = new Object[len];
1013         for (int i = 0; i < len; ++i) {
1014             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1015         }
1016         test41(src, dst);
1017         verify(src, dst);
1018         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test41")) {
1019             test41(src, dst);
1020             verify(src, dst);
1021         }
1022     }
1023 
1024     @Test
1025     public void test42(Object[] src, Object[] dst) {
1026         System.arraycopy(src, 0, dst, 0, src.length);
1027     }
1028 
1029     @DontCompile
1030     public void test42_verifier(boolean warmup) {
1031         int len = Math.abs(rI) % 10;
1032         Object[] src = new Object[len];
1033         Object[] dst = new Object[len];
1034         for (int i = 0; i < len; ++i) {
1035             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1036         }
1037         test42(src, dst);
1038         verify(src, dst);
1039         if (!warmup) {
1040             Method m = tests.get("TestArrays::test42");
1041             if (!WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1042                 throw new RuntimeException("unexpected deoptimization");
1043             }
1044         }
1045     }
1046 
1047     // short arraycopy()'s
1048     @Test
1049     public void test43(Object src, Object dst) {
1050         System.arraycopy(src, 0, dst, 0, 8);
1051     }
1052 
1053     @DontCompile
1054     public void test43_verifier(boolean warmup) {
1055         MyValue1[] src = new MyValue1[8];
1056         MyValue1[] dst = new MyValue1[8];
1057         for (int i = 0; i < 8; ++i) {
1058             src[i] = MyValue1.createWithFieldsInline(rI, rL);
1059         }
1060         test43(src, dst);
1061         verify(src, dst);
1062         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test43")) {
1063             test43(src, dst);
1064             verify(src, dst);
1065         }
1066     }
1067 
1068     @Test
1069     public void test44(Object src, MyValue2[] dst) {
1070         System.arraycopy(src, 0, dst, 0, 8);
1071     }
1072 
1073     @DontCompile
1074     public void test44_verifier(boolean warmup) {
1075         MyValue2[] src = new MyValue2[8];
1076         MyValue2[] dst = new MyValue2[8];
1077         for (int i = 0; i < 8; ++i) {
1078             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1079         }
1080         test44(src, dst);
1081         verify(src, dst);
1082         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test44")) {
1083             test44(src, dst);
1084             verify(src, dst);
1085         }
1086     }
1087 
1088     @Test
1089     public void test45(MyValue2[] src, Object dst) {
1090         System.arraycopy(src, 0, dst, 0, 8);
1091     }
1092 
1093     @DontCompile
1094     public void test45_verifier(boolean warmup) {
1095         MyValue2[] src = new MyValue2[8];
1096         MyValue2[] dst = new MyValue2[8];
1097         for (int i = 0; i < 8; ++i) {
1098             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1099         }
1100         test45(src, dst);
1101         verify(src, dst);
1102         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test45")) {
1103             test45(src, dst);
1104             verify(src, dst);
1105         }
1106     }
1107 
1108     @Test
1109     @Warmup(1) // Avoid early compilation
1110     public void test46(Object[] src, MyValue2[] dst) {
1111         System.arraycopy(src, 0, dst, 0, 8);
1112     }
1113 
1114     @DontCompile
1115     public void test46_verifier(boolean warmup) {
1116         Object[] src = new Object[8];
1117         MyValue2[] dst = new MyValue2[8];
1118         for (int i = 0; i < 8; ++i) {
1119             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1120         }
1121         test46(src, dst);
1122         verify(dst, src);
1123         if (!warmup) {
1124             Method m = tests.get("TestArrays::test46");
1125             assertDeoptimizedByC2(m);
1126             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1127             test46(src, dst);
1128             verify(dst, src);
1129             if (!WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1130                 throw new RuntimeException("unexpected deoptimization");
1131             }
1132         }
1133     }
1134 
1135     @Test
1136     public void test47(MyValue2[] src, Object[] dst) {
1137         System.arraycopy(src, 0, dst, 0, 8);
1138     }
1139 
1140     @DontCompile
1141     public void test47_verifier(boolean warmup) {
1142         MyValue2[] src = new MyValue2[8];
1143         Object[] dst = new Object[8];
1144         for (int i = 0; i < 8; ++i) {
1145             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1146         }
1147         test47(src, dst);
1148         verify(src, dst);
1149         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test47")) {
1150             test47(src, dst);
1151             verify(src, dst);
1152         }
1153     }
1154 
1155     @Test
1156     @Warmup(1) // Avoid early compilation
1157     public void test48(Object[] src, Object dst) {
1158         System.arraycopy(src, 0, dst, 0, 8);
1159     }
1160 
1161     @DontCompile
1162     public void test48_verifier(boolean warmup) {
1163         Object[] src = new Object[8];
1164         MyValue2[] dst = new MyValue2[8];
1165         for (int i = 0; i < 8; ++i) {
1166             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1167         }
1168         test48(src, dst);
1169         verify(dst, src);
1170         if (!warmup) {
1171             Method m = tests.get("TestArrays::test48");
1172             assertDeoptimizedByC2(m);
1173             WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION);
1174             test48(src, dst);
1175             verify(dst, src);
1176             if (!WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1177                 throw new RuntimeException("unexpected deoptimization");
1178             }
1179         }
1180     }
1181 
1182     @Test
1183     public void test49(Object src, Object[] dst) {
1184         System.arraycopy(src, 0, dst, 0, 8);
1185     }
1186 
1187     @DontCompile
1188     public void test49_verifier(boolean warmup) {
1189         MyValue2[] src = new MyValue2[8];
1190         Object[] dst = new Object[8];
1191         for (int i = 0; i < 8; ++i) {
1192             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1193         }
1194         test49(src, dst);
1195         verify(src, dst);
1196         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test49")) {
1197             test49(src, dst);
1198             verify(src, dst);
1199         }
1200     }
1201 
1202     @Test
1203     public void test50(Object[] src, Object[] dst) {
1204         System.arraycopy(src, 0, dst, 0, 8);
1205     }
1206 
1207     @DontCompile
1208     public void test50_verifier(boolean warmup) {
1209         Object[] src = new Object[8];
1210         Object[] dst = new Object[8];
1211         for (int i = 0; i < 8; ++i) {
1212             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
1213         }
1214         test50(src, dst);
1215         verify(src, dst);
1216         if (!warmup) {
1217             Method m = tests.get("TestArrays::test50");
1218             if (!WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) {
1219                 throw new RuntimeException("unexpected deoptimization");
1220             }
1221         }
1222     }
1223 
1224     @Test
1225     public MyValue1[] test51(MyValue1[] va) {
1226         return Arrays.copyOf(va, va.length, MyValue1[].class);
1227     }
1228 
1229     @DontCompile
1230     public void test51_verifier(boolean warmup) {
1231         int len = Math.abs(rI) % 10;
1232         MyValue1[] va = new MyValue1[len];
1233         for (int i = 0; i < len; ++i) {
1234             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1235         }
1236         MyValue1[] result = test51(va);
1237         verify(va, result);
1238     }
1239 
1240     static final MyValue1[] test52_va = new MyValue1[8];
1241 
1242     @Test
1243     public MyValue1[] test52() {
1244         return Arrays.copyOf(test52_va, 8, MyValue1[].class);
1245     }
1246 
1247     @DontCompile
1248     public void test52_verifier(boolean warmup) {
1249         for (int i = 0; i < 8; ++i) {
1250             test52_va[i] = MyValue1.createWithFieldsInline(rI, rL);
1251         }
1252         MyValue1[] result = test52();
1253         verify(test52_va, result);
1254     }
1255 
1256     @Test
1257     public MyValue1[] test53(Object[] va) {
1258         return Arrays.copyOf(va, va.length, MyValue1[].class);
1259     }
1260 
1261     @DontCompile
1262     public void test53_verifier(boolean warmup) {
1263         int len = Math.abs(rI) % 10;
1264         MyValue1[] va = new MyValue1[len];
1265         for (int i = 0; i < len; ++i) {
1266             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1267         }
1268         MyValue1[] result = test53(va);
1269         verify(result, va);
1270     }
1271 
1272     @Test
1273     public Object[] test54(MyValue1[] va) {
1274         return Arrays.copyOf(va, va.length, Object[].class);
1275     }
1276 
1277     @DontCompile
1278     public void test54_verifier(boolean warmup) {
1279         int len = Math.abs(rI) % 10;
1280         MyValue1[] va = new MyValue1[len];
1281         for (int i = 0; i < len; ++i) {
1282             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1283         }
1284         Object[] result = test54(va);
1285         verify(va, result);
1286     }
1287 
1288     @Test
1289     public Object[] test55(Object[] va) {
1290         return Arrays.copyOf(va, va.length, Object[].class);
1291     }
1292 
1293     @DontCompile
1294     public void test55_verifier(boolean warmup) {
1295         int len = Math.abs(rI) % 10;
1296         MyValue1[] va = new MyValue1[len];
1297         for (int i = 0; i < len; ++i) {
1298             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1299         }
1300         Object[] result = test55(va);
1301         verify(va, result);
1302     }
1303 
1304     @Test
1305     public MyValue1[] test56(Object[] va) {
1306         return Arrays.copyOf(va, va.length, MyValue1[].class);
1307     }
1308 
1309     @DontCompile
1310     public void test56_verifier(boolean warmup) {
1311         int len = Math.abs(rI) % 10;
1312         Object[] va = new Object[len];
1313         for (int i = 0; i < len; ++i) {
1314             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1315         }
1316         MyValue1[] result = test56(va);
1317         verify(result, va);
1318     }
1319 
1320    @Test
1321     public Object[] test57(Object[] va, Class klass) {
1322         // Arrays.copyOf returns a MyValue1[], which cannot be
1323         // type-casted to Object[] without array co-variance.
1324         return Arrays.copyOf(va, va.length, klass);
1325     }
1326 
1327     @DontCompile
1328     public void test57_verifier(boolean warmup) {
1329         int len = Math.abs(rI) % 10;
1330         Object[] va = new MyValue1[len];
1331         for (int i = 0; i < len; ++i) {
1332             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1333         }
1334         Object[] result = test57(va, MyValue1[].class);
1335         verify(va, result);
1336     }
1337 
1338     @Test
1339     public Object[] test58(MyValue1[] va, Class klass) {
1340         return Arrays.copyOf(va, va.length, klass);
1341     }
1342 
1343     @DontCompile
1344     public void test58_verifier(boolean warmup) {
1345         int len = Math.abs(rI) % 10;
1346         MyValue1[] va = new MyValue1[len];
1347         for (int i = 0; i < len; ++i) {
1348             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1349         }
1350         for (int i = 0; i < 10; i++) {
1351             Object[] result = test58(va, MyValue1[].class);
1352             verify(va, result);
1353         }
1354         if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test58")) {
1355             Object[] result = test58(va, MyValue1[].class);
1356             verify(va, result);
1357         }
1358     }
1359 
1360     @Test
1361     public Object[] test59(MyValue1[] va) {
1362         return Arrays.copyOf(va, va.length+1, MyValue1[].class);
1363     }
1364 
1365     @DontCompile
1366     public void test59_verifier(boolean warmup) {
1367         int len = Math.abs(rI) % 10;
1368         MyValue1[] va = new MyValue1[len];
1369         MyValue1[] verif = new MyValue1[len+1];
1370         for (int i = 0; i < len; ++i) {
1371             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1372             verif[i] = va[i];
1373         }
1374         Object[] result = test59(va);
1375         verify(verif, result);
1376     }
1377 
1378     @Test
1379     public Object[] test60(Object[] va, Class klass) {
1380         // Arrays.copyOf returns a MyValue1[], which cannot be
1381         // type-casted to Object[] without array co-variance.
1382         return Arrays.copyOf(va, va.length+1, klass);
1383     }
1384 
1385     @DontCompile
1386     public void test60_verifier(boolean warmup) {
1387         int len = Math.abs(rI) % 10;
1388         MyValue1[] va = new MyValue1[len];
1389         MyValue1[] verif = new MyValue1[len+1];
1390         for (int i = 0; i < len; ++i) {
1391             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1392             verif[i] = (MyValue1)va[i];
1393         }
1394         Object[] result = test60(va, MyValue1[].class);
1395         verify(verif, result);
1396     }
1397 
1398     @Test
1399     public Object[] test61(Object[] va, Class klass) {
1400         return Arrays.copyOf(va, va.length+1, klass);
1401     }
1402 
1403     @DontCompile
1404     public void test61_verifier(boolean warmup) {
1405         int len = Math.abs(rI) % 10;
1406         Object[] va = new Integer[len];
1407         for (int i = 0; i < len; ++i) {
1408             va[i] = new Integer(rI);
1409         }
1410         Object[] result = test61(va, Integer[].class);
1411         for (int i = 0; i < va.length; ++i) {
1412             Asserts.assertEQ(va[i], result[i]);
1413         }
1414     }
1415 
1416     @ForceInline
1417     public Object[] test62_helper(int i, MyValue1[] va, Integer[] oa) {
1418         Object[] arr = null;
1419         if (i == 10) {
1420             arr = oa;
1421         } else {
1422             arr = va;
1423         }
1424         return arr;
1425     }
1426 
1427     @Test
1428     public Object[] test62(MyValue1[] va, Integer[] oa) {
1429         int i = 0;
1430         for (; i < 10; i++);
1431 
1432         Object[] arr = test62_helper(i, va, oa);
1433 
1434         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1435     }
1436 
1437     @DontCompile
1438     public void test62_verifier(boolean warmup) {
1439         int len = Math.abs(rI) % 10;
1440         MyValue1[] va = new MyValue1[len];
1441         Integer[] oa = new Integer[len];
1442         for (int i = 0; i < len; ++i) {
1443             oa[i] = new Integer(rI);
1444         }
1445         test62_helper(42, va, oa);
1446         Object[] result = test62(va, oa);
1447         for (int i = 0; i < va.length; ++i) {
1448             Asserts.assertEQ(oa[i], result[i]);
1449         }
1450     }
1451 
1452     @ForceInline
1453     public Object[] test63_helper(int i, MyValue1[] va, Integer[] oa) {
1454         Object[] arr = null;
1455         if (i == 10) {
1456             arr = va;
1457         } else {
1458             arr = oa;
1459         }
1460         return arr;
1461     }
1462 
1463     @Test
1464     public Object[] test63(MyValue1[] va, Integer[] oa) {
1465         int i = 0;
1466         for (; i < 10; i++);
1467 
1468         Object[] arr = test63_helper(i, va, oa);
1469 
1470         return Arrays.copyOf(arr, arr.length+1, arr.getClass());
1471     }
1472 
1473     @DontCompile
1474     public void test63_verifier(boolean warmup) {
1475         int len = Math.abs(rI) % 10;
1476         MyValue1[] va = new MyValue1[len];
1477         MyValue1[] verif = new MyValue1[len+1];
1478         for (int i = 0; i < len; ++i) {
1479             va[i] = MyValue1.createWithFieldsInline(rI, rL);
1480             verif[i] = va[i];
1481         }
1482         Integer[] oa = new Integer[len];
1483         test63_helper(42, va, oa);
1484         Object[] result = test63(va, oa);
1485         verify(verif, result);
1486     }
1487 
1488     // Test default initialization of value type arrays: small array
1489     @Test
1490     public MyValue1[] test64() {
1491         return new MyValue1[8];
1492     }
1493 
1494     @DontCompile
1495     public void test64_verifier(boolean warmup) {
1496         MyValue1[] va = new MyValue1[8];
1497         MyValue1[] var = test64();
1498         for (int i = 0; i < 8; ++i) {
1499             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1500         }
1501     }
1502 
1503     // Test default initialization of value type arrays: large array
1504     @Test
1505     public MyValue1[] test65() {
1506         return new MyValue1[32];
1507     }
1508 
1509     @DontCompile
1510     public void test65_verifier(boolean warmup) {
1511         MyValue1[] va = new MyValue1[32];
1512         MyValue1[] var = test65();
1513         for (int i = 0; i < 32; ++i) {
1514             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1515         }
1516     }
1517 
1518     // Check init store elimination
1519     @Test
1520     public MyValue1[] test66(MyValue1 vt) {
1521         MyValue1[] va = new MyValue1[1];
1522         va[0] = vt;
1523         return va;
1524     }
1525 
1526     @DontCompile
1527     public void test66_verifier(boolean warmup) {
1528         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1529         MyValue1[] va = test66(vt);
1530         Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive());
1531     }
1532 
1533     // Zeroing elimination and arraycopy
1534     @Test
1535     public MyValue1[] test67(MyValue1[] src) {
1536         MyValue1[] dst = new MyValue1[16];
1537         System.arraycopy(src, 0, dst, 0, 13);
1538         return dst;
1539     }
1540 
1541     @DontCompile
1542     public void test67_verifier(boolean warmup) {
1543         MyValue1[] va = new MyValue1[16];
1544         MyValue1[] var = test67(va);
1545         for (int i = 0; i < 16; ++i) {
1546             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1547         }
1548     }
1549 
1550     // A store with a default value can be eliminated
1551     @Test
1552     public MyValue1[] test68() {
1553         MyValue1[] va = new MyValue1[2];
1554         va[0] = va[1];
1555         return va;
1556     }
1557 
1558     @DontCompile
1559     public void test68_verifier(boolean warmup) {
1560         MyValue1[] va = new MyValue1[2];
1561         MyValue1[] var = test68();
1562         for (int i = 0; i < 2; ++i) {
1563             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1564         }
1565     }
1566 
1567     // Requires individual stores to init array
1568     @Test
1569     public MyValue1[] test69(MyValue1 vt) {
1570         MyValue1[] va = new MyValue1[4];
1571         va[0] = vt;
1572         va[3] = vt;
1573         return va;
1574     }
1575 
1576     @DontCompile
1577     public void test69_verifier(boolean warmup) {
1578         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL);
1579         MyValue1[] va = new MyValue1[4];
1580         va[0] = vt;
1581         va[3] = vt;
1582         MyValue1[] var = test69(vt);
1583         for (int i = 0; i < va.length; ++i) {
1584             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1585         }
1586     }
1587 
1588     // A store with a default value can be eliminated: same as test68
1589     // but store is farther away from allocation
1590     @Test
1591     public MyValue1[] test70(MyValue1[] other) {
1592         other[1] = other[0];
1593         MyValue1[] va = new MyValue1[2];
1594         other[0] = va[1];
1595         va[0] = va[1];
1596         return va;
1597     }
1598 
1599     @DontCompile
1600     public void test70_verifier(boolean warmup) {
1601         MyValue1[] va = new MyValue1[2];
1602         MyValue1[] var = test70(va);
1603         for (int i = 0; i < 2; ++i) {
1604             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
1605         }
1606     }
1607 
1608     // EA needs to consider oop fields in flattened arrays
1609     @Test
1610     public void test71() {
1611         int len = 10;
1612         MyValue2[] src = new MyValue2[len];
1613         MyValue2[] dst = new MyValue2[len];
1614         for (int i = 0; i < len; ++i) {
1615             src[i] = MyValue2.createWithFieldsDontInline(rI, (i % 2) == 0);
1616         }
1617         System.arraycopy(src, 0, dst, 0, src.length);
1618         for (int i = 0; i < len; ++i) {
1619             Asserts.assertEQ(src[i].hash(), dst[i].hash());
1620         }
1621     }
1622 
1623     @DontCompile
1624     public void test71_verifier(boolean warmup) {
1625         test71();
1626     }
1627 
1628     // Test EA with leaf call to 'store_unknown_value'
1629     @Test
1630     public void test72(Object[] o, boolean b, Object element) {
1631         Object[] arr1 = new Object[10];
1632         Object[] arr2 = new Object[10];
1633         if (b) {
1634           arr1 = o;
1635         }
1636         arr1[0] = element;
1637         arr2[0] = element;
1638     }
1639 
1640     @DontCompile
1641     public void test72_verifier(boolean warmup) {
1642         Object[] arr = new Object[1];
1643         Object elem = new Object();
1644         test72(arr, true, elem);
1645         test72(arr, false, elem);
1646     }
1647 
1648     @Test
1649     public void test73(Object[] oa, MyValue1 v, Object o) {
1650         // TestLWorld.test38 use a C1 Phi node for the array. This test
1651         // adds the case where the stored value is a C1 Phi node.
1652         Object o2 = (o == null) ? v : o;
1653         oa[0] = v;  // The stored value is known to be flattenable
1654         oa[1] = o;  // The stored value may be flattenable
1655         oa[2] = o2; // The stored value may be flattenable (a C1 Phi node)
1656         oa[0] = oa; // The stored value is known to be not flattenable (an Object[])
1657     }
1658 
1659     @DontCompile
1660     public void test73_verifier(boolean warmup) {
1661         MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL);
1662         MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1);
1663         MyValue1[] arr = new MyValue1[3];
1664         try {
1665             test73(arr, v0, v1);
1666             throw new RuntimeException("ArrayStoreException expected");
1667         } catch (ArrayStoreException t) {
1668             // expected
1669         }
1670         Asserts.assertEQ(arr[0].hash(), v0.hash());
1671         Asserts.assertEQ(arr[1].hash(), v1.hash());
1672         Asserts.assertEQ(arr[2].hash(), v1.hash());
1673     }
1674 }