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