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