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 jdk.test.whitebox.WhiteBox; 29 30 import java.lang.reflect.Method; 31 32 import jdk.internal.value.ValueClass; 33 import jdk.internal.vm.annotation.ImplicitlyConstructible; 34 import jdk.internal.vm.annotation.LooselyConsistentValue; 35 import jdk.internal.vm.annotation.NullRestricted; 36 37 import static compiler.valhalla.inlinetypes.InlineTypeIRNode.*; 38 import static compiler.valhalla.inlinetypes.InlineTypes.*; 39 40 /* 41 * @test 42 * @key randomness 43 * @summary Test value class specific type profiling. 44 * @library /test/lib / 45 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") 46 * @enablePreview 47 * @modules java.base/jdk.internal.value 48 * java.base/jdk.internal.vm.annotation 49 * @run main/othervm/timeout=300 compiler.valhalla.inlinetypes.TestLWorldProfiling 50 */ 51 52 @ForceCompileClassInitializer 53 public class TestLWorldProfiling { 54 55 public static void main(String[] args) { 56 final Scenario[] scenarios = { 57 new Scenario(0, 58 "-XX:FlatArrayElementMaxSize=-1", 59 "-XX:-UseArrayLoadStoreProfile", 60 "-XX:-UseACmpProfile", 61 "-XX:TypeProfileLevel=0", 62 "-XX:-MonomorphicArrayCheck"), 63 new Scenario(1, 64 "-XX:FlatArrayElementMaxSize=-1", 65 "-XX:+UseArrayLoadStoreProfile", 66 "-XX:+UseACmpProfile", 67 "-XX:TypeProfileLevel=0"), 68 new Scenario(2, 69 "-XX:FlatArrayElementMaxSize=-1", 70 "-XX:-UseArrayLoadStoreProfile", 71 "-XX:-UseACmpProfile", 72 "-XX:TypeProfileLevel=222", 73 "-XX:-MonomorphicArrayCheck"), 74 new Scenario(3, 75 "-XX:FlatArrayElementMaxSize=-1", 76 "-XX:-UseArrayLoadStoreProfile", 77 "-XX:-UseACmpProfile", 78 "-XX:TypeProfileLevel=0", 79 "-XX:-MonomorphicArrayCheck", 80 "-XX:TieredStopAtLevel=4", 81 "-XX:-TieredCompilation"), 82 new Scenario(4, 83 "-XX:FlatArrayElementMaxSize=-1", 84 "-XX:+UseArrayLoadStoreProfile", 85 "-XX:+UseACmpProfile", 86 "-XX:TypeProfileLevel=0", 87 "-XX:TieredStopAtLevel=4", 88 "-XX:-TieredCompilation"), 89 new Scenario(5, 90 "-XX:FlatArrayElementMaxSize=-1", 91 "-XX:-UseArrayLoadStoreProfile", 92 "-XX:-UseACmpProfile", 93 "-XX:TypeProfileLevel=222", 94 "-XX:-MonomorphicArrayCheck", 95 "-XX:TieredStopAtLevel=4", 96 "-XX:-TieredCompilation") 97 }; 98 99 InlineTypes.getFramework() 100 .addScenarios(scenarios) 101 .addFlags("-XX:+IgnoreUnrecognizedVMOptions", "--enable-preview", 102 "--add-exports", "java.base/jdk.internal.vm.annotation=ALL-UNNAMED", 103 "--add-exports", "java.base/jdk.internal.value=ALL-UNNAMED") 104 .addHelperClasses(MyValue1.class, 105 MyValue2.class) 106 .start(); 107 } 108 109 @NullRestricted 110 private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); 111 @NullRestricted 112 private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, rD); 113 private static final MyValue1[] testValue1Array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 114 static { 115 testValue1Array[0] = testValue1; 116 } 117 private static final MyValue2[] testValue2Array = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1); 118 static { 119 testValue2Array[0] = testValue2; 120 } 121 private static final Integer[] testIntegerArray = new Integer[] { 42 }; 122 private static final Long[] testLongArray = new Long[] { 42L }; 123 private static final Double[] testDoubleArray = new Double[] { 42.0D }; 124 private static final MyValue1[] testValue1NotFlatArray = new MyValue1[] { testValue1 }; 125 private static final MyValue1[][] testValue1ArrayArray = new MyValue1[][] { testValue1Array }; 126 127 // Wrap these variables into helper class because 128 // WhiteBox API needs to be initialized by TestFramework first. 129 static class WBFlags { 130 static final boolean UseACmpProfile = (Boolean) WhiteBox.getWhiteBox().getVMFlag("UseACmpProfile"); 131 static final boolean TieredCompilation = (Boolean) WhiteBox.getWhiteBox().getVMFlag("TieredCompilation"); 132 static final boolean ProfileInterpreter = (Boolean) WhiteBox.getWhiteBox().getVMFlag("ProfileInterpreter"); 133 static final boolean UseArrayLoadStoreProfile = (Boolean) WhiteBox.getWhiteBox().getVMFlag("UseArrayLoadStoreProfile"); 134 static final long TypeProfileLevel = (Long) WhiteBox.getWhiteBox().getVMFlag("TypeProfileLevel"); 135 } 136 137 static abstract class NonValueAbstract { 138 139 } 140 141 static class NonValueClass1 extends NonValueAbstract { 142 int x; 143 144 public NonValueClass1(int x) { 145 this.x = x; 146 } 147 } 148 149 static class NonValueClass2 extends NonValueAbstract { 150 int x; 151 152 public NonValueClass2(int x) { 153 this.x = x; 154 } 155 } 156 157 static final NonValueClass1 obj = new NonValueClass1(rI); 158 static final NonValueClass2 otherObj = new NonValueClass2(rI); 159 160 // aaload 161 162 @Test 163 @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, 164 failOn = {LOAD_UNKNOWN_INLINE}) 165 @IR(applyIfAnd={"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 166 counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 167 public Object test1(Object[] array) { 168 return array[0]; 169 } 170 171 @Run(test = "test1") 172 @Warmup(10000) 173 public void test1_verifier(RunInfo info) { 174 if (info.isWarmUp()) { 175 Object o = test1(testValue1Array); 176 Asserts.assertEQ(((MyValue1)o).hash(), testValue1.hash()); 177 } else { 178 Object o = test1(testValue2Array); 179 Asserts.assertEQ(((MyValue2)o).hash(), testValue2.hash()); 180 } 181 } 182 183 @Test 184 @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, 185 failOn = {LOAD_UNKNOWN_INLINE}) 186 @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, 187 counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 188 public Object test2(Object[] array) { 189 return array[0]; 190 } 191 192 @Run(test = "test2") 193 @Warmup(10000) 194 public void test2_verifier(RunInfo info) { 195 if (info.isWarmUp()) { 196 Object o = test2(testIntegerArray); 197 Asserts.assertEQ(o, 42); 198 } else { 199 Object o = test2(testLongArray); 200 Asserts.assertEQ(o, 42L); 201 } 202 } 203 204 @Test 205 @IR(counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 206 public Object test3(Object[] array) { 207 return array[0]; 208 } 209 210 @Run(test = "test3") 211 @Warmup(10000) 212 public void test3_verifier() { 213 Object o = test3(testValue1Array); 214 Asserts.assertEQ(((MyValue1)o).hash(), testValue1.hash()); 215 o = test3(testValue2Array); 216 Asserts.assertEQ(((MyValue2)o).hash(), testValue2.hash()); 217 } 218 219 @Test 220 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 221 failOn = {LOAD_UNKNOWN_INLINE}) 222 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 223 counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 224 public Object test4(Object[] array) { 225 return array[0]; 226 } 227 228 @Run(test = "test4") 229 @Warmup(10000) 230 public void test4_verifier(RunInfo info) { 231 if (info.isWarmUp()) { 232 Object o = test4(testIntegerArray); 233 Asserts.assertEQ(o, 42); 234 o = test4(testLongArray); 235 Asserts.assertEQ(o, 42L); 236 } else { 237 Object o = test4(testValue2Array); 238 Asserts.assertEQ(((MyValue2)o).hash(), testValue2.hash()); 239 } 240 } 241 242 @Test 243 @IR(counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 244 public Object test5(Object[] array) { 245 return array[0]; 246 } 247 248 @Run(test = "test5") 249 @Warmup(10000) 250 public void test5_verifier() { 251 Object o = test5(testValue1Array); 252 Asserts.assertEQ(((MyValue1)o).hash(), testValue1.hash()); 253 o = test5(testValue1NotFlatArray); 254 Asserts.assertEQ(((MyValue1)o).hash(), testValue1.hash()); 255 } 256 257 // Check that profile data that's useless at the aaload is 258 // leveraged at a later point 259 @DontInline 260 public void test6_no_inline() { 261 } 262 263 @ForceInline 264 public void test6_helper(NonValueAbstract[] arg) { 265 if (arg instanceof NonValueClass1[]) { 266 test6_no_inline(); 267 } 268 } 269 270 @Test 271 // TODO 8325106 double-check rule modifications done by 8325660 272 @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, 273 counts = {CALL, "= 4", CLASS_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 1", RANGE_CHECK_TRAP, "= 1"}) 274 @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, 275 counts = {CALL, "= 3", RANGE_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 1"}) 276 public Object test6(NonValueAbstract[] array) { 277 NonValueAbstract v = array[0]; 278 test6_helper(array); 279 return v; 280 } 281 282 @Run(test = "test6") 283 @Warmup(10000) 284 public void test6_verifier(RunInfo info) { 285 if (info.isWarmUp()) { 286 // pollute profile 287 test6_helper(new NonValueClass1[1]); 288 test6_helper(new NonValueClass2[1]); 289 } 290 test6(new NonValueClass1[1]); 291 } 292 293 @DontInline 294 public void test7_no_inline() { 295 } 296 297 @ForceInline 298 public void test7_helper(Object arg) { 299 if (arg instanceof NonValueClass1) { 300 test7_no_inline(); 301 } 302 } 303 304 @Test 305 // TODO 8325106 double-check rule modifications done by 8325660 306 @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, 307 counts = {CALL, "= 3", CLASS_CHECK_TRAP, "= 0", NULL_CHECK_TRAP, "= 1", RANGE_CHECK_TRAP, "= 1"}) 308 @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, 309 counts = {CALL, "= 3", RANGE_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 1"}) 310 public Object test7(NonValueAbstract[] array) { 311 NonValueAbstract v = array[0]; 312 test7_helper(v); 313 return v; 314 } 315 316 @Run(test = "test7") 317 @Warmup(10000) 318 public void test7_verifier(RunInfo info) { 319 if (info.isWarmUp()) { 320 // pollute profile 321 test7_helper(new NonValueClass1(rI)); 322 test7_helper(new NonValueClass2(rI)); 323 } 324 test7(new NonValueClass1[1]); 325 } 326 327 @DontInline 328 public void test8_no_inline() { 329 } 330 331 public void test8_helper(Object arg) { 332 if (arg instanceof Long) { 333 test8_no_inline(); 334 } 335 } 336 337 @Test 338 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 339 counts = {CALL, "= 5", CLASS_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 2", 340 RANGE_CHECK_TRAP, "= 1"}) 341 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 342 counts = {CALL, "= 5", RANGE_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 2"}) 343 public Object test8(Object[] array) { 344 Object v = array[0]; 345 test8_helper(v); 346 return v; 347 } 348 349 @Run(test = "test8") 350 @Warmup(10000) 351 public void test8_verifier(RunInfo info) { 352 if (info.isWarmUp()) { 353 // pollute profile 354 test8_helper(42L); 355 test8_helper(42.0D); 356 } 357 test8(testValue1Array); 358 test8(testValue1NotFlatArray); 359 } 360 361 // aastore 362 363 @Test 364 @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, 365 failOn = {STORE_UNKNOWN_INLINE}) 366 @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, 367 counts = {STORE_UNKNOWN_INLINE, "= 1"}) 368 public void test9(Object[] array, Object v) { 369 array[0] = v; 370 } 371 372 @Run(test = "test9") 373 @Warmup(10000) 374 public void test9_verifier() { 375 test9(testValue1Array, testValue1); 376 Asserts.assertEQ(testValue1Array[0].hash(), testValue1.hash()); 377 } 378 379 @Test 380 @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, 381 failOn = {STORE_UNKNOWN_INLINE}) 382 @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, 383 counts = {STORE_UNKNOWN_INLINE, "= 1"}) 384 public void test10(Object[] array, Object v) { 385 array[0] = v; 386 } 387 388 @Run(test = "test10") 389 @Warmup(10000) 390 public void test10_verifier() { 391 test10(testIntegerArray, 42); 392 } 393 394 @Test 395 @IR(counts = {STORE_UNKNOWN_INLINE, "= 1"}) 396 public void test11(Object[] array, Object v) { 397 array[0] = v; 398 } 399 400 @Run(test = "test11") 401 @Warmup(10000) 402 public void test11_verifier() { 403 test11(testValue1Array, testValue1); 404 test11(testValue2Array, testValue2); 405 } 406 407 @Test 408 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 409 failOn = {STORE_UNKNOWN_INLINE}) 410 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 411 counts = {STORE_UNKNOWN_INLINE, "= 1"}) 412 public void test12(Object[] array, Object v) { 413 array[0] = v; 414 } 415 416 @Run(test = "test12") 417 @Warmup(10000) 418 public void test12_verifier() { 419 test12(testIntegerArray, 42); 420 test12(testLongArray, 42L); 421 } 422 423 @Test 424 @IR(counts = {STORE_UNKNOWN_INLINE, "= 1"}) 425 public void test13(Object[] array, Object v) { 426 array[0] = v; 427 } 428 429 @Run(test = "test13") 430 @Warmup(10000) 431 public void test13_verifier() { 432 test13(testValue1Array, testValue1); 433 test13(testValue1NotFlatArray, testValue1); 434 } 435 436 // MonomorphicArrayCheck 437 @Test 438 public void test14(Number[] array, Number v) { 439 array[0] = v; 440 } 441 442 @Run(test = "test14") 443 @Warmup(10000) 444 public void test14_verifier(RunInfo info) { 445 if (info.isWarmUp()) { 446 test14(testIntegerArray, 42); 447 } else { 448 Method m = info.getTest(); 449 boolean deopt = false; 450 for (int i = 0; i < 100; i++) { 451 test14(testIntegerArray, 42); 452 if (!info.isCompilationSkipped() && !TestFramework.isCompiled(m)) { 453 deopt = true; 454 } 455 } 456 if (deopt && TestFramework.isStableDeopt(m, CompLevel.C2) && !WBFlags.TieredCompilation && WBFlags.ProfileInterpreter && 457 (WBFlags.UseArrayLoadStoreProfile || WBFlags.TypeProfileLevel == 222)) { 458 throw new RuntimeException("Monomorphic array check should rely on profiling and be accurate"); 459 } 460 } 461 } 462 463 // null free array profiling 464 465 @ImplicitlyConstructible 466 @LooselyConsistentValue 467 static value class NotFlattenable { 468 private Object o1 = null; 469 private Object o2 = null; 470 private Object o3 = null; 471 private Object o4 = null; 472 private Object o5 = null; 473 private Object o6 = null; 474 } 475 476 @NullRestricted 477 private static final NotFlattenable notFlattenable = new NotFlattenable(); 478 private static final NotFlattenable[] testNotFlattenableArray = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1); 479 480 @Test 481 // TODO 8325106 482 // @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, 483 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 484 counts = {NULL_CHECK_TRAP, "= 2"}, 485 failOn = {STORE_UNKNOWN_INLINE}) 486 @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, 487 counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) 488 public void test15(Object[] array, Object v) { 489 array[0] = v; 490 } 491 492 @Run(test = "test15") 493 @Warmup(10000) 494 public void test15_verifier() { 495 test15(testNotFlattenableArray, notFlattenable); 496 try { 497 test15(testNotFlattenableArray, null); 498 throw new RuntimeException("NullPointerException expected"); 499 } catch (NullPointerException npe) { 500 // Expected 501 } 502 } 503 504 @Test 505 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 506 counts = {NULL_CHECK_TRAP, "= 2"}, 507 failOn = {STORE_UNKNOWN_INLINE}) 508 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 509 counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) 510 public void test16(Object[] array, Object v) { 511 array[0] = v; 512 } 513 514 @Run(test = "test16") 515 @Warmup(10000) 516 public void test16_verifier() { 517 test16(testNotFlattenableArray, notFlattenable); 518 try { 519 test16(testNotFlattenableArray, null); 520 throw new RuntimeException("NullPointerException expected"); 521 } catch (NullPointerException npe) { 522 // Expected 523 } 524 test16(testIntegerArray, 42); 525 } 526 527 @Test 528 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 529 counts = {NULL_CHECK_TRAP, "= 1"}, 530 failOn = {STORE_UNKNOWN_INLINE}) 531 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 532 counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) 533 public void test17(Object[] array, Object v) { 534 array[0] = v; 535 } 536 537 @Run(test = "test17") 538 @Warmup(10000) 539 public void test17_verifier() { 540 test17(testIntegerArray, 42); 541 test17(testIntegerArray, null); 542 testIntegerArray[0] = 42; 543 test17(testLongArray, 42L); 544 } 545 546 public void test18_helper(Object[] array, Object v) { 547 array[0] = v; 548 } 549 550 @Test 551 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 552 counts = {NULL_CHECK_TRAP, "= 1"}, 553 failOn = {STORE_UNKNOWN_INLINE}) 554 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 555 counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) 556 public Object test18(Object[] array, Object v1) { 557 Object v2 = array[0]; 558 test18_helper(array, v1); 559 return v2; 560 } 561 562 @Run(test = "test18") 563 @Warmup(10000) 564 public void test18_verifier() { 565 test18_helper(testValue1Array, testValue1); // pollute profile 566 test18(testIntegerArray, 42); 567 test18(testIntegerArray, null); 568 testIntegerArray[0] = 42; 569 test18(testLongArray, 42L); 570 } 571 572 // maybe null free, not flat 573 574 @Test 575 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 576 failOn = {LOAD_UNKNOWN_INLINE}) 577 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 578 counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 579 public Object test19(Object[] array) { 580 return array[0]; 581 } 582 583 @Run(test = "test19") 584 @Warmup(10000) 585 public void test19_verifier() { 586 Object o = test19(testIntegerArray); 587 Asserts.assertEQ(o, 42); 588 o = test19(testNotFlattenableArray); 589 Asserts.assertEQ(o, notFlattenable); 590 } 591 592 @Test 593 @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, 594 failOn = {STORE_UNKNOWN_INLINE}) 595 @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, 596 counts = {STORE_UNKNOWN_INLINE, "= 1"}) 597 public void test20(Object[] array, Object o) { 598 array[0] = o; 599 } 600 601 @Run(test = "test20") 602 @Warmup(10000) 603 public void test20_verifier() { 604 test20(testIntegerArray, 42); 605 test20(testNotFlattenableArray, notFlattenable); 606 } 607 608 // acmp tests 609 610 // branch frequency profiling causes not equal branch to be optimized out 611 @Test 612 @IR(counts = {IRNode.UNSTABLE_IF_TRAP, " = 1"}) 613 public boolean test21(Object o1, Object o2) { 614 return o1 == o2; 615 } 616 617 @Run(test = "test21") 618 @Warmup(10000) 619 public void test21_verifier() { 620 test21(obj, obj); 621 test21(testValue1, testValue1); 622 } 623 624 // Input profiled non null 625 @Test 626 @IR(applyIf = {"UseACmpProfile", "true"}, 627 failOn = {SUBSTITUTABILITY_TEST}, 628 counts = {NULL_ASSERT_TRAP, "= 1"}) 629 @IR(applyIf = {"UseACmpProfile", "false"}, 630 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 631 public boolean test22(Object o1, Object o2) { 632 return o1 == o2; 633 } 634 635 @Run(test = "test22") 636 @Warmup(10000) 637 public void test22_verifier(RunInfo info) { 638 test22(obj, null); 639 test22(otherObj, null); 640 if (!info.isWarmUp()) { 641 Method m = info.getTest(); 642 TestFramework.assertCompiledByC2(m); 643 test22(obj, otherObj); 644 if (WBFlags.UseACmpProfile) { 645 TestFramework.assertDeoptimizedByC2(m); 646 } 647 } 648 } 649 650 @Test 651 @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, 652 failOn = {SUBSTITUTABILITY_TEST}, 653 counts = {NULL_ASSERT_TRAP, "= 1"}) 654 @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 655 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 656 public boolean test23(Object o1, Object o2) { 657 return o1 == o2; 658 } 659 660 @Run(test = "test23") 661 @Warmup(10000) 662 public void test23_verifier(RunInfo info) { 663 test23(null, obj); 664 test23(null, otherObj); 665 if (!info.isWarmUp()) { 666 Method m = info.getTest(); 667 TestFramework.assertCompiledByC2(m); 668 test23(obj, otherObj); 669 if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { 670 TestFramework.assertDeoptimizedByC2(m); 671 } 672 } 673 } 674 675 @Test 676 @IR(applyIf = {"UseACmpProfile", "true"}, 677 failOn = {SUBSTITUTABILITY_TEST}, 678 counts = {NULL_ASSERT_TRAP, "= 1"}) 679 @IR(applyIf = {"UseACmpProfile", "false"}, 680 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 681 public boolean test24(Object o1, Object o2) { 682 return o1 != o2; 683 } 684 685 @Run(test = "test24") 686 @Warmup(10000) 687 public void test24_verifier(RunInfo info) { 688 test24(obj, null); 689 test24(otherObj, null); 690 if (!info.isWarmUp()) { 691 Method m = info.getTest(); 692 TestFramework.assertCompiledByC2(m); 693 test24(obj, otherObj); 694 if (WBFlags.UseACmpProfile) { 695 TestFramework.assertDeoptimizedByC2(m); 696 } 697 } 698 } 699 700 @Test 701 @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, 702 failOn = {SUBSTITUTABILITY_TEST}, 703 counts = {NULL_ASSERT_TRAP, "= 1"}) 704 @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 705 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 706 public boolean test25(Object o1, Object o2) { 707 return o1 != o2; 708 } 709 710 @Run(test = "test25") 711 @Warmup(10000) 712 public void test25_verifier(RunInfo info) { 713 test25(null, obj); 714 test25(null, otherObj); 715 if (!info.isWarmUp()) { 716 Method m = info.getTest(); 717 TestFramework.assertCompiledByC2(m); 718 test25(obj, otherObj); 719 if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { 720 TestFramework.assertDeoptimizedByC2(m); 721 } 722 } 723 } 724 725 // Input profiled not value class with known type 726 @Test 727 @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, 728 failOn = {SUBSTITUTABILITY_TEST}, 729 counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 730 @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 731 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 732 public boolean test26(Object o1, Object o2) { 733 return o1 == o2; 734 } 735 736 @Run(test = "test26") 737 @Warmup(10000) 738 public void test26_verifier(RunInfo info) { 739 test26(obj, obj); 740 test26(obj, otherObj); 741 if (!info.isWarmUp()) { 742 Method m = info.getTest(); 743 TestFramework.assertCompiledByC2(m); 744 for (int i = 0; i < 10; i++) { 745 test26(otherObj, obj); 746 } 747 if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { 748 TestFramework.assertDeoptimizedByC2(m); 749 } 750 } 751 } 752 753 @Test 754 @IR(applyIf = {"UseACmpProfile", "true"}, 755 failOn = {SUBSTITUTABILITY_TEST}, 756 counts = { NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 757 @IR(applyIf = {"UseACmpProfile", "false"}, 758 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 759 public boolean test27(Object o1, Object o2) { 760 return o1 == o2; 761 } 762 763 @Run(test = "test27") 764 @Warmup(10000) 765 public void test27_verifier(RunInfo info) { 766 test27(obj, obj); 767 test27(otherObj, obj); 768 if (!info.isWarmUp()) { 769 Method m = info.getTest(); 770 TestFramework.assertCompiledByC2(m); 771 for (int i = 0; i < 10; i++) { 772 test27(obj, otherObj); 773 } 774 if (WBFlags.UseACmpProfile) { 775 TestFramework.assertDeoptimizedByC2(m); 776 } 777 } 778 } 779 780 @Test 781 @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, 782 failOn = {SUBSTITUTABILITY_TEST}, 783 counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 784 @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 785 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 786 public boolean test28(Object o1, Object o2) { 787 return o1 != o2; 788 } 789 790 @Run(test = "test28") 791 @Warmup(10000) 792 public void test28_verifier(RunInfo info) { 793 test28(obj, obj); 794 test28(obj, otherObj); 795 if (!info.isWarmUp()) { 796 Method m = info.getTest(); 797 TestFramework.assertCompiledByC2(m); 798 for (int i = 0; i < 10; i++) { 799 test28(otherObj, obj); 800 } 801 if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { 802 TestFramework.assertDeoptimizedByC2(m); 803 } 804 } 805 } 806 807 @Test 808 @IR(applyIf = {"UseACmpProfile", "true"}, 809 failOn = {SUBSTITUTABILITY_TEST}, 810 counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 811 @IR(applyIf = {"UseACmpProfile", "false"}, 812 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 813 public boolean test29(Object o1, Object o2) { 814 return o1 != o2; 815 } 816 817 @Run(test = "test29") 818 @Warmup(10000) 819 public void test29_verifier(RunInfo info) { 820 test29(obj, obj); 821 test29(otherObj, obj); 822 if (!info.isWarmUp()) { 823 Method m = info.getTest(); 824 TestFramework.assertCompiledByC2(m); 825 for (int i = 0; i < 10; i++) { 826 test29(obj, otherObj); 827 } 828 if (WBFlags.UseACmpProfile) { 829 TestFramework.assertDeoptimizedByC2(m); 830 } 831 } 832 } 833 834 @Test 835 @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, 836 failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}, 837 counts = {CLASS_CHECK_TRAP, "= 1"}) 838 @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 839 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 840 public boolean test30(Object o1, Object o2) { 841 return o1 == o2; 842 } 843 844 @Run(test = "test30") 845 @Warmup(10000) 846 public void test30_verifier(RunInfo info) { 847 test30(obj, obj); 848 test30(obj, otherObj); 849 test30(null, 42); 850 if (!info.isWarmUp()) { 851 Method m = info.getTest(); 852 TestFramework.assertCompiledByC2(m); 853 for (int i = 0; i < 10; i++) { 854 test30(otherObj, obj); 855 } 856 if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { 857 TestFramework.assertDeoptimizedByC2(m); 858 } 859 } 860 } 861 862 @Test 863 @IR(applyIf = {"UseACmpProfile", "true"}, 864 failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}) 865 @IR(applyIf = {"UseACmpProfile", "false"}, 866 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 867 public boolean test31(Object o1, Object o2) { 868 return o1 == o2; 869 } 870 871 @Run(test = "test31") 872 @Warmup(10000) 873 public void test31_verifier(RunInfo info) { 874 test31(obj, obj); 875 test31(otherObj, obj); 876 test31(obj, null); 877 if (!info.isWarmUp()) { 878 Method m = info.getTest(); 879 TestFramework.assertCompiledByC2(m); 880 for (int i = 0; i < 10; i++) { 881 test31(obj, otherObj); 882 } 883 if (WBFlags.UseACmpProfile) { 884 TestFramework.assertDeoptimizedByC2(m); 885 } 886 } 887 } 888 889 // Input profiled not value class with unknown type 890 @Test 891 @IR(applyIf = {"UseACmpProfile", "true"}, 892 failOn = {SUBSTITUTABILITY_TEST}, 893 counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 894 @IR(applyIf = {"UseACmpProfile", "false"}, 895 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 896 public boolean test32(Object o1, Object o2) { 897 return o1 == o2; 898 } 899 900 @Run(test = "test32") 901 @Warmup(10000) 902 public void test32_verifier(RunInfo info) { 903 test32(obj, obj); 904 test32(obj, testValue1); 905 test32(otherObj, obj); 906 if (!info.isWarmUp()) { 907 Method m = info.getTest(); 908 TestFramework.assertCompiledByC2(m); 909 for (int i = 0; i < 10; i++) { 910 test32(testValue1, 42); 911 } 912 if (WBFlags.UseACmpProfile) { 913 TestFramework.assertDeoptimizedByC2(m); 914 } 915 } 916 } 917 918 @Test 919 @IR(applyIf = {"UseACmpProfile", "true"}, 920 failOn = {SUBSTITUTABILITY_TEST}, 921 counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 922 @IR(applyIf = {"UseACmpProfile", "false"}, 923 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 924 public boolean test33(Object o1, Object o2) { 925 return o1 == o2; 926 } 927 928 @Run(test = "test33") 929 @Warmup(10000) 930 public void test33_verifier(RunInfo info) { 931 test33(obj, obj); 932 test33(testValue1, obj); 933 test33(obj, otherObj); 934 if (!info.isWarmUp()) { 935 Method m = info.getTest(); 936 TestFramework.assertCompiledByC2(m); 937 for (int i = 0; i < 10; i++) { 938 test33(obj, testValue1); 939 } 940 if (WBFlags.UseACmpProfile) { 941 TestFramework.assertDeoptimizedByC2(m); 942 } 943 } 944 } 945 946 @Test 947 @IR(applyIf = {"UseACmpProfile", "true"}, 948 failOn = {SUBSTITUTABILITY_TEST}, 949 counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 950 @IR(applyIf = {"UseACmpProfile", "false"}, 951 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 952 public boolean test34(Object o1, Object o2) { 953 return o1 != o2; 954 } 955 956 @Run(test = "test34") 957 @Warmup(10000) 958 public void test34_verifier(RunInfo info) { 959 test34(obj, obj); 960 test34(obj, testValue1); 961 test34(otherObj, obj); 962 if (!info.isWarmUp()) { 963 Method m = info.getTest(); 964 TestFramework.assertCompiledByC2(m); 965 for (int i = 0; i < 10; i++) { 966 test34(testValue1, 42); 967 } 968 if (WBFlags.UseACmpProfile) { 969 TestFramework.assertDeoptimizedByC2(m); 970 } 971 } 972 } 973 974 @Test 975 @IR(applyIf = {"UseACmpProfile", "true"}, 976 failOn = {SUBSTITUTABILITY_TEST}, 977 counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) 978 @IR(applyIf = {"UseACmpProfile", "false"}, 979 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 980 public boolean test35(Object o1, Object o2) { 981 return o1 != o2; 982 } 983 984 @Run(test = "test35") 985 @Warmup(10000) 986 public void test35_verifier(RunInfo info) { 987 test35(obj, obj); 988 test35(testValue1, obj); 989 test35(obj, otherObj); 990 if (!info.isWarmUp()) { 991 Method m = info.getTest(); 992 TestFramework.assertCompiledByC2(m); 993 for (int i = 0; i < 10; i++) { 994 test35(obj, testValue1); 995 } 996 if (WBFlags.UseACmpProfile) { 997 TestFramework.assertDeoptimizedByC2(m); 998 } 999 } 1000 } 1001 1002 @Test 1003 @IR(applyIf = {"UseACmpProfile", "true"}, 1004 failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}, 1005 counts = {CLASS_CHECK_TRAP, "= 1"}) 1006 @IR(applyIf = {"UseACmpProfile", "false"}, 1007 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 1008 public boolean test36(Object o1, Object o2) { 1009 return o1 == o2; 1010 } 1011 1012 @Run(test = "test36") 1013 @Warmup(10000) 1014 public void test36_verifier(RunInfo info) { 1015 test36(obj, otherObj); 1016 test36(otherObj, testValue1); 1017 test36(null, obj); 1018 if (!info.isWarmUp()) { 1019 Method m = info.getTest(); 1020 TestFramework.assertCompiledByC2(m); 1021 for (int i = 0; i < 10; i++) { 1022 test36(testValue1, obj); 1023 } 1024 if (WBFlags.UseACmpProfile) { 1025 TestFramework.assertDeoptimizedByC2(m); 1026 } 1027 } 1028 } 1029 1030 @Test 1031 @IR(applyIf = {"UseACmpProfile", "true"}, 1032 failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}) 1033 @IR(applyIf = {"UseACmpProfile", "false"}, 1034 counts = {SUBSTITUTABILITY_TEST, "= 1"}) 1035 public boolean test37(Object o1, Object o2) { 1036 return o1 == o2; 1037 } 1038 1039 @Run(test = "test37") 1040 @Warmup(10000) 1041 public void test37_verifier(RunInfo info) { 1042 test37(otherObj, obj); 1043 test37(testValue1, otherObj); 1044 test37(obj, null); 1045 if (!info.isWarmUp()) { 1046 Method m = info.getTest(); 1047 TestFramework.assertCompiledByC2(m); 1048 for (int i = 0; i < 10; i++) { 1049 test37(obj, testValue1); 1050 } 1051 if (WBFlags.UseACmpProfile) { 1052 TestFramework.assertDeoptimizedByC2(m); 1053 } 1054 } 1055 } 1056 1057 // Test that acmp profile data that's unused at the acmp is fed to 1058 // speculation and leverage later 1059 @Test 1060 @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, 1061 failOn = {SUBSTITUTABILITY_TEST}, 1062 counts = {CLASS_CHECK_TRAP, "= 2"}) 1063 @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 1064 counts = {SUBSTITUTABILITY_TEST, "= 2"}) 1065 public void test38(Object o1, Object o2, Object o3) { 1066 if (o1 == o2) { 1067 test38_helper2(); 1068 } 1069 test38_helper(o1, o3); 1070 } 1071 1072 public void test38_helper(Object o1, Object o2) { 1073 if (o1 == o2) { 1074 } 1075 } 1076 1077 public void test38_helper2() { 1078 } 1079 1080 @Run(test = "test38") 1081 @Warmup(10000) 1082 public void test38_verifier() { 1083 test38(obj, obj, obj); 1084 test38_helper(testValue1, testValue2); 1085 } 1086 1087 @Test 1088 @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, 1089 failOn = {SUBSTITUTABILITY_TEST}, 1090 counts = {CLASS_CHECK_TRAP, "= 2"}) 1091 @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, 1092 counts = {SUBSTITUTABILITY_TEST, "= 2"}) 1093 public void test39(Object o1, Object o2, Object o3) { 1094 if (o1 == o2) { 1095 test39_helper2(); 1096 } 1097 test39_helper(o2, o3); 1098 } 1099 1100 public void test39_helper(Object o1, Object o2) { 1101 if (o1 == o2) { 1102 } 1103 } 1104 1105 public void test39_helper2() { 1106 } 1107 1108 @Run(test = "test39") 1109 @Warmup(10000) 1110 public void test39_verifier() { 1111 test39(obj, obj, obj); 1112 test39_helper(testValue1, testValue2); 1113 } 1114 1115 // Test array access with polluted array type profile 1116 static abstract value class Test40Abstract { } 1117 static value class Test40Class extends Test40Abstract { } 1118 1119 @ImplicitlyConstructible 1120 @LooselyConsistentValue 1121 static value class Test40Inline extends Test40Abstract { } 1122 1123 @ForceInline 1124 public Object test40_access(Object[] array) { 1125 return array[0]; 1126 } 1127 1128 @Test 1129 public Object test40(Test40Abstract[] array) { 1130 return test40_access(array); 1131 } 1132 1133 @Run(test = "test40") 1134 @Warmup(10000) 1135 public void test40_verifier(RunInfo info) { 1136 // Make sure multiple implementors of Test40Abstract are loaded 1137 Test40Inline tmp1 = new Test40Inline(); 1138 Test40Class tmp2 = new Test40Class(); 1139 if (info.isWarmUp()) { 1140 // Pollute profile with Object[] (exact) 1141 test40_access(new Object[1]); 1142 } else { 1143 // When inlining test40_access, profiling contradicts actual type of array 1144 test40(new Test40Class[1]); 1145 } 1146 } 1147 1148 // Same as test40 but with array store 1149 @ForceInline 1150 public void test41_access(Object[] array, Object val) { 1151 array[0] = val; 1152 } 1153 1154 @Test 1155 public void test41(Test40Inline[] array, Object val) { 1156 test41_access(array, val); 1157 } 1158 1159 @Run(test = "test41") 1160 @Warmup(10000) 1161 public void test41_verifier(RunInfo info) { 1162 // Make sure multiple implementors of Test40Abstract are loaded 1163 Test40Inline tmp1 = new Test40Inline(); 1164 Test40Class tmp2 = new Test40Class(); 1165 if (info.isWarmUp()) { 1166 // Pollute profile with exact Object[] 1167 test41_access(new Object[1], new Object()); 1168 } else { 1169 // When inlining test41_access, profiling contradicts actual type of array 1170 Test40Inline[] array = (Test40Inline[])ValueClass.newNullRestrictedArray(Test40Inline.class, 1); 1171 test41(array, new Test40Inline()); 1172 } 1173 } 1174 }