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