1 /* 2 * Copyright (c) 2019, 2024, 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.inlinetypes; 25 26 import compiler.lib.ir_framework.*; 27 import jdk.test.lib.Asserts; 28 import test.java.lang.invoke.lib.OldInstructionHelper; 29 30 31 import java.lang.invoke.MethodHandle; 32 import java.lang.invoke.MethodHandles; 33 import java.lang.invoke.MethodType; 34 import java.lang.reflect.Method; 35 import jdk.experimental.bytecode.TypeTag; 36 import java.util.Arrays; 37 import java.util.Objects; 38 39 import jdk.internal.value.ValueClass; 40 import jdk.internal.vm.annotation.ImplicitlyConstructible; 41 import jdk.internal.vm.annotation.LooselyConsistentValue; 42 import jdk.internal.vm.annotation.NullRestricted; 43 44 import static compiler.valhalla.inlinetypes.InlineTypeIRNode.*; 45 import static compiler.valhalla.inlinetypes.InlineTypes.*; 46 47 /* 48 * @test 49 * @key randomness 50 * @summary Test inline types in LWorld. 51 * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common / 52 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") 53 * @enablePreview 54 * @modules java.base/jdk.internal.value 55 * java.base/jdk.internal.vm.annotation 56 * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.OldInstructionHelper 57 * @run main/othervm/timeout=450 compiler.valhalla.inlinetypes.TestLWorld 58 */ 59 60 @ForceCompileClassInitializer 61 public class TestLWorld { 62 63 public static void main(String[] args) { 64 // Make sure Test140Value is loaded but not linked 65 Class<?> class1 = Test140Value.class; 66 // Make sure Test141Value is linked but not initialized 67 Class<?> class2 = Test141Value.class; 68 class2.getDeclaredFields(); 69 70 Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; 71 scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); 72 scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); 73 74 InlineTypes.getFramework() 75 .addScenarios(scenarios) 76 .addHelperClasses(MyValue1.class, 77 MyValue2.class, 78 MyValue2Inline.class, 79 MyValue3.class, 80 MyValue3Inline.class) 81 .start(); 82 } 83 84 static { 85 // Make sure RuntimeException is loaded to prevent uncommon traps in IR verified tests 86 RuntimeException tmp = new RuntimeException("42"); 87 } 88 89 // Helper methods 90 91 @NullRestricted 92 private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); 93 @NullRestricted 94 private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, rD); 95 96 protected long hash() { 97 return testValue1.hash(); 98 } 99 100 // Test passing an inline type as an Object 101 @DontInline 102 public Object test1_dontinline1(Object o) { 103 return o; 104 } 105 106 @DontInline 107 public MyValue1 test1_dontinline2(Object o) { 108 return (MyValue1)o; 109 } 110 111 @ForceInline 112 public Object test1_inline1(Object o) { 113 return o; 114 } 115 116 @ForceInline 117 public MyValue1 test1_inline2(Object o) { 118 return (MyValue1)o; 119 } 120 121 @Test 122 @IR(failOn = {ALLOC_G}) 123 public MyValue1 test1() { 124 MyValue1 vt = testValue1; 125 vt = (MyValue1)test1_dontinline1(vt); 126 vt = test1_dontinline2(vt); 127 vt = (MyValue1)test1_inline1(vt); 128 vt = test1_inline2(vt); 129 return vt; 130 } 131 132 @Run(test = "test1") 133 public void test1_verifier() { 134 Asserts.assertEQ(test1().hash(), hash()); 135 } 136 137 // Test storing/loading inline types to/from Object and inline type fields 138 Object objectField1 = null; 139 Object objectField2 = null; 140 Object objectField3 = null; 141 Object objectField4 = null; 142 Object objectField5 = null; 143 Object objectField6 = null; 144 145 @NullRestricted 146 MyValue1 valueField1 = testValue1; 147 @NullRestricted 148 MyValue1 valueField2 = testValue1; 149 MyValue1 valueField3 = testValue1; 150 @NullRestricted 151 MyValue1 valueField4; 152 MyValue1 valueField5; 153 154 static MyValue1 staticValueField1 = testValue1; 155 @NullRestricted 156 static MyValue1 staticValueField2 = testValue1; 157 @NullRestricted 158 static MyValue1 staticValueField3; 159 static MyValue1 staticValueField4; 160 161 @DontInline 162 public Object readValueField5() { 163 return (Object)valueField5; 164 } 165 166 @DontInline 167 public Object readStaticValueField4() { 168 return (Object)staticValueField4; 169 } 170 171 @Test 172 public long test2(MyValue1 vt1, Object vt2) { 173 objectField1 = vt1; 174 objectField2 = (MyValue1)vt2; 175 objectField3 = testValue1; 176 objectField4 = MyValue1.createWithFieldsDontInline(rI, rL); 177 objectField5 = valueField1; 178 objectField6 = valueField3; 179 valueField1 = (MyValue1)objectField1; 180 valueField2 = (MyValue1)vt2; 181 valueField3 = (MyValue1)vt2; 182 staticValueField1 = (MyValue1)objectField1; 183 staticValueField2 = (MyValue1)vt1; 184 // Don't inline these methods because reading NULL will trigger a deoptimization 185 if (readValueField5() != null || readStaticValueField4() != null) { 186 throw new RuntimeException("Should be null"); 187 } 188 return ((MyValue1)objectField1).hash() + ((MyValue1)objectField2).hash() + 189 ((MyValue1)objectField3).hash() + ((MyValue1)objectField4).hash() + 190 ((MyValue1)objectField5).hash() + ((MyValue1)objectField6).hash() + 191 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() + 192 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); 193 } 194 195 @Run(test = "test2") 196 public void test2_verifier() { 197 MyValue1 vt = testValue1; 198 MyValue1 def = MyValue1.createDefaultDontInline(); 199 long result = test2(vt, vt); 200 Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); 201 } 202 203 // Test merging inline types and objects 204 @Test 205 public Object test3(int state) { 206 Object res = null; 207 if (state == 0) { 208 res = new NonValueClass(rI); 209 } else if (state == 1) { 210 res = MyValue1.createWithFieldsInline(rI, rL); 211 } else if (state == 2) { 212 res = MyValue1.createWithFieldsDontInline(rI, rL); 213 } else if (state == 3) { 214 res = (MyValue1)objectField1; 215 } else if (state == 4) { 216 res = valueField1; 217 } else if (state == 5) { 218 res = null; 219 } else if (state == 6) { 220 res = MyValue2.createWithFieldsInline(rI, rD); 221 } else if (state == 7) { 222 res = testValue2; 223 } 224 return res; 225 } 226 227 @Run(test = "test3") 228 public void test3_verifier() { 229 objectField1 = valueField1; 230 Object result = null; 231 result = test3(0); 232 Asserts.assertEQ(((NonValueClass)result).x, rI); 233 result = test3(1); 234 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 235 result = test3(2); 236 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 237 result = test3(3); 238 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 239 result = test3(4); 240 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 241 result = test3(5); 242 Asserts.assertEQ(result, null); 243 result = test3(6); 244 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 245 result = test3(7); 246 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 247 } 248 249 // Test merging inline types and objects in loops 250 @Test 251 public Object test4(int iters) { 252 Object res = new NonValueClass(rI); 253 for (int i = 0; i < iters; ++i) { 254 if (res instanceof NonValueClass) { 255 res = MyValue1.createWithFieldsInline(rI, rL); 256 } else { 257 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL); 258 } 259 } 260 return res; 261 } 262 263 @Run(test = "test4") 264 public void test4_verifier() { 265 NonValueClass result1 = (NonValueClass)test4(0); 266 Asserts.assertEQ(result1.x, rI); 267 int iters = (Math.abs(rI) % 10) + 1; 268 MyValue1 result2 = (MyValue1)test4(iters); 269 MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL); 270 Asserts.assertEQ(result2.hash(), vt.hash()); 271 } 272 273 // Test inline types in object variables that are live at safepoint 274 @Test 275 @IR(failOn = {ALLOC, STORE, LOOP}) 276 public long test5(MyValue1 arg, boolean deopt, Method m) { 277 Object vt1 = MyValue1.createWithFieldsInline(rI, rL); 278 Object vt2 = MyValue1.createWithFieldsDontInline(rI, rL); 279 Object vt3 = arg; 280 Object vt4 = valueField1; 281 if (deopt) { 282 // uncommon trap 283 TestFramework.deoptimize(m); 284 } 285 return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + 286 ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); 287 } 288 289 @Run(test = "test5") 290 public void test5_verifier(RunInfo info) { 291 long result = test5(valueField1, !info.isWarmUp(), info.getTest()); 292 Asserts.assertEQ(result, 4*hash()); 293 } 294 295 // Test comparing inline types with objects 296 @Test 297 public boolean test6(Object arg) { 298 Object vt = MyValue1.createWithFieldsInline(rI, rL); 299 if (vt == arg || vt == (Object)valueField1 || vt == objectField1 || vt == null || 300 arg == vt || (Object)valueField1 == vt || objectField1 == vt || null == vt) { 301 return true; 302 } 303 return false; 304 } 305 306 @Run(test = "test6") 307 public void test6_verifier() { 308 boolean result = test6(null); 309 Asserts.assertFalse(result); 310 } 311 312 // merge of inline type and non-inline type 313 @Test 314 public Object test7(boolean flag) { 315 Object res = null; 316 if (flag) { 317 res = valueField1; 318 } else { 319 res = objectField1; 320 } 321 return res; 322 } 323 324 @Run(test = "test7") 325 public void test7_verifier() { 326 test7(true); 327 test7(false); 328 } 329 330 @Test 331 public Object test8(boolean flag) { 332 Object res = null; 333 if (flag) { 334 res = objectField1; 335 } else { 336 res = valueField1; 337 } 338 return res; 339 } 340 341 @Run(test = "test8") 342 public void test8_verifier() { 343 test8(true); 344 test8(false); 345 } 346 347 // merge of inline types in a loop, stored in an object local 348 @Test 349 public Object test9() { 350 Object o = valueField1; 351 for (int i = 1; i < 100; i *= 2) { 352 MyValue1 v = (MyValue1)o; 353 o = MyValue1.setX(v, v.x + 1); 354 } 355 return o; 356 } 357 358 @Run(test = "test9") 359 public void test9_verifier() { 360 test9(); 361 } 362 363 // merge of inline types in an object local 364 @ForceInline 365 public Object test10_helper() { 366 return valueField1; 367 } 368 369 @Test 370 @IR(failOn = {ALLOC_G}) 371 public void test10(boolean flag) { 372 Object o = null; 373 if (flag) { 374 o = valueField1; 375 } else { 376 o = test10_helper(); 377 } 378 valueField1 = (MyValue1)o; 379 } 380 381 @Run(test = "test10") 382 public void test10_verifier() { 383 test10(true); 384 test10(false); 385 } 386 387 // Interface tests 388 389 @DontInline 390 public MyInterface test11_dontinline1(MyInterface o) { 391 return o; 392 } 393 394 @DontInline 395 public MyValue1 test11_dontinline2(MyInterface o) { 396 return (MyValue1)o; 397 } 398 399 @ForceInline 400 public MyInterface test11_inline1(MyInterface o) { 401 return o; 402 } 403 404 @ForceInline 405 public MyValue1 test11_inline2(MyInterface o) { 406 return (MyValue1)o; 407 } 408 409 @Test 410 public MyValue1 test11() { 411 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 412 vt = (MyValue1)test11_dontinline1(vt); 413 vt = test11_dontinline2(vt); 414 vt = (MyValue1)test11_inline1(vt); 415 vt = test11_inline2(vt); 416 return vt; 417 } 418 419 @Run(test = "test11") 420 public void test11_verifier() { 421 Asserts.assertEQ(test11().hash(), hash()); 422 } 423 424 // Test storing/loading inline types to/from interface and inline type fields 425 MyInterface interfaceField1 = null; 426 MyInterface interfaceField2 = null; 427 MyInterface interfaceField3 = null; 428 MyInterface interfaceField4 = null; 429 MyInterface interfaceField5 = null; 430 MyInterface interfaceField6 = null; 431 432 @DontInline 433 public MyInterface readValueField5AsInterface() { 434 return (MyInterface)valueField5; 435 } 436 437 @DontInline 438 public MyInterface readStaticValueField4AsInterface() { 439 return (MyInterface)staticValueField4; 440 } 441 442 @Test 443 public long test12(MyValue1 vt1, MyInterface vt2) { 444 interfaceField1 = vt1; 445 interfaceField2 = (MyValue1)vt2; 446 interfaceField3 = MyValue1.createWithFieldsInline(rI, rL); 447 interfaceField4 = MyValue1.createWithFieldsDontInline(rI, rL); 448 interfaceField5 = valueField1; 449 interfaceField6 = valueField3; 450 valueField1 = (MyValue1)interfaceField1; 451 valueField2 = (MyValue1)vt2; 452 valueField3 = (MyValue1)vt2; 453 staticValueField1 = (MyValue1)interfaceField1; 454 staticValueField2 = (MyValue1)vt1; 455 // Don't inline these methods because reading NULL will trigger a deoptimization 456 if (readValueField5AsInterface() != null || readStaticValueField4AsInterface() != null) { 457 throw new RuntimeException("Should be null"); 458 } 459 return ((MyValue1)interfaceField1).hash() + ((MyValue1)interfaceField2).hash() + 460 ((MyValue1)interfaceField3).hash() + ((MyValue1)interfaceField4).hash() + 461 ((MyValue1)interfaceField5).hash() + ((MyValue1)interfaceField6).hash() + 462 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() + 463 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); 464 } 465 466 @Run(test = "test12") 467 public void test12_verifier() { 468 MyValue1 vt = testValue1; 469 MyValue1 def = MyValue1.createDefaultDontInline(); 470 long result = test12(vt, vt); 471 Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); 472 } 473 474 class MyObject1 implements MyInterface { 475 public int x; 476 477 public MyObject1(int x) { 478 this.x = x; 479 } 480 481 @ForceInline 482 public long hash() { 483 return x; 484 } 485 } 486 487 // Test merging inline types and interfaces 488 @Test 489 public MyInterface test13(int state) { 490 MyInterface res = null; 491 if (state == 0) { 492 res = new MyObject1(rI); 493 } else if (state == 1) { 494 res = MyValue1.createWithFieldsInline(rI, rL); 495 } else if (state == 2) { 496 res = MyValue1.createWithFieldsDontInline(rI, rL); 497 } else if (state == 3) { 498 res = (MyValue1)objectField1; 499 } else if (state == 4) { 500 res = valueField1; 501 } else if (state == 5) { 502 res = null; 503 } 504 return res; 505 } 506 507 @Run(test = "test13") 508 public void test13_verifier() { 509 objectField1 = valueField1; 510 MyInterface result = null; 511 result = test13(0); 512 Asserts.assertEQ(((MyObject1)result).x, rI); 513 result = test13(1); 514 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 515 result = test13(2); 516 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 517 result = test13(3); 518 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 519 result = test13(4); 520 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 521 result = test13(5); 522 Asserts.assertEQ(result, null); 523 } 524 525 // Test merging inline types and interfaces in loops 526 @Test 527 public MyInterface test14(int iters) { 528 MyInterface res = new MyObject1(rI); 529 for (int i = 0; i < iters; ++i) { 530 if (res instanceof MyObject1) { 531 res = MyValue1.createWithFieldsInline(rI, rL); 532 } else { 533 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL); 534 } 535 } 536 return res; 537 } 538 539 @Run(test = "test14") 540 public void test14_verifier() { 541 MyObject1 result1 = (MyObject1)test14(0); 542 Asserts.assertEQ(result1.x, rI); 543 int iters = (Math.abs(rI) % 10) + 1; 544 MyValue1 result2 = (MyValue1)test14(iters); 545 MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL); 546 Asserts.assertEQ(result2.hash(), vt.hash()); 547 } 548 549 // Test inline types in interface variables that are live at safepoint 550 @Test 551 @IR(failOn = {ALLOC, STORE, LOOP}) 552 public long test15(MyValue1 arg, boolean deopt, Method m) { 553 MyInterface vt1 = MyValue1.createWithFieldsInline(rI, rL); 554 MyInterface vt2 = MyValue1.createWithFieldsDontInline(rI, rL); 555 MyInterface vt3 = arg; 556 MyInterface vt4 = valueField1; 557 return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + 558 ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); 559 } 560 561 @Run(test = "test15") 562 public void test15_verifier(RunInfo info) { 563 long result = test15(valueField1, !info.isWarmUp(), info.getTest()); 564 Asserts.assertEQ(result, 4*hash()); 565 } 566 567 // Test comparing inline types with interfaces 568 @Test 569 public boolean test16(Object arg) { 570 MyInterface vt = MyValue1.createWithFieldsInline(rI, rL); 571 if (vt == arg || vt == (MyInterface)valueField1 || vt == interfaceField1 || vt == null || 572 arg == vt || (MyInterface)valueField1 == vt || interfaceField1 == vt || null == vt) { 573 return true; 574 } 575 return false; 576 } 577 578 @Run(test = "test16") 579 public void test16_verifier() { 580 boolean result = test16(null); 581 Asserts.assertFalse(result); 582 } 583 584 // Test subtype check when casting to inline type 585 @Test 586 @IR(failOn = {ALLOC}) 587 public MyValue1 test17(MyValue1 vt, Object obj) { 588 try { 589 vt = (MyValue1)obj; 590 throw new RuntimeException("ClassCastException expected"); 591 } catch (ClassCastException e) { 592 // Expected 593 } 594 return vt; 595 } 596 597 @Run(test = "test17") 598 public void test17_verifier() { 599 MyValue1 vt = testValue1; 600 MyValue1 result = test17(vt, new NonValueClass(rI)); 601 Asserts.assertEquals(result.hash(), vt.hash()); 602 } 603 604 @Test 605 public MyValue1 test18(MyValue1 vt) { 606 Object obj = vt; 607 vt = (MyValue1)obj; 608 return vt; 609 } 610 611 @Run(test = "test18") 612 public void test18_verifier() { 613 MyValue1 vt = testValue1; 614 MyValue1 result = test18(vt); 615 Asserts.assertEquals(result.hash(), vt.hash()); 616 } 617 618 @Test 619 @IR(failOn = {ALLOC_G}) 620 public void test19(MyValue1 vt) { 621 if (vt == null) { 622 return; 623 } 624 Object obj = vt; 625 try { 626 MyValue2 vt2 = (MyValue2)obj; 627 throw new RuntimeException("ClassCastException expected"); 628 } catch (ClassCastException e) { 629 // Expected 630 } 631 } 632 633 @Run(test = "test19") 634 public void test19_verifier() { 635 test19(valueField1); 636 } 637 638 @Test 639 @IR(failOn = {ALLOC_G}) 640 public void test20(MyValue1 vt) { 641 if (vt == null) { 642 return; 643 } 644 Object obj = vt; 645 try { 646 NonValueClass i = (NonValueClass)obj; 647 throw new RuntimeException("ClassCastException expected"); 648 } catch (ClassCastException e) { 649 // Expected 650 } 651 } 652 653 @Run(test = "test20") 654 public void test20_verifier() { 655 test20(valueField1); 656 } 657 658 // Array tests 659 660 private static final MyValue1[] testValue1Array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 3); 661 static { 662 for (int i = 0; i < 3; ++i) { 663 testValue1Array[i] = testValue1; 664 } 665 } 666 667 private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array, 668 testValue1Array, 669 testValue1Array}; 670 671 private static final MyValue2[] testValue2Array = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 3); 672 static { 673 for (int i = 0; i < 3; ++i) { 674 testValue2Array[i] = testValue2; 675 } 676 } 677 678 private static final NonValueClass[] testNonValueArray = new NonValueClass[42]; 679 680 // Test load from (flattened) inline type array disguised as object array 681 @Test 682 public Object test21(Object[] oa, int index) { 683 return oa[index]; 684 } 685 686 @Run(test = "test21") 687 public void test21_verifier() { 688 MyValue1 result = (MyValue1)test21(testValue1Array, Math.abs(rI) % 3); 689 Asserts.assertEQ(result.hash(), hash()); 690 } 691 692 // Test load from (flattened) inline type array disguised as interface array 693 @Test 694 public Object test22Interface(MyInterface[] ia, int index) { 695 return ia[index]; 696 } 697 698 @Run(test = "test22Interface") 699 public void test22Interface_verifier() { 700 MyValue1 result = (MyValue1)test22Interface(testValue1Array, Math.abs(rI) % 3); 701 Asserts.assertEQ(result.hash(), hash()); 702 } 703 704 // Test load from (flattened) inline type array disguised as abstract array 705 @Test 706 public Object test22Abstract(MyAbstract[] ia, int index) { 707 return ia[index]; 708 } 709 710 @Run(test = "test22Abstract") 711 public void test22Abstract_verifier() { 712 MyValue1 result = (MyValue1)test22Abstract(testValue1Array, Math.abs(rI) % 3); 713 Asserts.assertEQ(result.hash(), hash()); 714 } 715 716 // Test inline store to (flattened) inline type array disguised as object array 717 @ForceInline 718 public void test23_inline(Object[] oa, Object o, int index) { 719 oa[index] = o; 720 } 721 722 @Test 723 public void test23(Object[] oa, MyValue1 vt, int index) { 724 test23_inline(oa, vt, index); 725 } 726 727 @Run(test = "test23") 728 public void test23_verifier() { 729 int index = Math.abs(rI) % 3; 730 MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 731 test23(testValue1Array, vt, index); 732 Asserts.assertEQ(testValue1Array[index].hash(), vt.hash()); 733 testValue1Array[index] = testValue1; 734 try { 735 test23(testValue2Array, vt, index); 736 throw new RuntimeException("No ArrayStoreException thrown"); 737 } catch (ArrayStoreException e) { 738 // Expected 739 } 740 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 741 } 742 743 @ForceInline 744 public void test24_inline(Object[] oa, Object o, int index) { 745 oa[index] = o; 746 } 747 748 @Test 749 public void test24(Object[] oa, MyValue1 vt, int index) { 750 test24_inline(oa, vt, index); 751 } 752 753 @Run(test = "test24") 754 public void test24_verifier() { 755 int index = Math.abs(rI) % 3; 756 try { 757 test24(testNonValueArray, testValue1, index); 758 throw new RuntimeException("No ArrayStoreException thrown"); 759 } catch (ArrayStoreException e) { 760 // Expected 761 } 762 } 763 764 @ForceInline 765 public void test25_inline(Object[] oa, Object o, int index) { 766 oa[index] = o; 767 } 768 769 @Test 770 public void test25(Object[] oa, MyValue1 vt, int index) { 771 test25_inline(oa, vt, index); 772 } 773 774 @Run(test = "test25") 775 public void test25_verifier() { 776 int index = Math.abs(rI) % 3; 777 try { 778 test25(null, testValue1, index); 779 throw new RuntimeException("No NPE thrown"); 780 } catch (NullPointerException e) { 781 // Expected 782 } 783 } 784 785 // Test inline store to (flattened) inline type array disguised as interface array 786 @ForceInline 787 public void test26Interface_inline(MyInterface[] ia, MyInterface i, int index) { 788 ia[index] = i; 789 } 790 791 @Test 792 public void test26Interface(MyInterface[] ia, MyValue1 vt, int index) { 793 test26Interface_inline(ia, vt, index); 794 } 795 796 @Run(test = "test26Interface") 797 public void test26Interface_verifier() { 798 int index = Math.abs(rI) % 3; 799 MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 800 test26Interface(testValue1Array, vt, index); 801 Asserts.assertEQ(testValue1Array[index].hash(), vt.hash()); 802 testValue1Array[index] = testValue1; 803 try { 804 test26Interface(testValue2Array, vt, index); 805 throw new RuntimeException("No ArrayStoreException thrown"); 806 } catch (ArrayStoreException e) { 807 // Expected 808 } 809 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 810 } 811 812 @ForceInline 813 public void test27Interface_inline(MyInterface[] ia, MyInterface i, int index) { 814 ia[index] = i; 815 } 816 817 @Test 818 public void test27Interface(MyInterface[] ia, MyValue1 vt, int index) { 819 test27Interface_inline(ia, vt, index); 820 } 821 822 @Run(test = "test27Interface") 823 public void test27Interface_verifier() { 824 int index = Math.abs(rI) % 3; 825 try { 826 test27Interface(null, testValue1, index); 827 throw new RuntimeException("No NPE thrown"); 828 } catch (NullPointerException e) { 829 // Expected 830 } 831 } 832 833 // Test inline store to (flattened) inline type array disguised as abstract array 834 @ForceInline 835 public void test26Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { 836 ia[index] = i; 837 } 838 839 @Test 840 public void test26Abstract(MyAbstract[] ia, MyValue1 vt, int index) { 841 test26Abstract_inline(ia, vt, index); 842 } 843 844 @Run(test = "test26Abstract") 845 public void test26Abstract_verifier() { 846 int index = Math.abs(rI) % 3; 847 MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 848 test26Abstract(testValue1Array, vt, index); 849 Asserts.assertEQ(testValue1Array[index].hash(), vt.hash()); 850 testValue1Array[index] = testValue1; 851 try { 852 test26Abstract(testValue2Array, vt, index); 853 throw new RuntimeException("No ArrayStoreException thrown"); 854 } catch (ArrayStoreException e) { 855 // Expected 856 } 857 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 858 } 859 860 @ForceInline 861 public void test27Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { 862 ia[index] = i; 863 } 864 865 @Test 866 public void test27Abstract(MyAbstract[] ia, MyValue1 vt, int index) { 867 test27Abstract_inline(ia, vt, index); 868 } 869 870 @Run(test = "test27Abstract") 871 public void test27Abstract_verifier() { 872 int index = Math.abs(rI) % 3; 873 try { 874 test27Abstract(null, testValue1, index); 875 throw new RuntimeException("No NPE thrown"); 876 } catch (NullPointerException e) { 877 // Expected 878 } 879 } 880 881 // Test object store to (flattened) inline type array disguised as object array 882 @ForceInline 883 public void test28_inline(Object[] oa, Object o, int index) { 884 oa[index] = o; 885 } 886 887 @Test 888 public void test28(Object[] oa, Object o, int index) { 889 test28_inline(oa, o, index); 890 } 891 892 @Run(test = "test28") 893 public void test28_verifier() { 894 int index = Math.abs(rI) % 3; 895 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 896 test28(testValue1Array, vt1, index); 897 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 898 try { 899 test28(testValue1Array, testValue2, index); 900 throw new RuntimeException("No ArrayStoreException thrown"); 901 } catch (ArrayStoreException e) { 902 // Expected 903 } 904 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 905 testValue1Array[index] = testValue1; 906 } 907 908 @ForceInline 909 public void test29_inline(Object[] oa, Object o, int index) { 910 oa[index] = o; 911 } 912 913 @Test 914 public void test29(Object[] oa, Object o, int index) { 915 test29_inline(oa, o, index); 916 } 917 918 @Run(test = "test29") 919 public void test29_verifier() { 920 int index = Math.abs(rI) % 3; 921 try { 922 test29(testValue2Array, testValue1, index); 923 throw new RuntimeException("No ArrayStoreException thrown"); 924 } catch (ArrayStoreException e) { 925 // Expected 926 } 927 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 928 } 929 930 @ForceInline 931 public void test30_inline(Object[] oa, Object o, int index) { 932 oa[index] = o; 933 } 934 935 @Test 936 public void test30(Object[] oa, Object o, int index) { 937 test30_inline(oa, o, index); 938 } 939 940 @Run(test = "test30") 941 public void test30_verifier() { 942 int index = Math.abs(rI) % 3; 943 try { 944 test30(testNonValueArray, testValue1, index); 945 throw new RuntimeException("No ArrayStoreException thrown"); 946 } catch (ArrayStoreException e) { 947 // Expected 948 } 949 } 950 951 // Test inline store to (flattened) inline type array disguised as interface array 952 @ForceInline 953 public void test31Interface_inline(MyInterface[] ia, MyInterface i, int index) { 954 ia[index] = i; 955 } 956 957 @Test 958 public void test31Interface(MyInterface[] ia, MyInterface i, int index) { 959 test31Interface_inline(ia, i, index); 960 } 961 962 @Run(test = "test31Interface") 963 public void test31Interface_verifier() { 964 int index = Math.abs(rI) % 3; 965 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 966 test31Interface(testValue1Array, vt1, index); 967 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 968 try { 969 test31Interface(testValue1Array, testValue2, index); 970 throw new RuntimeException("No ArrayStoreException thrown"); 971 } catch (ArrayStoreException e) { 972 // Expected 973 } 974 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 975 testValue1Array[index] = testValue1; 976 } 977 978 @ForceInline 979 public void test32Interface_inline(MyInterface[] ia, MyInterface i, int index) { 980 ia[index] = i; 981 } 982 983 @Test 984 public void test32Interface(MyInterface[] ia, MyInterface i, int index) { 985 test32Interface_inline(ia, i, index); 986 } 987 988 @Run(test = "test32Interface") 989 public void test32Interface_verifier() { 990 int index = Math.abs(rI) % 3; 991 try { 992 test32Interface(testValue2Array, testValue1, index); 993 throw new RuntimeException("No ArrayStoreException thrown"); 994 } catch (ArrayStoreException e) { 995 // Expected 996 } 997 } 998 999 // Test inline store to (flattened) inline type array disguised as abstract array 1000 @ForceInline 1001 public void test31Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { 1002 ia[index] = i; 1003 } 1004 1005 @Test 1006 public void test31Abstract(MyAbstract[] ia, MyAbstract i, int index) { 1007 test31Abstract_inline(ia, i, index); 1008 } 1009 1010 @Run(test = "test31Abstract") 1011 public void test31Abstract_verifier() { 1012 int index = Math.abs(rI) % 3; 1013 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1014 test31Abstract(testValue1Array, vt1, index); 1015 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1016 try { 1017 test31Abstract(testValue1Array, testValue2, index); 1018 throw new RuntimeException("No ArrayStoreException thrown"); 1019 } catch (ArrayStoreException e) { 1020 // Expected 1021 } 1022 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1023 testValue1Array[index] = testValue1; 1024 } 1025 1026 @ForceInline 1027 public void test32Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { 1028 ia[index] = i; 1029 } 1030 1031 @Test 1032 public void test32Abstract(MyAbstract[] ia, MyAbstract i, int index) { 1033 test32Abstract_inline(ia, i, index); 1034 } 1035 1036 @Run(test = "test32Abstract") 1037 public void test32Abstract_verifier() { 1038 int index = Math.abs(rI) % 3; 1039 try { 1040 test32Abstract(testValue2Array, testValue1, index); 1041 throw new RuntimeException("No ArrayStoreException thrown"); 1042 } catch (ArrayStoreException e) { 1043 // Expected 1044 } 1045 } 1046 1047 // Test writing null to a (flattened) inline type array disguised as object array 1048 @ForceInline 1049 public void test33_inline(Object[] oa, Object o, int index) { 1050 oa[index] = o; 1051 } 1052 1053 @Test 1054 public void test33(Object[] oa, Object o, int index) { 1055 test33_inline(oa, o, index); 1056 } 1057 1058 @Run(test = "test33") 1059 public void test33_verifier() { 1060 int index = Math.abs(rI) % 3; 1061 try { 1062 test33(testValue1Array, null, index); 1063 throw new RuntimeException("No NPE thrown"); 1064 } catch (NullPointerException e) { 1065 // Expected 1066 } 1067 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1068 } 1069 1070 // Test writing constant null to a (flattened) inline type array disguised as object array 1071 1072 @ForceInline 1073 public void test34_inline(Object[] oa, Object o, int index) { 1074 oa[index] = o; 1075 } 1076 1077 @Test 1078 public void test34(Object[] oa, int index) { 1079 test34_inline(oa, null, index); 1080 } 1081 1082 @Run(test = "test34") 1083 public void test34_verifier() { 1084 int index = Math.abs(rI) % 3; 1085 try { 1086 test34(testValue1Array, index); 1087 throw new RuntimeException("No NPE thrown"); 1088 } catch (NullPointerException e) { 1089 // Expected 1090 } 1091 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1092 } 1093 1094 // Test writing constant null to a (flattened) inline type array 1095 1096 private static final MethodHandle setArrayElementNull = OldInstructionHelper.loadCode(MethodHandles.lookup(), 1097 "setArrayElementNull", 1098 MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class), 1099 CODE -> { 1100 CODE. 1101 aload_1(). 1102 iload_2(). 1103 aconst_null(). 1104 aastore(). 1105 return_(); 1106 }); 1107 1108 @Test 1109 public void test35(MyValue1[] va, int index) throws Throwable { 1110 setArrayElementNull.invoke(this, va, index); 1111 } 1112 1113 @Run(test = "test35") 1114 @Warmup(10000) 1115 public void test35_verifier() throws Throwable { 1116 int index = Math.abs(rI) % 3; 1117 try { 1118 test35(testValue1Array, index); 1119 throw new RuntimeException("No NPE thrown"); 1120 } catch (NullPointerException e) { 1121 // Expected 1122 } 1123 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1124 } 1125 1126 // Test writing an inline type to a null inline type array 1127 @Test 1128 public void test36(MyValue1[] va, MyValue1 vt, int index) { 1129 va[index] = vt; 1130 } 1131 1132 @Run(test = "test36") 1133 public void test36_verifier() { 1134 int index = Math.abs(rI) % 3; 1135 try { 1136 test36(null, testValue1Array[index], index); 1137 throw new RuntimeException("No NPE thrown"); 1138 } catch (NullPointerException e) { 1139 // Expected 1140 } 1141 } 1142 1143 // Test incremental inlining 1144 @ForceInline 1145 public void test37_inline(Object[] oa, Object o, int index) { 1146 oa[index] = o; 1147 } 1148 1149 @Test 1150 @IR(failOn = {ALLOC_G}) 1151 public void test37(MyValue1[] va, Object o, int index) { 1152 test37_inline(va, o, index); 1153 } 1154 1155 @Run(test = "test37") 1156 public void test37_verifier() { 1157 int index = Math.abs(rI) % 3; 1158 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1159 test37(testValue1Array, vt1, index); 1160 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1161 try { 1162 test37(testValue1Array, testValue2, index); 1163 throw new RuntimeException("No ArrayStoreException thrown"); 1164 } catch (ArrayStoreException e) { 1165 // Expected 1166 } 1167 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1168 testValue1Array[index] = testValue1; 1169 } 1170 1171 // Test merging of inline type arrays 1172 1173 @ForceInline 1174 public Object[] test38_inline() { 1175 return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42); 1176 } 1177 1178 @Test 1179 @IR(failOn = {ALLOC}) 1180 public Object[] test38(Object[] oa, Object o, int i1, int i2, int num) { 1181 Object[] result = null; 1182 switch (num) { 1183 case 0: 1184 result = test38_inline(); 1185 break; 1186 case 1: 1187 result = oa; 1188 break; 1189 case 2: 1190 result = testValue1Array; 1191 break; 1192 case 3: 1193 result = testValue2Array; 1194 break; 1195 case 4: 1196 result = testNonValueArray; 1197 break; 1198 case 5: 1199 result = null; 1200 break; 1201 case 6: 1202 result = testValue1Array2; 1203 break; 1204 } 1205 result[i1] = result[i2]; 1206 result[i2] = o; 1207 return result; 1208 } 1209 1210 @Run(test = "test38") 1211 public void test38_verifier() { 1212 int index = Math.abs(rI) % 3; 1213 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42); 1214 Object[] result = test38(null, testValue1, index, index, 0); 1215 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1216 result = test38(testValue1Array, testValue1, index, index, 1); 1217 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1218 result = test38(null, testValue1, index, index, 2); 1219 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1220 result = test38(null, testValue2, index, index, 3); 1221 Asserts.assertEQ(((MyValue2)result[index]).hash(), testValue2.hash()); 1222 try { 1223 result = test38(null, null, index, index, 3); 1224 throw new RuntimeException("No NPE thrown"); 1225 } catch (NullPointerException e) { 1226 // Expected 1227 } 1228 result = test38(null, null, index, index, 4); 1229 try { 1230 result = test38(null, testValue1, index, index, 4); 1231 throw new RuntimeException("No ArrayStoreException thrown"); 1232 } catch (ArrayStoreException e) { 1233 // Expected 1234 } 1235 try { 1236 result = test38(null, testValue1, index, index, 5); 1237 throw new RuntimeException("No NPE thrown"); 1238 } catch (NullPointerException e) { 1239 // Expected 1240 } 1241 result = test38(null, testValue1Array, index, index, 6); 1242 Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash()); 1243 } 1244 1245 @ForceInline 1246 public Object test39_inline() { 1247 return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42); 1248 } 1249 1250 // Same as above but merging into Object instead of Object[] 1251 @Test 1252 public Object test39(Object oa, Object o, int i1, int i2, int num) { 1253 Object result = null; 1254 switch (num) { 1255 case 0: 1256 result = test39_inline(); 1257 break; 1258 case 1: 1259 result = oa; 1260 break; 1261 case 2: 1262 result = testValue1Array; 1263 break; 1264 case 3: 1265 result = testValue2Array; 1266 break; 1267 case 4: 1268 result = testNonValueArray; 1269 break; 1270 case 5: 1271 result = null; 1272 break; 1273 case 6: 1274 result = testValue1; 1275 break; 1276 case 7: 1277 result = testValue2; 1278 break; 1279 case 8: 1280 result = MyValue1.createWithFieldsInline(rI, rL); 1281 break; 1282 case 9: 1283 result = new NonValueClass(42); 1284 break; 1285 case 10: 1286 result = testValue1Array2; 1287 break; 1288 } 1289 if (result instanceof Object[]) { 1290 ((Object[])result)[i1] = ((Object[])result)[i2]; 1291 ((Object[])result)[i2] = o; 1292 } 1293 return result; 1294 } 1295 1296 @Run(test = "test39") 1297 public void test39_verifier() { 1298 int index = Math.abs(rI) % 3; 1299 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 42); 1300 Object result = test39(null, testValue1, index, index, 0); 1301 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1302 result = test39(testValue1Array, testValue1, index, index, 1); 1303 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1304 result = test39(null, testValue1, index, index, 2); 1305 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1306 result = test39(null, testValue2, index, index, 3); 1307 Asserts.assertEQ(((MyValue2[])result)[index].hash(), testValue2.hash()); 1308 try { 1309 result = test39(null, null, index, index, 3); 1310 throw new RuntimeException("No NPE thrown"); 1311 } catch (NullPointerException e) { 1312 // Expected 1313 } 1314 result = test39(null, null, index, index, 4); 1315 try { 1316 result = test39(null, testValue1, index, index, 4); 1317 throw new RuntimeException("No ArrayStoreException thrown"); 1318 } catch (ArrayStoreException e) { 1319 // Expected 1320 } 1321 result = test39(null, testValue1, index, index, 5); 1322 Asserts.assertEQ(result, null); 1323 result = test39(null, testValue1, index, index, 6); 1324 Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash()); 1325 result = test39(null, testValue1, index, index, 7); 1326 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 1327 result = test39(null, testValue1, index, index, 8); 1328 Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash()); 1329 result = test39(null, testValue1, index, index, 9); 1330 Asserts.assertEQ(((NonValueClass)result).x, 42); 1331 result = test39(null, testValue1Array, index, index, 10); 1332 Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash()); 1333 } 1334 1335 // Test instanceof with inline types and arrays 1336 @Test 1337 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, 1338 failOn = {ALLOC_G}) 1339 public long test40(Object o, int index) { 1340 if (o instanceof MyValue1) { 1341 return ((MyValue1)o).hashInterpreted(); 1342 } else if (o instanceof MyValue1[]) { 1343 return ((MyValue1[])o)[index].hashInterpreted(); 1344 } else if (o instanceof MyValue2) { 1345 return ((MyValue2)o).hash(); 1346 } else if (o instanceof MyValue2[]) { 1347 return ((MyValue2[])o)[index].hash(); 1348 } else if (o instanceof MyValue1[][]) { 1349 return ((MyValue1[][])o)[index][index].hash(); 1350 } else if (o instanceof Long) { 1351 return (long)o; 1352 } 1353 return 0; 1354 } 1355 1356 @Run(test = "test40") 1357 public void test40_verifier() { 1358 int index = Math.abs(rI) % 3; 1359 long result = test40(testValue1, 0); 1360 Asserts.assertEQ(result, testValue1.hashInterpreted()); 1361 result = test40(testValue1Array, index); 1362 Asserts.assertEQ(result, testValue1.hashInterpreted()); 1363 result = test40(testValue2, index); 1364 Asserts.assertEQ(result, testValue2.hash()); 1365 result = test40(testValue2Array, index); 1366 Asserts.assertEQ(result, testValue2.hash()); 1367 result = test40(testValue1Array2, index); 1368 Asserts.assertEQ(result, testValue1.hash()); 1369 result = test40(Long.valueOf(42), index); 1370 Asserts.assertEQ(result, 42L); 1371 } 1372 1373 // Test for bug in Escape Analysis 1374 // TODO 8325106 Re-enable 1375 /* 1376 @DontInline 1377 public void test41_dontinline(Object o) { 1378 Asserts.assertEQ(o, rI); 1379 } 1380 1381 @Test 1382 @IR(failOn = {ALLOC}) 1383 public void test41() { 1384 MyValue1[] vals = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 1385 vals[0] = testValue1; 1386 test41_dontinline(vals[0].oa[0]); 1387 test41_dontinline(vals[0].oa[0]); 1388 } 1389 1390 @Run(test = "test41") 1391 public void test41_verifier() { 1392 test41(); 1393 } 1394 */ 1395 1396 // Test for bug in Escape Analysis 1397 private static final MyValue1 test42VT1 = MyValue1.createWithFieldsInline(rI, rL); 1398 private static final MyValue1 test42VT2 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1399 1400 @Test 1401 @IR(failOn = {ALLOC}) 1402 public void test42() { 1403 MyValue1[] vals = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 1404 vals[0] = test42VT1; 1405 vals[1] = test42VT2; 1406 Asserts.assertEQ(vals[0].hash(), test42VT1.hash()); 1407 Asserts.assertEQ(vals[1].hash(), test42VT2.hash()); 1408 } 1409 1410 @Run(test = "test42") 1411 public void test42_verifier(RunInfo info) { 1412 if (!info.isWarmUp()) test42(); // We need -Xcomp behavior 1413 } 1414 1415 // Test for bug in Escape Analysis 1416 @Test 1417 @IR(failOn = {ALLOC}) 1418 public long test43(boolean deopt, Method m) { 1419 MyValue1[] vals = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 1420 vals[0] = test42VT1; 1421 vals[1] = test42VT2; 1422 1423 if (deopt) { 1424 // uncommon trap 1425 TestFramework.deoptimize(m); 1426 Asserts.assertEQ(vals[0].hash(), test42VT1.hash()); 1427 Asserts.assertEQ(vals[1].hash(), test42VT2.hash()); 1428 } 1429 1430 return vals[0].hash(); 1431 } 1432 1433 @Run(test = "test43") 1434 public void test43_verifier(RunInfo info) { 1435 test43(!info.isWarmUp(), info.getTest()); 1436 } 1437 1438 // Tests writing an array element with a (statically known) incompatible type 1439 private static final MethodHandle setArrayElementIncompatible = OldInstructionHelper.loadCode(MethodHandles.lookup(), 1440 "setArrayElementIncompatible", 1441 MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class), 1442 CODE -> { 1443 CODE. 1444 aload_1(). 1445 iload_2(). 1446 aload_3(). 1447 aastore(). 1448 return_(); 1449 }); 1450 1451 @Test 1452 public void test44(MyValue1[] va, int index, MyValue2 v) throws Throwable { 1453 setArrayElementIncompatible.invoke(this, va, index, v); 1454 } 1455 1456 @Run(test = "test44") 1457 @Warmup(10000) 1458 public void test44_verifier() throws Throwable { 1459 int index = Math.abs(rI) % 3; 1460 try { 1461 test44(testValue1Array, index, testValue2); 1462 throw new RuntimeException("No ArrayStoreException thrown"); 1463 } catch (ArrayStoreException e) { 1464 // Expected 1465 } 1466 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1467 } 1468 1469 // Tests writing an array element with a (statically known) incompatible type 1470 @ForceInline 1471 public void test45_inline(Object[] oa, Object o, int index) { 1472 oa[index] = o; 1473 } 1474 1475 @Test 1476 public void test45(MyValue1[] va, int index, MyValue2 v) throws Throwable { 1477 test45_inline(va, v, index); 1478 } 1479 1480 @Run(test = "test45") 1481 public void test45_verifier() throws Throwable { 1482 int index = Math.abs(rI) % 3; 1483 try { 1484 test45(testValue1Array, index, testValue2); 1485 throw new RuntimeException("No ArrayStoreException thrown"); 1486 } catch (ArrayStoreException e) { 1487 // Expected 1488 } 1489 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1490 } 1491 1492 // instanceof tests with inline types 1493 @Test 1494 @IR(failOn = {ALLOC_G}) 1495 public boolean test46(MyValue1 vt) { 1496 Object obj = vt; 1497 return obj instanceof MyValue1; 1498 } 1499 1500 @Run(test = "test46") 1501 public void test46_verifier() { 1502 MyValue1 vt = testValue1; 1503 boolean result = test46(vt); 1504 Asserts.assertTrue(result); 1505 } 1506 1507 @Test 1508 @IR(failOn = {ALLOC_G}) 1509 public boolean test47(MyValue1 vt) { 1510 Object obj = vt; 1511 return obj instanceof MyValue2; 1512 } 1513 1514 @Run(test = "test47") 1515 public void test47_verifier() { 1516 MyValue1 vt = testValue1; 1517 boolean result = test47(vt); 1518 Asserts.assertFalse(result); 1519 } 1520 1521 @Test 1522 @IR(failOn = {ALLOC_G}) 1523 public boolean test48(Object obj) { 1524 return obj instanceof MyValue1; 1525 } 1526 1527 @Run(test = "test48") 1528 public void test48_verifier() { 1529 MyValue1 vt = testValue1; 1530 boolean result = test48(vt); 1531 Asserts.assertTrue(result); 1532 } 1533 1534 @Test 1535 @IR(failOn = {ALLOC_G}) 1536 public boolean test49(Object obj) { 1537 return obj instanceof MyValue2; 1538 } 1539 1540 @Run(test = "test49") 1541 public void test49_verifier() { 1542 MyValue1 vt = testValue1; 1543 boolean result = test49(vt); 1544 Asserts.assertFalse(result); 1545 } 1546 1547 @Test 1548 @IR(failOn = {ALLOC_G}) 1549 public boolean test50(Object obj) { 1550 return obj instanceof MyValue1; 1551 } 1552 1553 @Run(test = "test50") 1554 public void test50_verifier() { 1555 Asserts.assertFalse(test49(new NonValueClass(42))); 1556 } 1557 1558 // Inline type with some non-flattened fields 1559 @ImplicitlyConstructible 1560 @LooselyConsistentValue 1561 value class Test51Value { 1562 Object objectField1; 1563 Object objectField2; 1564 Object objectField3; 1565 Object objectField4; 1566 Object objectField5; 1567 Object objectField6; 1568 1569 @NullRestricted 1570 MyValue1 valueField1; 1571 @NullRestricted 1572 MyValue1 valueField2; 1573 MyValue1 valueField3; 1574 @NullRestricted 1575 MyValue1 valueField4; 1576 MyValue1 valueField5; 1577 1578 public Test51Value() { 1579 objectField1 = null; 1580 objectField2 = null; 1581 objectField3 = null; 1582 objectField4 = null; 1583 objectField5 = null; 1584 objectField6 = null; 1585 valueField1 = testValue1; 1586 valueField2 = testValue1; 1587 valueField3 = testValue1; 1588 valueField4 = MyValue1.createDefaultDontInline(); 1589 valueField5 = MyValue1.createDefaultDontInline(); 1590 } 1591 1592 public Test51Value(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, 1593 MyValue1 vt1, MyValue1 vt2, MyValue1 vt3, MyValue1 vt4, MyValue1 vt5) { 1594 objectField1 = o1; 1595 objectField2 = o2; 1596 objectField3 = o3; 1597 objectField4 = o4; 1598 objectField5 = o5; 1599 objectField6 = o6; 1600 valueField1 = vt1; 1601 valueField2 = vt2; 1602 valueField3 = vt3; 1603 valueField4 = vt4; 1604 valueField5 = vt5; 1605 } 1606 1607 @ForceInline 1608 public long test(Test51Value holder, MyValue1 vt1, Object vt2) { 1609 holder = new Test51Value(vt1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6, 1610 holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5); 1611 holder = new Test51Value(holder.objectField1, (MyValue1)vt2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6, 1612 holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5); 1613 holder = new Test51Value(holder.objectField1, holder.objectField2, testValue1, holder.objectField4, holder.objectField5, holder.objectField6, 1614 holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5); 1615 holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, MyValue1.createWithFieldsDontInline(rI, rL), holder.objectField5, holder.objectField6, 1616 holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5); 1617 holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.valueField1, holder.objectField6, 1618 holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5); 1619 holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.valueField3, 1620 holder.valueField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5); 1621 holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6, 1622 (MyValue1)holder.objectField1, holder.valueField2, holder.valueField3, holder.valueField4, holder.valueField5); 1623 holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6, 1624 holder.valueField1, (MyValue1)vt2, holder.valueField3, holder.valueField4, holder.valueField5); 1625 holder = new Test51Value(holder.objectField1, holder.objectField2, holder.objectField3, holder.objectField4, holder.objectField5, holder.objectField6, 1626 holder.valueField1, holder.valueField2, (MyValue1)vt2, holder.valueField4, holder.valueField5); 1627 1628 return ((MyValue1)holder.objectField1).hash() + 1629 ((MyValue1)holder.objectField2).hash() + 1630 ((MyValue1)holder.objectField3).hash() + 1631 ((MyValue1)holder.objectField4).hash() + 1632 ((MyValue1)holder.objectField5).hash() + 1633 ((MyValue1)holder.objectField6).hash() + 1634 holder.valueField1.hash() + 1635 holder.valueField2.hash() + 1636 holder.valueField3.hash() + 1637 holder.valueField4.hashPrimitive(); 1638 } 1639 } 1640 1641 // Pass arguments via fields to avoid exzessive spilling leading to compilation bailouts 1642 @NullRestricted 1643 static Test51Value test51_arg1; 1644 @NullRestricted 1645 static MyValue1 test51_arg2; 1646 static Object test51_arg3; 1647 1648 // Same as test2 but with field holder being an inline type 1649 @Test 1650 public long test51() { 1651 return test51_arg1.test(test51_arg1, test51_arg2, test51_arg3); 1652 } 1653 1654 @Run(test = "test51") 1655 public void test51_verifier() { 1656 MyValue1 vt = testValue1; 1657 MyValue1 def = MyValue1.createDefaultDontInline(); 1658 Test51Value holder = new Test51Value(); 1659 Asserts.assertEQ(testValue1.hash(), vt.hash()); 1660 Asserts.assertEQ(holder.valueField1.hash(), vt.hash()); 1661 test51_arg1 = holder; 1662 test51_arg2 = vt; 1663 test51_arg3 = vt; 1664 long result = test51(); 1665 Asserts.assertEQ(result, 9*vt.hash() + def.hashPrimitive()); 1666 } 1667 1668 // Access non-flattened, uninitialized inline type field with inline type holder 1669 @Test 1670 @IR(failOn = {ALLOC}) 1671 public void test52(Test51Value holder) { 1672 if ((Object)holder.valueField5 != null) { 1673 throw new RuntimeException("Should be null"); 1674 } 1675 } 1676 1677 @Run(test = "test52") 1678 public void test52_verifier() { 1679 Test51Value vt = new Test51Value(null, null, null, null, null, null, 1680 MyValue1.createDefaultInline(), MyValue1.createDefaultInline(), null, MyValue1.createDefaultInline(), null); 1681 test52(vt); 1682 } 1683 1684 // Merging inline types of different types 1685 @Test 1686 public Object test53(Object o, boolean b) { 1687 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1688 return b ? vt : o; 1689 } 1690 1691 @Run(test = "test53") 1692 public void test53_verifier() { 1693 test53(new Object(), false); 1694 MyValue1 result = (MyValue1)test53(new Object(), true); 1695 Asserts.assertEQ(result.hash(), hash()); 1696 } 1697 1698 @Test 1699 public Object test54(boolean b) { 1700 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1701 return b ? vt : testValue2; 1702 } 1703 1704 @Run(test = "test54") 1705 public void test54_verifier() { 1706 MyValue1 result1 = (MyValue1)test54(true); 1707 Asserts.assertEQ(result1.hash(), hash()); 1708 MyValue2 result2 = (MyValue2)test54(false); 1709 Asserts.assertEQ(result2.hash(), testValue2.hash()); 1710 } 1711 1712 @Test 1713 public Object test55(boolean b) { 1714 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI, rL); 1715 MyValue2 vt2 = MyValue2.createWithFieldsInline(rI, rD); 1716 return b ? vt1 : vt2; 1717 } 1718 1719 @Run(test = "test55") 1720 public void test55_verifier() { 1721 MyValue1 result1 = (MyValue1)test55(true); 1722 Asserts.assertEQ(result1.hash(), hash()); 1723 MyValue2 result2 = (MyValue2)test55(false); 1724 Asserts.assertEQ(result2.hash(), testValue2.hash()); 1725 } 1726 1727 // Test synchronization on inline types 1728 @Test 1729 public void test56(Object vt) { 1730 synchronized (vt) { 1731 throw new RuntimeException("test56 failed: synchronization on inline type should not succeed"); 1732 } 1733 } 1734 1735 @Run(test = "test56") 1736 public void test56_verifier() { 1737 try { 1738 test56(testValue1); 1739 throw new RuntimeException("test56 failed: no exception thrown"); 1740 } catch (IllegalMonitorStateException ex) { 1741 // Expected 1742 } 1743 } 1744 1745 @ForceInline 1746 public void test57_inline(Object vt) { 1747 synchronized (vt) { 1748 throw new RuntimeException("test57 failed: synchronization on inline type should not succeed"); 1749 } 1750 } 1751 1752 @Test 1753 @IR(failOn = {ALLOC_G}) 1754 public void test57(MyValue1 vt) { 1755 test57_inline(vt); 1756 } 1757 1758 @Run(test = "test57") 1759 public void test57_verifier() { 1760 try { 1761 test57(testValue1); 1762 throw new RuntimeException("test57 failed: no exception thrown"); 1763 } catch (IllegalMonitorStateException ex) { 1764 // Expected 1765 } 1766 } 1767 1768 @ForceInline 1769 public void test58_inline(Object vt) { 1770 synchronized (vt) { 1771 throw new RuntimeException("test58 failed: synchronization on inline type should not succeed"); 1772 } 1773 } 1774 1775 @Test 1776 @IR(failOn = {ALLOC}) 1777 public void test58() { 1778 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1779 test58_inline(vt); 1780 } 1781 1782 @Run(test = "test58") 1783 public void test58_verifier() { 1784 try { 1785 test58(); 1786 throw new RuntimeException("test58 failed: no exception thrown"); 1787 } catch (IllegalMonitorStateException ex) { 1788 // Expected 1789 } 1790 } 1791 1792 @Test 1793 public void test59(Object o, boolean b) { 1794 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1795 Object sync = b ? vt : o; 1796 synchronized (sync) { 1797 if (b) { 1798 throw new RuntimeException("test59 failed: synchronization on inline type should not succeed"); 1799 } 1800 } 1801 } 1802 1803 @Run(test = "test59") 1804 public void test59_verifier() { 1805 test59(new Object(), false); 1806 try { 1807 test59(new Object(), true); 1808 throw new RuntimeException("test59 failed: no exception thrown"); 1809 } catch (IllegalMonitorStateException ex) { 1810 // Expected 1811 } 1812 } 1813 1814 @Test 1815 public void test60(boolean b) { 1816 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1817 Object sync = b ? vt : testValue2; 1818 synchronized (sync) { 1819 throw new RuntimeException("test60 failed: synchronization on inline type should not succeed"); 1820 } 1821 } 1822 1823 @Run(test = "test60") 1824 public void test60_verifier() { 1825 try { 1826 test60(false); 1827 throw new RuntimeException("test60 failed: no exception thrown"); 1828 } catch (IllegalMonitorStateException ex) { 1829 // Expected 1830 } 1831 try { 1832 test60(true); 1833 throw new RuntimeException("test60 failed: no exception thrown"); 1834 } catch (IllegalMonitorStateException ex) { 1835 // Expected 1836 } 1837 } 1838 1839 // Test catching the IllegalMonitorStateException in compiled code 1840 @Test 1841 public void test61(Object vt) { 1842 boolean thrown = false; 1843 try { 1844 synchronized (vt) { 1845 throw new RuntimeException("test61 failed: no exception thrown"); 1846 } 1847 } catch (IllegalMonitorStateException ex) { 1848 thrown = true; 1849 } 1850 if (!thrown) { 1851 throw new RuntimeException("test61 failed: no exception thrown"); 1852 } 1853 } 1854 1855 @Run(test = "test61") 1856 public void test61_verifier() { 1857 test61(testValue1); 1858 } 1859 1860 @Test 1861 public void test62(Object o) { 1862 try { 1863 synchronized (o) { } 1864 } catch (IllegalMonitorStateException ex) { 1865 // Expected 1866 return; 1867 } 1868 throw new RuntimeException("test62 failed: no exception thrown"); 1869 } 1870 1871 @Run(test = "test62") 1872 public void test62_verifier() { 1873 test62(testValue1); 1874 } 1875 1876 // Test synchronization without any instructions in the synchronized block 1877 @Test 1878 public void test63(Object o) { 1879 synchronized (o) { } 1880 } 1881 1882 @Run(test = "test63") 1883 public void test63_verifier() { 1884 try { 1885 test63(testValue1); 1886 } catch (IllegalMonitorStateException ex) { 1887 // Expected 1888 return; 1889 } 1890 throw new RuntimeException("test63 failed: no exception thrown"); 1891 } 1892 1893 // type system test with interface and inline type 1894 @ForceInline 1895 public MyInterface test64Interface_helper(MyValue1 vt) { 1896 return vt; 1897 } 1898 1899 @Test 1900 public MyInterface test64Interface(MyValue1 vt) { 1901 return test64Interface_helper(vt); 1902 } 1903 1904 @Run(test = "test64Interface") 1905 public void test64Interface_verifier() { 1906 test64Interface(testValue1); 1907 } 1908 1909 // type system test with abstract and inline type 1910 @ForceInline 1911 public MyAbstract test64Abstract_helper(MyValue1 vt) { 1912 return vt; 1913 } 1914 1915 @Test 1916 public MyAbstract test64Abstract(MyValue1 vt) { 1917 return test64Abstract_helper(vt); 1918 } 1919 1920 @Run(test = "test64Abstract") 1921 public void test64Abstract_verifier() { 1922 test64Abstract(testValue1); 1923 } 1924 1925 // Array store tests 1926 @Test 1927 public void test65(Object[] array, MyValue1 vt) { 1928 array[0] = vt; 1929 } 1930 1931 @Run(test = "test65") 1932 public void test65_verifier() { 1933 Object[] array = new Object[1]; 1934 test65(array, testValue1); 1935 Asserts.assertEQ(((MyValue1)array[0]).hash(), testValue1.hash()); 1936 } 1937 1938 @Test 1939 public void test66(Object[] array, MyValue1 vt) { 1940 array[0] = vt; 1941 } 1942 1943 @Run(test = "test66") 1944 public void test66_verifier() { 1945 MyValue1[] array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 1946 test66(array, testValue1); 1947 Asserts.assertEQ(array[0].hash(), testValue1.hash()); 1948 } 1949 1950 @Test 1951 public void test67(Object[] array, Object vt) { 1952 array[0] = vt; 1953 } 1954 1955 @Run(test = "test67") 1956 public void test67_verifier() { 1957 MyValue1[] array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 1958 test67(array, testValue1); 1959 Asserts.assertEQ(array[0].hash(), testValue1.hash()); 1960 } 1961 1962 @Test 1963 public void test68(Object[] array, NonValueClass o) { 1964 array[0] = o; 1965 } 1966 1967 @Run(test = "test68") 1968 public void test68_verifier() { 1969 NonValueClass[] array = new NonValueClass[1]; 1970 NonValueClass obj = new NonValueClass(1); 1971 test68(array, obj); 1972 Asserts.assertEQ(array[0], obj); 1973 } 1974 1975 // Test convertion between an inline type and java.lang.Object without an allocation 1976 @ForceInline 1977 public Object test69_sum(Object a, Object b) { 1978 int sum = ((MyValue1)a).x + ((MyValue1)b).x; 1979 return MyValue1.setX(((MyValue1)a), sum); 1980 } 1981 1982 @Test 1983 @IR(failOn = {ALLOC_G, STORE}) 1984 public int test69(MyValue1[] array) { 1985 MyValue1 result = MyValue1.createDefaultInline(); 1986 for (int i = 0; i < array.length; ++i) { 1987 result = (MyValue1)test69_sum(result, array[i]); 1988 } 1989 return result.x; 1990 } 1991 1992 @Run(test = "test69") 1993 public void test69_verifier() { 1994 int result = test69(testValue1Array); 1995 Asserts.assertEQ(result, rI * testValue1Array.length); 1996 } 1997 1998 // Same as test69 but with an Interface 1999 @ForceInline 2000 public MyInterface test70Interface_sum(MyInterface a, MyInterface b) { 2001 int sum = ((MyValue1)a).x + ((MyValue1)b).x; 2002 return MyValue1.setX(((MyValue1)a), sum); 2003 } 2004 2005 @Test 2006 @IR(failOn = {ALLOC_G, STORE}) 2007 public int test70Interface(MyValue1[] array) { 2008 MyValue1 result = MyValue1.createDefaultInline(); 2009 for (int i = 0; i < array.length; ++i) { 2010 result = (MyValue1)test70Interface_sum(result, array[i]); 2011 } 2012 return result.x; 2013 } 2014 2015 @Run(test = "test70Interface") 2016 public void test70Interface_verifier() { 2017 int result = test70Interface(testValue1Array); 2018 Asserts.assertEQ(result, rI * testValue1Array.length); 2019 } 2020 2021 // Same as test69 but with an Abstract 2022 @ForceInline 2023 public MyAbstract test70Abstract_sum(MyAbstract a, MyAbstract b) { 2024 int sum = ((MyValue1)a).x + ((MyValue1)b).x; 2025 return MyValue1.setX(((MyValue1)a), sum); 2026 } 2027 2028 @Test 2029 @IR(failOn = {ALLOC_G, STORE}) 2030 public int test70Abstract(MyValue1[] array) { 2031 MyValue1 result = MyValue1.createDefaultInline(); 2032 for (int i = 0; i < array.length; ++i) { 2033 result = (MyValue1)test70Abstract_sum(result, array[i]); 2034 } 2035 return result.x; 2036 } 2037 2038 @Run(test = "test70Abstract") 2039 public void test70Abstract_verifier() { 2040 int result = test70Abstract(testValue1Array); 2041 Asserts.assertEQ(result, rI * testValue1Array.length); 2042 } 2043 2044 // Test that allocated inline type is not used in non-dominated path 2045 public MyValue1 test71_inline(Object obj) { 2046 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 2047 try { 2048 vt = (MyValue1)Objects.requireNonNull(obj); 2049 throw new RuntimeException("NullPointerException expected"); 2050 } catch (NullPointerException e) { 2051 // Expected 2052 } 2053 return vt; 2054 } 2055 2056 @Test 2057 @IR(failOn = {ALLOC}) 2058 public MyValue1 test71() { 2059 return test71_inline(null); 2060 } 2061 2062 @Run(test = "test71") 2063 public void test71_verifier() { 2064 MyValue1 vt = test71(); 2065 Asserts.assertEquals(vt.hash(), hash()); 2066 } 2067 2068 // Test calling a method on an uninitialized inline type 2069 @ImplicitlyConstructible 2070 @LooselyConsistentValue 2071 value class Test72Value { 2072 int x = 0; 2073 2074 public int get() { 2075 return x; 2076 } 2077 } 2078 2079 // Make sure Test72Value is loaded but not initialized 2080 public void unused(Test72Value vt) { } 2081 2082 @Test 2083 @IR(failOn = {ALLOC_G}) 2084 public int test72() { 2085 Test72Value vt = new Test72Value(); 2086 return vt.get(); 2087 } 2088 2089 @Run(test = "test72") 2090 @Warmup(0) 2091 public void test72_verifier() { 2092 int result = test72(); 2093 Asserts.assertEquals(result, 0); 2094 } 2095 2096 // Tests for loading/storing unkown values 2097 @Test 2098 public Object test73(Object[] va) { 2099 return va[0]; 2100 } 2101 2102 @Run(test = "test73") 2103 public void test73_verifier() { 2104 MyValue1 vt = (MyValue1)test73(testValue1Array); 2105 Asserts.assertEquals(testValue1Array[0].hash(), vt.hash()); 2106 } 2107 2108 @Test 2109 public void test74(Object[] va, Object vt) { 2110 va[0] = vt; 2111 } 2112 2113 @Run(test = "test74") 2114 public void test74_verifier() { 2115 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2116 test74(va, testValue1); 2117 Asserts.assertEquals(va[0].hash(), testValue1.hash()); 2118 } 2119 2120 // Verify that mixing instances and arrays with the clone api 2121 // doesn't break anything 2122 @Test 2123 @IR(failOn = {ALLOC_G}) 2124 public Object test75(Object o) { 2125 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2126 Object[] next = va; 2127 Object[] arr = va; 2128 for (int i = 0; i < 10; i++) { 2129 arr = next; 2130 next = new NonValueClass[1]; 2131 } 2132 return arr[0]; 2133 } 2134 2135 @Run(test = "test75") 2136 public void test75_verifier() { 2137 test75(42); 2138 } 2139 2140 // Casting an NonValueClass to a inline type should throw a ClassCastException 2141 @ForceInline 2142 public MyValue1 test77_helper(Object o) { 2143 return (MyValue1)o; 2144 } 2145 2146 @Test 2147 @IR(failOn = {ALLOC_G}) 2148 public MyValue1 test77(NonValueClass obj) throws Throwable { 2149 return test77_helper(obj); 2150 } 2151 2152 @Run(test = "test77") 2153 public void test77_verifier() throws Throwable { 2154 try { 2155 test77(new NonValueClass(42)); 2156 throw new RuntimeException("ClassCastException expected"); 2157 } catch (ClassCastException e) { 2158 // Expected 2159 } catch (Exception e) { 2160 throw new RuntimeException("test77 failed: unexpected exception", e); 2161 } 2162 } 2163 2164 // Casting a null NonValueClass to a nullable inline type should not throw 2165 @ForceInline 2166 public MyValue1 test78_helper(Object o) { 2167 return (MyValue1)o; 2168 } 2169 2170 @Test 2171 @IR(failOn = {ALLOC_G}) 2172 public MyValue1 test78(NonValueClass obj) throws Throwable { 2173 return test78_helper(obj); 2174 } 2175 2176 @Run(test = "test78") 2177 public void test78_verifier() throws Throwable { 2178 try { 2179 test78(null); // Should not throw 2180 } catch (Exception e) { 2181 throw new RuntimeException("test78 failed: unexpected exception", e); 2182 } 2183 } 2184 2185 // Casting an NonValueClass to a nullable inline type should throw a ClassCastException 2186 @ForceInline 2187 public MyValue1 test79_helper(Object o) { 2188 return (MyValue1)o; 2189 } 2190 2191 @Test 2192 @IR(failOn = {ALLOC_G}) 2193 public MyValue1 test79(NonValueClass obj) throws Throwable { 2194 return test79_helper(obj); 2195 } 2196 2197 @Run(test = "test79") 2198 public void test79_verifier() throws Throwable { 2199 try { 2200 test79(new NonValueClass(42)); 2201 throw new RuntimeException("ClassCastException expected"); 2202 } catch (ClassCastException e) { 2203 // Expected 2204 } catch (Exception e) { 2205 throw new RuntimeException("test79 failed: unexpected exception", e); 2206 } 2207 } 2208 2209 // Test flattened field with non-flattenend (but flattenable) inline type field 2210 @ImplicitlyConstructible 2211 @LooselyConsistentValue 2212 static value class Small { 2213 int i; 2214 @NullRestricted 2215 Big big; // Too big to be flattened 2216 2217 private Small() { 2218 i = rI; 2219 big = new Big(); 2220 } 2221 } 2222 2223 @ImplicitlyConstructible 2224 @LooselyConsistentValue 2225 static value class Big { 2226 long l0,l1,l2,l3,l4,l5,l6,l7,l8,l9; 2227 long l10,l11,l12,l13,l14,l15,l16,l17,l18,l19; 2228 long l20,l21,l22,l23,l24,l25,l26,l27,l28,l29; 2229 2230 private Big() { 2231 l0 = l1 = l2 = l3 = l4 = l5 = l6 = l7 = l8 = l9 = rL; 2232 l10 = l11 = l12 = l13 = l14 = l15 = l16 = l17 = l18 = l19 = rL+1; 2233 l20 = l21 = l22 = l23 = l24 = l25 = l26 = l27 = l28 = l29 = rL+2; 2234 } 2235 } 2236 2237 @NullRestricted 2238 Small small = new Small(); 2239 @NullRestricted 2240 Small smallDefault; 2241 @NullRestricted 2242 Big big = new Big(); 2243 @NullRestricted 2244 Big bigDefault; 2245 2246 @Test 2247 public long test80() { 2248 return small.i + small.big.l0 + smallDefault.i + smallDefault.big.l29 + big.l0 + bigDefault.l29; 2249 } 2250 2251 @Run(test = "test80") 2252 public void test80_verifier() throws Throwable { 2253 long result = test80(); 2254 Asserts.assertEQ(result, rI + 2*rL); 2255 } 2256 2257 // Test scalarization with exceptional control flow 2258 public int test81Callee(MyValue1 vt) { 2259 return vt.x; 2260 } 2261 2262 @Test 2263 @IR(failOn = {ALLOC_G, LOAD, STORE}) 2264 public int test81() { 2265 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 2266 int result = 0; 2267 for (int i = 0; i < 10; i++) { 2268 try { 2269 result += test81Callee(vt); 2270 } catch (NullPointerException npe) { 2271 result += rI; 2272 } 2273 } 2274 return result; 2275 } 2276 2277 @Run(test = "test81") 2278 public void test81_verifier() { 2279 int result = test81(); 2280 Asserts.assertEQ(result, 10*rI); 2281 } 2282 2283 // Test check for null free array when storing to inline tpye array 2284 @Test 2285 public void test82(Object[] dst, Object v) { 2286 dst[0] = v; 2287 } 2288 2289 @Run(test = "test82") 2290 public void test82_verifier(RunInfo info) { 2291 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1); 2292 test82(dst, testValue2); 2293 if (!info.isWarmUp()) { 2294 try { 2295 test82(dst, null); 2296 throw new RuntimeException("No ArrayStoreException thrown"); 2297 } catch (NullPointerException e) { 2298 // Expected 2299 } 2300 } 2301 } 2302 2303 @Test 2304 @IR(failOn = {ALLOC_G}) 2305 public void test83(Object[] dst, Object v, boolean flag) { 2306 if (dst == null) { // null check 2307 } 2308 if (flag) { 2309 if (dst.getClass() == MyValue1[].class) { // trigger split if 2310 } 2311 } else { 2312 dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1); // constant null free property 2313 } 2314 dst[0] = v; 2315 } 2316 2317 @Run(test = "test83") 2318 @Warmup(10000) 2319 public void test83_verifier(RunInfo info) { 2320 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1); 2321 test83(dst, testValue2, false); 2322 test83(dst, testValue2, true); 2323 if (!info.isWarmUp()) { 2324 try { 2325 test83(dst, null, true); 2326 throw new RuntimeException("No ArrayStoreException thrown"); 2327 } catch (NullPointerException e) { 2328 // Expected 2329 } 2330 } 2331 } 2332 2333 private void rerun_and_recompile_for(Method m, int num, Runnable test) { 2334 for (int i = 1; i < num; i++) { 2335 test.run(); 2336 2337 if (!TestFramework.isCompiled(m)) { 2338 TestFramework.compile(m, CompLevel.C2); 2339 } 2340 } 2341 } 2342 2343 // Tests for the Loop Unswitching optimization 2344 // Should make 2 copies of the loop, one for non flattened arrays, one for other cases. 2345 @Test 2346 @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, 2347 counts = {COUNTEDLOOP_MAIN, "= 2"}) 2348 @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, 2349 counts = {COUNTEDLOOP_MAIN, "= 1"}) 2350 public void test84(Object[] src, Object[] dst) { 2351 for (int i = 0; i < src.length; i++) { 2352 dst[i] = src[i]; 2353 } 2354 } 2355 2356 @Run(test = "test84") 2357 @Warmup(0) 2358 public void test84_verifier(RunInfo info) { 2359 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 2360 Arrays.fill(src, testValue2); 2361 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 2362 rerun_and_recompile_for(info.getTest(), 10, 2363 () -> { test84(src, dst); 2364 Asserts.assertTrue(Arrays.equals(src, dst)); }); 2365 } 2366 2367 @Test 2368 @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"}, 2369 counts = {COUNTEDLOOP, "= 2", LOAD_UNKNOWN_INLINE, "= 1"}) 2370 @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"}, 2371 counts = {COUNTEDLOOP_MAIN, "= 2", LOAD_UNKNOWN_INLINE, "= 4"}) 2372 public void test85(Object[] src, Object[] dst) { 2373 for (int i = 0; i < src.length; i++) { 2374 dst[i] = src[i]; 2375 } 2376 } 2377 2378 @Run(test = "test85") 2379 @Warmup(0) 2380 public void test85_verifier(RunInfo info) { 2381 Object[] src = new Object[100]; 2382 Arrays.fill(src, new Object()); 2383 src[0] = null; 2384 Object[] dst = new Object[100]; 2385 rerun_and_recompile_for(info.getTest(), 10, 2386 () -> { test85(src, dst); 2387 Asserts.assertTrue(Arrays.equals(src, dst)); }); 2388 } 2389 2390 @Test 2391 @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"}, 2392 counts = {COUNTEDLOOP, "= 2"}) 2393 @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"}, 2394 counts = {COUNTEDLOOP_MAIN, "= 2"}) 2395 public void test86(Object[] src, Object[] dst) { 2396 for (int i = 0; i < src.length; i++) { 2397 dst[i] = src[i]; 2398 } 2399 } 2400 2401 @Run(test = "test86") 2402 @Warmup(0) 2403 public void test86_verifier(RunInfo info) { 2404 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 2405 Arrays.fill(src, testValue2); 2406 Object[] dst = new Object[100]; 2407 rerun_and_recompile_for(info.getTest(), 10, 2408 () -> { test86(src, dst); 2409 Asserts.assertTrue(Arrays.equals(src, dst)); }); 2410 } 2411 2412 @Test 2413 @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, 2414 counts = {COUNTEDLOOP_MAIN, "= 2"}) 2415 @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, 2416 counts = {COUNTEDLOOP_MAIN, "= 1"}) 2417 public void test87(Object[] src, Object[] dst) { 2418 for (int i = 0; i < src.length; i++) { 2419 dst[i] = src[i]; 2420 } 2421 } 2422 2423 @Run(test = "test87") 2424 @Warmup(0) 2425 public void test87_verifier(RunInfo info) { 2426 Object[] src = new Object[100]; 2427 Arrays.fill(src, testValue2); 2428 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 2429 2430 rerun_and_recompile_for(info.getTest(), 10, 2431 () -> { test87(src, dst); 2432 Asserts.assertTrue(Arrays.equals(src, dst)); }); 2433 } 2434 2435 @Test 2436 @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, 2437 counts = {COUNTEDLOOP_MAIN, "= 2"}) 2438 @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, 2439 counts = {COUNTEDLOOP_MAIN, "= 0"}) 2440 public void test88(Object[] src1, Object[] dst1, Object[] src2, Object[] dst2) { 2441 for (int i = 0; i < src1.length; i++) { 2442 dst1[i] = src1[i]; 2443 dst2[i] = src2[i]; 2444 } 2445 } 2446 2447 @Run(test = "test88") 2448 @Warmup(0) 2449 public void test88_verifier(RunInfo info) { 2450 MyValue2[] src1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 2451 Arrays.fill(src1, testValue2); 2452 MyValue2[] dst1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 2453 Object[] src2 = new Object[100]; 2454 Arrays.fill(src2, new Object()); 2455 Object[] dst2 = new Object[100]; 2456 2457 rerun_and_recompile_for(info.getTest(), 10, 2458 () -> { test88(src1, dst1, src2, dst2); 2459 Asserts.assertTrue(Arrays.equals(src1, dst1)); 2460 Asserts.assertTrue(Arrays.equals(src2, dst2)); }); 2461 } 2462 2463 @Test 2464 public boolean test89(Object obj) { 2465 return obj.getClass() == NonValueClass.class; 2466 } 2467 2468 @Run(test = "test89") 2469 public void test89_verifier() { 2470 Asserts.assertTrue(test89(new NonValueClass(42))); 2471 Asserts.assertFalse(test89(new Object())); 2472 } 2473 2474 @Test 2475 public NonValueClass test90(Object obj) { 2476 return (NonValueClass)obj; 2477 } 2478 2479 @Run(test = "test90") 2480 public void test90_verifier() { 2481 test90(new NonValueClass(42)); 2482 try { 2483 test90(new Object()); 2484 throw new RuntimeException("ClassCastException expected"); 2485 } catch (ClassCastException e) { 2486 // Expected 2487 } 2488 } 2489 2490 @Test 2491 public boolean test91(Object obj) { 2492 return obj.getClass() == MyValue2[].class; 2493 } 2494 2495 @Run(test = "test91") 2496 public void test91_verifier() { 2497 Asserts.assertFalse(test91((MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1))); 2498 Asserts.assertTrue(test91(new MyValue2[1])); 2499 Asserts.assertFalse(test91(new Object())); 2500 } 2501 2502 @ImplicitlyConstructible 2503 @LooselyConsistentValue 2504 static value class Test92Value { 2505 int field; 2506 2507 public Test92Value() { 2508 field = 0x42; 2509 } 2510 } 2511 2512 @Test 2513 @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, 2514 counts = {CLASS_CHECK_TRAP, "= 2"}, 2515 failOn = {LOAD_UNKNOWN_INLINE, ALLOC_G, MEMBAR}) 2516 public Object test92(Object[] array) { 2517 // Dummy loops to ensure we run enough passes of split if 2518 for (int i = 0; i < 2; i++) { 2519 for (int j = 0; j < 2; j++) { 2520 for (int k = 0; k < 2; k++) { 2521 } 2522 } 2523 } 2524 2525 return (NonValueClass)array[0]; 2526 } 2527 2528 @Run(test = "test92") 2529 @Warmup(10000) 2530 public void test92_verifier() { 2531 Object[] array = new Object[1]; 2532 Object obj = new NonValueClass(rI); 2533 array[0] = obj; 2534 Object result = test92(array); 2535 Asserts.assertEquals(result, obj); 2536 } 2537 2538 // If the class check succeeds, the flattened array check that 2539 // precedes will never succeed and the flat array branch should 2540 // trigger an uncommon trap. 2541 @Test 2542 public Object test93(Object[] array) { 2543 for (int i = 0; i < 2; i++) { 2544 for (int j = 0; j < 2; j++) { 2545 } 2546 } 2547 2548 Object v = (NonValueClass)array[0]; 2549 return v; 2550 } 2551 2552 @Run(test = "test93") 2553 @Warmup(10000) 2554 public void test93_verifier(RunInfo info) { 2555 if (info.isWarmUp()) { 2556 Object[] array = new Object[1]; 2557 array[0] = new NonValueClass(42); 2558 Object result = test93(array); 2559 Asserts.assertEquals(((NonValueClass)result).x, 42); 2560 } else { 2561 Object[] array = (Test92Value[])ValueClass.newNullRestrictedArray(Test92Value.class, 1); 2562 Method m = info.getTest(); 2563 int extra = 3; 2564 for (int j = 0; j < extra; j++) { 2565 for (int i = 0; i < 10; i++) { 2566 try { 2567 test93(array); 2568 } catch (ClassCastException cce) { 2569 } 2570 } 2571 boolean compiled = TestFramework.isCompiled(m); 2572 boolean compilationSkipped = info.isCompilationSkipped(); 2573 Asserts.assertTrue(compilationSkipped || compiled || (j != extra-1)); 2574 if (!compilationSkipped && !compiled) { 2575 TestFramework.compile(m, CompLevel.ANY); 2576 } 2577 } 2578 } 2579 } 2580 2581 @Test 2582 @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, 2583 counts = {CLASS_CHECK_TRAP, "= 2", LOOP, "= 1"}, 2584 failOn = {LOAD_UNKNOWN_INLINE, ALLOC_G, MEMBAR}) 2585 public int test94(Object[] array) { 2586 int res = 0; 2587 for (int i = 1; i < 4; i *= 2) { 2588 Object v = array[i]; 2589 res += ((NonValueClass)v).x; 2590 } 2591 return res; 2592 } 2593 2594 @Run(test = "test94") 2595 @Warmup(10000) 2596 public void test94_verifier() { 2597 Object[] array = new Object[4]; 2598 Object obj = new NonValueClass(rI); 2599 array[0] = obj; 2600 array[1] = obj; 2601 array[2] = obj; 2602 array[3] = obj; 2603 int result = test94(array); 2604 Asserts.assertEquals(result, rI * 2); 2605 } 2606 2607 @Test 2608 public boolean test95(Object o1, Object o2) { 2609 return o1 == o2; 2610 } 2611 2612 @Run(test = "test95") 2613 @Warmup(10000) 2614 public void test95_verifier() { 2615 Object o1 = new Object(); 2616 Object o2 = new Object(); 2617 Asserts.assertTrue(test95(o1, o1)); 2618 Asserts.assertTrue(test95(null, null)); 2619 Asserts.assertFalse(test95(o1, null)); 2620 Asserts.assertFalse(test95(o1, o2)); 2621 } 2622 2623 @Test 2624 public boolean test96(Object o1, Object o2) { 2625 return o1 == o2; 2626 } 2627 2628 @Run(test = "test96") 2629 @Warmup(10000) 2630 public void test96_verifier(RunInfo info) { 2631 Object o1 = new Object(); 2632 Object o2 = new Object(); 2633 Asserts.assertTrue(test96(o1, o1)); 2634 Asserts.assertFalse(test96(o1, o2)); 2635 if (!info.isWarmUp()) { 2636 Asserts.assertTrue(test96(null, null)); 2637 Asserts.assertFalse(test96(o1, null)); 2638 } 2639 } 2640 2641 // Abstract class tests 2642 2643 @DontInline 2644 public MyAbstract test97_dontinline1(MyAbstract o) { 2645 return o; 2646 } 2647 2648 @DontInline 2649 public MyValue1 test97_dontinline2(MyAbstract o) { 2650 return (MyValue1)o; 2651 } 2652 2653 @ForceInline 2654 public MyAbstract test97_inline1(MyAbstract o) { 2655 return o; 2656 } 2657 2658 @ForceInline 2659 public MyValue1 test97_inline2(MyAbstract o) { 2660 return (MyValue1)o; 2661 } 2662 2663 @Test 2664 public MyValue1 test97() { 2665 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 2666 vt = (MyValue1)test97_dontinline1(vt); 2667 vt = test97_dontinline2(vt); 2668 vt = (MyValue1)test97_inline1(vt); 2669 vt = test97_inline2(vt); 2670 return vt; 2671 } 2672 2673 @Run(test = "test97") 2674 public void test97_verifier() { 2675 Asserts.assertEQ(test97().hash(), hash()); 2676 } 2677 2678 // Test storing/loading inline types to/from abstract and inline type fields 2679 MyAbstract abstractField1 = null; 2680 MyAbstract abstractField2 = null; 2681 MyAbstract abstractField3 = null; 2682 MyAbstract abstractField4 = null; 2683 MyAbstract abstractField5 = null; 2684 MyAbstract abstractField6 = null; 2685 2686 @DontInline 2687 public MyAbstract readValueField5AsAbstract() { 2688 return (MyAbstract)valueField5; 2689 } 2690 2691 @DontInline 2692 public MyAbstract readStaticValueField4AsAbstract() { 2693 return (MyAbstract)staticValueField4; 2694 } 2695 2696 @Test 2697 public long test98(MyValue1 vt1, MyAbstract vt2) { 2698 abstractField1 = vt1; 2699 abstractField2 = (MyValue1)vt2; 2700 abstractField3 = MyValue1.createWithFieldsInline(rI, rL); 2701 abstractField4 = MyValue1.createWithFieldsDontInline(rI, rL); 2702 abstractField5 = valueField1; 2703 abstractField6 = valueField3; 2704 valueField1 = (MyValue1)abstractField1; 2705 valueField2 = (MyValue1)vt2; 2706 valueField3 = (MyValue1)vt2; 2707 staticValueField1 = (MyValue1)abstractField1; 2708 staticValueField2 = (MyValue1)vt1; 2709 // Don't inline these methods because reading NULL will trigger a deoptimization 2710 if (readValueField5AsAbstract() != null || readStaticValueField4AsAbstract() != null) { 2711 throw new RuntimeException("Should be null"); 2712 } 2713 return ((MyValue1)abstractField1).hash() + ((MyValue1)abstractField2).hash() + 2714 ((MyValue1)abstractField3).hash() + ((MyValue1)abstractField4).hash() + 2715 ((MyValue1)abstractField5).hash() + ((MyValue1)abstractField6).hash() + 2716 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() + 2717 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); 2718 } 2719 2720 @Run(test = "test98") 2721 public void test98_verifier() { 2722 MyValue1 vt = testValue1; 2723 MyValue1 def = MyValue1.createDefaultDontInline(); 2724 long result = test98(vt, vt); 2725 Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); 2726 } 2727 2728 value class MyObject2 extends MyAbstract { 2729 public int x; 2730 2731 public MyObject2(int x) { 2732 this.x = x; 2733 } 2734 2735 @ForceInline 2736 public long hash() { 2737 return x; 2738 } 2739 } 2740 2741 // Test merging inline types and abstract classes 2742 @Test 2743 public MyAbstract test99(int state) { 2744 MyAbstract res = null; 2745 if (state == 0) { 2746 res = new MyObject2(rI); 2747 } else if (state == 1) { 2748 res = MyValue1.createWithFieldsInline(rI, rL); 2749 } else if (state == 2) { 2750 res = MyValue1.createWithFieldsDontInline(rI, rL); 2751 } else if (state == 3) { 2752 res = (MyValue1)objectField1; 2753 } else if (state == 4) { 2754 res = valueField1; 2755 } else if (state == 5) { 2756 res = null; 2757 } 2758 return res; 2759 } 2760 2761 @Run(test = "test99") 2762 public void test99_verifier() { 2763 objectField1 = valueField1; 2764 MyAbstract result = null; 2765 result = test99(0); 2766 Asserts.assertEQ(((MyObject2)result).x, rI); 2767 result = test99(1); 2768 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 2769 result = test99(2); 2770 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 2771 result = test99(3); 2772 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 2773 result = test99(4); 2774 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 2775 result = test99(5); 2776 Asserts.assertEQ(result, null); 2777 } 2778 2779 // Test merging inline types and abstract classes in loops 2780 @Test 2781 public MyAbstract test100(int iters) { 2782 MyAbstract res = new MyObject2(rI); 2783 for (int i = 0; i < iters; ++i) { 2784 if (res instanceof MyObject2) { 2785 res = MyValue1.createWithFieldsInline(rI, rL); 2786 } else { 2787 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL); 2788 } 2789 } 2790 return res; 2791 } 2792 2793 @Run(test = "test100") 2794 public void test100_verifier() { 2795 MyObject2 result1 = (MyObject2)test100(0); 2796 Asserts.assertEQ(result1.x, rI); 2797 int iters = (Math.abs(rI) % 10) + 1; 2798 MyValue1 result2 = (MyValue1)test100(iters); 2799 MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL); 2800 Asserts.assertEQ(result2.hash(), vt.hash()); 2801 } 2802 2803 // Test inline types in abstract class variables that are live at safepoint 2804 @Test 2805 @IR(failOn = {ALLOC, STORE, LOOP}) 2806 public long test101(MyValue1 arg, boolean deopt, Method m) { 2807 MyAbstract vt1 = MyValue1.createWithFieldsInline(rI, rL); 2808 MyAbstract vt2 = MyValue1.createWithFieldsDontInline(rI, rL); 2809 MyAbstract vt3 = arg; 2810 MyAbstract vt4 = valueField1; 2811 if (deopt) { 2812 // uncommon trap 2813 TestFramework.deoptimize(m); 2814 } 2815 return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + 2816 ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); 2817 } 2818 2819 @Run(test = "test101") 2820 public void test101_verifier(RunInfo info) { 2821 long result = test101(valueField1, !info.isWarmUp(), info.getTest()); 2822 Asserts.assertEQ(result, 4*hash()); 2823 } 2824 2825 // Test comparing inline types with abstract classes 2826 @Test 2827 public boolean test102(Object arg) { 2828 MyAbstract vt = MyValue1.createWithFieldsInline(rI, rL); 2829 if (vt == arg || vt == (MyAbstract)valueField1 || vt == abstractField1 || vt == null || 2830 arg == vt || (MyAbstract)valueField1 == vt || abstractField1 == vt || null == vt) { 2831 return true; 2832 } 2833 return false; 2834 } 2835 2836 @Run(test = "test102") 2837 public void test102_verifier() { 2838 boolean result = test102(null); 2839 Asserts.assertFalse(result); 2840 } 2841 2842 // An abstract class with a non-static field can never be implemented by an inline type 2843 abstract class NoValueImplementors1 { 2844 int field = 42; 2845 } 2846 2847 class MyObject3 extends NoValueImplementors1 { 2848 2849 } 2850 2851 class MyObject4 extends NoValueImplementors1 { 2852 2853 } 2854 2855 // Loading from an abstract class array does not require a flatness check if the abstract class has a non-static field 2856 @Test 2857 @IR(failOn = {ALLOC_G, MEMBAR, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 2858 public NoValueImplementors1 test103(NoValueImplementors1[] array, int i) { 2859 return array[i]; 2860 } 2861 2862 @Run(test = "test103") 2863 public void test103_verifier() { 2864 NoValueImplementors1[] array1 = new NoValueImplementors1[3]; 2865 MyObject3[] array2 = new MyObject3[3]; 2866 MyObject4[] array3 = new MyObject4[3]; 2867 NoValueImplementors1 result = test103(array1, 0); 2868 Asserts.assertEquals(result, array1[0]); 2869 2870 result = test103(array2, 1); 2871 Asserts.assertEquals(result, array1[1]); 2872 2873 result = test103(array3, 2); 2874 Asserts.assertEquals(result, array1[2]); 2875 } 2876 2877 // Storing to an abstract class array does not require a flatness/null check if the abstract class has a non-static field 2878 @Test 2879 @IR(failOn = {ALLOC_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 2880 public NoValueImplementors1 test104(NoValueImplementors1[] array, NoValueImplementors1 v, MyObject3 o, int i) { 2881 array[0] = v; 2882 array[1] = array[0]; 2883 array[2] = o; 2884 return array[i]; 2885 } 2886 2887 @Run(test = "test104") 2888 public void test104_verifier() { 2889 MyObject4 v = new MyObject4(); 2890 MyObject3 o = new MyObject3(); 2891 NoValueImplementors1[] array1 = new NoValueImplementors1[3]; 2892 MyObject3[] array2 = new MyObject3[3]; 2893 MyObject4[] array3 = new MyObject4[3]; 2894 NoValueImplementors1 result = test104(array1, v, o, 0); 2895 Asserts.assertEquals(array1[0], v); 2896 Asserts.assertEquals(array1[1], v); 2897 Asserts.assertEquals(array1[2], o); 2898 Asserts.assertEquals(result, v); 2899 2900 result = test104(array2, o, o, 1); 2901 Asserts.assertEquals(array2[0], o); 2902 Asserts.assertEquals(array2[1], o); 2903 Asserts.assertEquals(array2[2], o); 2904 Asserts.assertEquals(result, o); 2905 2906 result = test104(array3, v, null, 1); 2907 Asserts.assertEquals(array3[0], v); 2908 Asserts.assertEquals(array3[1], v); 2909 Asserts.assertEquals(array3[2], null); 2910 Asserts.assertEquals(result, v); 2911 } 2912 2913 // An abstract class with a single, non-inline implementor 2914 abstract class NoValueImplementors2 { 2915 2916 } 2917 2918 class MyObject5 extends NoValueImplementors2 { 2919 2920 } 2921 2922 // Loading from an abstract class array does not require a flatness check if the abstract class has no inline implementor 2923 @Test 2924 @IR(failOn = {ALLOC_G, MEMBAR, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 2925 public NoValueImplementors2 test105(NoValueImplementors2[] array, int i) { 2926 return array[i]; 2927 } 2928 2929 @Run(test = "test105") 2930 public void test105_verifier() { 2931 NoValueImplementors2[] array1 = new NoValueImplementors2[3]; 2932 MyObject5[] array2 = new MyObject5[3]; 2933 NoValueImplementors2 result = test105(array1, 0); 2934 Asserts.assertEquals(result, array1[0]); 2935 2936 result = test105(array2, 1); 2937 Asserts.assertEquals(result, array1[1]); 2938 } 2939 2940 // Storing to an abstract class array does not require a flatness/null check if the abstract class has no inline implementor 2941 @Test 2942 @IR(failOn = {ALLOC_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 2943 public NoValueImplementors2 test106(NoValueImplementors2[] array, NoValueImplementors2 v, MyObject5 o, int i) { 2944 array[0] = v; 2945 array[1] = array[0]; 2946 array[2] = o; 2947 return array[i]; 2948 } 2949 2950 @Run(test = "test106") 2951 public void test106_verifier() { 2952 MyObject5 v = new MyObject5(); 2953 NoValueImplementors2[] array1 = new NoValueImplementors2[3]; 2954 MyObject5[] array2 = new MyObject5[3]; 2955 NoValueImplementors2 result = test106(array1, v, null, 0); 2956 Asserts.assertEquals(array1[0], v); 2957 Asserts.assertEquals(array1[1], v); 2958 Asserts.assertEquals(array1[2], null); 2959 Asserts.assertEquals(result, v); 2960 2961 result = test106(array2, v, v, 1); 2962 Asserts.assertEquals(array2[0], v); 2963 Asserts.assertEquals(array2[1], v); 2964 Asserts.assertEquals(array2[2], v); 2965 Asserts.assertEquals(result, v); 2966 } 2967 2968 // More tests for the Loop Unswitching optimization (similar to test84 and following) 2969 Object oFld1, oFld2; 2970 2971 @Test 2972 @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"}, 2973 failOn = {STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, 2974 counts = {COUNTEDLOOP, "= 2", LOAD_UNKNOWN_INLINE, "= 2"}) 2975 @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"}, 2976 failOn = {STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, 2977 counts = {COUNTEDLOOP, "= 3", LOAD_UNKNOWN_INLINE, "= 2"}) 2978 public void test107(Object[] src1, Object[] src2) { 2979 for (int i = 0; i < src1.length; i++) { 2980 oFld1 = src1[i]; 2981 oFld2 = src2[i]; 2982 } 2983 } 2984 2985 @Run(test = "test107") 2986 @Warmup(0) 2987 public void test107_verifier(RunInfo info) { 2988 MyValue2[] src1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 2989 Arrays.fill(src1, testValue2); 2990 Object[] src2 = new Object[100]; 2991 Object obj = new Object(); 2992 Arrays.fill(src2, obj); 2993 rerun_and_recompile_for(info.getTest(), 10, 2994 () -> { test107(src1, src2); 2995 Asserts.assertEquals(oFld1, testValue2); 2996 Asserts.assertEquals(oFld2, obj); 2997 test107(src2, src1); 2998 Asserts.assertEquals(oFld1, obj); 2999 Asserts.assertEquals(oFld2, testValue2); }); 3000 } 3001 3002 @Test 3003 @IR(applyIfAnd = {"UseG1GC", "true", "FlatArrayElementMaxSize", "= -1"}, 3004 failOn = {LOAD_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, 3005 counts = {COUNTEDLOOP, "= 4", STORE_UNKNOWN_INLINE, "= 9"}) 3006 @IR(applyIfAnd = {"UseG1GC", "false", "FlatArrayElementMaxSize", "= -1"}, 3007 failOn = {LOAD_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, 3008 counts = {COUNTEDLOOP, "= 4", STORE_UNKNOWN_INLINE, "= 12"}) 3009 public void test108(Object[] dst1, Object[] dst2, Object o1, Object o2) { 3010 for (int i = 0; i < dst1.length; i++) { 3011 dst1[i] = o1; 3012 dst2[i] = o2; 3013 } 3014 } 3015 3016 @Run(test = "test108") 3017 @Warmup(0) 3018 public void test108_verifier(RunInfo info) { 3019 MyValue2[] dst1 = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 100); 3020 Object[] dst2 = new Object[100]; 3021 Object o1 = new Object(); 3022 rerun_and_recompile_for(info.getTest(), 10, 3023 () -> { test108(dst1, dst2, testValue2, o1); 3024 for (int i = 0; i < dst1.length; i++) { 3025 Asserts.assertEquals(dst1[i], testValue2); 3026 Asserts.assertEquals(dst2[i], o1); 3027 } 3028 test108(dst2, dst1, o1, testValue2); 3029 for (int i = 0; i < dst1.length; i++) { 3030 Asserts.assertEquals(dst1[i], testValue2); 3031 Asserts.assertEquals(dst2[i], o1); 3032 } }); 3033 } 3034 3035 // Escape analysis tests 3036 3037 static interface WrapperInterface { 3038 long value(); 3039 3040 final static WrapperInterface ZERO = new LongWrapper(0); 3041 3042 @ForceInline 3043 static WrapperInterface wrap(long val) { 3044 return (val == 0L) ? ZERO : new LongWrapper(val); 3045 } 3046 } 3047 3048 @ForceCompileClassInitializer 3049 @ImplicitlyConstructible 3050 @LooselyConsistentValue 3051 static value class LongWrapper implements WrapperInterface { 3052 @NullRestricted 3053 final static LongWrapper ZERO = new LongWrapper(0); 3054 private long val; 3055 3056 @ForceInline 3057 LongWrapper(long val) { 3058 this.val = val; 3059 } 3060 3061 @ForceInline 3062 static LongWrapper wrap(long val) { 3063 return (val == 0L) ? ZERO : new LongWrapper(val); 3064 } 3065 3066 @ForceInline 3067 public long value() { 3068 return val; 3069 } 3070 } 3071 3072 static class InterfaceBox { 3073 WrapperInterface content; 3074 3075 @ForceInline 3076 InterfaceBox(WrapperInterface content) { 3077 this.content = content; 3078 } 3079 3080 @ForceInline 3081 static InterfaceBox box_sharp(long val) { 3082 return new InterfaceBox(LongWrapper.wrap(val)); 3083 } 3084 3085 @ForceInline 3086 static InterfaceBox box(long val) { 3087 return new InterfaceBox(WrapperInterface.wrap(val)); 3088 } 3089 } 3090 3091 static class ObjectBox { 3092 Object content; 3093 3094 @ForceInline 3095 ObjectBox(Object content) { 3096 this.content = content; 3097 } 3098 3099 @ForceInline 3100 static ObjectBox box_sharp(long val) { 3101 return new ObjectBox(LongWrapper.wrap(val)); 3102 } 3103 3104 @ForceInline 3105 static ObjectBox box(long val) { 3106 return new ObjectBox(WrapperInterface.wrap(val)); 3107 } 3108 } 3109 3110 static class RefBox { 3111 LongWrapper content; 3112 3113 @ForceInline 3114 RefBox(LongWrapper content) { 3115 this.content = content; 3116 } 3117 3118 @ForceInline 3119 static RefBox box_sharp(long val) { 3120 return new RefBox(LongWrapper.wrap(val)); 3121 } 3122 3123 @ForceInline 3124 static RefBox box(long val) { 3125 return new RefBox((LongWrapper)WrapperInterface.wrap(val)); 3126 } 3127 } 3128 3129 static class InlineBox { 3130 @NullRestricted 3131 LongWrapper content; 3132 3133 @ForceInline 3134 InlineBox(long val) { 3135 this.content = LongWrapper.wrap(val); 3136 } 3137 3138 @ForceInline 3139 static InlineBox box(long val) { 3140 return new InlineBox(val); 3141 } 3142 } 3143 3144 static class GenericBox<T> { 3145 T content; 3146 3147 @ForceInline 3148 static GenericBox<LongWrapper> box_sharp(long val) { 3149 GenericBox<LongWrapper> res = new GenericBox<>(); 3150 res.content = LongWrapper.wrap(val); 3151 return res; 3152 } 3153 3154 @ForceInline 3155 static GenericBox<WrapperInterface> box(long val) { 3156 GenericBox<WrapperInterface> res = new GenericBox<>(); 3157 res.content = WrapperInterface.wrap(val); 3158 return res; 3159 } 3160 } 3161 3162 long[] lArr = {0L, rL, 0L, rL, 0L, rL, 0L, rL, 0L, rL}; 3163 3164 // Test removal of allocations when inline type instance is wrapped into box object 3165 @Test 3166 @IR(failOn = {ALLOC_G, MEMBAR}, 3167 counts = {PREDICATE_TRAP, "= 1"}) 3168 public long test109() { 3169 long res = 0; 3170 for (int i = 0; i < lArr.length; i++) { 3171 res += InterfaceBox.box(lArr[i]).content.value(); 3172 } 3173 return res; 3174 } 3175 3176 @Run(test = "test109") 3177 @Warmup(10000) // Make sure interface calls are inlined 3178 public void test109_verifier() { 3179 long res = test109(); 3180 Asserts.assertEquals(res, 5*rL); 3181 } 3182 3183 @Test 3184 @IR(failOn = {ALLOC_G, MEMBAR}, 3185 counts = {PREDICATE_TRAP, "= 1"}) 3186 @IR(failOn = {ALLOC_G, MEMBAR}) 3187 public long test109_sharp() { 3188 long res = 0; 3189 for (int i = 0; i < lArr.length; i++) { 3190 res += InterfaceBox.box_sharp(lArr[i]).content.value(); 3191 } 3192 return res; 3193 } 3194 3195 @Run(test = "test109_sharp") 3196 @Warmup(10000) // Make sure interface calls are inlined 3197 public void test109_sharp_verifier() { 3198 long res = test109_sharp(); 3199 Asserts.assertEquals(res, 5*rL); 3200 } 3201 3202 // Same as test109 but with ObjectBox 3203 @Test 3204 @IR(failOn = {ALLOC_G, MEMBAR}, 3205 counts = {PREDICATE_TRAP, "= 1"}) 3206 public long test110() { 3207 long res = 0; 3208 for (int i = 0; i < lArr.length; i++) { 3209 res += ((WrapperInterface)ObjectBox.box(lArr[i]).content).value(); 3210 } 3211 return res; 3212 } 3213 3214 @Run(test = "test110") 3215 @Warmup(10000) // Make sure interface calls are inlined 3216 public void test110_verifier() { 3217 long res = test110(); 3218 Asserts.assertEquals(res, 5*rL); 3219 } 3220 3221 @Test 3222 @IR(failOn = {ALLOC_G, MEMBAR}, 3223 counts = {PREDICATE_TRAP, "= 1"}) 3224 @IR(failOn = {ALLOC_G, MEMBAR}) 3225 public long test110_sharp() { 3226 long res = 0; 3227 for (int i = 0; i < lArr.length; i++) { 3228 res += ((WrapperInterface)ObjectBox.box_sharp(lArr[i]).content).value(); 3229 } 3230 return res; 3231 } 3232 3233 @Run(test = "test110_sharp") 3234 @Warmup(10000) // Make sure interface calls are inlined 3235 public void test110_sharp_verifier() { 3236 long res = test110_sharp(); 3237 Asserts.assertEquals(res, 5*rL); 3238 } 3239 3240 // Same as test109 but with RefBox 3241 @Test 3242 @IR(failOn = {ALLOC_G, MEMBAR}, 3243 counts = {PREDICATE_TRAP, "= 1"}) 3244 public long test111() { 3245 long res = 0; 3246 for (int i = 0; i < lArr.length; i++) { 3247 res += RefBox.box(lArr[i]).content.value(); 3248 } 3249 return res; 3250 } 3251 3252 @Run(test = "test111") 3253 public void test111_verifier() { 3254 long res = test111(); 3255 Asserts.assertEquals(res, 5*rL); 3256 } 3257 3258 @Test 3259 @IR(failOn = {ALLOC_G, MEMBAR}, 3260 counts = {PREDICATE_TRAP, "= 1"}) 3261 public long test111_sharp() { 3262 long res = 0; 3263 for (int i = 0; i < lArr.length; i++) { 3264 res += RefBox.box_sharp(lArr[i]).content.value(); 3265 } 3266 return res; 3267 } 3268 3269 @Run(test = "test111_sharp") 3270 public void test111_sharp_verifier() { 3271 long res = test111_sharp(); 3272 Asserts.assertEquals(res, 5*rL); 3273 } 3274 3275 // Same as test109 but with InlineBox 3276 @Test 3277 @IR(failOn = {ALLOC_G, MEMBAR}, 3278 counts = {PREDICATE_TRAP, "= 1"}) 3279 public long test112() { 3280 long res = 0; 3281 for (int i = 0; i < lArr.length; i++) { 3282 res += InlineBox.box(lArr[i]).content.value(); 3283 } 3284 return res; 3285 } 3286 3287 @Run(test = "test112") 3288 public void test112_verifier() { 3289 long res = test112(); 3290 Asserts.assertEquals(res, 5*rL); 3291 } 3292 3293 // Same as test109 but with GenericBox 3294 @Test 3295 @IR(failOn = {ALLOC_G, MEMBAR}, 3296 counts = {PREDICATE_TRAP, "= 1"}) 3297 public long test113() { 3298 long res = 0; 3299 for (int i = 0; i < lArr.length; i++) { 3300 res += GenericBox.box(lArr[i]).content.value(); 3301 } 3302 return res; 3303 } 3304 3305 @Run(test = "test113") 3306 @Warmup(10000) // Make sure interface calls are inlined 3307 public void test113_verifier() { 3308 long res = test113(); 3309 Asserts.assertEquals(res, 5*rL); 3310 } 3311 3312 @Test 3313 @IR(failOn = {ALLOC_G, MEMBAR}) 3314 // TODO 8326401 3315 // counts = {PREDICATE_TRAP, "= 1"}) 3316 public long test113_sharp() { 3317 long res = 0; 3318 for (int i = 0; i < lArr.length; i++) { 3319 res += GenericBox.box_sharp(lArr[i]).content.value(); 3320 } 3321 return res; 3322 } 3323 3324 @Run(test = "test113_sharp") 3325 @Warmup(10000) // Make sure interface calls are inlined 3326 public void test113_sharp_verifier() { 3327 long res = test113_sharp(); 3328 Asserts.assertEquals(res, 5*rL); 3329 } 3330 3331 static interface WrapperInterface2 { 3332 public long value(); 3333 3334 static final InlineWrapper ZERO = new InlineWrapper(0); 3335 3336 @ForceInline 3337 public static WrapperInterface2 wrap(long val) { 3338 return (val == 0) ? ZERO.content : new LongWrapper2(val); 3339 } 3340 3341 @ForceInline 3342 public static WrapperInterface2 wrap_default(long val) { 3343 return (val == 0) ? new LongWrapper2(0) : new LongWrapper2(val); 3344 } 3345 } 3346 3347 @ImplicitlyConstructible 3348 @LooselyConsistentValue 3349 static value class LongWrapper2 implements WrapperInterface2 { 3350 private long val; 3351 3352 @ForceInline 3353 public LongWrapper2(long val) { 3354 this.val = val; 3355 } 3356 3357 @ForceInline 3358 public long value() { 3359 return val; 3360 } 3361 } 3362 3363 @ImplicitlyConstructible 3364 @LooselyConsistentValue 3365 static value class InlineWrapper { 3366 WrapperInterface2 content; 3367 3368 @ForceInline 3369 public InlineWrapper(long val) { 3370 content = new LongWrapper2(val); 3371 } 3372 } 3373 3374 static class InterfaceBox2 { 3375 WrapperInterface2 content; 3376 3377 @ForceInline 3378 public InterfaceBox2(long val, boolean def) { 3379 this.content = def ? WrapperInterface2.wrap_default(val) : WrapperInterface2.wrap(val); 3380 } 3381 3382 @ForceInline 3383 static InterfaceBox2 box(long val) { 3384 return new InterfaceBox2(val, false); 3385 } 3386 3387 @ForceInline 3388 static InterfaceBox2 box_default(long val) { 3389 return new InterfaceBox2(val, true); 3390 } 3391 } 3392 3393 // Same as tests above but with ZERO hidden in field of another inline type 3394 @Test 3395 @IR(failOn = {ALLOC_G, MEMBAR}, 3396 counts = {PREDICATE_TRAP, "= 1"}) 3397 public long test114() { 3398 long res = 0; 3399 for (int i = 0; i < lArr.length; i++) { 3400 res += InterfaceBox2.box(lArr[i]).content.value(); 3401 } 3402 return res; 3403 } 3404 3405 @Run(test = "test114") 3406 @Warmup(10000) 3407 public void test114_verifier() { 3408 long res = test114(); 3409 Asserts.assertEquals(res, 5*rL); 3410 } 3411 3412 // Same as test114 but with default instead of ZERO field 3413 @Test 3414 @IR(failOn = {ALLOC_G, MEMBAR}, 3415 counts = {PREDICATE_TRAP, "= 1"}) 3416 public long test115() { 3417 long res = 0; 3418 for (int i = 0; i < lArr.length; i++) { 3419 res += InterfaceBox2.box_default(lArr[i]).content.value(); 3420 } 3421 return res; 3422 } 3423 3424 @Run(test = "test115") 3425 @Warmup(10000) 3426 public void test115_verifier() { 3427 long res = test115(); 3428 Asserts.assertEquals(res, 5*rL); 3429 } 3430 3431 @NullRestricted 3432 static MyValueEmpty fEmpty1; 3433 static MyValueEmpty fEmpty2 = new MyValueEmpty(); 3434 @NullRestricted 3435 MyValueEmpty fEmpty3; 3436 MyValueEmpty fEmpty4 = new MyValueEmpty(); 3437 3438 // Test fields loads/stores with empty inline types 3439 @Test 3440 @IR(failOn = {ALLOC_G, TRAP}) 3441 public void test116() { 3442 fEmpty1 = fEmpty4; 3443 fEmpty2 = fEmpty1; 3444 fEmpty3 = fEmpty2; 3445 fEmpty4 = fEmpty3; 3446 } 3447 3448 @Run(test = "test116") 3449 public void test116_verifier() { 3450 test116(); 3451 Asserts.assertEquals(fEmpty1, fEmpty2); 3452 Asserts.assertEquals(fEmpty2, fEmpty3); 3453 Asserts.assertEquals(fEmpty3, fEmpty4); 3454 } 3455 3456 // Test array loads/stores with empty inline types 3457 @Test 3458 @IR(failOn = {ALLOC_G}) 3459 public MyValueEmpty test117(MyValueEmpty[] arr1, MyValueEmpty[] arr2) { 3460 arr1[0] = arr2[0]; 3461 arr2[0] = new MyValueEmpty(); 3462 return arr1[0]; 3463 } 3464 3465 @Run(test = "test117") 3466 public void test117_verifier() { 3467 MyValueEmpty[] arr1 = new MyValueEmpty[] { new MyValueEmpty() }; 3468 MyValueEmpty res = test117(arr1, arr1); 3469 Asserts.assertEquals(res, new MyValueEmpty()); 3470 Asserts.assertEquals(arr1[0], new MyValueEmpty()); 3471 } 3472 3473 // Test acmp with empty inline types 3474 @Test 3475 public boolean test118(MyValueEmpty v1, MyValueEmpty v2, Object o1) { 3476 return (v1 == v2) && (v2 == o1); 3477 } 3478 3479 @Run(test = "test118") 3480 public void test118_verifier() { 3481 boolean res = test118(new MyValueEmpty(), new MyValueEmpty(), new MyValueEmpty()); 3482 Asserts.assertTrue(res); 3483 } 3484 3485 @ImplicitlyConstructible 3486 @LooselyConsistentValue 3487 static value class EmptyContainer { 3488 @NullRestricted 3489 private MyValueEmpty empty = new MyValueEmpty(); 3490 } 3491 3492 @ImplicitlyConstructible 3493 @LooselyConsistentValue 3494 static value class MixedContainer { 3495 public int val = 0; 3496 @NullRestricted 3497 private EmptyContainer empty = new EmptyContainer(); 3498 } 3499 3500 @NullRestricted 3501 static final MyValueEmpty empty = new MyValueEmpty(); 3502 3503 @NullRestricted 3504 static final EmptyContainer emptyC = new EmptyContainer(); 3505 3506 @NullRestricted 3507 static final MixedContainer mixedContainer = new MixedContainer(); 3508 3509 // Test re-allocation of empty inline type array during deoptimization 3510 @Test 3511 @IR(failOn = {ALLOC_G}) 3512 public void test119(boolean deopt, Method m) { 3513 MyValueEmpty[] array1 = new MyValueEmpty[] { empty }; 3514 EmptyContainer[] array2 = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 1); 3515 array2[0] = emptyC; 3516 MixedContainer[] array3 = (MixedContainer[])ValueClass.newNullRestrictedArray(MixedContainer.class, 1); 3517 array3[0] = mixedContainer; 3518 if (deopt) { 3519 // uncommon trap 3520 TestFramework.deoptimize(m); 3521 } 3522 Asserts.assertEquals(array1[0], empty); 3523 Asserts.assertEquals(array2[0], emptyC); 3524 Asserts.assertEquals(array3[0], mixedContainer); 3525 } 3526 3527 @Run(test = "test119") 3528 public void test119_verifier(RunInfo info) { 3529 test119(!info.isWarmUp(), info.getTest()); 3530 } 3531 3532 // Test removal of empty inline type field stores 3533 @Test 3534 @IR(failOn = {ALLOC_G, LOAD, STORE, FIELD_ACCESS, NULL_CHECK_TRAP, TRAP}) 3535 public void test120() { 3536 fEmpty1 = empty; 3537 fEmpty3 = empty; 3538 // fEmpty2 and fEmpty4 could be null, store can't be removed 3539 } 3540 3541 @Run(test = "test120") 3542 public void test120_verifier() { 3543 test120(); 3544 Asserts.assertEquals(fEmpty1, empty); 3545 Asserts.assertEquals(fEmpty2, empty); 3546 } 3547 3548 // Test removal of empty inline type field loads 3549 @Test 3550 @IR(failOn = {ALLOC_G, LOAD, STORE, FIELD_ACCESS, NULL_CHECK_TRAP, TRAP}) 3551 public boolean test121() { 3552 return fEmpty1.equals(fEmpty3); 3553 // fEmpty2 and fEmpty4 could be null, load can't be removed 3554 } 3555 3556 @Run(test = "test121") 3557 public void test121_verifier() { 3558 boolean res = test121(); 3559 Asserts.assertTrue(res); 3560 } 3561 3562 // Verify that empty inline type field loads check for null holder 3563 @Test 3564 @IR(failOn = {ALLOC_G}) 3565 public MyValueEmpty test122(TestLWorld t) { 3566 return t.fEmpty3; 3567 } 3568 3569 @Run(test = "test122") 3570 public void test122_verifier() { 3571 MyValueEmpty res = test122(this); 3572 Asserts.assertEquals(res, new MyValueEmpty()); 3573 try { 3574 test122(null); 3575 throw new RuntimeException("No NPE thrown"); 3576 } catch (NullPointerException e) { 3577 // Expected 3578 } 3579 } 3580 3581 // Verify that empty inline type field stores check for null holder 3582 @Test 3583 @IR(failOn = {ALLOC_G}) 3584 public void test123(TestLWorld t) { 3585 t.fEmpty3 = new MyValueEmpty(); 3586 } 3587 3588 @Run(test = "test123") 3589 public void test123_verifier() { 3590 test123(this); 3591 Asserts.assertEquals(fEmpty3, new MyValueEmpty()); 3592 try { 3593 test123(null); 3594 throw new RuntimeException("No NPE thrown"); 3595 } catch (NullPointerException e) { 3596 // Expected 3597 } 3598 } 3599 3600 // acmp doesn't need substitutability test when one input is known 3601 // not to be a value type 3602 @Test 3603 @IR(failOn = SUBSTITUTABILITY_TEST) 3604 public boolean test124(NonValueClass o1, Object o2) { 3605 return o1 == o2; 3606 } 3607 3608 @Run(test = "test124") 3609 public void test124_verifier() { 3610 NonValueClass obj = new NonValueClass(rI); 3611 test124(obj, obj); 3612 test124(obj, testValue1); 3613 } 3614 3615 // acmp doesn't need substitutability test when one input is null 3616 @Test 3617 @IR(failOn = {SUBSTITUTABILITY_TEST}) 3618 public boolean test125(Object o1) { 3619 Object o2 = null; 3620 return o1 == o2; 3621 } 3622 3623 @Run(test = "test125") 3624 public void test125_verifier() { 3625 test125(testValue1); 3626 test125(null); 3627 } 3628 3629 // Test inline type that can only be scalarized after loop opts 3630 @Test 3631 @IR(failOn = {ALLOC_G, LOAD, STORE}) 3632 public long test126(boolean trap) { 3633 MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); 3634 MyValue2 val = null; 3635 3636 for (int i = 0; i < 4; i++) { 3637 if ((i % 2) == 0) { 3638 val = nonNull; 3639 } 3640 } 3641 // 'val' is always non-null here but that's only known after loop opts 3642 if (trap) { 3643 // Uncommon trap with an inline input that can only be scalarized after loop opts 3644 return val.hash(); 3645 } 3646 return 0; 3647 } 3648 3649 @Run(test = "test126") 3650 @Warmup(10000) 3651 public void test126_verifier(RunInfo info) { 3652 long res = test126(false); 3653 Asserts.assertEquals(res, 0L); 3654 if (!info.isWarmUp()) { 3655 res = test126(true); 3656 Asserts.assertEquals(res, testValue2.hash()); 3657 } 3658 } 3659 3660 // Same as test126 but with interface type 3661 @Test 3662 @IR(failOn = {ALLOC_G, LOAD, STORE}) 3663 public long test127(boolean trap) { 3664 MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); 3665 MyInterface val = null; 3666 3667 for (int i = 0; i < 4; i++) { 3668 if ((i % 2) == 0) { 3669 val = nonNull; 3670 } 3671 } 3672 // 'val' is always non-null here but that's only known after loop opts 3673 if (trap) { 3674 // Uncommon trap with an inline input that can only be scalarized after loop opts 3675 return val.hash(); 3676 } 3677 return 0; 3678 } 3679 3680 @Run(test = "test127") 3681 @Warmup(10000) 3682 public void test127_verifier(RunInfo info) { 3683 long res = test127(false); 3684 Asserts.assertEquals(res, 0L); 3685 if (!info.isWarmUp()) { 3686 res = test127(true); 3687 Asserts.assertEquals(res, testValue2.hash()); 3688 } 3689 } 3690 3691 // Test inline type that can only be scalarized after CCP 3692 @Test 3693 @IR(failOn = {ALLOC_G, LOAD, STORE}) 3694 public long test128(boolean trap) { 3695 MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); 3696 MyValue2 val = null; 3697 3698 int limit = 2; 3699 for (; limit < 4; limit *= 2); 3700 for (int i = 2; i < limit; i++) { 3701 val = nonNull; 3702 } 3703 // 'val' is always non-null here but that's only known after CCP 3704 if (trap) { 3705 // Uncommon trap with an inline input that can only be scalarized after CCP 3706 return val.hash(); 3707 } 3708 return 0; 3709 } 3710 3711 @Run(test = "test128") 3712 @Warmup(10000) 3713 public void test128_verifier(RunInfo info) { 3714 long res = test128(false); 3715 Asserts.assertEquals(res, 0L); 3716 if (!info.isWarmUp()) { 3717 res = test128(true); 3718 Asserts.assertEquals(res, testValue2.hash()); 3719 } 3720 } 3721 3722 // Same as test128 but with interface type 3723 @Test 3724 @IR(failOn = {ALLOC_G, LOAD, STORE}) 3725 public long test129(boolean trap) { 3726 MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); 3727 MyInterface val = null; 3728 3729 int limit = 2; 3730 for (; limit < 4; limit *= 2); 3731 for (int i = 0; i < limit; i++) { 3732 val = nonNull; 3733 } 3734 // 'val' is always non-null here but that's only known after CCP 3735 if (trap) { 3736 // Uncommon trap with an inline input that can only be scalarized after CCP 3737 return val.hash(); 3738 } 3739 return 0; 3740 } 3741 3742 @Run(test = "test129") 3743 @Warmup(10000) 3744 public void test129_verifier(RunInfo info) { 3745 long res = test129(false); 3746 Asserts.assertEquals(res, 0L); 3747 if (!info.isWarmUp()) { 3748 res = test129(true); 3749 Asserts.assertEquals(res, testValue2.hash()); 3750 } 3751 } 3752 3753 // Lock on inline type (known after inlining) 3754 @ForceInline 3755 public Object test130_inlinee() { 3756 return MyValue1.createWithFieldsInline(rI, rL); 3757 } 3758 3759 @Test 3760 // TODO 8325106 3761 /* 3762 @IR(failOn = {LOAD}, 3763 // LockNode keeps MyValue1 allocation alive up until macro expansion which in turn keeps MyValue2 3764 // alloc alive. Although the MyValue1 allocation is removed (unused), MyValue2 is expanded first 3765 // and therefore stays. 3766 counts = {ALLOC, "<= 1", STORE, "<= 1"}) 3767 */ 3768 public void test130() { 3769 Object obj = test130_inlinee(); 3770 synchronized (obj) { 3771 throw new RuntimeException("test130 failed: synchronization on inline type should not succeed"); 3772 } 3773 } 3774 3775 @Run(test = "test130") 3776 public void test130_verifier() { 3777 try { 3778 test130(); 3779 throw new RuntimeException("test130 failed: no exception thrown"); 3780 } catch (IllegalMonitorStateException ex) { 3781 // Expected 3782 } 3783 } 3784 3785 // Same as test130 but with field load instead of allocation 3786 @ForceInline 3787 public Object test131_inlinee() { 3788 return testValue1; 3789 } 3790 3791 @Test 3792 @IR(failOn = {ALLOC_G}) 3793 public void test131() { 3794 Object obj = test131_inlinee(); 3795 synchronized (obj) { 3796 throw new RuntimeException("test131 failed: synchronization on inline type should not succeed"); 3797 } 3798 } 3799 3800 @Run(test = "test131") 3801 public void test131_verifier() { 3802 try { 3803 test131(); 3804 throw new RuntimeException("test131 failed: no exception thrown"); 3805 } catch (IllegalMonitorStateException ex) { 3806 // Expected 3807 } 3808 } 3809 3810 // Test locking on object that is known to be an inline type only after CCP 3811 @Test 3812 @IR(failOn = {ALLOC, LOAD, STORE}) 3813 public void test132() { 3814 MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); 3815 Object obj = new NonValueClass(42); 3816 3817 int limit = 2; 3818 for (; limit < 4; limit *= 2); 3819 for (int i = 2; i < limit; i++) { 3820 obj = vt; 3821 } 3822 synchronized (obj) { 3823 throw new RuntimeException("test132 failed: synchronization on inline type should not succeed"); 3824 } 3825 } 3826 3827 @Run(test = "test132") 3828 @Warmup(10000) 3829 public void test132_verifier() { 3830 try { 3831 test132(); 3832 throw new RuntimeException("test132 failed: no exception thrown"); 3833 } catch (IllegalMonitorStateException ex) { 3834 // Expected 3835 } 3836 } 3837 3838 // Test conditional locking on inline type and non-escaping object 3839 @Test 3840 public void test133(boolean b) { 3841 Object obj = b ? new NonValueClass(rI) : MyValue2.createWithFieldsInline(rI, rD); 3842 synchronized (obj) { 3843 if (!b) { 3844 throw new RuntimeException("test133 failed: synchronization on inline type should not succeed"); 3845 } 3846 } 3847 } 3848 3849 @Run(test = "test133") 3850 public void test133_verifier() { 3851 test133(true); 3852 try { 3853 test133(false); 3854 throw new RuntimeException("test133 failed: no exception thrown"); 3855 } catch (IllegalMonitorStateException ex) { 3856 // Expected 3857 } 3858 } 3859 3860 // Variant with non-scalarized inline type 3861 @Test 3862 @IR(failOn = {ALLOC_G}) 3863 public void test134(boolean b) { 3864 Object obj = null; 3865 if (b) { 3866 obj = MyValue2.createWithFieldsInline(rI, rD); 3867 } 3868 synchronized (obj) { 3869 3870 } 3871 } 3872 3873 @Run(test = "test134") 3874 public void test134_verifier() { 3875 try { 3876 test134(true); 3877 throw new RuntimeException("test134 failed: no exception thrown"); 3878 } catch (IllegalMonitorStateException ex) { 3879 // Expected 3880 } 3881 } 3882 3883 // Test that acmp of the same inline object is removed 3884 @Test 3885 @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) 3886 public boolean test135() { 3887 MyValue1 val = MyValue1.createWithFieldsInline(rI, rL); 3888 return val == val; 3889 } 3890 3891 @Run(test = "test135") 3892 public void test135_verifier() { 3893 Asserts.assertTrue(test135()); 3894 } 3895 3896 // Same as test135 but with null 3897 @Test 3898 @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) 3899 public boolean test136(boolean b) { 3900 MyValue1 val = MyValue1.createWithFieldsInline(rI, rL); 3901 if (b) { 3902 val = null; 3903 } 3904 return val == val; 3905 } 3906 3907 @Run(test = "test136") 3908 public void test136_verifier() { 3909 Asserts.assertTrue(test136(false)); 3910 Asserts.assertTrue(test136(true)); 3911 } 3912 3913 // Test that acmp of different inline objects with same content is removed 3914 @Test 3915 // TODO 8228361 3916 // @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) 3917 public boolean test137(int i) { 3918 MyValue2 val1 = MyValue2.createWithFieldsInline(i, rD); 3919 MyValue2 val2 = MyValue2.createWithFieldsInline(i, rD); 3920 return val1 == val2; 3921 } 3922 3923 @Run(test = "test137") 3924 public void test137_verifier() { 3925 Asserts.assertTrue(test137(rI)); 3926 } 3927 3928 // Same as test137 but with null 3929 @Test 3930 // TODO 8228361 3931 // @IR(failOn = {ALLOC_G, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) 3932 public boolean test138(int i, boolean b) { 3933 MyValue2 val1 = MyValue2.createWithFieldsInline(i, rD); 3934 MyValue2 val2 = MyValue2.createWithFieldsInline(i, rD); 3935 if (b) { 3936 val1 = null; 3937 val2 = null; 3938 } 3939 return val1 == val2; 3940 } 3941 3942 @Run(test = "test138") 3943 public void test138_verifier() { 3944 Asserts.assertTrue(test138(rI, false)); 3945 Asserts.assertTrue(test138(rI, true)); 3946 } 3947 3948 @ImplicitlyConstructible 3949 @LooselyConsistentValue 3950 static value class Test139Value { 3951 Object obj = null; 3952 @NullRestricted 3953 MyValueEmpty empty = new MyValueEmpty(); 3954 } 3955 3956 @ImplicitlyConstructible 3957 @LooselyConsistentValue 3958 static value class Test139Wrapper { 3959 @NullRestricted 3960 Test139Value value = new Test139Value(); 3961 } 3962 3963 @Test 3964 @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP}) 3965 public MyValueEmpty test139() { 3966 Test139Wrapper w = new Test139Wrapper(); 3967 return w.value.empty; 3968 } 3969 3970 @Run(test = "test139") 3971 public void test139_verifier() { 3972 MyValueEmpty empty = test139(); 3973 Asserts.assertEquals(empty, new MyValueEmpty()); 3974 } 3975 3976 // Test calling a method on a loaded but not linked inline type 3977 @ImplicitlyConstructible 3978 @LooselyConsistentValue 3979 value class Test140Value { 3980 int x = 0; 3981 3982 public int get() { 3983 return x; 3984 } 3985 } 3986 3987 @Test 3988 @IR(failOn = {ALLOC_G}) 3989 public int test140() { 3990 Test140Value vt = new Test140Value(); 3991 return vt.get(); 3992 } 3993 3994 @Run(test = "test140") 3995 @Warmup(0) 3996 public void test140_verifier() { 3997 int result = test140(); 3998 Asserts.assertEquals(result, 0); 3999 } 4000 4001 // Test calling a method on a linked but not initialized inline type 4002 @ImplicitlyConstructible 4003 @LooselyConsistentValue 4004 value class Test141Value { 4005 int x = 0; 4006 4007 public int get() { 4008 return x; 4009 } 4010 } 4011 4012 @Test 4013 @IR(failOn = {ALLOC_G}) 4014 public int test141() { 4015 Test141Value vt = new Test141Value(); 4016 return vt.get(); 4017 } 4018 4019 @Run(test = "test141") 4020 @Warmup(0) 4021 public void test141_verifier() { 4022 int result = test141(); 4023 Asserts.assertEquals(result, 0); 4024 } 4025 4026 // Test that virtual calls on inline type receivers are properly inlined 4027 @Test 4028 @IR(failOn = {ALLOC_G, LOAD, STORE}) 4029 public long test142() { 4030 MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); 4031 MyInterface val = null; 4032 4033 for (int i = 0; i < 4; i++) { 4034 if ((i % 2) == 0) { 4035 val = nonNull; 4036 } 4037 } 4038 return val.hash(); 4039 } 4040 4041 @Run(test = "test142") 4042 public void test142_verifier() { 4043 long res = test142(); 4044 Asserts.assertEquals(res, testValue2.hash()); 4045 } 4046 4047 // Test merging of buffered default and non-default inline types 4048 @Test 4049 // TODO 8325106 With incremental inlining, we already buffer the larval which can't use the default oop because it might be overridden. 4050 @IR(applyIf = {"AlwaysIncrementalInline", "false"}, 4051 failOn = {ALLOC_G}) 4052 public Object test144(int i) { 4053 if (i == 0) { 4054 return MyValue1.createDefaultInline(); 4055 } else if (i == 1) { 4056 return testValue1; 4057 } else { 4058 return MyValue1.createDefaultInline(); 4059 } 4060 } 4061 4062 @Run(test = "test144") 4063 public void test144_verifier() { 4064 Asserts.assertEquals(test144(0), MyValue1.createDefaultInline()); 4065 Asserts.assertEquals(test144(1), testValue1); 4066 Asserts.assertEquals(test144(2), MyValue1.createDefaultInline()); 4067 } 4068 4069 // Tests writing an array element with a (statically known) incompatible type 4070 private static final MethodHandle setArrayElementIncompatibleRef = OldInstructionHelper.loadCode(MethodHandles.lookup(), 4071 "setArrayElementIncompatibleRef", 4072 MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class), 4073 CODE -> { 4074 CODE. 4075 aload_1(). 4076 iload_2(). 4077 aload_3(). 4078 aastore(). 4079 return_(); 4080 }); 4081 4082 // Test inline type connected to result node 4083 @Test 4084 @IR(failOn = {ALLOC_G}) 4085 public MyValue1 test146(Object obj) { 4086 return (MyValue1)obj; 4087 } 4088 4089 @Run(test = "test146") 4090 @Warmup(10000) 4091 public void test146_verifier() { 4092 Asserts.assertEQ(test146(testValue1), testValue1); 4093 } 4094 4095 @ForceInline 4096 public Object test148_helper(Object obj) { 4097 return (MyValue1)obj; 4098 } 4099 4100 // Same as test146 but with helper method 4101 @Test 4102 public Object test148(Object obj) { 4103 return test148_helper(obj); 4104 } 4105 4106 @Run(test = "test148") 4107 @Warmup(10000) 4108 public void test148_verifier() { 4109 Asserts.assertEQ(test148(testValue1), testValue1); 4110 } 4111 4112 @ForceInline 4113 public Object test149_helper(Object obj) { 4114 return (MyValue1)obj; 4115 } 4116 4117 // Same as test147 but with helper method 4118 @Test 4119 public Object test149(Object obj) { 4120 return test149_helper(obj); 4121 } 4122 4123 @Run(test = "test149") 4124 @Warmup(10000) 4125 public void test149_verifier() { 4126 Asserts.assertEQ(test149(testValue1), testValue1); 4127 Asserts.assertEQ(test149(null), null); 4128 } 4129 4130 // Test post-parse call devirtualization with inline type receiver 4131 @Test 4132 // TODO 8325106 4133 /* 4134 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, 4135 failOn = {ALLOC}) 4136 */ 4137 @IR(failOn = {compiler.lib.ir_framework.IRNode.DYNAMIC_CALL_OF_METHOD, "MyValue2::hash"}, 4138 counts = {compiler.lib.ir_framework.IRNode.STATIC_CALL_OF_METHOD, "MyValue2::hash", "= 1"}) 4139 public long test150() { 4140 MyValue2 val = MyValue2.createWithFieldsInline(rI, rD); 4141 MyInterface receiver = MyValue1.createWithFieldsInline(rI, rL); 4142 4143 for (int i = 0; i < 4; i++) { 4144 if ((i % 2) == 0) { 4145 receiver = val; 4146 } 4147 } 4148 // Trigger post parse call devirtualization (strength-reducing 4149 // virtual calls to direct calls). 4150 return receiver.hash(); 4151 } 4152 4153 @Run(test = "test150") 4154 public void test150_verifier() { 4155 Asserts.assertEquals(test150(), testValue2.hash()); 4156 } 4157 4158 // TODO 8325106 This triggers # assert(false) failed: Should have been buffered 4159 /* 4160 // Same as test150 but with val not being allocated in the scope of the method 4161 @Test 4162 @IR(failOn = {compiler.lib.ir_framework.IRNode.DYNAMIC_CALL_OF_METHOD, "MyValue2::hash"}, 4163 counts = {compiler.lib.ir_framework.IRNode.STATIC_CALL_OF_METHOD, "MyValue2::hash", "= 1"}) 4164 public long test151(MyValue2 val) { 4165 MyAbstract receiver = MyValue1.createWithFieldsInline(rI, rL); 4166 4167 for (int i = 0; i < 100; i++) { 4168 if ((i % 2) == 0) { 4169 receiver = val; 4170 } 4171 } 4172 // Trigger post parse call devirtualization (strength-reducing 4173 // virtual calls to direct calls). 4174 return receiver.hash(); 4175 } 4176 4177 @Run(test = "test151") 4178 @Warmup(0) // Make sure there is no receiver type profile 4179 public void test151_verifier() { 4180 Asserts.assertEquals(test151(testValue2), testValue2.hash()); 4181 } 4182 */ 4183 4184 static interface MyInterface2 { 4185 public int val(); 4186 } 4187 4188 static abstract value class MyAbstract2 implements MyInterface2 { 4189 4190 } 4191 4192 static class MyClass152 extends MyAbstract2 { 4193 private int val; 4194 4195 @ForceInline 4196 public MyClass152(int val) { 4197 this.val = val; 4198 } 4199 4200 @Override 4201 public int val() { 4202 return val; 4203 } 4204 } 4205 4206 @ImplicitlyConstructible 4207 @LooselyConsistentValue 4208 static value class MyValue152 extends MyAbstract2 { 4209 private int unused = 0; // Make sure sub-offset of val is field non-zero 4210 private int val; 4211 4212 @ForceInline 4213 public MyValue152(int val) { 4214 this.val = val; 4215 } 4216 4217 @Override 4218 public int val() { 4219 return val; 4220 } 4221 } 4222 4223 @ImplicitlyConstructible 4224 @LooselyConsistentValue 4225 static value class MyWrapper152 { 4226 private int unused = 0; // Make sure sub-offset of val field is non-zero 4227 @NullRestricted 4228 MyValue152 val; 4229 4230 @ForceInline 4231 public MyWrapper152(MyInterface2 val) { 4232 this.val = (MyValue152)val; 4233 } 4234 } 4235 4236 // Test that checkcast with speculative type does not break scalarization in return 4237 @Test 4238 public MyWrapper152 test152(MyInterface2 val) { 4239 return new MyWrapper152(val); 4240 } 4241 4242 @Run(test = "test152") 4243 @Warmup(10000) // Make sure profile information is available at cast 4244 public void test152_verifier() { 4245 MyClass152 unused = new MyClass152(rI); 4246 MyValue152 val = new MyValue152(rI); 4247 Asserts.assertEquals(test152(val).val, val); 4248 } 4249 4250 @DontInline 4251 static void test153_helper(MyWrapper152 arg) { 4252 4253 } 4254 4255 // Test that checkcast with speculative type does not prevent scalarization in args 4256 @Test 4257 public void test153(MyInterface2 val) { 4258 test153_helper(new MyWrapper152(val)); 4259 } 4260 4261 @Run(test = "test153") 4262 @Warmup(10000) // Make sure profile information is available at cast 4263 public void test153_verifier() { 4264 MyClass152 unused = new MyClass152(rI); 4265 MyValue152 val = new MyValue152(rI); 4266 test153(val); 4267 } 4268 4269 // Test that checkcast with speculative type enables scalarization 4270 @Test 4271 @IR(failOn = {ALLOC_G, STORE}) 4272 public int test154(Method m, MyInterface2 val, boolean b1, boolean b2) { 4273 MyInterface2 obj = new MyValue152(rI); 4274 if (b1) { 4275 // Speculative cast to MyValue152 enables scalarization 4276 obj = (MyAbstract2)val; 4277 } 4278 if (b2) { 4279 // Uncommon trap 4280 TestFramework.deoptimize(m); 4281 return obj.val(); 4282 } 4283 return -1; 4284 } 4285 4286 @Run(test = "test154") 4287 @Warmup(10000) // Make sure profile information is available at cast 4288 public void test154_verifier(RunInfo info) { 4289 MyClass152 unused = new MyClass152(rI); 4290 MyValue152 val = new MyValue152(rI); 4291 Asserts.assertEquals(test154(info.getTest(), val, false, false), -1); 4292 Asserts.assertEquals(test154(info.getTest(), val, true, false), -1); 4293 if (!info.isWarmUp()) { 4294 Asserts.assertEquals(test154(info.getTest(), val, false, true), rI); 4295 } 4296 } 4297 4298 // Same as test154 but with null val 4299 @Test 4300 @IR(failOn = {ALLOC_G, STORE}) 4301 public int test155(Method m, MyInterface2 val, boolean b1, boolean b2) { 4302 MyInterface2 obj = new MyValue152(rI); 4303 if (b1) { 4304 // Speculative cast to MyValue152 enables scalarization 4305 obj = (MyAbstract2)val; 4306 } 4307 if (b2) { 4308 // Uncommon trap 4309 TestFramework.deoptimize(m); 4310 return obj.val(); 4311 } 4312 return -1; 4313 } 4314 4315 @Run(test = "test155") 4316 @Warmup(10000) // Make sure profile information is available at cast 4317 public void test155_verifier(RunInfo info) { 4318 MyClass152 unused = new MyClass152(rI); 4319 MyValue152 val = new MyValue152(rI); 4320 Asserts.assertEquals(test155(info.getTest(), val, false, false), -1); 4321 Asserts.assertEquals(test155(info.getTest(), val, true, false), -1); 4322 Asserts.assertEquals(test155(info.getTest(), null, true, false), -1); 4323 if (!info.isWarmUp()) { 4324 Asserts.assertEquals(test155(info.getTest(), val, false, true), rI); 4325 } 4326 } 4327 4328 @NullRestricted 4329 final static MyValue1 test157Cache = MyValue1.createWithFieldsInline(rI, 0); 4330 4331 // Test merging buffered inline type from field load with non-buffered inline type 4332 @Test 4333 public MyValue1 test157(long val) { 4334 return (val == 0L) ? test157Cache : MyValue1.createWithFieldsInline(rI, val); 4335 } 4336 4337 @Run(test = "test157") 4338 public void test157_verifier() { 4339 Asserts.assertEquals(test157(0), test157Cache); 4340 Asserts.assertEquals(test157(rL).hash(), testValue1.hash()); 4341 } 4342 4343 @NullRestricted 4344 static MyValue1 test158Cache = MyValue1.createWithFieldsInline(rI, 0); 4345 4346 // Same as test157 but with non-final field load 4347 @Test 4348 public MyValue1 test158(long val) { 4349 return (val == 0L) ? test158Cache : MyValue1.createWithFieldsInline(rI, val); 4350 } 4351 4352 @Run(test = "test158") 4353 public void test158_verifier() { 4354 Asserts.assertEquals(test158(0), test158Cache); 4355 Asserts.assertEquals(test158(rL).hash(), testValue1.hash()); 4356 } 4357 4358 // Verify that cast that with incompatible types is properly handled 4359 @Test 4360 public void test160(NonValueClass arg) { 4361 Object tmp = arg; 4362 MyValue1 res = (MyValue1)tmp; 4363 } 4364 4365 @Run(test = "test160") 4366 @Warmup(10000) 4367 public void test160_verifier(RunInfo info) { 4368 try { 4369 test160(new NonValueClass(42)); 4370 throw new RuntimeException("No CCE thrown"); 4371 } catch (ClassCastException e) { 4372 // Expected 4373 } 4374 test160(null); 4375 } 4376 }