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 java.lang.reflect.Array;
  27 import java.lang.reflect.Field;
  28 import java.util.Arrays;
  29 import java.util.List;
  30 
  31 import jdk.test.lib.Asserts;
  32 import jdk.internal.misc.Unsafe;
  33 
  34 /*
  35  * @test
  36  * @summary Test intrinsic support for value types
  37  * @library /testlibrary /test/lib /compiler/whitebox /
  38  * @modules java.base/jdk.internal.misc
  39  * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
  40  * @compile TestIntrinsics.java
  41  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  42  * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  43  *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI
  44  *                               compiler.valhalla.valuetypes.ValueTypeTest
  45  *                               compiler.valhalla.valuetypes.TestIntrinsics
  46  */
  47 public class TestIntrinsics extends ValueTypeTest {
  48     // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters()
  49     @Override
  50     public String[] getExtraVMParameters(int scenario) {
  51         switch (scenario) {
  52         case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:ValueArrayElemMaxFlatSize=-1"};
  53         case 4: return new String[] {"-XX:-MonomorphicArrayCheck"};
  54         }
  55         return null;
  56     }
  57 
  58     public static void main(String[] args) throws Throwable {
  59         TestIntrinsics test = new TestIntrinsics();
  60         test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class);
  61     }
  62 
  63     // Test correctness of the Class::isAssignableFrom intrinsic
  64     @Test()
  65     public boolean test1(Class<?> supercls, Class<?> subcls) {
  66         return supercls.isAssignableFrom(subcls);
  67     }
  68 
  69     public void test1_verifier(boolean warmup) {
  70         Asserts.assertTrue(test1(java.util.AbstractList.class, java.util.ArrayList.class), "test1_1 failed");
  71         Asserts.assertTrue(test1(MyValue1.class.asIndirectType(), MyValue1.class.asIndirectType()), "test1_2 failed");
  72         Asserts.assertTrue(test1(MyValue1.class, MyValue1.class), "test1_3 failed");
  73         Asserts.assertTrue(test1(MyValue1.class.asIndirectType(), MyValue1.class), "test1_4 failed");
  74         Asserts.assertFalse(test1(MyValue1.class, MyValue1.class.asIndirectType()), "test1_5 failed");
  75         Asserts.assertTrue(test1(Object.class, java.util.ArrayList.class), "test1_6 failed");
  76         Asserts.assertTrue(test1(Object.class, MyValue1.class.asIndirectType()), "test1_7 failed");
  77         Asserts.assertTrue(test1(Object.class, MyValue1.class), "test1_8 failed");
  78         Asserts.assertTrue(!test1(MyValue1.class.asIndirectType(), Object.class), "test1_9 failed");
  79         Asserts.assertTrue(!test1(MyValue1.class, Object.class), "test1_10 failed");
  80     }
  81 
  82     // Verify that Class::isAssignableFrom checks with statically known classes are folded
  83     @Test(failOn = LOADK)
  84     public boolean test2() {
  85         boolean check1 = java.util.AbstractList.class.isAssignableFrom(java.util.ArrayList.class);
  86         boolean check2 = MyValue1.class.asIndirectType().isAssignableFrom(MyValue1.class.asIndirectType());
  87         boolean check3 = MyValue1.class.isAssignableFrom(MyValue1.class);
  88         boolean check4 = MyValue1.class.asIndirectType().isAssignableFrom(MyValue1.class);
  89         boolean check5 = !MyValue1.class.isAssignableFrom(MyValue1.class.asIndirectType());
  90         boolean check6 = Object.class.isAssignableFrom(java.util.ArrayList.class);
  91         boolean check7 = Object.class.isAssignableFrom(MyValue1.class.asIndirectType());
  92         boolean check8 = Object.class.isAssignableFrom(MyValue1.class);
  93         boolean check9 = !MyValue1.class.asIndirectType().isAssignableFrom(Object.class);
  94         boolean check10 = !MyValue1.class.isAssignableFrom(Object.class);
  95         return check1 && check2 && check3 && check4 && check5 && check6 && check7 && check8 && check9 && check10;
  96     }
  97 
  98     public void test2_verifier(boolean warmup) {
  99         Asserts.assertTrue(test2(), "test2 failed");
 100     }
 101 
 102     // Test correctness of the Class::getSuperclass intrinsic
 103     @Test()
 104     public Class<?> test3(Class<?> cls) {
 105         return cls.getSuperclass();
 106     }
 107 
 108     public void test3_verifier(boolean warmup) {
 109         Asserts.assertTrue(test3(Object.class) == null, "test3_1 failed");
 110         Asserts.assertTrue(test3(MyValue1.class.asIndirectType()) == Object.class, "test3_2 failed");
 111         Asserts.assertTrue(test3(MyValue1.class.asPrimaryType()) == Object.class, "test3_3 failed");
 112         Asserts.assertTrue(test3(Class.class) == Object.class, "test3_4 failed");
 113     }
 114 
 115     // Verify that Class::getSuperclass checks with statically known classes are folded
 116     @Test(failOn = LOADK)
 117     public boolean test4() {
 118         boolean check1 = Object.class.getSuperclass() == null;
 119         boolean check2 = MyValue1.class.asIndirectType().getSuperclass() == Object.class;
 120         boolean check3 = MyValue1.class.asPrimaryType().getSuperclass() == Object.class;
 121         boolean check4 = Class.class.getSuperclass() == Object.class;
 122         return check1 && check2 && check3 && check4;
 123     }
 124 
 125     public void test4_verifier(boolean warmup) {
 126         Asserts.assertTrue(test4(), "test4 failed");
 127     }
 128 
 129     // Test toString() method
 130     @Test()
 131     public String test5(MyValue1 v) {
 132         return v.toString();
 133     }
 134 
 135     @DontCompile
 136     public void test5_verifier(boolean warmup) {
 137         MyValue1 v = MyValue1.createDefaultInline();
 138         test5(v);
 139     }
 140 
 141     // Test hashCode() method
 142     @Test()
 143     public int test6(MyValue1 v) {
 144         return v.hashCode();
 145     }
 146 
 147     @DontCompile
 148     public void test6_verifier(boolean warmup) {
 149         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 150         int res = test6(v);
 151         Asserts.assertEQ(res, v.hashCode());
 152     }
 153 
 154     // Test default value type array creation via reflection
 155     @Test()
 156     public Object[] test7(Class<?> componentType, int len) {
 157         Object[] va = (Object[])Array.newInstance(componentType, len);
 158         return va;
 159     }
 160 
 161     @DontCompile
 162     public void test7_verifier(boolean warmup) {
 163         int len = Math.abs(rI) % 42;
 164         long hash = MyValue1.createDefaultDontInline().hashPrimitive();
 165         Object[] va = test7(MyValue1.class, len);
 166         for (int i = 0; i < len; ++i) {
 167             Asserts.assertEQ(((MyValue1)va[i]).hashPrimitive(), hash);
 168         }
 169     }
 170 
 171     // Class.isInstance
 172     @Test()
 173     public boolean test8(Class c, MyValue1 vt) {
 174         return c.isInstance(vt);
 175     }
 176 
 177     @DontCompile
 178     public void test8_verifier(boolean warmup) {
 179         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 180         boolean result = test8(MyValue1.class, vt);
 181         Asserts.assertTrue(result);
 182         result = test8(MyValue1.class.asIndirectType(), vt);
 183         Asserts.assertTrue(result);
 184     }
 185 
 186     @Test()
 187     public boolean test9(Class c, MyValue1 vt) {
 188         return c.isInstance(vt);
 189     }
 190 
 191     @DontCompile
 192     public void test9_verifier(boolean warmup) {
 193         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 194         boolean result = test9(MyValue2.class, vt);
 195         Asserts.assertFalse(result);
 196         result = test9(MyValue2.class.asIndirectType(), vt);
 197         Asserts.assertFalse(result);
 198     }
 199 
 200     // Class.cast
 201     @Test()
 202     public Object test10(Class c, MyValue1 vt) {
 203         return c.cast(vt);
 204     }
 205 
 206     @DontCompile
 207     public void test10_verifier(boolean warmup) {
 208         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 209         Object result = test10(MyValue1.class, vt);
 210         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 211     }
 212 
 213     @Test()
 214     public Object test11(Class c, MyValue1 vt) {
 215         return c.cast(vt);
 216     }
 217 
 218     @DontCompile
 219     public void test11_verifier(boolean warmup) {
 220         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 221         try {
 222             test11(MyValue2.class, vt);
 223             throw new RuntimeException("should have thrown");
 224         } catch (ClassCastException cce) {
 225         }
 226     }
 227 
 228     @Test()
 229     public Object test12(MyValue1 vt) {
 230         return MyValue1.class.cast(vt);
 231     }
 232 
 233     @DontCompile
 234     public void test12_verifier(boolean warmup) {
 235         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 236         Object result = test12(vt);
 237         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 238     }
 239 
 240     @Test()
 241     public Object test13(MyValue1 vt) {
 242         return MyValue2.class.cast(vt);
 243     }
 244 
 245     @DontCompile
 246     public void test13_verifier(boolean warmup) {
 247         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 248         try {
 249             test13(vt);
 250             throw new RuntimeException("should have thrown");
 251         } catch (ClassCastException cce) {
 252         }
 253     }
 254 
 255     // value type array creation via reflection
 256     @Test()
 257     public void test14(int len, long hash) {
 258         Object[] va = (Object[])Array.newInstance(MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), len);
 259         for (int i = 0; i < len; ++i) {
 260             Asserts.assertEQ(((MyValue1)va[i]).hashPrimitive(), hash);
 261         }
 262     }
 263 
 264     @DontCompile
 265     public void test14_verifier(boolean warmup) {
 266         int len = Math.abs(rI) % 42;
 267         long hash = MyValue1.createDefaultDontInline().hashPrimitive();
 268         test14(len, hash);
 269     }
 270 
 271     // Test hashCode() method
 272     @Test()
 273     public int test15(Object v) {
 274         return v.hashCode();
 275     }
 276 
 277     @DontCompile
 278     public void test15_verifier(boolean warmup) {
 279         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 280         int res = test15(v);
 281         Asserts.assertEQ(res, v.hashCode());
 282     }
 283 
 284     @Test()
 285     public int test16(Object v) {
 286         return System.identityHashCode(v);
 287     }
 288 
 289     @DontCompile
 290     public void test16_verifier(boolean warmup) {
 291         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 292         int res = test16(v);
 293         Asserts.assertEQ(res, System.identityHashCode((Object)v));
 294     }
 295 
 296     @Test()
 297     public int test17(Object v) {
 298         return System.identityHashCode(v);
 299     }
 300 
 301     @DontCompile
 302     public void test17_verifier(boolean warmup) {
 303         Integer v = new Integer(rI);
 304         int res = test17(v);
 305         Asserts.assertEQ(res, System.identityHashCode(v));
 306     }
 307 
 308     @Test()
 309     public int test18(Object v) {
 310         return System.identityHashCode(v);
 311     }
 312 
 313     @DontCompile
 314     public void test18_verifier(boolean warmup) {
 315         Object v = null;
 316         int res = test18(v);
 317         Asserts.assertEQ(res, System.identityHashCode(v));
 318     }
 319 
 320     // hashCode() and toString() with different value types
 321     @Test()
 322     public int test19(MyValue1 vt1, MyValue1 vt2, boolean b) {
 323         MyValue1 res = b ? vt1 : vt2;
 324         return res.hashCode();
 325     }
 326 
 327     @DontCompile
 328     public void test19_verifier(boolean warmup) {
 329         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 330         int res = test19(vt, vt, true);
 331         Asserts.assertEQ(res, vt.hashCode());
 332         res = test19(vt, vt, false);
 333         Asserts.assertEQ(res, vt.hashCode());
 334     }
 335 
 336     @Test()
 337     public String test20(MyValue1 vt1, MyValue1 vt2, boolean b) {
 338         MyValue1 res = b ? vt1 : vt2;
 339         return res.toString();
 340     }
 341 
 342     @DontCompile
 343     public void test20_verifier(boolean warmup) {
 344         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 345         String res = test20(vt, vt, true);
 346         Asserts.assertEQ(res, vt.toString());
 347         res = test20(vt, vt, false);
 348         Asserts.assertEQ(res, vt.toString());
 349     }
 350 
 351     private static final Unsafe U = Unsafe.getUnsafe();
 352     private static final long X_OFFSET;
 353     private static final long Y_OFFSET;
 354     private static final long V1_OFFSET;
 355     private static final boolean V1_FLATTENED;
 356     static {
 357         try {
 358             Field xField = MyValue1.class.getDeclaredField("x");
 359             X_OFFSET = U.objectFieldOffset(xField);
 360             Field yField = MyValue1.class.getDeclaredField("y");
 361             Y_OFFSET = U.objectFieldOffset(yField);
 362             Field v1Field = MyValue1.class.getDeclaredField("v1");
 363             V1_OFFSET = U.objectFieldOffset(v1Field);
 364             V1_FLATTENED = U.isFlattened(v1Field);
 365         } catch (Exception e) {
 366             throw new RuntimeException(e);
 367         }
 368     }
 369 
 370     protected static final String CALL_Unsafe = START + "CallStaticJava" + MID + "# Static  jdk.internal.misc.Unsafe::" + END;
 371 
 372     @Test(failOn=CALL_Unsafe)
 373     public int test21(MyValue1 v) {
 374        return U.getInt(v, X_OFFSET);
 375     }
 376 
 377     @DontCompile
 378     public void test21_verifier(boolean warmup) {
 379         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 380         int res = test21(v);
 381         Asserts.assertEQ(res, v.x);
 382     }
 383 
 384     MyValue1 test22_vt;
 385     @Test(failOn=CALL_Unsafe + ALLOC)
 386     public void test22(MyValue1 v) {
 387         v = U.makePrivateBuffer(v);
 388         U.putInt(v, X_OFFSET, rI);
 389         v = U.finishPrivateBuffer(v);
 390         test22_vt = v;
 391     }
 392 
 393     @DontCompile
 394     public void test22_verifier(boolean warmup) {
 395         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 396         test22(v.setX(v, 0));
 397         Asserts.assertEQ(test22_vt.hash(), v.hash());
 398     }
 399 
 400     @Test(failOn=CALL_Unsafe)
 401     public int test23(MyValue1 v, long offset) {
 402         return U.getInt(v, offset);
 403     }
 404 
 405     @DontCompile
 406     public void test23_verifier(boolean warmup) {
 407         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 408         int res = test23(v, X_OFFSET);
 409         Asserts.assertEQ(res, v.x);
 410     }
 411 
 412     MyValue1 test24_vt = MyValue1.createWithFieldsInline(rI, rL);
 413 
 414     @Test(failOn=CALL_Unsafe)
 415     public int test24(long offset) {
 416         return U.getInt(test24_vt, offset);
 417     }
 418 
 419     @DontCompile
 420     public void test24_verifier(boolean warmup) {
 421         int res = test24(X_OFFSET);
 422         Asserts.assertEQ(res, test24_vt.x);
 423     }
 424 
 425     // Test copyOf intrinsic with allocated value type in it's debug information
 426     final inline class Test25Value {
 427         final int x;
 428         public Test25Value() {
 429             this.x = 42;
 430         }
 431     }
 432 
 433     final Test25Value[] test25Array = new Test25Value[10];
 434 
 435     @Test
 436     public Test25Value[] test25(Test25Value element) {
 437         Test25Value[] newArray = Arrays.copyOf(test25Array, test25Array.length + 1);
 438         newArray[test25Array.length] = element;
 439         return newArray;
 440     }
 441 
 442     @DontCompile
 443     public void test25_verifier(boolean warmup) {
 444         Test25Value vt = new Test25Value();
 445         test25(vt);
 446     }
 447 
 448     @Test
 449     public Object test26() {
 450         Class<?>[] ca = new Class<?>[1];
 451         for (int i = 0; i < 1; ++i) {
 452           // Folds during loop opts
 453           ca[i] = MyValue1.class.asPrimaryType();
 454         }
 455         return Array.newInstance(ca[0], 1);
 456     }
 457 
 458     @DontCompile
 459     public void test26_verifier(boolean warmup) {
 460         Object[] res = (Object[])test26();
 461         Asserts.assertEQ(((MyValue1)res[0]).hashPrimitive(), MyValue1.createDefaultInline().hashPrimitive());
 462     }
 463 
 464     // Load non-flattenable value type field with unsafe
 465     MyValue1? test27_vt = MyValue1.createWithFieldsInline(rI, rL);
 466     private static final long TEST27_OFFSET;
 467     static {
 468         try {
 469             Field field = TestIntrinsics.class.getDeclaredField("test27_vt");
 470             TEST27_OFFSET = U.objectFieldOffset(field);
 471         } catch (Exception e) {
 472             throw new RuntimeException(e);
 473         }
 474     }
 475 
 476     @Test(failOn=CALL_Unsafe)
 477     public MyValue1 test27() {
 478         return (MyValue1)U.getReference(this, TEST27_OFFSET);
 479     }
 480 
 481     @DontCompile
 482     public void test27_verifier(boolean warmup) {
 483         MyValue1 res = test27();
 484         Asserts.assertEQ(res.hash(), test24_vt.hash());
 485     }
 486 
 487     // Mismatched type
 488     @Test(failOn=CALL_Unsafe)
 489     public int test28(MyValue1 v) {
 490         return U.getByte(v, X_OFFSET);
 491     }
 492 
 493     @DontCompile
 494     public void test28_verifier(boolean warmup) {
 495         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 496         int res = test28(v);
 497         if (java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN) {
 498             Asserts.assertEQ(res, (int)((byte)v.x));
 499         } else {
 500             Asserts.assertEQ(res, (int)((byte)Integer.reverseBytes(v.x)));
 501         }
 502     }
 503 
 504     // Wrong alignment
 505     @Test(failOn=CALL_Unsafe)
 506     public long test29(MyValue1 v) {
 507         // Read the field that's guaranteed to not be last in the
 508         // value so we don't read out of the value
 509         if (X_OFFSET < Y_OFFSET) {
 510             return U.getInt(v, X_OFFSET+1);
 511         }
 512         return U.getLong(v, Y_OFFSET+1);
 513     }
 514 
 515     @DontCompile
 516     public void test29_verifier(boolean warmup) {
 517         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 518         long res = test29(v);
 519         if (java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN) {
 520             if (X_OFFSET < Y_OFFSET) {
 521                 Asserts.assertEQ(((int)res) << 8, (v.x >> 8) << 8);
 522             } else {
 523                 Asserts.assertEQ(res << 8, (v.y >> 8) << 8);
 524             }
 525         } else {
 526             if (X_OFFSET < Y_OFFSET) {
 527                 Asserts.assertEQ(((int)res), v.x >>> 8);
 528             } else {
 529                 Asserts.assertEQ(res, v.y >>> 8);
 530             }
 531         }
 532     }
 533 
 534     // getValue to retrieve flattened field from value
 535     @Test(failOn=CALL_Unsafe)
 536     public MyValue2 test30(MyValue1 v) {
 537         if (V1_FLATTENED) {
 538             return U.getValue(v, V1_OFFSET, MyValue2.class.asPrimaryType().asIndirectType().asPrimaryType());
 539         }
 540         return (MyValue2)U.getReference(v, V1_OFFSET);
 541     }
 542 
 543     @DontCompile
 544     public void test30_verifier(boolean warmup) {
 545         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 546         MyValue2 res = test30(v);
 547         Asserts.assertEQ(res.hash(), v.v1.hash());
 548     }
 549 
 550     MyValue1 test31_vt;
 551     private static final long TEST31_VT_OFFSET;
 552     private static final boolean TEST31_VT_FLATTENED;
 553     static {
 554         try {
 555             Field test31_vt_Field = TestIntrinsics.class.getDeclaredField("test31_vt");
 556             TEST31_VT_OFFSET = U.objectFieldOffset(test31_vt_Field);
 557             TEST31_VT_FLATTENED = U.isFlattened(test31_vt_Field);
 558         } catch (Exception e) {
 559             throw new RuntimeException(e);
 560         }
 561     }
 562 
 563     // getValue to retrieve flattened field from object
 564     @Test(failOn=CALL_Unsafe)
 565     public MyValue1 test31() {
 566         if (TEST31_VT_FLATTENED) {
 567             return U.getValue(this, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
 568         }
 569         return (MyValue1)U.getReference(this, TEST31_VT_OFFSET);
 570     }
 571 
 572     @DontCompile
 573     public void test31_verifier(boolean warmup) {
 574         test31_vt = MyValue1.createWithFieldsInline(rI, rL);
 575         MyValue1 res = test31();
 576         Asserts.assertEQ(res.hash(), test31_vt.hash());
 577     }
 578 
 579     // putValue to set flattened field in object
 580     @Test(failOn=CALL_Unsafe)
 581     public void test32(MyValue1 vt) {
 582         if (TEST31_VT_FLATTENED) {
 583             U.putValue(this, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), vt);
 584         } else {
 585             U.putReference(this, TEST31_VT_OFFSET, vt);
 586         }
 587     }
 588 
 589     @DontCompile
 590     public void test32_verifier(boolean warmup) {
 591         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 592         test31_vt = MyValue1.createDefaultInline();
 593         test32(vt);
 594         Asserts.assertEQ(vt.hash(), test31_vt.hash());
 595     }
 596 
 597     private static final int TEST33_BASE_OFFSET;
 598     private static final int TEST33_INDEX_SCALE;
 599     private static final boolean TEST33_FLATTENED_ARRAY;
 600     static {
 601         try {
 602             TEST33_BASE_OFFSET = U.arrayBaseOffset(MyValue1[].class);
 603             TEST33_INDEX_SCALE = U.arrayIndexScale(MyValue1[].class);
 604             TEST33_FLATTENED_ARRAY = U.isFlattenedArray(MyValue1[].class);
 605         } catch (Exception e) {
 606             throw new RuntimeException(e);
 607         }
 608     }
 609     // getValue to retrieve flattened field from array
 610     @Test(failOn=CALL_Unsafe)
 611     public MyValue1 test33(MyValue1[] arr) {
 612         if (TEST33_FLATTENED_ARRAY) {
 613             return U.getValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
 614         }
 615         return (MyValue1)U.getReference(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE);
 616     }
 617 
 618     @DontCompile
 619     public void test33_verifier(boolean warmup) {
 620         MyValue1[] arr = new MyValue1[2];
 621         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 622         arr[1] = vt;
 623         MyValue1 res = test33(arr);
 624         Asserts.assertEQ(res.hash(), vt.hash());
 625     }
 626 
 627     // putValue to set flattened field in array
 628     @Test(failOn=CALL_Unsafe)
 629     public void test34(MyValue1[] arr, MyValue1 vt) {
 630         if (TEST33_FLATTENED_ARRAY) {
 631             U.putValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), vt);
 632         } else {
 633             U.putReference(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, vt);
 634         }
 635     }
 636 
 637     @DontCompile
 638     public void test34_verifier(boolean warmup) {
 639         MyValue1[] arr = new MyValue1[2];
 640         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 641         test34(arr, vt);
 642         Asserts.assertEQ(arr[1].hash(), vt.hash());
 643     }
 644 
 645     // getValue to retrieve flattened field from object with unknown
 646     // container type
 647     @Test(failOn=CALL_Unsafe)
 648     public MyValue1 test35(Object o) {
 649         if (TEST31_VT_FLATTENED) {
 650             return U.getValue(o, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
 651         }
 652         return (MyValue1)U.getReference(o, TEST31_VT_OFFSET);
 653     }
 654 
 655     @DontCompile
 656     public void test35_verifier(boolean warmup) {
 657         test31_vt = MyValue1.createWithFieldsInline(rI, rL);
 658         MyValue1 res = test35(this);
 659         Asserts.assertEQ(res.hash(), test31_vt.hash());
 660     }
 661 
 662     // getValue to retrieve flattened field from object at unknown
 663     // offset
 664     @Test(failOn=CALL_Unsafe)
 665     public MyValue1 test36(long offset) {
 666         if (TEST31_VT_FLATTENED) {
 667             return U.getValue(this, offset, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
 668         }
 669         return (MyValue1)U.getReference(this, offset);
 670     }
 671 
 672     @DontCompile
 673     public void test36_verifier(boolean warmup) {
 674         test31_vt = MyValue1.createWithFieldsInline(rI, rL);
 675         MyValue1 res = test36(TEST31_VT_OFFSET);
 676         Asserts.assertEQ(res.hash(), test31_vt.hash());
 677     }
 678 
 679     // putValue to set flattened field in object with unknown
 680     // container
 681     @Test(failOn=CALL_Unsafe)
 682     public void test37(Object o, MyValue1 vt) {
 683         if (TEST31_VT_FLATTENED) {
 684             U.putValue(o, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), vt);
 685         } else {
 686             U.putReference(o, TEST31_VT_OFFSET, vt);
 687         }
 688     }
 689 
 690     @DontCompile
 691     public void test37_verifier(boolean warmup) {
 692         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 693         test31_vt = MyValue1.createDefaultInline();
 694         test37(this, vt);
 695         Asserts.assertEQ(vt.hash(), test31_vt.hash());
 696     }
 697 
 698     // putValue to set flattened field in object, non value argument
 699     // to store
 700     @Test(match = { CALL_Unsafe }, matchCount = { 1 })
 701     public void test38(Object o) {
 702         if (TEST31_VT_FLATTENED) {
 703             U.putValue(this, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), o);
 704         } else {
 705             U.putReference(this, TEST31_VT_OFFSET, o);
 706         }
 707     }
 708 
 709     @DontCompile
 710     public void test38_verifier(boolean warmup) {
 711         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 712         test31_vt = MyValue1.createDefaultInline();
 713         test38(vt);
 714         Asserts.assertEQ(vt.hash(), test31_vt.hash());
 715     }
 716 
 717     @Test(failOn=CALL_Unsafe)
 718     public MyValue1 test39(MyValue1 v) {
 719         v = U.makePrivateBuffer(v);
 720         U.putInt(v, X_OFFSET, rI);
 721         v = U.finishPrivateBuffer(v);
 722         return v;
 723     }
 724 
 725     @DontCompile
 726     public void test39_verifier(boolean warmup) {
 727         MyValue1 v = MyValue1.createWithFieldsInline(rI, rL);
 728         MyValue1 res = test39(v.setX(v, 0));
 729         Asserts.assertEQ(res.hash(), v.hash());
 730     }
 731 
 732     // Test default value type array creation via reflection
 733     @Test()
 734     public Object[] test40(Class<?> componentType, int len) {
 735         Object[] va = (Object[])Array.newInstance(componentType, len);
 736         return va;
 737     }
 738 
 739     @DontCompile
 740     public void test40_verifier(boolean warmup) {
 741         int len = Math.abs(rI) % 42;
 742         Object[] va = test40(MyValue1.class.asIndirectType(), len);
 743         for (int i = 0; i < len; ++i) {
 744             Asserts.assertEQ(va[i], null);
 745         }
 746     }
 747 
 748     // Class.isInstance
 749     @Test()
 750     public boolean test41(Class c, MyValue1? vt) {
 751         return c.isInstance(vt);
 752     }
 753 
 754     @DontCompile
 755     public void test41_verifier(boolean warmup) {
 756         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 757         boolean result = test41(MyValue1.class.asIndirectType(), vt);
 758         Asserts.assertTrue(result);
 759         result = test41(MyValue1.class, vt);
 760         Asserts.assertTrue(result);
 761     }
 762 
 763     @Test()
 764     public boolean test42(Class c, MyValue1? vt) {
 765         return c.isInstance(vt);
 766     }
 767 
 768     @DontCompile
 769     public void test42_verifier(boolean warmup) {
 770         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 771         boolean result = test42(MyValue2.class.asIndirectType(), vt);
 772         Asserts.assertFalse(result);
 773         result = test42(MyValue2.class, vt);
 774         Asserts.assertFalse(result);
 775     }
 776 
 777     // Class.cast
 778     @Test()
 779     public Object test43(Class c, MyValue1? vt) {
 780         return c.cast(vt);
 781     }
 782 
 783     @DontCompile
 784     public void test43_verifier(boolean warmup) {
 785         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 786         Object result = test43(MyValue1.class.asIndirectType(), vt);
 787         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 788         result = test43(MyValue1.class.asIndirectType(), null);
 789         Asserts.assertEQ(result, null);
 790     }
 791 
 792     @Test()
 793     public Object test44(Class c, MyValue1? vt) {
 794         return c.cast(vt);
 795     }
 796 
 797     @DontCompile
 798     public void test44_verifier(boolean warmup) {
 799         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 800         try {
 801             test44(MyValue2.class.asIndirectType(), vt);
 802             throw new RuntimeException("should have thrown");
 803         } catch (ClassCastException cce) {
 804         }
 805     }
 806 
 807     @Test()
 808     public Object test45(MyValue1? vt) {
 809         return MyValue1.class.asIndirectType().cast(vt);
 810     }
 811 
 812     @DontCompile
 813     public void test45_verifier(boolean warmup) {
 814         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 815         Object result = test45(vt);
 816         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 817         result = test45(null);
 818         Asserts.assertEQ(result, null);
 819     }
 820 
 821     @Test()
 822     public Object test46(MyValue1? vt) {
 823         return MyValue2.class.asIndirectType().cast(vt);
 824     }
 825 
 826     @DontCompile
 827     public void test46_verifier(boolean warmup) {
 828         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 829         test46(null);
 830         try {
 831             test46(vt);
 832             throw new RuntimeException("should have thrown");
 833         } catch (ClassCastException cce) {
 834         }
 835     }
 836 
 837     @Test()
 838     public Object test47(MyValue1? vt) {
 839         return MyValue1.class.asPrimaryType().cast(vt);
 840     }
 841 
 842     @DontCompile
 843     public void test47_verifier(boolean warmup) {
 844         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 845         Object result = test47(vt);
 846         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 847         try {
 848             test47(null);
 849             throw new RuntimeException("should have thrown");
 850         } catch (NullPointerException npe) {
 851         }
 852     }
 853 
 854     @Test()
 855     public Object test48(Class c, MyValue1? vt) {
 856         return c.cast(vt);
 857     }
 858 
 859     @DontCompile
 860     public void test48_verifier(boolean warmup) {
 861         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
 862         Object result = test48(MyValue1.class, vt);
 863         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 864         try {
 865             test48(MyValue1.class, null);
 866             throw new RuntimeException("should have thrown");
 867         } catch (NullPointerException npe) {
 868         }
 869     }
 870 
 871     @Test()
 872     public Object test49(MyValue1 vt) {
 873         return MyValue1.class.asIndirectType().cast(vt);
 874     }
 875 
 876     @DontCompile
 877     public void test49_verifier(boolean warmup) {
 878         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 879         Object result = test49(vt);
 880         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 881     }
 882 
 883     @Test()
 884     public Object test50(Class c, Object obj) {
 885         return c.cast(obj);
 886     }
 887 
 888     @DontCompile
 889     public void test50_verifier(boolean warmup) {
 890         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 891         MyValue1[] va  = new MyValue1[42];
 892         MyValue1?[] vba = new MyValue1?[42];
 893         Object result = test50(MyValue1.class, vt);
 894         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 895         result = test50(MyValue1.class.asIndirectType(), vt);
 896         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
 897         result = test50(MyValue1[].class, va);
 898         Asserts.assertEQ(result, va);
 899         result = test50(MyValue1?[].class, vba);
 900         Asserts.assertEQ(result, vba);
 901         result = test50(MyValue1?[].class, va);
 902         Asserts.assertEQ(result, va);
 903         try {
 904             test50(MyValue1.class, null);
 905             throw new RuntimeException("should have thrown");
 906         } catch (NullPointerException npe) {
 907         }
 908         try {
 909             test50(MyValue1[].class, vba);
 910             throw new RuntimeException("should have thrown");
 911         } catch (ClassCastException cce) {
 912         }
 913     }
 914 
 915     // value type array creation via reflection
 916     @Test()
 917     public void test51(int len) {
 918         Object[] va = (Object[])Array.newInstance(MyValue1.class.asIndirectType().asPrimaryType().asIndirectType(), len);
 919         for (int i = 0; i < len; ++i) {
 920             Asserts.assertEQ(va[i], null);
 921         }
 922     }
 923 
 924     @DontCompile
 925     public void test51_verifier(boolean warmup) {
 926         int len = Math.abs(rI) % 42;
 927         test51(len);
 928     }
 929 
 930     // multidimensional value type array creation via reflection
 931     @Test()
 932     public Object[][] test52(int len, int val) {
 933         MyValue1[][] va1 = (MyValue1[][])Array.newInstance(MyValue1[].class, len);
 934         MyValue1?[][] va2 = (MyValue1?[][])Array.newInstance(MyValue1?[].class, len);
 935         Object[][] result;
 936         if (val == 1) {
 937             va1[0] = new MyValue1[1];
 938             result = va1;
 939         } else {
 940             va2[0] = new MyValue1?[1];
 941             result = va2;
 942         }
 943         if (val == 1) {
 944             Asserts.assertEQ(va1[0][0].hash(), ((MyValue1)result[0][0]).hash());
 945         } else {
 946             Asserts.assertEQ(result[0][0], null);
 947             result[0][0] = null;
 948         }
 949         return result;
 950     }
 951 
 952     @DontCompile
 953     public void test52_verifier(boolean warmup) {
 954         test52(1, 1);
 955         test52(1, 2);
 956     }
 957 
 958     @Test()
 959     public Object[][] test53(Class<?> c1, Class<?> c2, int len, int val) {
 960         MyValue1[][] va1 = (MyValue1[][])Array.newInstance(MyValue1[].class, len);
 961         MyValue1?[][] va2 = (MyValue1?[][])Array.newInstance(MyValue1?[].class, len);
 962         Object[][] va3 = (Object[][])Array.newInstance(c1, len);
 963         Object[][] va4 = (Object[][])Array.newInstance(c2, len);
 964         for (int i = 0; i < len; ++i) {
 965             Asserts.assertEQ(va1[i], null);
 966             Asserts.assertEQ(va2[i], null);
 967             Asserts.assertEQ(va3[i], null);
 968             Asserts.assertEQ(va4[i], null);
 969             va1[i] = new MyValue1[1];
 970             va2[i] = new MyValue1?[1];
 971             va3[i] = new MyValue1[1];
 972             va4[i] = new MyValue1?[1];
 973             Asserts.assertEQ(va1[i][0].hash(), ((MyValue1)va3[i][0]).hash());
 974             Asserts.assertEQ(va2[i][0], null);
 975             Asserts.assertEQ(va4[i][0], null);
 976         }
 977         Object[][] result;
 978         if (val == 1) {
 979             result = va1;
 980         } else if (val == 2) {
 981             result = va2;
 982         } else if (val == 3) {
 983             result = va3;
 984         } else {
 985             result = va4;
 986         }
 987         if ((val == 1 || val == 3) && len > 0) {
 988             Asserts.assertEQ(va1[0][0].hash(), ((MyValue1)result[0][0]).hash());
 989         } else if (len > 0) {
 990             Asserts.assertEQ(result[0][0], null);
 991             result[0][0] = null;
 992         }
 993         return result;
 994     }
 995 
 996     @DontCompile
 997     public void test53_verifier(boolean warmup) {
 998         int len = Math.abs(rI) % 42;
 999         test53(MyValue1[].class, MyValue1?[].class, len, 1);
1000         test53(MyValue1[].class, MyValue1?[].class, len, 2);
1001         test53(MyValue1[].class, MyValue1?[].class, len, 3);
1002         test53(MyValue1[].class, MyValue1?[].class, len, 4);
1003     }
1004 
1005     // Test asIndirectType intrinsic with non-value mirror
1006     @Test()
1007     public Class<?> test54(Class<?> c) {
1008         if (c.asIndirectType() != Integer.class) {
1009             throw new RuntimeException("Unexpected class");
1010         }
1011         return Integer.class.asIndirectType();
1012     }
1013 
1014     @DontCompile
1015     public void test54_verifier(boolean warmup) {
1016         Class<?> result = test54(Integer.class);
1017         Asserts.assertEQ(result, Integer.class);
1018     }
1019 
1020     // Test asPrimaryType intrinsic with non-value mirror
1021     @Test()
1022     public Class<?> test55(Class<?> c) {
1023         if (c.asPrimaryType() != Integer.class) {
1024             throw new RuntimeException("Unexpected class");
1025         }
1026         return Integer.class.asPrimaryType();
1027     }
1028 
1029     @DontCompile
1030     public void test55_verifier(boolean warmup) {
1031         Class<?> result = test55(Integer.class);
1032         Asserts.assertEQ(result, Integer.class);
1033     }
1034 }