1 /* 2 * Copyright (c) 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 java.lang.invoke.*; 27 28 import jdk.experimental.value.MethodHandleBuilder; 29 import jdk.experimental.bytecode.MacroCodeBuilder; 30 import jdk.experimental.bytecode.MacroCodeBuilder.CondKind; 31 import jdk.experimental.bytecode.TypeTag; 32 import jdk.test.lib.Asserts; 33 34 /* 35 * @test 36 * @summary Test value types in LWorld. 37 * @modules java.base/jdk.experimental.bytecode 38 * java.base/jdk.experimental.value 39 * @library /testlibrary /test/lib /compiler/whitebox / 40 * @requires os.simpleArch == "x64" 41 * @compile -XDenableValueTypes -XDallowFlattenabilityModifiers TestLWorld.java 42 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 43 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 44 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline 45 * -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten 46 * -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 47 * compiler.valhalla.valuetypes.TestLWorld 48 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 49 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedOops -XX:-UseOptoBiasInlining 50 * -XX:+EnableValhalla -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten 51 * -XX:ValueFieldMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 52 * compiler.valhalla.valuetypes.TestLWorld 53 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 54 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedOops -XX:-UseBiasedLocking 55 * -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:-ValueArrayFlatten 56 * -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0 57 * -DVerifyIR=false compiler.valhalla.valuetypes.TestLWorld 58 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 59 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline -XX:-UseBiasedLocking 60 * -XX:+EnableValhalla -XX:-ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten 61 * -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=0 -XX:ValueArrayElemMaxFlatOops=0 62 * -XX:-MonomorphicArrayCheck 63 * -DVerifyIR=false compiler.valhalla.valuetypes.TestLWorld 64 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 65 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI 66 * -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:-ValueTypeReturnedAsFields -XX:+ValueArrayFlatten 67 * -XX:ValueFieldMaxFlatSize=0 -XX:ValueArrayElemMaxFlatSize=-1 -XX:ValueArrayElemMaxFlatOops=-1 68 * -XX:-MonomorphicArrayCheck 69 * -DVerifyIR=false compiler.valhalla.valuetypes.TestLWorld 70 */ 71 public class TestLWorld extends ValueTypeTest { 72 73 public static void main(String[] args) throws Throwable { 74 TestLWorld test = new TestLWorld(); 75 test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class, Test65Value.class); 76 } 77 78 // Helper methods 79 80 private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); 81 private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, true); 82 83 protected long hash() { 84 return testValue1.hash(); 85 } 86 87 // Test passing a value type as an Object 88 @DontInline 89 public Object test1_dontinline1(Object o) { 90 return o; 91 } 92 93 @DontInline 94 public MyValue1 test1_dontinline2(Object o) { 95 return (MyValue1)o; 96 } 97 98 @ForceInline 99 public Object test1_inline1(Object o) { 100 return o; 101 } 102 103 @ForceInline 104 public MyValue1 test1_inline2(Object o) { 105 return (MyValue1)o; 106 } 107 108 @Test() 109 public MyValue1 test1() { 110 MyValue1 vt = testValue1; 111 vt = (MyValue1)test1_dontinline1(vt); 112 vt = test1_dontinline2(vt); 113 vt = (MyValue1)test1_inline1(vt); 114 vt = test1_inline2(vt); 115 return vt; 116 } 117 118 @DontCompile 119 public void test1_verifier(boolean warmup) { 120 Asserts.assertEQ(test1().hash(), hash()); 121 } 122 123 // Test storing/loading value types to/from Object and value type fields 124 Object objectField1 = null; 125 Object objectField2 = null; 126 Object objectField3 = null; 127 Object objectField4 = null; 128 Object objectField5 = null; 129 Object objectField6 = null; 130 131 __Flattenable MyValue1 valueField1 = testValue1; 132 __Flattenable MyValue1 valueField2 = testValue1; 133 __NotFlattened MyValue1 valueField3 = testValue1; 134 __Flattenable MyValue1 valueField4; 135 __NotFlattened MyValue1 valueField5; 136 137 static __NotFlattened MyValue1 staticValueField1 = testValue1; 138 static __Flattenable MyValue1 staticValueField2 = testValue1; 139 static __Flattenable MyValue1 staticValueField3; 140 static __NotFlattened MyValue1 staticValueField4; 141 142 @DontInline 143 public Object readValueField5() { 144 return (Object)valueField5; 145 } 146 147 @DontInline 148 public Object readStaticValueField4() { 149 return (Object)staticValueField4; 150 } 151 152 @Test() 153 public long test2(MyValue1 vt1, Object vt2) { 154 objectField1 = vt1; 155 objectField2 = (MyValue1)vt2; 156 objectField3 = testValue1; 157 objectField4 = MyValue1.createWithFieldsDontInline(rI, rL); 158 objectField5 = valueField1; 159 objectField6 = valueField3; 160 valueField1 = (MyValue1)objectField1; 161 valueField2 = (MyValue1)vt2; 162 valueField3 = (MyValue1)vt2; 163 staticValueField1 = (MyValue1)objectField1; 164 staticValueField2 = (MyValue1)vt1; 165 // Don't inline these methods because reading NULL will trigger a deoptimization 166 if (readValueField5() != null || readStaticValueField4() != null) { 167 throw new RuntimeException("Should be null"); 168 } 169 return ((MyValue1)objectField1).hash() + ((MyValue1)objectField2).hash() + 170 ((MyValue1)objectField3).hash() + ((MyValue1)objectField4).hash() + 171 ((MyValue1)objectField5).hash() + ((MyValue1)objectField6).hash() + 172 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() + 173 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); 174 } 175 176 @DontCompile 177 public void test2_verifier(boolean warmup) { 178 MyValue1 vt = testValue1; 179 MyValue1 def = MyValue1.createDefaultDontInline(); 180 long result = test2(vt, vt); 181 Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); 182 } 183 184 // Test merging value types and objects 185 @Test() 186 public Object test3(int state) { 187 Object res = null; 188 if (state == 0) { 189 res = new Integer(rI); 190 } else if (state == 1) { 191 res = MyValue1.createWithFieldsInline(rI, rL); 192 } else if (state == 2) { 193 res = MyValue1.createWithFieldsDontInline(rI, rL); 194 } else if (state == 3) { 195 res = (MyValue1)objectField1; 196 } else if (state == 4) { 197 res = valueField1; 198 } else if (state == 5) { 199 res = null; 200 } else if (state == 6) { 201 res = MyValue2.createWithFieldsInline(rI, true); 202 } else if (state == 7) { 203 res = testValue2; 204 } 205 return res; 206 } 207 208 @DontCompile 209 public void test3_verifier(boolean warmup) { 210 objectField1 = valueField1; 211 Object result = null; 212 result = test3(0); 213 Asserts.assertEQ((Integer)result, rI); 214 result = test3(1); 215 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 216 result = test3(2); 217 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 218 result = test3(3); 219 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 220 result = test3(4); 221 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 222 result = test3(5); 223 Asserts.assertEQ(result, null); 224 result = test3(6); 225 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 226 result = test3(7); 227 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 228 } 229 230 // Test merging value types and objects in loops 231 @Test() 232 public Object test4(int iters) { 233 Object res = new Integer(rI); 234 for (int i = 0; i < iters; ++i) { 235 if (res instanceof Integer) { 236 res = MyValue1.createWithFieldsInline(rI, rL); 237 } else { 238 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL); 239 } 240 } 241 return res; 242 } 243 244 @DontCompile 245 public void test4_verifier(boolean warmup) { 246 Integer result1 = (Integer)test4(0); 247 Asserts.assertEQ(result1, rI); 248 int iters = (Math.abs(rI) % 10) + 1; 249 MyValue1 result2 = (MyValue1)test4(iters); 250 MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL); 251 Asserts.assertEQ(result2.hash(), vt.hash()); 252 } 253 254 // Test value types in object variables that are live at safepoint 255 @Test(failOn = ALLOC + STORE + LOOP) 256 public long test5(MyValue1 arg, boolean deopt) { 257 Object vt1 = MyValue1.createWithFieldsInline(rI, rL); 258 Object vt2 = MyValue1.createWithFieldsDontInline(rI, rL); 259 Object vt3 = arg; 260 Object vt4 = valueField1; 261 if (deopt) { 262 // uncommon trap 263 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test5")); 264 } 265 return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + 266 ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); 267 } 268 269 @DontCompile 270 public void test5_verifier(boolean warmup) { 271 long result = test5(valueField1, !warmup); 272 Asserts.assertEQ(result, 4*hash()); 273 } 274 275 // Test comparing value types with objects 276 @Test(failOn = ALLOC + LOAD + STORE + LOOP) 277 public boolean test6(Object arg) { 278 Object vt = MyValue1.createWithFieldsInline(rI, rL); 279 if (vt == arg || vt == (Object)valueField1 || vt == objectField1 || vt == null || 280 arg == vt || (Object)valueField1 == vt || objectField1 == vt || null == vt) { 281 return true; 282 } 283 return false; 284 } 285 286 @DontCompile 287 public void test6_verifier(boolean warmup) { 288 boolean result = test6(null); 289 Asserts.assertFalse(result); 290 } 291 292 // Test correct handling of null-ness of value types 293 294 __NotFlattened MyValue1 nullField; 295 296 @Test 297 @Warmup(10000) // Warmup to make sure 'callTest7WithNull' is compiled 298 public long test7(MyValue1 vt) { 299 long result = 0; 300 try { 301 result = vt.hash(); 302 throw new RuntimeException("NullPointerException expected"); 303 } catch (NullPointerException e) { 304 // Expected 305 } 306 return result; 307 } 308 309 private static final MethodHandle callTest7WithNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 310 "callTest7WithNull", 311 MethodType.methodType(void.class, TestLWorld.class), 312 CODE -> { 313 CODE. 314 aload_0(). 315 aconst_null(). 316 invokevirtual(TestLWorld.class, "test7", "(Lcompiler/valhalla/valuetypes/MyValue1;)J", false). 317 return_(); 318 } 319 ); 320 321 @DontCompile 322 public void test7_verifier(boolean warmup) throws Throwable { 323 long result = (long)callTest7WithNull.invoke(this); 324 Asserts.assertEquals(result, 0L); 325 } 326 327 @Test 328 public long test8(MyValue1 vt) { 329 long result = 0; 330 try { 331 result = vt.hashInterpreted(); 332 throw new RuntimeException("NullPointerException expected"); 333 } catch (NullPointerException e) { 334 // Expected 335 } 336 return result; 337 } 338 339 @DontCompile 340 public void test8_verifier(boolean warmup) { 341 long result = test8(nullField); 342 Asserts.assertEquals(result, 0L); 343 } 344 345 @Test 346 public long test9() { 347 long result = 0; 348 try { 349 if ((Object)nullField != null) { 350 throw new RuntimeException("nullField should be null"); 351 } 352 result = nullField.hash(); 353 throw new RuntimeException("NullPointerException expected"); 354 } catch (NullPointerException e) { 355 // Expected 356 } 357 return result; 358 } 359 360 @DontCompile 361 public void test9_verifier(boolean warmup) { 362 long result = test9(); 363 Asserts.assertEquals(result, 0L); 364 } 365 366 @Test 367 public void test10() { 368 try { 369 valueField1 = nullField; 370 throw new RuntimeException("NullPointerException expected"); 371 } catch (NullPointerException e) { 372 // Expected 373 } 374 } 375 376 @DontCompile 377 public void test10_verifier(boolean warmup) { 378 test10(); 379 } 380 381 @Test 382 public MyValue1 test11(MyValue1 vt) { 383 try { 384 Object o = vt; 385 vt = (MyValue1)o; 386 throw new RuntimeException("NullPointerException expected"); 387 } catch (NullPointerException e) { 388 // Expected 389 } 390 391 // Should not throw 392 vt = test11_dontinline(vt); 393 vt = test11_inline(vt); 394 return vt; 395 } 396 397 @DontCompile 398 public void test11_verifier(boolean warmup) { 399 MyValue1 vt = test11(nullField); 400 Asserts.assertEquals((Object)vt, null); 401 } 402 403 @DontInline 404 public MyValue1 test11_dontinline(MyValue1 vt) { 405 return vt; 406 } 407 408 @ForceInline 409 public MyValue1 test11_inline(MyValue1 vt) { 410 return vt; 411 } 412 413 @Test 414 public MyValue1 test12(Object obj) { 415 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 416 try { 417 vt = (MyValue1)obj; 418 throw new RuntimeException("NullPointerException expected"); 419 } catch (NullPointerException e) { 420 // Expected 421 } 422 return vt; 423 } 424 425 @DontCompile 426 public void test12_verifier(boolean warmup) { 427 MyValue1 vt = test12(null); 428 Asserts.assertEquals(vt.hash(), hash()); 429 } 430 431 private static final MethodHandle getNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 432 "getNull", 433 MethodType.methodType(MyValue1.class), 434 CODE -> { 435 CODE. 436 aconst_null(). 437 areturn(); 438 } 439 ); 440 441 @Test 442 public void test13() throws Throwable { 443 try { 444 valueField1 = (MyValue1)getNull.invoke(); 445 throw new RuntimeException("NullPointerException expected"); 446 } catch (NullPointerException e) { 447 // Expected 448 } 449 nullField = (MyValue1)getNull.invoke(); // Should not throw 450 } 451 452 @DontCompile 453 public void test13_verifier(boolean warmup) throws Throwable { 454 test13(); 455 } 456 457 // null constant 458 private static final MethodHandle setNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 459 "setNull", 460 MethodType.methodType(void.class, TestLWorld.class), 461 CODE -> { 462 CODE. 463 aload_0(). 464 aconst_null(). 465 putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 466 return_(); 467 } 468 ); 469 470 @Test 471 public void test14() throws Throwable { 472 try { 473 setNull.invoke(this); 474 throw new RuntimeException("NullPointerException expected"); 475 } catch (NullPointerException e) { 476 // Expected 477 } 478 } 479 480 @DontCompile 481 public void test14_verifier(boolean warmup) throws Throwable { 482 test14(); 483 } 484 485 // merge of 2 values, one being null 486 @Test 487 public void test15(boolean flag1) { 488 MyValue1 v; 489 if (flag1) { 490 v = valueField1; 491 } else { 492 v = valueField5; 493 } 494 valueField1 = v; 495 } 496 497 @DontCompile 498 public void test15_verifier(boolean warmup) { 499 test15(true); 500 try { 501 test15(false); 502 throw new RuntimeException("NullPointerException expected"); 503 } catch (NullPointerException e) { 504 // Expected 505 } 506 } 507 508 // null constant 509 private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 510 "mergeNull", 511 MethodType.methodType(void.class, TestLWorld.class, boolean.class), 512 CODE -> { 513 CODE. 514 iload_1(). 515 iconst_0(). 516 ifcmp(TypeTag.I, CondKind.EQ, "null"). 517 aload_0(). 518 getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 519 goto_("continue"). 520 label("null"). 521 aconst_null(). 522 label("continue"). 523 aload_0(). 524 swap(). 525 putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 526 return_(); 527 } 528 ); 529 530 @Test 531 public void test16(boolean flag) throws Throwable { 532 mergeNull.invoke(this, flag); 533 } 534 535 @DontCompile 536 public void test16_verifier(boolean warmup) throws Throwable { 537 test16(true); 538 try { 539 test16(false); 540 throw new RuntimeException("NullPointerException expected"); 541 } catch (NullPointerException e) { 542 // Expected 543 } 544 } 545 546 // merge of value and non value 547 @Test 548 public Object test17(boolean flag) { 549 Object res = null; 550 if (flag) { 551 res = valueField1; 552 } else { 553 res = objectField1; 554 } 555 return res; 556 } 557 558 @DontCompile 559 public void test17_verifier(boolean warmup) { 560 test17(true); 561 test17(false); 562 } 563 564 @Test 565 public Object test18(boolean flag) { 566 Object res = null; 567 if (flag) { 568 res = objectField1; 569 } else { 570 res = valueField1; 571 } 572 return res; 573 } 574 575 @DontCompile 576 public void test18_verifier(boolean warmup) { 577 test18(true); 578 test18(false); 579 } 580 581 // null constant 582 private static final MethodHandle mergeNull2 = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 583 "mergeNull2", 584 MethodType.methodType(void.class, TestLWorld.class, boolean.class), 585 CODE -> { 586 CODE. 587 iload_1(). 588 iconst_0(). 589 ifcmp(TypeTag.I, CondKind.EQ, "not_null"). 590 aconst_null(). 591 goto_("continue"). 592 label("not_null"). 593 aload_0(). 594 getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 595 label("continue"). 596 aload_0(). 597 swap(). 598 putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 599 return_(); 600 } 601 ); 602 603 @Test 604 public void test19(boolean flag) throws Throwable { 605 mergeNull2.invoke(this, flag); 606 } 607 608 @DontCompile 609 public void test19_verifier(boolean warmup) throws Throwable { 610 test19(false); 611 try { 612 test19(true); 613 throw new RuntimeException("NullPointerException expected"); 614 } catch (NullPointerException e) { 615 // Expected 616 } 617 } 618 619 // merge of values in a loop, stored in an object local 620 @Test 621 public Object test20() { 622 Object o = valueField1; 623 for (int i = 1; i < 100; i *= 2) { 624 MyValue1 v = (MyValue1)o; 625 o = MyValue1.setX(v, v.x + 1); 626 } 627 return o; 628 } 629 630 @DontCompile 631 public void test20_verifier(boolean warmup) { 632 test20(); 633 } 634 635 // merge of values in an object local 636 public Object test21_helper() { 637 return valueField1; 638 } 639 640 @Test(failOn = ALLOC + LOAD + STORE) 641 public void test21(boolean flag) { 642 Object o = null; 643 if (flag) { 644 o = valueField1; 645 } else { 646 o = test21_helper(); 647 } 648 valueField1 = (MyValue1)o; 649 } 650 651 @DontCompile 652 public void test21_verifier(boolean warmup) { 653 test21(true); 654 test21(false); 655 } 656 657 // null return 658 int test_22_cnt; 659 660 @DontInline 661 public MyValue1 test22_helper() { 662 test_22_cnt++; 663 return valueField5; 664 } 665 666 @Test 667 public void test22() { 668 valueField1 = test22_helper(); 669 } 670 671 @DontCompile 672 public void test22_verifier(boolean warmup) { 673 try { 674 test_22_cnt = 0; 675 test22(); 676 throw new RuntimeException("NullPointerException expected"); 677 } catch (NullPointerException e) { 678 // Expected 679 } 680 if (test_22_cnt != 1) { 681 throw new RuntimeException("call executed twice"); 682 } 683 } 684 685 // null return at virtual call 686 class A { 687 public MyValue1 test23_helper() { 688 return valueField5; 689 } 690 } 691 692 class B extends A { 693 public MyValue1 test23_helper() { 694 return valueField5; 695 } 696 } 697 698 class C extends A { 699 public MyValue1 test23_helper() { 700 return valueField5; 701 } 702 } 703 704 class D extends A { 705 public MyValue1 test23_helper() { 706 return valueField5; 707 } 708 } 709 710 @Test 711 public void test23(A a) { 712 valueField1 = a.test23_helper(); 713 } 714 715 @DontCompile 716 public void test23_verifier(boolean warmup) { 717 A b = new B(); 718 A c = new C(); 719 A d = new D(); 720 try { 721 test23(b); 722 throw new RuntimeException("NullPointerException expected"); 723 } catch (NullPointerException e) { 724 // Expected 725 } 726 try { 727 test23(c); 728 throw new RuntimeException("NullPointerException expected"); 729 } catch (NullPointerException e) { 730 // Expected 731 } 732 try { 733 test23(d); 734 throw new RuntimeException("NullPointerException expected"); 735 } catch (NullPointerException e) { 736 // Expected 737 } 738 } 739 740 741 // Interface tests 742 743 @DontInline 744 public MyInterface test24_dontinline1(MyInterface o) { 745 return o; 746 } 747 748 @DontInline 749 public MyValue1 test24_dontinline2(MyInterface o) { 750 return (MyValue1)o; 751 } 752 753 @ForceInline 754 public MyInterface test24_inline1(MyInterface o) { 755 return o; 756 } 757 758 @ForceInline 759 public MyValue1 test24_inline2(MyInterface o) { 760 return (MyValue1)o; 761 } 762 763 @Test() 764 public MyValue1 test24() { 765 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 766 vt = (MyValue1)test24_dontinline1(vt); 767 vt = test24_dontinline2(vt); 768 vt = (MyValue1)test24_inline1(vt); 769 vt = test24_inline2(vt); 770 return vt; 771 } 772 773 @DontCompile 774 public void test24_verifier(boolean warmup) { 775 Asserts.assertEQ(test24().hash(), hash()); 776 } 777 778 // Test storing/loading value types to/from interface and value type fields 779 MyInterface interfaceField1 = null; 780 MyInterface interfaceField2 = null; 781 MyInterface interfaceField3 = null; 782 MyInterface interfaceField4 = null; 783 MyInterface interfaceField5 = null; 784 MyInterface interfaceField6 = null; 785 786 @DontInline 787 public MyInterface readValueField5AsInterface() { 788 return (MyInterface)valueField5; 789 } 790 791 @DontInline 792 public MyInterface readStaticValueField4AsInterface() { 793 return (MyInterface)staticValueField4; 794 } 795 796 @Test() 797 public long test25(MyValue1 vt1, MyInterface vt2) { 798 interfaceField1 = vt1; 799 interfaceField2 = (MyValue1)vt2; 800 interfaceField3 = MyValue1.createWithFieldsInline(rI, rL); 801 interfaceField4 = MyValue1.createWithFieldsDontInline(rI, rL); 802 interfaceField5 = valueField1; 803 interfaceField6 = valueField3; 804 valueField1 = (MyValue1)interfaceField1; 805 valueField2 = (MyValue1)vt2; 806 valueField3 = (MyValue1)vt2; 807 staticValueField1 = (MyValue1)interfaceField1; 808 staticValueField2 = (MyValue1)vt1; 809 // Don't inline these methods because reading NULL will trigger a deoptimization 810 if (readValueField5AsInterface() != null || readStaticValueField4AsInterface() != null) { 811 throw new RuntimeException("Should be null"); 812 } 813 return ((MyValue1)interfaceField1).hash() + ((MyValue1)interfaceField2).hash() + 814 ((MyValue1)interfaceField3).hash() + ((MyValue1)interfaceField4).hash() + 815 ((MyValue1)interfaceField5).hash() + ((MyValue1)interfaceField6).hash() + 816 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() + 817 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); 818 } 819 820 @DontCompile 821 public void test25_verifier(boolean warmup) { 822 MyValue1 vt = testValue1; 823 MyValue1 def = MyValue1.createDefaultDontInline(); 824 long result = test25(vt, vt); 825 Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); 826 } 827 828 class MyObject implements MyInterface { 829 public int x; 830 831 public MyObject(int x) { 832 this.x = x; 833 } 834 835 @ForceInline 836 public long hash() { 837 return x; 838 } 839 } 840 841 // Test merging value types and interfaces 842 @Test() 843 public MyInterface test26(int state) { 844 MyInterface res = null; 845 if (state == 0) { 846 res = new MyObject(rI); 847 } else if (state == 1) { 848 res = MyValue1.createWithFieldsInline(rI, rL); 849 } else if (state == 2) { 850 res = MyValue1.createWithFieldsDontInline(rI, rL); 851 } else if (state == 3) { 852 res = (MyValue1)objectField1; 853 } else if (state == 4) { 854 res = valueField1; 855 } else if (state == 5) { 856 res = null; 857 } 858 return res; 859 } 860 861 @DontCompile 862 public void test26_verifier(boolean warmup) { 863 objectField1 = valueField1; 864 MyInterface result = null; 865 result = test26(0); 866 Asserts.assertEQ(((MyObject)result).x, rI); 867 result = test26(1); 868 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 869 result = test26(2); 870 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 871 result = test26(3); 872 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 873 result = test26(4); 874 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 875 result = test26(5); 876 Asserts.assertEQ(result, null); 877 } 878 879 // Test merging value types and interfaces in loops 880 @Test() 881 public MyInterface test27(int iters) { 882 MyInterface res = new MyObject(rI); 883 for (int i = 0; i < iters; ++i) { 884 if (res instanceof MyObject) { 885 res = MyValue1.createWithFieldsInline(rI, rL); 886 } else { 887 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL); 888 } 889 } 890 return res; 891 } 892 893 @DontCompile 894 public void test27_verifier(boolean warmup) { 895 MyObject result1 = (MyObject)test27(0); 896 Asserts.assertEQ(result1.x, rI); 897 int iters = (Math.abs(rI) % 10) + 1; 898 MyValue1 result2 = (MyValue1)test27(iters); 899 MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL); 900 Asserts.assertEQ(result2.hash(), vt.hash()); 901 } 902 903 // Test value types in interface variables that are live at safepoint 904 @Test(failOn = ALLOC + STORE + LOOP) 905 public long test28(MyValue1 arg, boolean deopt) { 906 MyInterface vt1 = MyValue1.createWithFieldsInline(rI, rL); 907 MyInterface vt2 = MyValue1.createWithFieldsDontInline(rI, rL); 908 MyInterface vt3 = arg; 909 MyInterface vt4 = valueField1; 910 if (deopt) { 911 // uncommon trap 912 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test5")); 913 } 914 return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + 915 ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); 916 } 917 918 @DontCompile 919 public void test28_verifier(boolean warmup) { 920 long result = test28(valueField1, !warmup); 921 Asserts.assertEQ(result, 4*hash()); 922 } 923 924 // Test comparing value types with interfaces 925 @Test(failOn = ALLOC + LOAD + STORE + LOOP) 926 public boolean test29(Object arg) { 927 MyInterface vt = MyValue1.createWithFieldsInline(rI, rL); 928 if (vt == arg || vt == (MyInterface)valueField1 || vt == interfaceField1 || vt == null || 929 arg == vt || (MyInterface)valueField1 == vt || interfaceField1 == vt || null == vt) { 930 return true; 931 } 932 return false; 933 } 934 935 @DontCompile 936 public void test29_verifier(boolean warmup) { 937 boolean result = test29(null); 938 Asserts.assertFalse(result); 939 } 940 941 // Test subtype check when casting to value type 942 @Test 943 public MyValue1 test30(MyValue1 vt, Object obj) { 944 try { 945 vt = (MyValue1)obj; 946 throw new RuntimeException("ClassCastException expected"); 947 } catch (ClassCastException e) { 948 // Expected 949 } 950 return vt; 951 } 952 953 @DontCompile 954 public void test30_verifier(boolean warmup) { 955 MyValue1 vt = testValue1; 956 MyValue1 result = test30(vt, new Integer(rI)); 957 Asserts.assertEquals(result.hash(), vt.hash()); 958 } 959 960 @Test 961 public MyValue1 test31(MyValue1 vt) { 962 Object obj = vt; 963 vt = (MyValue1)obj; 964 return vt; 965 } 966 967 @DontCompile 968 public void test31_verifier(boolean warmup) { 969 MyValue1 vt = testValue1; 970 MyValue1 result = test31(vt); 971 Asserts.assertEquals(result.hash(), vt.hash()); 972 } 973 974 @Test 975 public void test32(MyValue1 vt) { 976 Object obj = vt; 977 try { 978 MyValue2 vt2 = (MyValue2)obj; 979 throw new RuntimeException("ClassCastException expected"); 980 } catch (ClassCastException e) { 981 // Expected 982 } 983 } 984 985 @DontCompile 986 public void test32_verifier(boolean warmup) { 987 test32(valueField1); 988 } 989 990 @Test 991 public void test33(MyValue1 vt) { 992 Object obj = vt; 993 try { 994 Integer i = (Integer)obj; 995 throw new RuntimeException("ClassCastException expected"); 996 } catch (ClassCastException e) { 997 // Expected 998 } 999 } 1000 1001 @DontCompile 1002 public void test33_verifier(boolean warmup) { 1003 test33(valueField1); 1004 } 1005 1006 1007 // Array tests 1008 1009 private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1, 1010 testValue1, 1011 testValue1}; 1012 1013 private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array, 1014 testValue1Array, 1015 testValue1Array}; 1016 1017 private static final MyValue2[] testValue2Array = new MyValue2[] {testValue2, 1018 testValue2, 1019 testValue2}; 1020 1021 private static final Integer[] testIntegerArray = new Integer[42]; 1022 1023 // Test load from (flattened) value type array disguised as object array 1024 @Test() 1025 public Object test34(Object[] oa, int index) { 1026 return oa[index]; 1027 } 1028 1029 @DontCompile 1030 public void test34_verifier(boolean warmup) { 1031 MyValue1 result = (MyValue1)test34(testValue1Array, Math.abs(rI) % 3); 1032 Asserts.assertEQ(result.hash(), hash()); 1033 } 1034 1035 // Test load from (flattened) value type array disguised as interface array 1036 @Test() 1037 public Object test35(MyInterface[] ia, int index) { 1038 return ia[index]; 1039 } 1040 1041 @DontCompile 1042 public void test35_verifier(boolean warmup) { 1043 MyValue1 result = (MyValue1)test35(testValue1Array, Math.abs(rI) % 3); 1044 Asserts.assertEQ(result.hash(), hash()); 1045 } 1046 1047 // Test value store to (flattened) value type array disguised as object array 1048 1049 @ForceInline 1050 public void test36_inline(Object[] oa, Object o, int index) { 1051 oa[index] = o; 1052 } 1053 1054 @Test() 1055 public void test36(Object[] oa, MyValue1 vt, int index) { 1056 test36_inline(oa, vt, index); 1057 } 1058 1059 @DontCompile 1060 public void test36_verifier(boolean warmup) { 1061 int index = Math.abs(rI) % 3; 1062 MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1063 test36(testValue1Array, vt, index); 1064 Asserts.assertEQ(testValue1Array[index].hash(), vt.hash()); 1065 testValue1Array[index] = testValue1; 1066 try { 1067 test36(testValue2Array, vt, index); 1068 throw new RuntimeException("No ArrayStoreException thrown"); 1069 } catch (ArrayStoreException e) { 1070 // Expected 1071 } 1072 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 1073 } 1074 1075 @ForceInline 1076 public void test37_inline(Object[] oa, Object o, int index) { 1077 oa[index] = o; 1078 } 1079 1080 @Test() 1081 public void test37(Object[] oa, MyValue1 vt, int index) { 1082 test37_inline(oa, vt, index); 1083 } 1084 1085 @DontCompile 1086 public void test37_verifier(boolean warmup) { 1087 int index = Math.abs(rI) % 3; 1088 try { 1089 test37(testIntegerArray, testValue1, index); 1090 throw new RuntimeException("No ArrayStoreException thrown"); 1091 } catch (ArrayStoreException e) { 1092 // Expected 1093 } 1094 } 1095 1096 @ForceInline 1097 public void test38_inline(Object[] oa, Object o, int index) { 1098 oa[index] = o; 1099 } 1100 1101 @Test() 1102 public void test38(Object[] oa, MyValue1 vt, int index) { 1103 test38_inline(oa, vt, index); 1104 } 1105 1106 @DontCompile 1107 public void test38_verifier(boolean warmup) { 1108 int index = Math.abs(rI) % 3; 1109 try { 1110 test38(null, testValue1, index); 1111 throw new RuntimeException("No NPE thrown"); 1112 } catch (NullPointerException e) { 1113 // Expected 1114 } 1115 } 1116 1117 // Test value store to (flattened) value type array disguised as interface array 1118 1119 @ForceInline 1120 public void test39_inline(MyInterface[] ia, MyInterface i, int index) { 1121 ia[index] = i; 1122 } 1123 1124 @Test() 1125 public void test39(MyInterface[] ia, MyValue1 vt, int index) { 1126 test39_inline(ia, vt, index); 1127 } 1128 1129 @DontCompile 1130 public void test39_verifier(boolean warmup) { 1131 int index = Math.abs(rI) % 3; 1132 MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1133 test39(testValue1Array, vt, index); 1134 Asserts.assertEQ(testValue1Array[index].hash(), vt.hash()); 1135 testValue1Array[index] = testValue1; 1136 try { 1137 test39(testValue2Array, vt, index); 1138 throw new RuntimeException("No ArrayStoreException thrown"); 1139 } catch (ArrayStoreException e) { 1140 // Expected 1141 } 1142 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 1143 } 1144 1145 @ForceInline 1146 public void test40_inline(MyInterface[] ia, MyInterface i, int index) { 1147 ia[index] = i; 1148 } 1149 1150 @Test() 1151 public void test40(MyInterface[] ia, MyValue1 vt, int index) { 1152 test40_inline(ia, vt, index); 1153 } 1154 1155 @DontCompile 1156 public void test40_verifier(boolean warmup) { 1157 int index = Math.abs(rI) % 3; 1158 try { 1159 test40(null, testValue1, index); 1160 throw new RuntimeException("No NPE thrown"); 1161 } catch (NullPointerException e) { 1162 // Expected 1163 } 1164 } 1165 1166 // Test object store to (flattened) value type array disguised as object array 1167 1168 @ForceInline 1169 public void test41_inline(Object[] oa, Object o, int index) { 1170 oa[index] = o; 1171 } 1172 1173 @Test() 1174 public void test41(Object[] oa, Object o, int index) { 1175 test41_inline(oa, o, index); 1176 } 1177 1178 @DontCompile 1179 public void test41_verifier(boolean warmup) { 1180 int index = Math.abs(rI) % 3; 1181 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1182 test41(testValue1Array, vt1, index); 1183 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1184 try { 1185 test41(testValue1Array, testValue2, index); 1186 throw new RuntimeException("No ArrayStoreException thrown"); 1187 } catch (ArrayStoreException e) { 1188 // Expected 1189 } 1190 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1191 testValue1Array[index] = testValue1; 1192 } 1193 1194 @ForceInline 1195 public void test42_inline(Object[] oa, Object o, int index) { 1196 oa[index] = o; 1197 } 1198 1199 @Test() 1200 public void test42(Object[] oa, Object o, int index) { 1201 test42_inline(oa, o, index); 1202 } 1203 1204 @DontCompile 1205 public void test42_verifier(boolean warmup) { 1206 int index = Math.abs(rI) % 3; 1207 try { 1208 test42(testValue2Array, testValue1, index); 1209 throw new RuntimeException("No ArrayStoreException thrown"); 1210 } catch (ArrayStoreException e) { 1211 // Expected 1212 } 1213 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 1214 } 1215 1216 @ForceInline 1217 public void test43_inline(Object[] oa, Object o, int index) { 1218 oa[index] = o; 1219 } 1220 1221 @Test() 1222 public void test43(Object[] oa, Object o, int index) { 1223 test43_inline(oa, o, index); 1224 } 1225 1226 @DontCompile 1227 public void test43_verifier(boolean warmup) { 1228 int index = Math.abs(rI) % 3; 1229 try { 1230 test43(testIntegerArray, testValue1, index); 1231 throw new RuntimeException("No ArrayStoreException thrown"); 1232 } catch (ArrayStoreException e) { 1233 // Expected 1234 } 1235 } 1236 1237 // Test value store to (flattened) value type array disguised as interface array 1238 1239 @ForceInline 1240 public void test43_inline(MyInterface[] ia, MyInterface i, int index) { 1241 ia[index] = i; 1242 } 1243 1244 @Test() 1245 public void test44(MyInterface[] ia, MyInterface i, int index) { 1246 test43_inline(ia, i, index); 1247 } 1248 1249 @DontCompile 1250 public void test44_verifier(boolean warmup) { 1251 int index = Math.abs(rI) % 3; 1252 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1253 test44(testValue1Array, vt1, index); 1254 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1255 try { 1256 test44(testValue1Array, testValue2, index); 1257 throw new RuntimeException("No ArrayStoreException thrown"); 1258 } catch (ArrayStoreException e) { 1259 // Expected 1260 } 1261 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1262 testValue1Array[index] = testValue1; 1263 } 1264 1265 @ForceInline 1266 public void test45_inline(MyInterface[] ia, MyInterface i, int index) { 1267 ia[index] = i; 1268 } 1269 1270 @Test() 1271 public void test45(MyInterface[] ia, MyInterface i, int index) { 1272 test45_inline(ia, i, index); 1273 } 1274 1275 @DontCompile 1276 public void test45_verifier(boolean warmup) { 1277 int index = Math.abs(rI) % 3; 1278 try { 1279 test45(testValue2Array, testValue1, index); 1280 throw new RuntimeException("No ArrayStoreException thrown"); 1281 } catch (ArrayStoreException e) { 1282 // Expected 1283 } 1284 } 1285 1286 // Test writing null to a (flattened) value type array disguised as object array 1287 1288 @ForceInline 1289 public void test46_inline(Object[] oa, Object o, int index) { 1290 oa[index] = o; 1291 } 1292 1293 @Test() 1294 public void test46(Object[] oa, Object o, int index) { 1295 test46_inline(oa, o, index); 1296 } 1297 1298 @DontCompile 1299 public void test46_verifier(boolean warmup) { 1300 int index = Math.abs(rI) % 3; 1301 try { 1302 test46(testValue1Array, null, index); 1303 throw new RuntimeException("No NPE thrown"); 1304 } catch (NullPointerException e) { 1305 // Expected 1306 } 1307 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1308 } 1309 1310 // Test writing constant null to a (flattened) value type array disguised as object array 1311 1312 @ForceInline 1313 public void test47_inline(Object[] oa, Object o, int index) { 1314 oa[index] = o; 1315 } 1316 1317 @Test() 1318 public void test47(Object[] oa, int index) { 1319 test47_inline(oa, null, index); 1320 } 1321 1322 @DontCompile 1323 public void test47_verifier(boolean warmup) { 1324 int index = Math.abs(rI) % 3; 1325 try { 1326 test47(testValue1Array, index); 1327 throw new RuntimeException("No NPE thrown"); 1328 } catch (NullPointerException e) { 1329 // Expected 1330 } 1331 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1332 } 1333 1334 // Test writing null to a (flattened) value type array 1335 1336 @ForceInline 1337 public void test48_inline(Object[] oa, Object o, int index) { 1338 oa[index] = o; 1339 } 1340 1341 @Test() 1342 public void test48(MyValue1[] va, int index) { 1343 test48_inline(va, nullField, index); 1344 } 1345 1346 @DontCompile 1347 public void test48_verifier(boolean warmup) { 1348 int index = Math.abs(rI) % 3; 1349 try { 1350 test48(testValue1Array, index); 1351 throw new RuntimeException("No NPE thrown"); 1352 } catch (NullPointerException e) { 1353 // Expected 1354 } 1355 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1356 } 1357 1358 // Test writing constant null to a (flattened) value type array 1359 1360 private static final MethodHandle setArrayElementNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 1361 "setArrayElementNull", 1362 MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class), 1363 CODE -> { 1364 CODE. 1365 aload_1(). 1366 iload_2(). 1367 aconst_null(). 1368 aastore(). 1369 return_(); 1370 } 1371 ); 1372 1373 @Test() 1374 public void test49(MyValue1[] va, int index) throws Throwable { 1375 setArrayElementNull.invoke(this, va, index); 1376 } 1377 1378 @DontCompile 1379 public void test49_verifier(boolean warmup) throws Throwable { 1380 int index = Math.abs(rI) % 3; 1381 try { 1382 test49(testValue1Array, index); 1383 throw new RuntimeException("No NPE thrown"); 1384 } catch (NullPointerException e) { 1385 // Expected 1386 } 1387 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1388 } 1389 1390 // Test writing a value type to a null value type array 1391 @Test() 1392 public void test50(MyValue1[] va, MyValue1 vt, int index) { 1393 va[index] = vt; 1394 } 1395 1396 @DontCompile 1397 public void test50_verifier(boolean warmup) { 1398 int index = Math.abs(rI) % 3; 1399 try { 1400 test50(null, testValue1Array[index], index); 1401 throw new RuntimeException("No NPE thrown"); 1402 } catch (NullPointerException e) { 1403 // Expected 1404 } 1405 } 1406 1407 // Test incremental inlining 1408 1409 @ForceInline 1410 public void test51_inline(Object[] oa, Object o, int index) { 1411 oa[index] = o; 1412 } 1413 1414 @Test() 1415 public void test51(MyValue1[] va, Object o, int index) { 1416 test51_inline(va, o, index); 1417 } 1418 1419 @DontCompile 1420 public void test51_verifier(boolean warmup) { 1421 int index = Math.abs(rI) % 3; 1422 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1423 test51(testValue1Array, vt1, index); 1424 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1425 try { 1426 test51(testValue1Array, testValue2, index); 1427 throw new RuntimeException("No ArrayStoreException thrown"); 1428 } catch (ArrayStoreException e) { 1429 // Expected 1430 } 1431 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1432 testValue1Array[index] = testValue1; 1433 } 1434 1435 // Test merging of value type arrays 1436 1437 @ForceInline 1438 public Object[] test52_inline() { 1439 return new MyValue1[42]; 1440 } 1441 1442 @Test() 1443 public Object[] test52(Object[] oa, Object o, int i1, int i2, int num) { 1444 Object[] result = null; 1445 switch (num) { 1446 case 0: 1447 result = test52_inline(); 1448 break; 1449 case 1: 1450 result = oa; 1451 break; 1452 case 2: 1453 result = testValue1Array; 1454 break; 1455 case 3: 1456 result = testValue2Array; 1457 break; 1458 case 4: 1459 result = testIntegerArray; 1460 break; 1461 case 5: 1462 result = null; 1463 break; 1464 case 6: 1465 result = testValue1Array2; 1466 break; 1467 } 1468 result[i1] = result[i2]; 1469 result[i2] = o; 1470 return result; 1471 } 1472 1473 @DontCompile 1474 public void test52_verifier(boolean warmup) { 1475 int index = Math.abs(rI) % 3; 1476 MyValue1[] va = new MyValue1[42]; 1477 Object[] result = test52(null, testValue1, index, index, 0); 1478 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1479 result = test52(testValue1Array, testValue1, index, index, 1); 1480 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1481 result = test52(null, testValue1, index, index, 2); 1482 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1483 result = test52(null, testValue2, index, index, 3); 1484 Asserts.assertEQ(((MyValue2)result[index]).hash(), testValue2.hash()); 1485 try { 1486 result = test52(null, null, index, index, 3); 1487 throw new RuntimeException("No NPE thrown"); 1488 } catch (NullPointerException e) { 1489 // Expected 1490 } 1491 result = test52(null, null, index, index, 4); 1492 try { 1493 result = test52(null, testValue1, index, index, 4); 1494 throw new RuntimeException("No ArrayStoreException thrown"); 1495 } catch (ArrayStoreException e) { 1496 // Expected 1497 } 1498 try { 1499 result = test52(null, testValue1, index, index, 5); 1500 throw new RuntimeException("No NPE thrown"); 1501 } catch (NullPointerException e) { 1502 // Expected 1503 } 1504 result = test52(null, testValue1Array, index, index, 6); 1505 Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash()); 1506 } 1507 1508 // Same as above but merging into Object instead of Object[] 1509 @Test() 1510 public Object test53(Object oa, Object o, int i1, int i2, int num) { 1511 Object result = null; 1512 switch (num) { 1513 case 0: 1514 result = test52_inline(); 1515 break; 1516 case 1: 1517 result = oa; 1518 break; 1519 case 2: 1520 result = testValue1Array; 1521 break; 1522 case 3: 1523 result = testValue2Array; 1524 break; 1525 case 4: 1526 result = testIntegerArray; 1527 break; 1528 case 5: 1529 result = null; 1530 break; 1531 case 6: 1532 result = testValue1; 1533 break; 1534 case 7: 1535 result = testValue2; 1536 break; 1537 case 8: 1538 result = MyValue1.createWithFieldsInline(rI, rL); 1539 break; 1540 case 9: 1541 result = new Integer(42); 1542 break; 1543 case 10: 1544 result = testValue1Array2; 1545 break; 1546 } 1547 if (result instanceof Object[]) { 1548 ((Object[])result)[i1] = ((Object[])result)[i2]; 1549 ((Object[])result)[i2] = o; 1550 } 1551 return result; 1552 } 1553 1554 @DontCompile 1555 public void test53_verifier(boolean warmup) { 1556 int index = Math.abs(rI) % 3; 1557 MyValue1[] va = new MyValue1[42]; 1558 Object result = test53(null, testValue1, index, index, 0); 1559 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1560 result = test53(testValue1Array, testValue1, index, index, 1); 1561 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1562 result = test53(null, testValue1, index, index, 2); 1563 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1564 result = test53(null, testValue2, index, index, 3); 1565 Asserts.assertEQ(((MyValue2[])result)[index].hash(), testValue2.hash()); 1566 try { 1567 result = test53(null, null, index, index, 3); 1568 throw new RuntimeException("No NPE thrown"); 1569 } catch (NullPointerException e) { 1570 // Expected 1571 } 1572 result = test53(null, null, index, index, 4); 1573 try { 1574 result = test53(null, testValue1, index, index, 4); 1575 throw new RuntimeException("No ArrayStoreException thrown"); 1576 } catch (ArrayStoreException e) { 1577 // Expected 1578 } 1579 result = test53(null, testValue1, index, index, 5); 1580 Asserts.assertEQ(result, null); 1581 result = test53(null, testValue1, index, index, 6); 1582 Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash()); 1583 result = test53(null, testValue1, index, index, 7); 1584 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 1585 result = test53(null, testValue1, index, index, 8); 1586 Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash()); 1587 result = test53(null, testValue1, index, index, 9); 1588 Asserts.assertEQ(((Integer)result), 42); 1589 result = test53(null, testValue1Array, index, index, 10); 1590 Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash()); 1591 } 1592 1593 // Test instanceof with value types and arrays 1594 @Test() 1595 public long test54(Object o, int index) { 1596 if (o instanceof MyValue1) { 1597 return ((MyValue1)o).hashInterpreted(); 1598 } else if (o instanceof MyValue1[]) { 1599 return ((MyValue1[])o)[index].hashInterpreted(); 1600 } else if (o instanceof MyValue2) { 1601 return ((MyValue2)o).hash(); 1602 } else if (o instanceof MyValue2[]) { 1603 return ((MyValue2[])o)[index].hash(); 1604 } else if (o instanceof MyValue1[][]) { 1605 return ((MyValue1[][])o)[index][index].hash(); 1606 } else if (o instanceof Long) { 1607 return (long)o; 1608 } 1609 return 0; 1610 } 1611 1612 @DontCompile 1613 public void test54_verifier(boolean warmup) { 1614 int index = Math.abs(rI) % 3; 1615 long result = test54(testValue1, 0); 1616 Asserts.assertEQ(result, testValue1.hash()); 1617 result = test54(testValue1Array, index); 1618 Asserts.assertEQ(result, testValue1.hash()); 1619 result = test54(testValue2, index); 1620 Asserts.assertEQ(result, testValue2.hash()); 1621 result = test54(testValue2Array, index); 1622 Asserts.assertEQ(result, testValue2.hash()); 1623 result = test54(testValue1Array2, index); 1624 Asserts.assertEQ(result, testValue1.hash()); 1625 result = test54(new Long(42), index); 1626 Asserts.assertEQ(result, 42L); 1627 } 1628 1629 // Test for bug in Escape Analysis 1630 @DontInline 1631 public void test55_dontinline(Object o) { 1632 Asserts.assertEQ(o, rI); 1633 } 1634 1635 @Test() 1636 public void test55() { 1637 MyValue1[] vals = new MyValue1[] {testValue1}; 1638 test55_dontinline(vals[0].oa[0]); 1639 test55_dontinline(vals[0].oa[0]); 1640 } 1641 1642 @DontCompile 1643 public void test55_verifier(boolean warmup) { 1644 test55(); 1645 } 1646 1647 // Test for bug in Escape Analysis 1648 private static __NotFlattened final MyValue1 test56VT1 = MyValue1.createWithFieldsInline(rI, rL); 1649 private static __NotFlattened final MyValue1 test56VT2 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1650 1651 @Test() 1652 public void test56() { 1653 MyValue1[] vals = new MyValue1[] {test56VT1, test56VT2}; 1654 Asserts.assertEQ(vals[0].hash(), test56VT1.hash()); 1655 Asserts.assertEQ(vals[1].hash(), test56VT2.hash()); 1656 } 1657 1658 @DontCompile 1659 public void test56_verifier(boolean warmup) { 1660 if (!warmup) test56(); // We need -Xcomp behavior 1661 } 1662 1663 // Test for bug in Escape Analysis 1664 @Test() 1665 public long test57(boolean deopt) { 1666 MyValue1[] vals = new MyValue1[] {test56VT1, test56VT2}; 1667 1668 if (deopt) { 1669 // uncommon trap 1670 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test57")); 1671 Asserts.assertEQ(vals[0].hash(), test56VT1.hash()); 1672 Asserts.assertEQ(vals[1].hash(), test56VT2.hash()); 1673 } 1674 1675 return vals[0].hash(); 1676 } 1677 1678 @DontCompile 1679 public void test57_verifier(boolean warmup) { 1680 test57(!warmup); 1681 } 1682 1683 // Tests writing an array element with a (statically known) incompatible type 1684 private static final MethodHandle setArrayElementIncompatible = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 1685 "setArrayElementIncompatible", 1686 MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class), 1687 CODE -> { 1688 CODE. 1689 aload_1(). 1690 iload_2(). 1691 aload_3(). 1692 aastore(). 1693 return_(); 1694 } 1695 ); 1696 1697 @Test() 1698 public void test58(MyValue1[] va, int index, MyValue2 v) throws Throwable { 1699 setArrayElementIncompatible.invoke(this, va, index, v); 1700 } 1701 1702 @DontCompile 1703 public void test58_verifier(boolean warmup) throws Throwable { 1704 int index = Math.abs(rI) % 3; 1705 try { 1706 test58(testValue1Array, index, testValue2); 1707 throw new RuntimeException("No ArrayStoreException thrown"); 1708 } catch (ArrayStoreException e) { 1709 // Expected 1710 } 1711 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1712 } 1713 1714 // Tests writing an array element with a (statically known) incompatible type 1715 @ForceInline 1716 public void test59_inline(Object[] oa, Object o, int index) { 1717 oa[index] = o; 1718 } 1719 1720 @Test() 1721 public void test59(MyValue1[] va, int index, MyValue2 v) throws Throwable { 1722 test59_inline(va, v, index); 1723 } 1724 1725 @DontCompile 1726 public void test59_verifier(boolean warmup) throws Throwable { 1727 int index = Math.abs(rI) % 3; 1728 try { 1729 test59(testValue1Array, index, testValue2); 1730 throw new RuntimeException("No ArrayStoreException thrown"); 1731 } catch (ArrayStoreException e) { 1732 // Expected 1733 } 1734 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1735 } 1736 1737 // instanceof tests with values 1738 @Test 1739 public boolean test60(MyValue1 vt) { 1740 Object obj = vt; 1741 return obj instanceof MyValue1; 1742 } 1743 1744 @DontCompile 1745 public void test60_verifier(boolean warmup) { 1746 MyValue1 vt = testValue1; 1747 boolean result = test60(vt); 1748 Asserts.assertTrue(result); 1749 } 1750 1751 @Test 1752 public boolean test61(MyValue1 vt) { 1753 Object obj = vt; 1754 return obj instanceof MyValue2; 1755 } 1756 1757 @DontCompile 1758 public void test61_verifier(boolean warmup) { 1759 MyValue1 vt = testValue1; 1760 boolean result = test61(vt); 1761 Asserts.assertFalse(result); 1762 } 1763 1764 @Test 1765 public boolean test62(Object obj) { 1766 return obj instanceof MyValue1; 1767 } 1768 1769 @DontCompile 1770 public void test62_verifier(boolean warmup) { 1771 MyValue1 vt = testValue1; 1772 boolean result = test62(vt); 1773 Asserts.assertTrue(result); 1774 } 1775 1776 @Test 1777 public boolean test63(Object obj) { 1778 return obj instanceof MyValue2; 1779 } 1780 1781 @DontCompile 1782 public void test63_verifier(boolean warmup) { 1783 MyValue1 vt = testValue1; 1784 boolean result = test63(vt); 1785 Asserts.assertFalse(result); 1786 } 1787 1788 @Test 1789 public boolean test64(Object obj) { 1790 return obj instanceof MyValue1; 1791 } 1792 1793 @DontCompile 1794 public void test64_verifier(boolean warmup) { 1795 boolean result = test63(new Integer(42)); 1796 Asserts.assertFalse(result); 1797 } 1798 1799 // Value type with some non-flattened fields 1800 __ByValue final class Test65Value { 1801 final Object objectField1 = null; 1802 final Object objectField2 = null; 1803 final Object objectField3 = null; 1804 final Object objectField4 = null; 1805 final Object objectField5 = null; 1806 final Object objectField6 = null; 1807 1808 final __Flattenable MyValue1 valueField1; 1809 final __Flattenable MyValue1 valueField2; 1810 final __NotFlattened MyValue1 valueField3; 1811 final __Flattenable MyValue1 valueField4; 1812 final __NotFlattened MyValue1 valueField5; 1813 1814 private Test65Value() { 1815 valueField1 = testValue1; 1816 valueField2 = testValue1; 1817 valueField3 = testValue1; 1818 valueField4 = MyValue1.createDefaultDontInline(); 1819 valueField5 = MyValue1.createDefaultDontInline(); 1820 } 1821 1822 public Test65Value init() { 1823 Test65Value vt = __WithField(this.valueField1, testValue1); 1824 vt = __WithField(vt.valueField2, testValue1); 1825 vt = __WithField(vt.valueField3, testValue1); 1826 return vt; 1827 } 1828 1829 @ForceInline 1830 public long test(Test65Value holder, MyValue1 vt1, Object vt2) { 1831 holder = __WithField(holder.objectField1, vt1); 1832 holder = __WithField(holder.objectField2, (MyValue1)vt2); 1833 holder = __WithField(holder.objectField3, testValue1); 1834 holder = __WithField(holder.objectField4, MyValue1.createWithFieldsDontInline(rI, rL)); 1835 holder = __WithField(holder.objectField5, holder.valueField1); 1836 holder = __WithField(holder.objectField6, holder.valueField3); 1837 holder = __WithField(holder.valueField1, (MyValue1)holder.objectField1); 1838 holder = __WithField(holder.valueField2, (MyValue1)vt2); 1839 holder = __WithField(holder.valueField3, (MyValue1)vt2); 1840 1841 return ((MyValue1)holder.objectField1).hash() + 1842 ((MyValue1)holder.objectField2).hash() + 1843 ((MyValue1)holder.objectField3).hash() + 1844 ((MyValue1)holder.objectField4).hash() + 1845 ((MyValue1)holder.objectField5).hash() + 1846 ((MyValue1)holder.objectField6).hash() + 1847 holder.valueField1.hash() + 1848 holder.valueField2.hash() + 1849 holder.valueField3.hash() + 1850 holder.valueField4.hashPrimitive(); 1851 } 1852 } 1853 1854 // Same as test2 but with field holder being a value type 1855 @Test() 1856 public long test65(Test65Value holder, MyValue1 vt1, Object vt2) { 1857 return holder.test(holder, vt1, vt2); 1858 } 1859 1860 @DontCompile 1861 public void test65_verifier(boolean warmup) { 1862 MyValue1 vt = testValue1; 1863 MyValue1 def = MyValue1.createDefaultDontInline(); 1864 Test65Value holder = __MakeDefault Test65Value(); 1865 Asserts.assertEQ(testValue1.hash(), vt.hash()); 1866 holder = holder.init(); 1867 Asserts.assertEQ(holder.valueField1.hash(), vt.hash()); 1868 long result = test65(holder, vt, vt); 1869 Asserts.assertEQ(result, 9*vt.hash() + def.hashPrimitive()); 1870 } 1871 1872 // Access non-flattened, uninitialized value type field with value type holder 1873 @Test() 1874 public void test66(Test65Value holder) { 1875 if ((Object)holder.valueField5 != null) { 1876 throw new RuntimeException("Should be null"); 1877 } 1878 } 1879 1880 @DontCompile 1881 public void test66_verifier(boolean warmup) { 1882 Test65Value vt = __MakeDefault Test65Value(); 1883 test66(vt); 1884 } 1885 1886 // Merging value types of different types 1887 @Test() 1888 public Object test67(Object o, boolean b) { 1889 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1890 return b ? vt : o; 1891 } 1892 1893 @DontCompile 1894 public void test67_verifier(boolean warmup) { 1895 test67(new Object(), false); 1896 MyValue1 result = (MyValue1)test67(new Object(), true); 1897 Asserts.assertEQ(result.hash(), hash()); 1898 } 1899 1900 @Test() 1901 public Object test68(boolean b) { 1902 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1903 return b ? vt : testValue2; 1904 } 1905 1906 @DontCompile 1907 public void test68_verifier(boolean warmup) { 1908 MyValue1 result1 = (MyValue1)test68(true); 1909 Asserts.assertEQ(result1.hash(), hash()); 1910 MyValue2 result2 = (MyValue2)test68(false); 1911 Asserts.assertEQ(result2.hash(), testValue2.hash()); 1912 } 1913 1914 @Test() 1915 public Object test69(boolean b) { 1916 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI, rL); 1917 MyValue2 vt2 = MyValue2.createWithFieldsInline(rI, true); 1918 return b ? vt1 : vt2; 1919 } 1920 1921 @DontCompile 1922 public void test69_verifier(boolean warmup) { 1923 MyValue1 result1 = (MyValue1)test69(true); 1924 Asserts.assertEQ(result1.hash(), hash()); 1925 MyValue2 result2 = (MyValue2)test69(false); 1926 Asserts.assertEQ(result2.hash(), testValue2.hash()); 1927 } 1928 1929 // Test synchronization on value types 1930 @Test() 1931 public void test70(Object vt) { 1932 synchronized (vt) { 1933 throw new RuntimeException("test70 failed: synchronization on value type should not succeed"); 1934 } 1935 } 1936 1937 @DontCompile 1938 public void test70_verifier(boolean warmup) { 1939 try { 1940 test70(testValue1); 1941 throw new RuntimeException("test70 failed: no exception thrown"); 1942 } catch (IllegalMonitorStateException ex) { 1943 // Expected 1944 } 1945 } 1946 1947 @ForceInline 1948 public void test71_inline(Object vt) { 1949 synchronized (vt) { 1950 throw new RuntimeException("test71 failed: synchronization on value type should not succeed"); 1951 } 1952 } 1953 1954 @Test() 1955 public void test71(MyValue1 vt) { 1956 test71_inline(vt); 1957 } 1958 1959 @DontCompile 1960 public void test71_verifier(boolean warmup) { 1961 try { 1962 test71(testValue1); 1963 throw new RuntimeException("test71 failed: no exception thrown"); 1964 } catch (IllegalMonitorStateException ex) { 1965 // Expected 1966 } 1967 } 1968 1969 @ForceInline 1970 public void test72_inline(Object vt) { 1971 synchronized (vt) { 1972 throw new RuntimeException("test72 failed: synchronization on value type should not succeed"); 1973 } 1974 } 1975 1976 @Test() 1977 public void test72() { 1978 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1979 test72_inline(vt); 1980 } 1981 1982 @DontCompile 1983 public void test72_verifier(boolean warmup) { 1984 try { 1985 test72(); 1986 throw new RuntimeException("test72 failed: no exception thrown"); 1987 } catch (IllegalMonitorStateException ex) { 1988 // Expected 1989 } 1990 } 1991 1992 @Test() 1993 public void test73(Object o, boolean b) { 1994 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1995 Object sync = b ? vt : o; 1996 synchronized (sync) { 1997 if (b) { 1998 throw new RuntimeException("test73 failed: synchronization on value type should not succeed"); 1999 } 2000 } 2001 } 2002 2003 @DontCompile 2004 public void test73_verifier(boolean warmup) { 2005 test73(new Object(), false); 2006 try { 2007 test73(new Object(), true); 2008 throw new RuntimeException("test73 failed: no exception thrown"); 2009 } catch (IllegalMonitorStateException ex) { 2010 // Expected 2011 } 2012 } 2013 2014 @Test() 2015 public void test74(boolean b) { 2016 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 2017 Object sync = b ? vt : testValue2; 2018 synchronized (sync) { 2019 throw new RuntimeException("test74 failed: synchronization on value type should not succeed"); 2020 } 2021 } 2022 2023 @DontCompile 2024 public void test74_verifier(boolean warmup) { 2025 try { 2026 test74(false); 2027 throw new RuntimeException("test74 failed: no exception thrown"); 2028 } catch (IllegalMonitorStateException ex) { 2029 // Expected 2030 } 2031 try { 2032 test74(true); 2033 throw new RuntimeException("test74 failed: no exception thrown"); 2034 } catch (IllegalMonitorStateException ex) { 2035 // Expected 2036 } 2037 } 2038 2039 // Test catching the IllegalMonitorStateException in compiled code 2040 @Test() 2041 public void test75(Object vt) { 2042 boolean thrown = false; 2043 try { 2044 synchronized (vt) { 2045 throw new RuntimeException("test75 failed: no exception thrown"); 2046 } 2047 } catch (IllegalMonitorStateException ex) { 2048 thrown = true; 2049 } 2050 if (!thrown) { 2051 throw new RuntimeException("test75 failed: no exception thrown"); 2052 } 2053 } 2054 2055 @DontCompile 2056 public void test75_verifier(boolean warmup) { 2057 test75(testValue1); 2058 } 2059 2060 @Test() 2061 public void test76(Object o) { 2062 try { 2063 synchronized (o) { } 2064 } catch (IllegalMonitorStateException ex) { 2065 // Expected 2066 return; 2067 } 2068 throw new RuntimeException("test76 failed: no exception thrown"); 2069 } 2070 2071 @DontCompile 2072 public void test76_verifier(boolean warmup) { 2073 test76(testValue1); 2074 } 2075 2076 // Test synchronization without any instructions in the synchronized block 2077 @Test() 2078 public void test77(Object o) { 2079 synchronized (o) { } 2080 } 2081 2082 @DontCompile 2083 public void test77_verifier(boolean warmup) { 2084 try { 2085 test77(testValue1); 2086 } catch (IllegalMonitorStateException ex) { 2087 // Expected 2088 return; 2089 } 2090 throw new RuntimeException("test77 failed: no exception thrown"); 2091 } 2092 }