1 /*
   2  * Copyright (c) 2017, 2018, 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 
  28 /*
  29  * @test
  30  * @summary Test value type arrays
  31  * @library /testlibrary /test/lib /compiler/whitebox /
  32  * @requires os.simpleArch == "x64"
  33  * @compile -XDenableValueTypes TestArrays.java
  34  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  35  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  36  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  37  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  38  *                   -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  39  *                   compiler.valhalla.valuetypes.TestArrays
  40  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  41  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedOops
  42  *                   -XX:+EnableValhalla -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  43  *                   -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  44  *                   compiler.valhalla.valuetypes.TestArrays
  45  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  46  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedOops
  47  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:-ValueArrayFlatten
  48  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0
  49  *                   -DVerifyIR=false compiler.valhalla.valuetypes.TestArrays
  50  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  51  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  52  *                   -XX:+EnableValhalla -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  53  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0
  54  *                   -XX:-MonomorphicArrayCheck
  55  *                   -DVerifyIR=false compiler.valhalla.valuetypes.TestArrays
  56  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  57  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI
  58  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
  59  *                   -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1
  60  *                   -XX:-MonomorphicArrayCheck
  61  *                   -DVerifyIR=false compiler.valhalla.valuetypes.TestArrays
  62  */
  63 public class TestArrays extends ValueTypeTest {
  64 
  65     public static void main(String[] args) throws Throwable {
  66         TestArrays test = new TestArrays();
  67         test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class);
  68     }
  69 
  70     // Helper methods
  71 
  72     protected long hash() {
  73         return hash(rI, rL);
  74     }
  75 
  76     protected long hash(int x, long y) {
  77         return MyValue1.createWithFieldsInline(x, y).hash();
  78     }
  79 
  80     // Test value type array creation and initialization
  81     @Test(valid = ValueTypeArrayFlattenOff, failOn = LOAD)
  82     @Test(valid = ValueTypeArrayFlattenOn)
  83     public MyValue1[] test1(int len) {
  84         MyValue1[] va = new MyValue1[len];
  85         for (int i = 0; i < len; ++i) {
  86             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
  87         }
  88         return va;
  89     }
  90 
  91     @DontCompile
  92     public void test1_verifier(boolean warmup) {
  93         int len = Math.abs(rI % 10);
  94         MyValue1[] va = test1(len);
  95         for (int i = 0; i < len; ++i) {
  96             Asserts.assertEQ(va[i].hash(), hash());
  97         }
  98     }
  99 
 100     // Test creation of a value type array and element access
 101     @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + LOADP + STORE + TRAP)
 102     public long test2() {
 103         MyValue1[] va = new MyValue1[1];
 104         va[0] = MyValue1.createWithFieldsInline(rI, rL);
 105         return va[0].hash();
 106     }
 107 
 108     @DontCompile
 109     public void test2_verifier(boolean warmup) {
 110         long result = test2();
 111         Asserts.assertEQ(result, hash());
 112     }
 113 
 114     // Test receiving a value type array from the interpreter,
 115     // updating its elements in a loop and computing a hash.
 116     @Test(failOn = ALLOCA)
 117     public long test3(MyValue1[] va) {
 118         long result = 0;
 119         for (int i = 0; i < 10; ++i) {
 120             result += va[i].hash();
 121             va[i] = MyValue1.createWithFieldsInline(rI + 1, rL + 1);
 122         }
 123         return result;
 124     }
 125 
 126     @DontCompile
 127     public void test3_verifier(boolean warmup) {
 128         MyValue1[] va = new MyValue1[10];
 129         long expected = 0;
 130         for (int i = 0; i < 10; ++i) {
 131             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 132             expected += va[i].hash();
 133         }
 134         long result = test3(va);
 135         Asserts.assertEQ(expected, result);
 136         for (int i = 0; i < 10; ++i) {
 137             if (va[i].hash() != hash(rI + 1, rL + 1)) {
 138                 Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1));
 139             }
 140         }
 141     }
 142 
 143     // Test returning a value type array received from the interpreter
 144     @Test(failOn = ALLOC + ALLOCA + LOAD + LOADP + STORE + LOOP + TRAP)
 145     public MyValue1[] test4(MyValue1[] va) {
 146         return va;
 147     }
 148 
 149     @DontCompile
 150     public void test4_verifier(boolean warmup) {
 151         MyValue1[] va = new MyValue1[10];
 152         for (int i = 0; i < 10; ++i) {
 153             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i);
 154         }
 155         va = test4(va);
 156         for (int i = 0; i < 10; ++i) {
 157             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 158         }
 159     }
 160 
 161     // Merge value type arrays created from two branches
 162     @Test
 163     public MyValue1[] test5(boolean b) {
 164         MyValue1[] va;
 165         if (b) {
 166             va = new MyValue1[5];
 167             for (int i = 0; i < 5; ++i) {
 168                 va[i] = MyValue1.createWithFieldsInline(rI, rL);
 169             }
 170         } else {
 171             va = new MyValue1[10];
 172             for (int i = 0; i < 10; ++i) {
 173                 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i);
 174             }
 175         }
 176         long sum = va[0].hashInterpreted();
 177         if (b) {
 178             va[0] = MyValue1.createWithFieldsDontInline(rI, sum);
 179         } else {
 180             va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1);
 181         }
 182         return va;
 183     }
 184 
 185     @DontCompile
 186     public void test5_verifier(boolean warmup) {
 187         MyValue1[] va = test5(true);
 188         Asserts.assertEQ(va.length, 5);
 189         Asserts.assertEQ(va[0].hash(), hash(rI, hash()));
 190         for (int i = 1; i < 5; ++i) {
 191             Asserts.assertEQ(va[i].hash(), hash());
 192         }
 193         va = test5(false);
 194         Asserts.assertEQ(va.length, 10);
 195         Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1));
 196         for (int i = 1; i < 10; ++i) {
 197             Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i));
 198         }
 199     }
 200 
 201     // Test creation of value type array with single element
 202     @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
 203     public MyValue1 test6() {
 204         MyValue1[] va = new MyValue1[1];
 205         return va[0];
 206     }
 207 
 208     @DontCompile
 209     public void test6_verifier(boolean warmup) {
 210         MyValue1[] va = new MyValue1[1];
 211         MyValue1 v = test6();
 212         Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive());
 213     }
 214 
 215     // Test default initialization of value type arrays
 216     @Test(failOn = LOAD)
 217     public MyValue1[] test7(int len) {
 218         return new MyValue1[len];
 219     }
 220 
 221     @DontCompile
 222     public void test7_verifier(boolean warmup) {
 223         int len = Math.abs(rI % 10);
 224         MyValue1[] va = new MyValue1[len];
 225         MyValue1[] var = test7(len);
 226         for (int i = 0; i < len; ++i) {
 227             Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive());
 228         }
 229     }
 230 
 231     // Test creation of value type array with zero length
 232     @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP)
 233     public MyValue1[] test8() {
 234         return new MyValue1[0];
 235     }
 236 
 237     @DontCompile
 238     public void test8_verifier(boolean warmup) {
 239         MyValue1[] va = test8();
 240         Asserts.assertEQ(va.length, 0);
 241     }
 242 
 243     static MyValue1[] test9_va;
 244 
 245     // Test that value type array loaded from field has correct type
 246     @Test(failOn = LOOP)
 247     public long test9() {
 248         return test9_va[0].hash();
 249     }
 250 
 251     @DontCompile
 252     public void test9_verifier(boolean warmup) {
 253         test9_va = new MyValue1[1];
 254         test9_va[0] = MyValue1.createWithFieldsInline(rI, rL);
 255         long result = test9();
 256         Asserts.assertEQ(result, hash());
 257     }
 258 
 259     // Multi-dimensional arrays
 260     @Test
 261     public MyValue1[][][] test10(int len1, int len2, int len3) {
 262         MyValue1[][][] arr = new MyValue1[len1][len2][len3];
 263         for (int i = 0; i < len1; i++) {
 264             for (int j = 0; j < len2; j++) {
 265                 for (int k = 0; k < len3; k++) {
 266                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i , rL + j + k);
 267                 }
 268             }
 269         }
 270         return arr;
 271     }
 272 
 273     @DontCompile
 274     public void test10_verifier(boolean warmup) {
 275         MyValue1[][][] arr = test10(2, 3, 4);
 276         for (int i = 0; i < 2; i++) {
 277             for (int j = 0; j < 3; j++) {
 278                 for (int k = 0; k < 4; k++) {
 279                     Asserts.assertEQ(arr[i][j][k].hash(), MyValue1.createWithFieldsDontInline(rI + i , rL + j + k).hash());
 280                 }
 281             }
 282         }
 283     }
 284 
 285     @Test
 286     public void test11(MyValue1[][][] arr, long[] res) {
 287         int l = 0;
 288         for (int i = 0; i < arr.length; i++) {
 289             for (int j = 0; j < arr[i].length; j++) {
 290                 for (int k = 0; k < arr[i][j].length; k++) {
 291                     res[l] = arr[i][j][k].hash();
 292                     l++;
 293                 }
 294             }
 295         }
 296     }
 297 
 298     @DontCompile
 299     public void test11_verifier(boolean warmup) {
 300         MyValue1[][][] arr = new MyValue1[2][3][4];
 301         long[] res = new long[2*3*4];
 302         long[] verif = new long[2*3*4];
 303         int l = 0;
 304         for (int i = 0; i < 2; i++) {
 305             for (int j = 0; j < 3; j++) {
 306                 for (int k = 0; k < 4; k++) {
 307                     arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i, rL + j + k);
 308                     verif[l] = arr[i][j][k].hash();
 309                     l++;
 310                 }
 311             }
 312         }
 313         test11(arr, res);
 314         for (int i = 0; i < verif.length; i++) {
 315             Asserts.assertEQ(res[i], verif[i]);
 316         }
 317     }
 318 
 319     // Array load out of bounds (upper bound) at compile time
 320     @Test
 321     public int test12() {
 322         int arraySize = Math.abs(rI) % 10;;
 323         MyValue1[] va = new MyValue1[arraySize];
 324 
 325         for (int i = 0; i < arraySize; i++) {
 326             va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 327         }
 328 
 329         try {
 330             return va[arraySize + 1].x;
 331         } catch (ArrayIndexOutOfBoundsException e) {
 332             return rI;
 333         }
 334     }
 335 
 336     public void test12_verifier(boolean warmup) {
 337         Asserts.assertEQ(test12(), rI);
 338     }
 339 
 340     // Array load  out of bounds (lower bound) at compile time
 341     @Test
 342     public int test13() {
 343         int arraySize = Math.abs(rI) % 10;;
 344         MyValue1[] va = new MyValue1[arraySize];
 345 
 346         for (int i = 0; i < arraySize; i++) {
 347             va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL);
 348         }
 349 
 350         try {
 351             return va[-arraySize].x;
 352         } catch (ArrayIndexOutOfBoundsException e) {
 353             return rI;
 354         }
 355     }
 356 
 357     public void test13_verifier(boolean warmup) {
 358         Asserts.assertEQ(test13(), rI);
 359     }
 360 
 361     // Array load out of bound not known to compiler (both lower and upper bound)
 362     @Test
 363     public int test14(MyValue1[] va, int index)  {
 364         return va[index].x;
 365     }
 366 
 367     public void test14_verifier(boolean warmup) {
 368         int arraySize = Math.abs(rI) % 10;
 369         MyValue1[] va = new MyValue1[arraySize];
 370 
 371         for (int i = 0; i < arraySize; i++) {
 372             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 373         }
 374 
 375         int result;
 376         for (int i = -20; i < 20; i++) {
 377             try {
 378                 result = test14(va, i);
 379             } catch (ArrayIndexOutOfBoundsException e) {
 380                 result = rI;
 381             }
 382             Asserts.assertEQ(result, rI);
 383         }
 384     }
 385 
 386     // Array store out of bounds (upper bound) at compile time
 387     @Test
 388     public int test15() {
 389         int arraySize = Math.abs(rI) % 10;;
 390         MyValue1[] va = new MyValue1[arraySize];
 391 
 392         try {
 393             for (int i = 0; i <= arraySize; i++) {
 394                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 395             }
 396             return rI - 1;
 397         } catch (ArrayIndexOutOfBoundsException e) {
 398             return rI;
 399         }
 400     }
 401 
 402     public void test15_verifier(boolean warmup) {
 403         Asserts.assertEQ(test15(), rI);
 404     }
 405 
 406     // Array store out of bounds (lower bound) at compile time
 407     @Test
 408     public int test16() {
 409         int arraySize = Math.abs(rI) % 10;;
 410         MyValue1[] va = new MyValue1[arraySize];
 411 
 412         try {
 413             for (int i = -1; i <= arraySize; i++) {
 414                 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 415             }
 416             return rI - 1;
 417         } catch (ArrayIndexOutOfBoundsException e) {
 418             return rI;
 419         }
 420     }
 421 
 422     public void test16_verifier(boolean warmup) {
 423         Asserts.assertEQ(test16(), rI);
 424     }
 425 
 426     // Array store out of bound not known to compiler (both lower and upper bound)
 427     @Test
 428     public int test17(MyValue1[] va, int index, MyValue1 vt)  {
 429         va[index] = vt;
 430         return va[index].x;
 431     }
 432 
 433     @DontCompile
 434     public void test17_verifier(boolean warmup) {
 435         int arraySize = Math.abs(rI) % 10;
 436         MyValue1[] va = new MyValue1[arraySize];
 437 
 438         for (int i = 0; i < arraySize; i++) {
 439             va[i] = MyValue1.createWithFieldsDontInline(rI, rL);
 440         }
 441 
 442         MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL);
 443         int result;
 444         for (int i = -20; i < 20; i++) {
 445             try {
 446                 result = test17(va, i, vt);
 447             } catch (ArrayIndexOutOfBoundsException e) {
 448                 result = rI + 1;
 449             }
 450             Asserts.assertEQ(result, rI + 1);
 451         }
 452 
 453         for (int i = 0; i < arraySize; i++) {
 454             Asserts.assertEQ(va[i].x, rI + 1);
 455         }
 456     }
 457 
 458     // clone() as stub call
 459     @Test
 460     public MyValue1[] test18(MyValue1[] va) {
 461         return va.clone();
 462     }
 463 
 464     @DontCompile
 465     public void test18_verifier(boolean warmup) {
 466         int len = Math.abs(rI) % 10;
 467         MyValue1[] va = new MyValue1[len];
 468         for (int i = 0; i < len; ++i) {
 469             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 470         }
 471         MyValue1[] result = test18(va);
 472         for (int i = 0; i < len; ++i) {
 473             Asserts.assertEQ(result[i].hash(), va[i].hash());
 474         }
 475     }
 476 
 477     // clone() as series of loads/stores
 478     static MyValue1[] test19_orig = null;
 479 
 480     @Test
 481     public MyValue1[] test19() {
 482         MyValue1[] va = new MyValue1[8];
 483         for (int i = 0; i < va.length; ++i) {
 484             va[i] = MyValue1.createWithFieldsInline(rI, rL);
 485         }
 486         test19_orig = va;
 487 
 488         return va.clone();
 489     }
 490 
 491     @DontCompile
 492     public void test19_verifier(boolean warmup) {
 493         MyValue1[] result = test19();
 494         for (int i = 0; i < test19_orig.length; ++i) {
 495             Asserts.assertEQ(result[i].hash(), test19_orig[i].hash());
 496         }
 497     }
 498 
 499     // arraycopy() of value type array with oop fields
 500     @Test
 501     public void test20(MyValue1[] src, MyValue1[] dst) {
 502         System.arraycopy(src, 0, dst, 0, src.length);
 503     }
 504 
 505     @DontCompile
 506     public void test20_verifier(boolean warmup) {
 507         int len = Math.abs(rI) % 10;
 508         MyValue1[] src = new MyValue1[len];
 509         MyValue1[] dst = new MyValue1[len];
 510         for (int i = 0; i < len; ++i) {
 511             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 512         }
 513         test20(src, dst);
 514         for (int i = 0; i < len; ++i) {
 515             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 516         }
 517     }
 518 
 519     // arraycopy() of value type array with no oop field
 520     @Test
 521     public void test21(MyValue2[] src, MyValue2[] dst) {
 522         System.arraycopy(src, 0, dst, 0, src.length);
 523     }
 524 
 525     @DontCompile
 526     public void test21_verifier(boolean warmup) {
 527         int len = Math.abs(rI) % 10;
 528         MyValue2[] src = new MyValue2[len];
 529         MyValue2[] dst = new MyValue2[len];
 530         for (int i = 0; i < len; ++i) {
 531             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 532         }
 533         test21(src, dst);
 534         for (int i = 0; i < len; ++i) {
 535             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 536         }
 537     }
 538 
 539     // arraycopy() of value type array with oop field and tightly
 540     // coupled allocation as dest
 541     @Test
 542     public MyValue1[] test22(MyValue1[] src) {
 543         MyValue1[] dst = new MyValue1[src.length];
 544         System.arraycopy(src, 0, dst, 0, src.length);
 545         return dst;
 546     }
 547 
 548     @DontCompile
 549     public void test22_verifier(boolean warmup) {
 550         int len = Math.abs(rI) % 10;
 551         MyValue1[] src = new MyValue1[len];
 552         for (int i = 0; i < len; ++i) {
 553             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 554         }
 555         MyValue1[] dst = test22(src);
 556         for (int i = 0; i < len; ++i) {
 557             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 558         }
 559     }
 560 
 561     // arraycopy() of value type array with oop fields and tightly
 562     // coupled allocation as dest
 563     @Test
 564     public MyValue1[] test23(MyValue1[] src) {
 565         MyValue1[] dst = new MyValue1[src.length + 10];
 566         System.arraycopy(src, 0, dst, 5, src.length);
 567         return dst;
 568     }
 569 
 570     @DontCompile
 571     public void test23_verifier(boolean warmup) {
 572         int len = Math.abs(rI) % 10;
 573         MyValue1[] src = new MyValue1[len];
 574         for (int i = 0; i < len; ++i) {
 575             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 576         }
 577         MyValue1[] dst = test23(src);
 578         for (int i = 5; i < len; ++i) {
 579             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 580         }
 581     }
 582 
 583     // arraycopy() of value type array passed as Object
 584     @Test
 585     public void test24(MyValue1[] src, Object dst) {
 586         System.arraycopy(src, 0, dst, 0, src.length);
 587     }
 588 
 589     @DontCompile
 590     public void test24_verifier(boolean warmup) {
 591         int len = Math.abs(rI) % 10;
 592         MyValue1[] src = new MyValue1[len];
 593         MyValue1[] dst = new MyValue1[len];
 594         for (int i = 0; i < len; ++i) {
 595             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 596         }
 597         test24(src, dst);
 598         for (int i = 0; i < len; ++i) {
 599             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 600         }
 601     }
 602 
 603     // short arraycopy() with no oop field
 604     @Test
 605     public void test25(MyValue2[] src, MyValue2[] dst) {
 606         System.arraycopy(src, 0, dst, 0, 8);
 607     }
 608 
 609     @DontCompile
 610     public void test25_verifier(boolean warmup) {
 611         MyValue2[] src = new MyValue2[8];
 612         MyValue2[] dst = new MyValue2[8];
 613         for (int i = 0; i < 8; ++i) {
 614             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 615         }
 616         test25(src, dst);
 617         for (int i = 0; i < 8; ++i) {
 618             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 619         }
 620     }
 621 
 622     // short arraycopy() with oop fields
 623     @Test
 624     public void test26(MyValue1[] src, MyValue1[] dst) {
 625         System.arraycopy(src, 0, dst, 0, 8);
 626     }
 627 
 628     @DontCompile
 629     public void test26_verifier(boolean warmup) {
 630         MyValue1[] src = new MyValue1[8];
 631         MyValue1[] dst = new MyValue1[8];
 632         for (int i = 0; i < 8; ++i) {
 633             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 634         }
 635         test26(src, dst);
 636         for (int i = 0; i < 8; ++i) {
 637             Asserts.assertEQ(src[i].hash(), dst[i].hash());
 638         }
 639     }
 640 
 641     // short arraycopy() with oop fields and offsets
 642     @Test
 643     public void test27(MyValue1[] src, MyValue1[] dst) {
 644         System.arraycopy(src, 1, dst, 2, 6);
 645     }
 646 
 647     @DontCompile
 648     public void test27_verifier(boolean warmup) {
 649         MyValue1[] src = new MyValue1[8];
 650         MyValue1[] dst = new MyValue1[8];
 651         for (int i = 0; i < 8; ++i) {
 652             src[i] = MyValue1.createWithFieldsInline(rI, rL);
 653         }
 654         test27(src, dst);
 655         for (int i = 2; i < 8; ++i) {
 656             Asserts.assertEQ(src[i-1].hash(), dst[i].hash());
 657         }
 658     }
 659 
 660     // non escaping allocations
 661     @Test(failOn = ALLOCA + LOOP + LOAD + LOADP + TRAP)
 662     public MyValue2 test28() {
 663         MyValue2[] src = new MyValue2[10];
 664         src[0] = MyValue2.createWithFieldsInline(rI, false);
 665         MyValue2[] dst = (MyValue2[])src.clone();
 666         return dst[0];
 667     }
 668 
 669     @DontCompile
 670     public void test28_verifier(boolean warmup) {
 671         MyValue2 v = MyValue2.createWithFieldsInline(rI, false);
 672         MyValue2 result = test28();
 673         Asserts.assertEQ(result.hash(), v.hash());
 674     }
 675 
 676     // non escaping allocations
 677     @Test(failOn = ALLOCA + LOOP + LOAD + LOADP + TRAP)
 678     public MyValue2 test29(MyValue2[] src) {
 679         MyValue2[] dst = new MyValue2[10];
 680         System.arraycopy(src, 0, dst, 0, 10);
 681         return dst[0];
 682     }
 683 
 684     @DontCompile
 685     public void test29_verifier(boolean warmup) {
 686         MyValue2[] src = new MyValue2[10];
 687         for (int i = 0; i < 10; ++i) {
 688             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 689         }
 690         MyValue2 v = test29(src);
 691         Asserts.assertEQ(src[0].hash(), v.hash());
 692     }
 693 
 694     // non escaping allocation with uncommon trap that needs
 695     // eliminated value type array element as debug info
 696     @Test
 697     @Warmup(10000)
 698     public MyValue2 test30(MyValue2[] src, boolean flag) {
 699         MyValue2[] dst = new MyValue2[10];
 700         System.arraycopy(src, 0, dst, 0, 10);
 701         if (flag) { }
 702         return dst[0];
 703     }
 704 
 705     @DontCompile
 706     public void test30_verifier(boolean warmup) {
 707         MyValue2[] src = new MyValue2[10];
 708         for (int i = 0; i < 10; ++i) {
 709             src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0);
 710         }
 711         MyValue2 v = test30(src, false);
 712         Asserts.assertEQ(src[0].hash(), v.hash());
 713     }
 714 
 715     // non escaping allocation with memory phi
 716     @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + LOADP + TRAP)
 717     public long test31(boolean b, boolean deopt) {
 718         MyValue2[] src = new MyValue2[1];
 719         if (b) {
 720             src[0] = MyValue2.createWithFieldsInline(rI, true);
 721         } else {
 722             src[0] = MyValue2.createWithFieldsInline(rI, false);
 723         }
 724         if (deopt) {
 725             // uncommon trap
 726             WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31"));
 727         }
 728         return src[0].hash();
 729     }
 730 
 731     @DontCompile
 732     public void test31_verifier(boolean warmup) {
 733         MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true);
 734         long result1 = test31(true, !warmup);
 735         Asserts.assertEQ(result1, v1.hash());
 736         MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false);
 737         long result2 = test31(false, !warmup);
 738         Asserts.assertEQ(result2, v2.hash());
 739     }
 740 }