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 jdk.internal.value.ValueClass; 31 import jdk.internal.vm.annotation.ImplicitlyConstructible; 32 import jdk.internal.vm.annotation.LooselyConsistentValue; 33 import jdk.internal.vm.annotation.NullRestricted; 34 35 import static compiler.valhalla.inlinetypes.InlineTypes.rI; 36 import static compiler.valhalla.inlinetypes.InlineTypes.rL; 37 38 /* 39 * @test 40 * @key randomness 41 * @summary Test calls from {C1} to {C2, Interpreter}, and vice versa. 42 * @library /test/lib / 43 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") 44 * @enablePreview 45 * @modules java.base/jdk.internal.value 46 * java.base/jdk.internal.vm.annotation 47 * @run main/othervm/timeout=300 compiler.valhalla.inlinetypes.TestCallingConventionC1 48 */ 49 50 @ForceCompileClassInitializer 51 public class TestCallingConventionC1 { 52 53 public static void main(String[] args) { 54 final Scenario[] scenarios = { 55 // Default: both C1 and C2 are enabled, tiered compilation enabled 56 new Scenario(0, 57 "--enable-preview", 58 "-XX:CICompilerCount=2", 59 "-XX:TieredStopAtLevel=4", 60 "-XX:+TieredCompilation"), 61 // Default: both C1 and C2 are enabled, tiered compilation enabled 62 new Scenario(1, 63 "--enable-preview", 64 "-XX:CICompilerCount=2", 65 "-XX:TieredStopAtLevel=4", 66 "-XX:+TieredCompilation", 67 "-XX:+IgnoreUnrecognizedVMOptions", 68 "-XX:+StressInlineTypeReturnedAsFields"), 69 // Same as above, but flip all the compLevel=CompLevel.C1_SIMPLE and compLevel=CompLevel.C2, so we test 70 // the compliment of the above scenario. 71 new Scenario(2, 72 "--enable-preview", 73 "-XX:CICompilerCount=2", 74 "-XX:TieredStopAtLevel=4", 75 "-XX:+TieredCompilation", 76 "-DFlipC1C2=true"), 77 // Only C1. Tiered compilation disabled. 78 new Scenario(3, 79 "--enable-preview", 80 "-XX:TieredStopAtLevel=1", 81 "-XX:+TieredCompilation", 82 "-XX:+IgnoreUnrecognizedVMOptions", 83 "-XX:-PatchALot"), 84 // Only C2. 85 new Scenario(4, 86 "--enable-preview", 87 "-XX:TieredStopAtLevel=4", 88 "-XX:-TieredCompilation") 89 }; 90 91 System.gc(); // Resolve this call, to avoid C1 code patching in the test cases. 92 93 InlineTypes.getFramework() 94 .addScenarios(scenarios) 95 .start(); 96 } 97 98 // Helper methods and classes 99 @ImplicitlyConstructible 100 @LooselyConsistentValue 101 static value class Point { 102 int x; 103 int y; 104 public Point(int x, int y) { 105 this.x = x; 106 this.y = y; 107 } 108 109 @DontCompile 110 public int func() { 111 return x + y; 112 } 113 114 @ForceCompile(CompLevel.C1_SIMPLE) 115 @DontInline 116 public int func_c1(Point p) { 117 return x + y + p.x + p.y; 118 } 119 } 120 121 static interface FunctorInterface { 122 public int apply_interp(Point p); 123 } 124 125 static class Functor implements FunctorInterface { 126 @DontCompile 127 public int apply_interp(Point p) { 128 return p.func() + 0; 129 } 130 } 131 132 static class Functor1 extends Functor { 133 @DontCompile 134 public int apply_interp(Point p) { 135 return p.func() + 10000; 136 } 137 } 138 139 static class Functor2 extends Functor { 140 @DontCompile 141 public int apply_interp(Point p) { 142 return p.func() + 20000; 143 } 144 } 145 146 static class Functor3 extends Functor { 147 @DontCompile 148 public int apply_interp(Point p) { 149 return p.func() + 30000; 150 } 151 } 152 153 static class Functor4 extends Functor { 154 @DontCompile 155 public int apply_interp(Point p) { 156 return p.func() + 40000; 157 } 158 } 159 160 static Functor functors[] = { 161 new Functor(), 162 new Functor1(), 163 new Functor2(), 164 new Functor3(), 165 new Functor4() 166 }; 167 static int functorCounter = 0; 168 static Functor getFunctor() { 169 int n = (++ functorCounter) % functors.length; 170 return functors[n]; 171 } 172 173 @NullRestricted 174 static Point pointField = new Point(123, 456); 175 @NullRestricted 176 static Point pointField1 = new Point(1123, 1456); 177 @NullRestricted 178 static Point pointField2 = new Point(2123, 2456); 179 180 static interface Intf { 181 public int func1(int a, int b); 182 public int func2(int a, int b, Point p); 183 } 184 185 static class MyImplPojo0 implements Intf { 186 int field = 0; 187 @DontCompile 188 public int func1(int a, int b) { return field + a + b + 1; } 189 @DontCompile 190 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } 191 } 192 193 static class MyImplPojo1 implements Intf { 194 int field = 1000; 195 196 @DontInline 197 @ForceCompile(CompLevel.C1_SIMPLE) 198 public int func1(int a, int b) { return field + a + b + 20; } 199 200 @DontInline 201 @ForceCompile(CompLevel.C1_SIMPLE) 202 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } 203 } 204 205 static class MyImplPojo2 implements Intf { 206 int field = 2000; 207 208 @DontInline 209 @ForceCompile(CompLevel.C2) 210 public int func1(int a, int b) { return field + a + b + 20; } 211 212 @DontInline 213 @ForceCompile(CompLevel.C2) 214 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } 215 } 216 217 static class MyImplPojo3 implements Intf { 218 int field = 0; 219 @DontInline // will be compiled with counters 220 public int func1(int a, int b) { return field + a + b + 1; } 221 @DontInline // will be compiled with counters 222 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } 223 } 224 225 @ImplicitlyConstructible 226 @LooselyConsistentValue 227 static value class MyImplVal1 implements Intf { 228 int field; 229 MyImplVal1() { 230 field = 11000; 231 } 232 233 @DontInline 234 @ForceCompile(CompLevel.C1_SIMPLE) 235 public int func1(int a, int b) { return field + a + b + 300; } 236 237 @DontInline 238 @ForceCompile(CompLevel.C1_SIMPLE) 239 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } 240 } 241 242 @ImplicitlyConstructible 243 @LooselyConsistentValue 244 static value class MyImplVal2 implements Intf { 245 int field; 246 MyImplVal2() { 247 field = 12000; 248 } 249 250 @DontInline 251 @ForceCompile(CompLevel.C2) 252 public int func1(int a, int b) { return field + a + b + 300; } 253 254 @DontInline 255 @ForceCompile(CompLevel.C2) 256 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } 257 } 258 259 @ImplicitlyConstructible 260 @LooselyConsistentValue 261 static value class MyImplVal1X implements Intf { 262 int field; 263 MyImplVal1X() { 264 field = 11000; 265 } 266 267 @DontCompile 268 public int func1(int a, int b) { return field + a + b + 300; } 269 270 @DontCompile 271 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } 272 } 273 274 @ImplicitlyConstructible 275 @LooselyConsistentValue 276 static value class MyImplVal2X implements Intf { 277 int field; 278 MyImplVal2X() { 279 field = 12000; 280 } 281 282 @DontInline // will be compiled with counters 283 public int func1(int a, int b) { return field + a + b + 300; } 284 285 @DontInline // will be compiled with counters 286 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } 287 } 288 289 static Intf intfs[] = { 290 new MyImplPojo0(), // methods not compiled 291 new MyImplPojo1(), // methods compiled by C1 292 new MyImplPojo2(), // methods compiled by C2 293 new MyImplVal1(), // methods compiled by C1 294 new MyImplVal2() // methods compiled by C2 295 }; 296 static Intf getIntf(int i) { 297 int n = i % intfs.length; 298 return intfs[n]; 299 } 300 301 @ImplicitlyConstructible 302 @LooselyConsistentValue 303 static value class FixedPoints { 304 boolean Z0 = false; 305 boolean Z1 = true; 306 byte B = (byte)2; 307 char C = (char)34; 308 short S = (short)456; 309 int I = 5678; 310 long J = 0x1234567800abcdefL; 311 } 312 @NullRestricted 313 static FixedPoints fixedPointsField = new FixedPoints(); 314 315 @ImplicitlyConstructible 316 @LooselyConsistentValue 317 static value class FloatPoint { 318 float x; 319 float y; 320 public FloatPoint(float x, float y) { 321 this.x = x; 322 this.y = y; 323 } 324 } 325 326 @ImplicitlyConstructible 327 @LooselyConsistentValue 328 static value class DoublePoint { 329 double x; 330 double y; 331 public DoublePoint(double x, double y) { 332 this.x = x; 333 this.y = y; 334 } 335 } 336 @NullRestricted 337 static FloatPoint floatPointField = new FloatPoint(123.456f, 789.012f); 338 @NullRestricted 339 static DoublePoint doublePointField = new DoublePoint(123.456, 789.012); 340 341 @ImplicitlyConstructible 342 @LooselyConsistentValue 343 static value class EightFloats { 344 float f1, f2, f3, f4, f5, f6, f7, f8; 345 public EightFloats() { 346 f1 = 1.1f; 347 f2 = 2.2f; 348 f3 = 3.3f; 349 f4 = 4.4f; 350 f5 = 5.5f; 351 f6 = 6.6f; 352 f7 = 7.7f; 353 f8 = 8.8f; 354 } 355 } 356 357 static EightFloats eightFloatsField = new EightFloats(); 358 359 static class Number { 360 int n; 361 Number(int v) { 362 n = v; 363 } 364 void set(int v) { 365 n = v; 366 } 367 } 368 369 static interface RefPoint_Access { 370 public int func1(RefPoint rp2); 371 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2); 372 } 373 374 @ImplicitlyConstructible 375 @LooselyConsistentValue 376 static value class RefPoint implements RefPoint_Access { 377 Number x; 378 Number y; 379 public RefPoint(int x, int y) { 380 this.x = new Number(x); 381 this.y = new Number(y); 382 } 383 public RefPoint(Number x, Number y) { 384 this.x = x; 385 this.y = y; 386 } 387 388 @DontInline 389 @ForceCompile(CompLevel.C1_SIMPLE) 390 public final int final_func(RefPoint rp2) { // opt_virtual_call 391 return this.x.n + this.y.n + rp2.x.n + rp2.y.n; 392 } 393 394 @DontInline 395 @ForceCompile(CompLevel.C1_SIMPLE) 396 public int func1(RefPoint rp2) { 397 return this.x.n + this.y.n + rp2.x.n + rp2.y.n; 398 } 399 400 @DontInline 401 @ForceCompile(CompLevel.C1_SIMPLE) 402 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 403 return x.n + y.n + 404 rp1.x.n + rp1.y.n + 405 rp2.x.n + rp2.y.n + 406 n1.n + 407 rp3.x.n + rp3.y.n + 408 rp4.x.n + rp4.y.n + 409 n2.n; 410 } 411 } 412 413 static class RefPoint_Access_Impl1 implements RefPoint_Access { 414 @DontCompile 415 public int func1(RefPoint rp2) { 416 return rp2.x.n + rp2.y.n + 1111111; 417 } 418 @DontInline 419 @ForceCompile(CompLevel.C1_SIMPLE) 420 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 421 return 111111 + 422 rp1.x.n + rp1.y.n + 423 rp2.x.n + rp2.y.n + 424 n1.n + 425 rp3.x.n + rp3.y.n + 426 rp4.x.n + rp4.y.n + 427 n2.n; 428 } 429 } 430 431 static class RefPoint_Access_Impl2 implements RefPoint_Access { 432 @DontCompile 433 public int func1(RefPoint rp2) { 434 return rp2.x.n + rp2.y.n + 2222222; 435 } 436 @DontInline 437 @ForceCompile(CompLevel.C1_SIMPLE) 438 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 439 return 222222 + 440 rp1.x.n + rp1.y.n + 441 rp2.x.n + rp2.y.n + 442 n1.n + 443 rp3.x.n + rp3.y.n + 444 rp4.x.n + rp4.y.n + 445 n2.n; 446 } 447 } 448 449 static RefPoint_Access refPoint_Access_impls[] = { 450 new RefPoint_Access_Impl1(), 451 new RefPoint_Access_Impl2(), 452 new RefPoint(0x12345, 0x6789a) 453 }; 454 455 static int next_RefPoint_Access = 0; 456 static RefPoint_Access get_RefPoint_Access() { 457 int i = next_RefPoint_Access ++; 458 return refPoint_Access_impls[i % refPoint_Access_impls.length]; 459 } 460 461 @NullRestricted 462 static RefPoint refPointField1 = new RefPoint(12, 34); 463 @NullRestricted 464 static RefPoint refPointField2 = new RefPoint(56789, 0x12345678); 465 466 // This value class has too many fields to fit in registers on x64 for 467 // InlineTypeReturnedAsFields. 468 @ImplicitlyConstructible 469 @LooselyConsistentValue 470 static value class TooBigToReturnAsFields { 471 int a0 = 0; 472 int a1 = 1; 473 int a2 = 2; 474 int a3 = 3; 475 int a4 = 4; 476 int a5 = 5; 477 int a6 = 6; 478 int a7 = 7; 479 int a8 = 8; 480 int a9 = 9; 481 } 482 483 @NullRestricted 484 static TooBigToReturnAsFields tooBig = new TooBigToReturnAsFields(); 485 486 //********************************************************************** 487 // PART 1 - C1 calls interpreted code 488 //********************************************************************** 489 490 //** C1 passes value object to interpreter (static) 491 @Test(compLevel = CompLevel.C1_SIMPLE) 492 public int test1() { 493 return test1_helper(pointField); 494 } 495 496 @DontCompile 497 private static int test1_helper(Point p) { 498 return p.func(); 499 } 500 501 @Run(test = "test1") 502 public void test1_verifier(RunInfo info) { 503 int count = info.isWarmUp() ? 1 : 10; 504 for (int i = 0; i < count; i++) { // need a loop to test inline cache 505 int result = test1() + i; 506 Asserts.assertEQ(result, pointField.func() + i); 507 } 508 } 509 510 //** C1 passes value object to interpreter (monomorphic) 511 @Test(compLevel = CompLevel.C1_SIMPLE) 512 public int test2() { 513 return test2_helper(pointField); 514 } 515 516 @DontCompile 517 private int test2_helper(Point p) { 518 return p.func(); 519 } 520 521 @Run(test = "test2") 522 public void test2_verifier(RunInfo info) { 523 int count = info.isWarmUp() ? 1 : 10; 524 for (int i = 0; i < count; i++) { // need a loop to test inline cache 525 int result = test2() + i; 526 Asserts.assertEQ(result, pointField.func() + i); 527 } 528 } 529 530 // C1 passes value object to interpreter (megamorphic: vtable) 531 @Test(compLevel = CompLevel.C1_SIMPLE) 532 public int test3(Functor functor) { 533 return functor.apply_interp(pointField); 534 } 535 536 @Run(test = "test3") 537 public void test3_verifier(RunInfo info) { 538 int count = info.isWarmUp() ? 1 : 100; 539 for (int i = 0; i < count; i++) { // need a loop to test inline cache and vtable indexing 540 Functor functor = info.isWarmUp() ? functors[0] : getFunctor(); 541 int result = test3(functor) + i; 542 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 543 } 544 } 545 546 // Same as test3, but compiled with C2. Test the hastable of VtableStubs 547 @Test(compLevel = CompLevel.C2) 548 public int test3b(Functor functor) { 549 return functor.apply_interp(pointField); 550 } 551 552 @Run(test = "test3b") 553 public void test3b_verifier(RunInfo info) { 554 int count = info.isWarmUp() ? 1 : 100; 555 for (int i = 0; i < count; i++) { // need a loop to test inline cache and vtable indexing 556 Functor functor = info.isWarmUp() ? functors[0] : getFunctor(); 557 int result = test3b(functor) + i; 558 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 559 } 560 } 561 562 // C1 passes value object to interpreter (megamorphic: itable) 563 @Test(compLevel = CompLevel.C1_SIMPLE) 564 public int test4(FunctorInterface fi) { 565 return fi.apply_interp(pointField); 566 } 567 568 @Run(test = "test4") 569 public void test4_verifier(RunInfo info) { 570 int count = info.isWarmUp() ? 1 : 100; 571 for (int i = 0; i < count; i++) { // need a loop to test inline cache and itable indexing 572 Functor functor = info.isWarmUp() ? functors[0] : getFunctor(); 573 int result = test4(functor) + i; 574 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 575 } 576 } 577 578 //********************************************************************** 579 // PART 2 - interpreter calls C1 580 //********************************************************************** 581 582 // Interpreter passes value object to C1 (static) 583 @Test(compLevel = CompLevel.C1_SIMPLE) 584 static public int test20(Point p1, long l, Point p2) { 585 return p1.x + p2.y; 586 } 587 588 @Run(test = "test20") 589 public void test20_verifier() { 590 int result = test20(pointField1, 0, pointField2); 591 int n = pointField1.x + pointField2.y; 592 Asserts.assertEQ(result, n); 593 } 594 595 // Interpreter passes value object to C1 (instance method in value class) 596 @Test 597 public int test21(Point p) { 598 return test21_helper(p); 599 } 600 601 @DontCompile 602 int test21_helper(Point p) { 603 return p.func_c1(p); 604 } 605 606 @Run(test = "test21") 607 public void test21_verifier() { 608 int result = test21(pointField); 609 int n = 2 * (pointField.x + pointField.y); 610 Asserts.assertEQ(result, n); 611 } 612 613 614 //********************************************************************** 615 // PART 3 - C2 calls C1 616 //********************************************************************** 617 618 // C2->C1 invokestatic, single inline arg 619 @Test(compLevel = CompLevel.C2) 620 public int test30() { 621 return test30_helper(pointField); 622 } 623 624 @DontInline 625 @ForceCompile(CompLevel.C1_SIMPLE) 626 private static int test30_helper(Point p) { 627 return p.x + p.y; 628 } 629 630 @Run(test = "test30") 631 public void test30_verifier(RunInfo info) { 632 int count = info.isWarmUp() ? 1 : 2; 633 for (int i = 0; i < count; i++) { // need a loop to test inline cache 634 int result = test30(); 635 int n = pointField.x + pointField.y; 636 Asserts.assertEQ(result, n); 637 } 638 } 639 640 // C2->C1 invokestatic, two single inline args 641 @Test(compLevel = CompLevel.C2) 642 public int test31() { 643 return test31_helper(pointField1, pointField2); 644 } 645 646 @DontInline 647 @ForceCompile(CompLevel.C1_SIMPLE) 648 private static int test31_helper(Point p1, Point p2) { 649 return p1.x + p2.y; 650 } 651 652 @Run(test = "test31") 653 public void test31_verifier(RunInfo info) { 654 int count = info.isWarmUp() ? 1 : 2; 655 for (int i = 0; i < count; i++) { // need a loop to test inline cache 656 int result = test31(); 657 int n = pointField1.x + pointField2.y; 658 Asserts.assertEQ(result, n); 659 } 660 } 661 662 // C2->C1 invokestatic, two single inline args and interleaving ints (all passed in registers on x64) 663 @Test(compLevel = CompLevel.C2) 664 public int test32() { 665 return test32_helper(0, pointField1, 1, pointField2); 666 } 667 668 @DontInline 669 @ForceCompile(CompLevel.C1_SIMPLE) 670 private static int test32_helper(int x, Point p1, int y, Point p2) { 671 return p1.x + p2.y + x + y; 672 } 673 674 @Run(test = "test32") 675 public void test32_verifier(RunInfo info) { 676 int count = info.isWarmUp() ? 1 : 2; 677 for (int i = 0; i < count; i++) { // need a loop to test inline cache 678 int result = test32(); 679 int n = pointField1.x + pointField2.y + 0 + 1; 680 Asserts.assertEQ(result, n); 681 } 682 } 683 684 // C2->C1 invokeinterface -- no verified_ro_entry (no inline args except for receiver) 685 @Test(compLevel = CompLevel.C2) 686 public int test33(Intf intf, int a, int b) { 687 return intf.func1(a, b); 688 } 689 690 @Run(test = "test33") 691 public void test33_verifier(RunInfo info) { 692 int count = info.isWarmUp() ? 1 : 20; 693 for (int i = 0; i < count; i++) { 694 Intf intf = info.isWarmUp() ? intfs[0] : getIntf(i+1); 695 int result = test33(intf, 123, 456) + i; 696 Asserts.assertEQ(result, intf.func1(123, 456) + i); 697 } 698 } 699 700 // C2->C1 invokeinterface -- use verified_ro_entry (has inline args other than receiver) 701 @Test(compLevel = CompLevel.C2) 702 public int test34(Intf intf, int a, int b) { 703 return intf.func2(a, b, pointField); 704 } 705 706 @Run(test = "test34") 707 public void test34_verifier(RunInfo info) { 708 int count = info.isWarmUp() ? 1 : 20; 709 for (int i = 0; i < count; i++) { 710 Intf intf = info.isWarmUp() ? intfs[0] : getIntf(i+1); 711 int result = test34(intf, 123, 456) + i; 712 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 713 } 714 } 715 716 // C2->C1 invokestatic, Point.y is on stack (x64) 717 @Test(compLevel = CompLevel.C2) 718 public int test35() { 719 return test35_helper(1, 2, 3, 4, 5, pointField); 720 } 721 722 @DontInline 723 @ForceCompile(CompLevel.C1_SIMPLE) 724 private static int test35_helper(int a1, int a2, int a3, int a4, int a5, Point p) { 725 return a1 + a2 + a3 + a4 + a5 + p.x + p.y; 726 } 727 728 @Run(test = "test35") 729 public void test35_verifier(RunInfo info) { 730 int count = info.isWarmUp() ? 1 : 2; 731 for (int i = 0; i < count; i++) { // need a loop to test inline cache 732 int result = test35(); 733 int n = 1 + 2 + 3 + 4 + 5 + pointField.x + pointField.y; 734 Asserts.assertEQ(result, n); 735 } 736 } 737 738 // C2->C1 invokestatic, shuffling arguments that are passed on stack 739 @Test(compLevel = CompLevel.C2) 740 public int test36() { 741 return test36_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); 742 } 743 744 @DontInline 745 @ForceCompile(CompLevel.C1_SIMPLE) 746 private static int test36_helper(Point p, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { 747 return a6 + a8; 748 } 749 750 @Run(test = "test36") 751 public void test36_verifier(RunInfo info) { 752 int count = info.isWarmUp() ? 1 : 2; 753 for (int i = 0; i < count; i++) { // need a loop to test inline cache 754 int result = test36(); 755 int n = 6 + 8; 756 Asserts.assertEQ(result, n); 757 } 758 } 759 760 // C2->C1 invokestatic, shuffling long arguments 761 @Test(compLevel = CompLevel.C2) 762 public int test37() { 763 return test37_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); 764 } 765 766 @DontInline 767 @ForceCompile(CompLevel.C1_SIMPLE) 768 private static int test37_helper(Point p, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { 769 return (int)(a6 + a8); 770 } 771 772 @Run(test = "test37") 773 public void test37_verifier(RunInfo info) { 774 int count = info.isWarmUp() ? 1 : 2; 775 for (int i = 0; i < count; i++) { // need a loop to test inline cache 776 int result = test37(); 777 int n = 6 + 8; 778 Asserts.assertEQ(result, n); 779 } 780 } 781 782 // C2->C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments 783 @Test(compLevel = CompLevel.C2) 784 public int test38() { 785 return test38_helper(pointField, true, (byte)1, (char)2, (short)3, 4, 5, (byte)6, (short)7, 8); 786 } 787 788 @DontInline 789 @ForceCompile(CompLevel.C1_SIMPLE) 790 private static int test38_helper(Point p, boolean a0, byte a1, char a2, short a3, int a4, long a5, byte a6, short a7, int a8) { 791 if (a0) { 792 return (int)(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8); 793 } else { 794 return -1; 795 } 796 } 797 798 @Run(test = "test38") 799 public void test38_verifier(RunInfo info) { 800 int count = info.isWarmUp() ? 1 : 2; 801 for (int i = 0; i < count; i++) { // need a loop to test inline cache 802 int result = test38(); 803 int n = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8; 804 Asserts.assertEQ(result, n); 805 } 806 } 807 808 // C2->C1 invokestatic, packing a value object with all types of fixed point primitive fields. 809 @Test(compLevel = CompLevel.C2) 810 public long test39() { 811 return test39_helper(1, fixedPointsField, 2, fixedPointsField); 812 } 813 814 @DontInline 815 @ForceCompile(CompLevel.C1_SIMPLE) 816 private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2) { 817 if (f1.Z0 == false && f1.Z1 == true && f2.Z0 == false && f2.Z1 == true) { 818 return f1.B + f2.C + f1.S + f2.I + f1.J; 819 } else { 820 return -1; 821 } 822 } 823 824 @Run(test = "test39") 825 public void test39_verifier(RunInfo info) { 826 int count = info.isWarmUp() ? 1 : 2; 827 for (int i = 0; i < count; i++) { // need a loop to test inline cache 828 long result = test39(); 829 long n = test39_helper(1, fixedPointsField, 2, fixedPointsField); 830 Asserts.assertEQ(result, n); 831 } 832 } 833 834 // C2->C1 invokestatic, shuffling floating point args 835 @Test(compLevel = CompLevel.C2) 836 public double test40() { 837 return test40_helper(1.1f, 1.2, floatPointField, doublePointField, 1.3f, 1.4, 1.5f, 1.7, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12); 838 } 839 840 @DontInline 841 @ForceCompile(CompLevel.C1_SIMPLE) 842 private static double test40_helper(float a1, double a2, FloatPoint fp, DoublePoint dp, float a3, double a4, float a5, double a6, double a7, double a8, double a9, double a10, double a11, double a12) { 843 return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + fp.x + fp.y - dp.x - dp.y; 844 } 845 846 @Run(test = "test40") 847 public void test40_verifier(RunInfo info) { 848 int count = info.isWarmUp() ? 1 : 2; 849 for (int i = 0; i < count; i++) { // need a loop to test inline cache 850 double result = test40(); 851 double n = test40_helper(1.1f, 1.2, floatPointField, doublePointField, 1.3f, 1.4, 1.5f, 1.7, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12); 852 Asserts.assertEQ(result, n); 853 } 854 } 855 856 // C2->C1 invokestatic, mixing floats and ints 857 @Test(compLevel = CompLevel.C2) 858 public double test41() { 859 return test41_helper(1, 1.2, pointField, floatPointField, doublePointField, 1.3f, 4, 1.5f, 1.7, 1.7, 1.8, 9, 1.10, 1.11, 1.12); 860 } 861 862 @DontInline 863 @ForceCompile(CompLevel.C1_SIMPLE) 864 private static double test41_helper(int a1, double a2, Point p, FloatPoint fp, DoublePoint dp, float a3, int a4, float a5, double a6, double a7, double a8, long a9, double a10, double a11, double a12) { 865 return a1 + a2 + fp.x + fp.y - dp.x - dp.y + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12; 866 } 867 868 @Run(test = "test41") 869 public void test41_verifier(RunInfo info) { 870 int count = info.isWarmUp() ? 1 : 2; 871 for (int i = 0; i < count; i++) { // need a loop to test inline cache 872 double result = test41(); 873 double n = test41_helper(1, 1.2, pointField, floatPointField, doublePointField, 1.3f, 4, 1.5f, 1.7, 1.7, 1.8, 9, 1.10, 1.11, 1.12); 874 Asserts.assertEQ(result, n); 875 } 876 } 877 878 // C2->C1 invokestatic, circular dependency (between rdi and first stack slot on x64) 879 @Test(compLevel = CompLevel.C2) 880 public float test42() { 881 return test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); 882 } 883 884 @DontInline 885 @ForceCompile(CompLevel.C1_SIMPLE) 886 private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi 887 Point p2, // (rsi, rdx) -> rdx 888 int i3, // rcx -> rcx 889 int i4, // r8 -> r8 890 int i5, // r9 -> r9 891 FloatPoint fp6, // (stk[0], stk[1]) -> rdi ** circ depend 892 int i7) // rdi -> stk[0] ** circ depend 893 { 894 return ep1.f1 + ep1.f2 + ep1.f3 + ep1.f4 + ep1.f5 + ep1.f6 + ep1.f7 + ep1.f8 + 895 p2.x + p2.y + i3 + i4 + i5 + fp6.x + fp6.y + i7; 896 } 897 898 @Run(test = "test42") 899 public void test42_verifier(RunInfo info) { 900 int count = info.isWarmUp() ? 1 : 2; 901 for (int i = 0; i < count; i++) { // need a loop to test inline cache 902 float result = test42(); 903 float n = test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); 904 Asserts.assertEQ(result, n); 905 } 906 } 907 908 // C2->C1 invokestatic, packing causes stack growth (1 extra stack word) 909 @Test(compLevel = CompLevel.C2) 910 public float test43() { 911 return test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); 912 } 913 914 @DontInline 915 @ForceCompile(CompLevel.C1_SIMPLE) 916 private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 917 // On x64: 918 // Scalarized entry -- all parameters are passed in registers 919 // Non-scalarized entry -- a6 is passed on stack[0] 920 return fp.x + fp.y + a1 + a2 + a3 + a4 + a5 + a6; 921 } 922 923 @Run(test = "test43") 924 public void test43_verifier(RunInfo info) { 925 int count = info.isWarmUp() ? 1 : 2; 926 for (int i = 0; i < count; i++) { // need a loop to test inline cache 927 float result = test43(); 928 float n = test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); 929 Asserts.assertEQ(result, n); 930 } 931 } 932 933 // C2->C1 invokestatic, packing causes stack growth (2 extra stack words) 934 @Test(compLevel = CompLevel.C2) 935 public float test44() { 936 return test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); 937 } 938 939 @DontInline 940 @ForceCompile(CompLevel.C1_SIMPLE) 941 private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a2, int a3, int a4, int a5, int a6) { 942 // On x64: 943 // Scalarized entry -- all parameters are passed in registers 944 // Non-scalarized entry -- a5 is passed on stack[0] 945 // Non-scalarized entry -- a6 is passed on stack[1] 946 return fp1.x + fp1.y + 947 fp2.x + fp2.y + 948 a1 + a2 + a3 + a4 + a5 + a6; 949 } 950 951 @Run(test = "test44") 952 public void test44_verifier(RunInfo info) { 953 int count = info.isWarmUp() ? 1 : 2; 954 for (int i = 0; i < count; i++) { // need a loop to test inline cache 955 float result = test44(); 956 float n = test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); 957 Asserts.assertEQ(result, n); 958 } 959 } 960 961 // C2->C1 invokestatic, packing causes stack growth (5 extra stack words) 962 @Test(compLevel = CompLevel.C2) 963 public float test45() { 964 return test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 965 } 966 967 @DontInline 968 @ForceCompile(CompLevel.C1_SIMPLE) 969 private static float test45_helper(FloatPoint fp1, FloatPoint fp2, FloatPoint fp3, FloatPoint fp4, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { 970 return fp1.x + fp1.y + 971 fp2.x + fp2.y + 972 fp3.x + fp3.y + 973 fp4.x + fp4.y + 974 fp5.x + fp5.y + 975 a1 + a2 + a3 + a4 + a5 + a6 + a7; 976 } 977 978 @Run(test = "test45") 979 public void test45_verifier(RunInfo info) { 980 int count = info.isWarmUp() ? 1 : 2; 981 for (int i = 0; i < count; i++) { // need a loop to test inline cache 982 float result = test45(); 983 float n = test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 984 Asserts.assertEQ(result, n); 985 } 986 } 987 988 // C2->C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint) 989 @Test(compLevel = CompLevel.C2) 990 public float test46() { 991 return test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 992 } 993 994 @DontInline 995 @ForceCompile(CompLevel.C1_SIMPLE) 996 private static float test46_helper(FloatPoint fp1, FloatPoint fp2, Point p1, FloatPoint fp3, FloatPoint fp4, Point p2, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { 997 return p1.x + p1.y + 998 p2.x + p2.y + 999 fp1.x + fp1.y + 1000 fp2.x + fp2.y + 1001 fp3.x + fp3.y + 1002 fp4.x + fp4.y + 1003 fp5.x + fp5.y + 1004 a1 + a2 + a3 + a4 + a5 + a6 + a7; 1005 } 1006 1007 @Run(test = "test46") 1008 public void test46_verifier(RunInfo info) { 1009 int count = info.isWarmUp() ? 1 : 2; 1010 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1011 float result = test46(); 1012 float n = test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 1013 Asserts.assertEQ(result, n); 1014 } 1015 } 1016 1017 static class MyRuntimeException extends RuntimeException { 1018 MyRuntimeException(String s) { 1019 super(s); 1020 } 1021 } 1022 1023 static void checkStackTrace(Throwable t, String... methodNames) { 1024 StackTraceElement[] trace = t.getStackTrace(); 1025 for (int i = 0; i < methodNames.length; i++) { 1026 if (!methodNames[i].equals(trace[i].getMethodName())) { 1027 String error = "Unexpected stack trace: level " + i + " should be " + methodNames[i]; 1028 System.out.println(error); 1029 t.printStackTrace(System.out); 1030 throw new RuntimeException(error, t); 1031 } 1032 } 1033 } 1034 //* 1035 1036 // C2->C1 invokestatic, make sure stack walking works (with static variable) 1037 @Test(compLevel = CompLevel.C2) 1038 public void test47(int n) { 1039 try { 1040 test47_helper(floatPointField, 1, 2, 3, 4, 5); 1041 test47_value = 666; 1042 } catch (MyRuntimeException e) { 1043 // expected; 1044 } 1045 test47_value = n; 1046 } 1047 1048 @DontInline 1049 @ForceCompile(CompLevel.C1_SIMPLE) 1050 private static float test47_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { 1051 test47_thrower(); 1052 return 0.0f; 1053 } 1054 1055 @DontCompile 1056 private static void test47_thrower() { 1057 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 1058 checkStackTrace(e, "test47_thrower", "test47_helper", "test47", "test47_verifier"); 1059 throw e; 1060 } 1061 1062 static int test47_value = 999; 1063 1064 @Run(test = "test47") 1065 public void test47_verifier(RunInfo info) { 1066 int count = info.isWarmUp() ? 1 : 5; 1067 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1068 test47_value = 777 + i; 1069 test47(i); 1070 Asserts.assertEQ(test47_value, i); 1071 } 1072 } 1073 1074 // C2->C1 invokestatic, make sure stack walking works (with returned value object) 1075 @Test(compLevel = CompLevel.C2) 1076 public int test48(int n) { 1077 try { 1078 test48_helper(floatPointField, 1, 2, 3, 4, 5); 1079 return 666; 1080 } catch (MyRuntimeException e) { 1081 // expected; 1082 } 1083 return n; 1084 } 1085 1086 @DontInline 1087 @ForceCompile(CompLevel.C1_SIMPLE) 1088 private static float test48_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { 1089 test48_thrower(); 1090 return 0.0f; 1091 } 1092 1093 @DontCompile 1094 private static void test48_thrower() { 1095 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 1096 checkStackTrace(e, "test48_thrower", "test48_helper", "test48", "test48_verifier"); 1097 throw e; 1098 } 1099 1100 @Run(test = "test48") 1101 public void test48_verifier(RunInfo info) { 1102 int count = info.isWarmUp() ? 1 : 5; 1103 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1104 int n = test48(i); 1105 Asserts.assertEQ(n, i); 1106 } 1107 } 1108 1109 // C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) 1110 // (this is the baseline for test50 -- 1111 // the only difference is: test49_helper is interpreted but test50_helper is compiled by C1). 1112 @Test(compLevel = CompLevel.C2) 1113 public int test49(int n) { 1114 try { 1115 test49_helper(floatPointField, 1, 2, 3, 4, 5, 6); 1116 return 666; 1117 } catch (MyRuntimeException e) { 1118 // expected; 1119 } 1120 return n; 1121 } 1122 1123 @DontCompile 1124 private static float test49_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 1125 test49_thrower(); 1126 return 0.0f; 1127 } 1128 1129 @DontCompile 1130 private static void test49_thrower() { 1131 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 1132 checkStackTrace(e, "test49_thrower", "test49_helper", "test49", "test49_verifier"); 1133 throw e; 1134 } 1135 1136 @Run(test = "test49") 1137 public void test49_verifier(RunInfo info) { 1138 int count = info.isWarmUp() ? 1 : 5; 1139 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1140 int n = test49(i); 1141 Asserts.assertEQ(n, i); 1142 } 1143 } 1144 1145 // C2->C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) 1146 @Test(compLevel = CompLevel.C2) 1147 public int test50(int n) { 1148 try { 1149 test50_helper(floatPointField, 1, 2, 3, 4, 5, 6); 1150 return 666; 1151 } catch (MyRuntimeException e) { 1152 // expected; 1153 } 1154 return n; 1155 } 1156 1157 @DontInline 1158 @ForceCompile(CompLevel.C1_SIMPLE) 1159 private static float test50_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 1160 test50_thrower(); 1161 return 0.0f; 1162 } 1163 1164 @DontCompile 1165 private static void test50_thrower() { 1166 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 1167 checkStackTrace(e, "test50_thrower", "test50_helper", "test50", "test50_verifier"); 1168 throw e; 1169 } 1170 1171 @Run(test = "test50") 1172 public void test50_verifier(RunInfo info) { 1173 int count = info.isWarmUp() ? 1 : 5; 1174 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1175 int n = test50(i); 1176 Asserts.assertEQ(n, i); 1177 } 1178 } 1179 1180 1181 // C2->C1 invokestatic, value class with ref fields (RefPoint) 1182 @Test(compLevel = CompLevel.C2) 1183 public int test51() { 1184 return test51_helper(refPointField1); 1185 } 1186 1187 @DontInline 1188 @ForceCompile(CompLevel.C1_SIMPLE) 1189 private static int test51_helper(RefPoint rp1) { 1190 return rp1.x.n + rp1.y.n; 1191 } 1192 1193 @Run(test = "test51") 1194 public void test51_verifier(RunInfo info) { 1195 int count = info.isWarmUp() ? 1 : 5; 1196 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1197 int result = test51(); 1198 int n = test51_helper(refPointField1); 1199 Asserts.assertEQ(result, n); 1200 } 1201 } 1202 1203 // C2->C1 invokestatic, value class with ref fields (Point, RefPoint) 1204 @Test(compLevel = CompLevel.C2) 1205 public int test52() { 1206 return test52_helper(pointField, refPointField1); 1207 } 1208 1209 @DontInline 1210 @ForceCompile(CompLevel.C1_SIMPLE) 1211 private static int test52_helper(Point p1, RefPoint rp1) { 1212 return p1.x + p1.y + rp1.x.n + rp1.y.n; 1213 } 1214 1215 @Run(test = "test52") 1216 public void test52_verifier(RunInfo info) { 1217 int count = info.isWarmUp() ? 1 : 5; 1218 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1219 int result = test52(); 1220 int n = test52_helper(pointField, refPointField1); 1221 Asserts.assertEQ(result, n); 1222 } 1223 } 1224 1225 // C2->C1 invokestatic, value class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint) 1226 @Test(compLevel = CompLevel.C2) 1227 public int test53() { 1228 return test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); 1229 } 1230 1231 @DontInline 1232 @ForceCompile(CompLevel.C1_SIMPLE) 1233 private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPoint rp4) { 1234 return rp1.x.n + rp1.y.n + 1235 rp2.x.n + rp2.y.n + 1236 rp3.x.n + rp3.y.n + 1237 rp4.x.n + rp4.y.n; 1238 } 1239 1240 @Run(test = "test53") 1241 public void test53_verifier(RunInfo info) { 1242 int count = info.isWarmUp() ? 1 : 5; 1243 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1244 int result = test53(); 1245 int n = test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); 1246 Asserts.assertEQ(result, n); 1247 } 1248 } 1249 1250 // C2->C1 invokestatic, value class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint) 1251 @Test(compLevel = CompLevel.C2) 1252 public int test54() { 1253 return test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); 1254 } 1255 1256 @DontInline 1257 @ForceCompile(CompLevel.C1_SIMPLE) 1258 private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, RefPoint rp3, RefPoint rp4) { 1259 return rp1.x.n + rp1.y.n + 1260 rp2.x.n + rp2.y.n + 1261 (int)(f) + i + 1262 rp3.x.n + rp3.y.n + 1263 rp4.x.n + rp4.y.n; 1264 } 1265 1266 @Run(test = "test54") 1267 public void test54_verifier(RunInfo info) { 1268 int count = info.isWarmUp() ? 1 : 5; 1269 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1270 int result = test54(); 1271 int n = test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); 1272 Asserts.assertEQ(result, n); 1273 } 1274 } 1275 1276 /** 1277 * Each allocation with a "try" block like this will cause a GC 1278 * 1279 * try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1280 * result = test55(p1); 1281 * } 1282 */ 1283 1284 static final String ScavengeALot = "ScavengeALot"; 1285 1286 static class ForceGCMarker implements java.io.Closeable { 1287 ForceGCMarker() { 1288 WhiteBox.getWhiteBox().setBooleanVMFlag(ScavengeALot, true); 1289 } 1290 public void close() { 1291 WhiteBox.getWhiteBox().setBooleanVMFlag(ScavengeALot, false); 1292 } 1293 1294 static ForceGCMarker mark(boolean warmup) { 1295 return warmup ? null : new ForceGCMarker(); 1296 } 1297 } 1298 1299 // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (Point) 1300 @Test(compLevel = CompLevel.C2) 1301 public int test55(Point p1) { 1302 return test55_helper(p1); 1303 } 1304 1305 @DontInline 1306 @ForceCompile(CompLevel.C1_SIMPLE) 1307 private static int test55_helper(Point p1) { 1308 return p1.x + p1.y; 1309 } 1310 1311 @Run(test = "test55") 1312 public void test55_verifier(RunInfo info) { 1313 int count = info.isWarmUp() ? 1 : 5; 1314 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1315 Point p1 = new Point(1, 2); 1316 int result; 1317 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1318 result = test55(p1); 1319 } 1320 int n = test55_helper(p1); 1321 Asserts.assertEQ(result, n); 1322 } 1323 } 1324 1325 // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (RefPoint) 1326 @Test(compLevel = CompLevel.C2) 1327 public int test56(RefPoint rp1) { 1328 return test56_helper(rp1); 1329 } 1330 1331 @DontInline 1332 @ForceCompile(CompLevel.C1_SIMPLE) 1333 private static int test56_helper(RefPoint rp1) { 1334 return rp1.x.n + rp1.y.n; 1335 } 1336 1337 @Run(test = "test56") 1338 public void test56_verifier(RunInfo info) { 1339 int count = info.isWarmUp() ? 1 : 5; 1340 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1341 RefPoint rp1 = new RefPoint(1, 2); 1342 int result; 1343 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1344 result = test56(rp1); 1345 } 1346 int n = test56_helper(rp1); 1347 Asserts.assertEQ(result, n); 1348 } 1349 } 1350 1351 // C2->Interpreter (same as test56, but test C2i entry instead of C1) 1352 @Test(compLevel = CompLevel.C2) 1353 public int test57(RefPoint rp1) { 1354 return test57_helper(rp1); 1355 } 1356 1357 @DontCompile 1358 private static int test57_helper(RefPoint rp1) { 1359 return rp1.x.n + rp1.y.n; 1360 } 1361 1362 @Run(test = "test57") 1363 public void test57_verifier(RunInfo info) { 1364 int count = info.isWarmUp() ? 1 : 5; 1365 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1366 RefPoint rp1 = new RefPoint(1, 2); 1367 int result; 1368 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1369 result = test57(rp1); 1370 } 1371 int n = test57_helper(rp1); 1372 Asserts.assertEQ(result, n); 1373 } 1374 } 1375 1376 // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (a bunch of RefPoints and Numbers); 1377 @Test(compLevel = CompLevel.C2) 1378 public int test58(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1379 return test58_helper(rp1, rp2, n1, rp3, rp4, n2); 1380 } 1381 1382 @DontInline 1383 @ForceCompile(CompLevel.C1_SIMPLE) 1384 private static int test58_helper(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1385 return rp1.x.n + rp1.y.n + 1386 rp2.x.n + rp2.y.n + 1387 n1.n + 1388 rp3.x.n + rp3.y.n + 1389 rp4.x.n + rp4.y.n + 1390 n2.n; 1391 } 1392 1393 @Run(test = "test58") 1394 public void test58_verifier(RunInfo info) { 1395 int count = info.isWarmUp() ? 1 : 5; 1396 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1397 RefPoint rp1 = new RefPoint(1, 2); 1398 RefPoint rp2 = refPointField1; 1399 RefPoint rp3 = new RefPoint(222, 777); 1400 RefPoint rp4 = refPointField2; 1401 Number n1 = new Number(5878); 1402 Number n2 = new Number(1234); 1403 int result; 1404 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1405 result = test58(rp1, rp2, n1, rp3, rp4, n2); 1406 } 1407 int n = test58_helper(rp1, rp2, n1, rp3, rp4, n2); 1408 Asserts.assertEQ(result, n); 1409 } 1410 } 1411 1412 // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). 1413 @Test(compLevel = CompLevel.C2) 1414 public int test59(RefPoint rp1, boolean doGC) { 1415 return test59_helper(rp1, 11, 222, 3333, 4444, doGC); 1416 } 1417 1418 @DontInline 1419 @ForceCompile(CompLevel.C1_SIMPLE) 1420 private static int test59_helper(RefPoint rp1, int a1, int a2, int a3, int a4, boolean doGC) { 1421 if (doGC) { 1422 System.gc(); 1423 } 1424 return rp1.x.n + rp1.y.n + a1 + a2 + a3 + a4; 1425 } 1426 1427 @Run(test = "test59") 1428 public void test59_verifier(RunInfo info) { 1429 int count = info.isWarmUp() ? 1 : 5; 1430 boolean doGC = !info.isWarmUp(); 1431 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1432 RefPoint rp1 = new RefPoint(1, 2); 1433 int result = test59(rp1, doGC); 1434 int n = test59_helper(rp1, 11, 222, 3333, 4444, doGC); 1435 Asserts.assertEQ(result, n); 1436 } 1437 } 1438 1439 // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). 1440 // same as test59, but the incoming (scalarized) oops are passed in both registers and stack. 1441 @Test(compLevel = CompLevel.C2) 1442 public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) { 1443 return test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC); 1444 } 1445 1446 @DontInline 1447 @ForceCompile(CompLevel.C1_SIMPLE) 1448 private static int test60_helper(int x0, int x1, int x2, RefPoint rp1, RefPoint rp2,int a1, int a2, int a3, int a4, boolean doGC) { 1449 // On x64, C2 passes: reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y .... 1450 // C1 expects: reg0=x1, reg1=x1, reg2=x2, reg3=rp1, reg4=rp2, reg5=a1 stack0=a2 ... 1451 // When GC happens, make sure it does not treat reg5 and stack0 as oops! 1452 if (doGC) { 1453 System.gc(); 1454 } 1455 return x0 + x1 + x2 + rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + a1 + a2 + a3 + a4; 1456 } 1457 1458 @Run(test = "test60") 1459 public void test60_verifier(RunInfo info) { 1460 int count = info.isWarmUp() ? 1 : 5; 1461 boolean doGC = !info.isWarmUp(); 1462 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1463 RefPoint rp1 = new RefPoint(1, 2); 1464 RefPoint rp2 = new RefPoint(33, 44); 1465 int result = test60(rp1, rp2, doGC); 1466 int n = test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC); 1467 Asserts.assertEQ(result, n); 1468 } 1469 } 1470 1471 // C2->C1 invokeinterface via VVEP(RO) 1472 @Test(compLevel = CompLevel.C2) 1473 public int test61(RefPoint_Access rpa, RefPoint rp2) { 1474 return rpa.func1(rp2); 1475 } 1476 1477 @Run(test = "test61") 1478 public void test61_verifier(RunInfo info) { 1479 int count = info.isWarmUp() ? 1 : 20; 1480 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1481 RefPoint_Access rpa = get_RefPoint_Access(); 1482 RefPoint rp2 = refPointField2; 1483 int result = test61(rpa, rp2); 1484 int n = rpa.func1(rp2); 1485 Asserts.assertEQ(result, n); 1486 } 1487 } 1488 1489 // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (RefPoint) 1490 @Test(compLevel = CompLevel.C2) 1491 public int test62(RefPoint_Access rpa, RefPoint rp2) { 1492 return rpa.func1(rp2); 1493 } 1494 1495 @Run(test = "test62") 1496 public void test62_verifier(RunInfo info) { 1497 int count = info.isWarmUp() ? 1 : 20; 1498 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1499 RefPoint_Access rpa = get_RefPoint_Access(); 1500 RefPoint rp2 = new RefPoint(111, 2222); 1501 int result; 1502 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1503 result = test62(rpa, rp2); 1504 } 1505 int n = rpa.func1(rp2); 1506 Asserts.assertEQ(result, n); 1507 } 1508 } 1509 1510 // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (a bunch of RefPoints and Numbers) 1511 @Test(compLevel = CompLevel.C2) 1512 public int test63(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1513 return rpa.func2(rp1, rp2, n1, rp3, rp4, n2); 1514 } 1515 1516 @Run(test = "test63") 1517 public void test63_verifier(RunInfo info) { 1518 int count = info.isWarmUp() ? 1 : 20; 1519 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1520 RefPoint_Access rpa = get_RefPoint_Access(); 1521 RefPoint rp1 = new RefPoint(1, 2); 1522 RefPoint rp2 = refPointField1; 1523 RefPoint rp3 = new RefPoint(222, 777); 1524 RefPoint rp4 = refPointField2; 1525 Number n1 = new Number(5878); 1526 Number n2 = new Number(1234); 1527 int result; 1528 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1529 result = test63(rpa, rp1, rp2, n1, rp3, rp4, n2); 1530 } 1531 int n = rpa.func2(rp1, rp2, n1, rp3, rp4, n2); 1532 Asserts.assertEQ(result, n); 1533 } 1534 } 1535 1536 // C2->C1 invokestatic (same as test63, but use invokestatic instead) 1537 @Test(compLevel = CompLevel.C2) 1538 public int test64(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1539 return test64_helper(rpa, rp1, rp2, n1, rp3, rp4, n2); 1540 } 1541 1542 @DontInline 1543 @ForceCompile(CompLevel.C1_SIMPLE) 1544 public static int test64_helper(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1545 return rp3.y.n; 1546 } 1547 1548 @Run(test = "test64") 1549 public void test64_verifier(RunInfo info) { 1550 int count = info.isWarmUp() ? 1 : 20; 1551 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1552 RefPoint_Access rpa = get_RefPoint_Access(); 1553 RefPoint rp1 = new RefPoint(1, 2); 1554 RefPoint rp2 = refPointField1; 1555 RefPoint rp3 = new RefPoint(222, 777); 1556 RefPoint rp4 = refPointField2; 1557 Number n1 = new Number(5878); 1558 Number n2 = new Number(1234); 1559 int result; 1560 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1561 result = test64(rpa, rp1, rp2, n1, rp3, rp4, n2); 1562 } 1563 int n = test64_helper(rpa, rp1, rp2, n1, rp3, rp4, n2); 1564 Asserts.assertEQ(result, n); 1565 } 1566 } 1567 1568 // C2->C1 invokevirtual via VVEP(RO) (opt_virtual_call) 1569 @Test(compLevel = CompLevel.C2) 1570 public int test76(RefPoint rp1, RefPoint rp2) { 1571 return rp1.final_func(rp2); 1572 } 1573 1574 @Run(test = "test76") 1575 public void test76_verifier(RunInfo info) { 1576 int count = info.isWarmUp() ? 1 : 5; 1577 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1578 RefPoint rp1 = refPointField1; 1579 RefPoint rp2 = refPointField2; 1580 int result = test76(rp1, rp2); 1581 int n = rp1.final_func(rp2); 1582 Asserts.assertEQ(result, n); 1583 } 1584 } 1585 1586 // C2->C1 invokevirtual, force GC for every allocation when entering a C1 VEP (RefPoint) 1587 // Same as test56, except we call the VVEP(RO) instead of VEP. 1588 @Test(compLevel = CompLevel.C2) 1589 public int test77(RefPoint rp1, RefPoint rp2) { 1590 return rp1.final_func(rp2); 1591 } 1592 1593 @Run(test = "test77") 1594 public void test77_verifier(RunInfo info) { 1595 int count = info.isWarmUp() ? 1 : 5; 1596 for (int i = 0; i < count; i++) { // need a loop to test inline cache 1597 RefPoint rp1 = new RefPoint(1, 2); 1598 RefPoint rp2 = new RefPoint(22, 33); 1599 int result; 1600 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 1601 result = test77(rp1, rp2); 1602 } 1603 int n = rp1.final_func(rp2); 1604 Asserts.assertEQ(result, n); 1605 } 1606 } 1607 1608 //------------------------------------------------------------------------------- 1609 // Tests for how C1 handles InlineTypeReturnedAsFields in both calls and returns 1610 //------------------------------------------------------------------------------- 1611 // C2->C1 invokestatic with InlineTypeReturnedAsFields (Point) 1612 @Test(compLevel = CompLevel.C2) 1613 public int test78(Point p) { 1614 Point np = test78_helper(p); 1615 return np.x + np.y; 1616 } 1617 1618 @DontInline 1619 @ForceCompile(CompLevel.C1_SIMPLE) 1620 private static Point test78_helper(Point p) { 1621 return p; 1622 } 1623 1624 @Run(test = "test78") 1625 public void test78_verifier() { 1626 int result = test78(pointField1); 1627 int n = pointField1.x + pointField1.y; 1628 Asserts.assertEQ(result, n); 1629 } 1630 1631 // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint) 1632 @Test(compLevel = CompLevel.C2) 1633 public int test79(RefPoint p) { 1634 RefPoint np = test79_helper(p); 1635 return np.x.n + np.y.n; 1636 } 1637 1638 @DontInline 1639 @ForceCompile(CompLevel.C1_SIMPLE) 1640 private static RefPoint test79_helper(RefPoint p) { 1641 return p; 1642 } 1643 1644 @Run(test = "test79") 1645 public void test79_verifier() { 1646 int result = test79(refPointField1); 1647 int n = refPointField1.x.n + refPointField1.y.n; 1648 Asserts.assertEQ(result, n); 1649 } 1650 1651 // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint) 1652 @Test(compLevel = CompLevel.C1_SIMPLE) 1653 public int test80(RefPoint p) { 1654 RefPoint np = test80_helper(p); 1655 return np.x.n + np.y.n; 1656 } 1657 1658 @DontInline 1659 @ForceCompile(CompLevel.C2) 1660 private static RefPoint test80_helper(RefPoint p) { 1661 return p; 1662 } 1663 1664 @Run(test = "test80") 1665 public void test80_verifier() { 1666 int result = test80(refPointField1); 1667 int n = refPointField1.x.n + refPointField1.y.n; 1668 Asserts.assertEQ(result, n); 1669 } 1670 1671 // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (Point) 1672 @Test(compLevel = CompLevel.C1_SIMPLE) 1673 public Point test81(Point p) { 1674 return p; 1675 } 1676 1677 @Run(test = "test81") 1678 public void test81_verifier() { 1679 Point p = test81(pointField1); 1680 Asserts.assertEQ(p.x, pointField1.x); 1681 Asserts.assertEQ(p.y, pointField1.y); 1682 p = test81(pointField2); 1683 Asserts.assertEQ(p.x, pointField2.x); 1684 Asserts.assertEQ(p.y, pointField2.y); 1685 } 1686 1687 // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (RefPoint) 1688 @Test(compLevel = CompLevel.C1_SIMPLE) 1689 public int test82(RefPoint p) { 1690 RefPoint np = test82_helper(p); 1691 return np.x.n + np.y.n; 1692 } 1693 1694 @DontCompile 1695 private static RefPoint test82_helper(RefPoint p) { 1696 return p; 1697 } 1698 1699 @Run(test = "test82") 1700 public void test82_verifier() { 1701 int result = test82(refPointField1); 1702 int n = refPointField1.x.n + refPointField1.y.n; 1703 Asserts.assertEQ(result, n); 1704 } 1705 1706 //------------------------------------------------------------------------------- 1707 // Tests for InlineTypeReturnedAsFields vs the value class TooBigToReturnAsFields 1708 //------------------------------------------------------------------------------- 1709 1710 // C2->C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) 1711 @Test(compLevel = CompLevel.C2) 1712 public int test83(TooBigToReturnAsFields p) { 1713 TooBigToReturnAsFields np = test83_helper(p); 1714 return p.a0 + p.a5; 1715 } 1716 1717 @DontInline 1718 @ForceCompile(CompLevel.C1_SIMPLE) 1719 private static TooBigToReturnAsFields test83_helper(TooBigToReturnAsFields p) { 1720 return p; 1721 } 1722 1723 @Run(test = "test83") 1724 public void test83_verifier() { 1725 int result = test83(tooBig); 1726 int n = tooBig.a0 + tooBig.a5; 1727 Asserts.assertEQ(result, n); 1728 } 1729 1730 // C1->C2 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) 1731 @Test(compLevel = CompLevel.C1_SIMPLE) 1732 public int test84(TooBigToReturnAsFields p) { 1733 TooBigToReturnAsFields np = test84_helper(p); 1734 return p.a0 + p.a5; 1735 } 1736 1737 @DontInline 1738 @ForceCompile(CompLevel.C2) 1739 private static TooBigToReturnAsFields test84_helper(TooBigToReturnAsFields p) { 1740 return p; 1741 } 1742 1743 @Run(test = "test84") 1744 public void test84_verifier() { 1745 int result = test84(tooBig); 1746 int n = tooBig.a0 + tooBig.a5; 1747 Asserts.assertEQ(result, n); 1748 } 1749 1750 // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) 1751 @Test(compLevel = CompLevel.C1_SIMPLE) 1752 public TooBigToReturnAsFields test85(TooBigToReturnAsFields p) { 1753 return p; 1754 } 1755 1756 @Run(test = "test85") 1757 public void test85_verifier() { 1758 TooBigToReturnAsFields p = test85(tooBig); 1759 Asserts.assertEQ(p.a0, tooBig.a0); 1760 Asserts.assertEQ(p.a2, tooBig.a2); 1761 } 1762 1763 // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) 1764 @Test(compLevel = CompLevel.C1_SIMPLE) 1765 public int test86(TooBigToReturnAsFields p) { 1766 TooBigToReturnAsFields np = test86_helper(p); 1767 return p.a0 + p.a5; 1768 } 1769 1770 @DontCompile 1771 private static TooBigToReturnAsFields test86_helper(TooBigToReturnAsFields p) { 1772 return p; 1773 } 1774 1775 @Run(test = "test86") 1776 public void test86_verifier() { 1777 int result = test86(tooBig); 1778 int n = tooBig.a0 + tooBig.a5; 1779 Asserts.assertEQ(result, n); 1780 } 1781 1782 //------------------------------------------------------------------------------- 1783 // Tests for how C1 handles InlineTypeReturnedAsFields in both calls and returns 1784 //------------------------------------------------------------------------------- 1785 1786 // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint) 1787 @Test(compLevel = CompLevel.C2) 1788 public RefPoint test87(RefPoint p) { 1789 return test87_helper(p); 1790 } 1791 1792 @DontInline 1793 @ForceCompile(CompLevel.C1_SIMPLE) 1794 private static RefPoint test87_helper(RefPoint p) { 1795 return p; 1796 } 1797 1798 @Run(test = "test87") 1799 public void test87_verifier() { 1800 Asserts.assertEQ(test87(null), null); 1801 Asserts.assertEQ(test87(refPointField1), refPointField1); 1802 } 1803 1804 // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint with constant null) 1805 @Test(compLevel = CompLevel.C2) 1806 public RefPoint test88() { 1807 return test88_helper(); 1808 } 1809 1810 @DontInline 1811 @ForceCompile(CompLevel.C1_SIMPLE) 1812 private static RefPoint test88_helper() { 1813 return null; 1814 } 1815 1816 @Run(test = "test88") 1817 public void test88_verifier() { 1818 Asserts.assertEQ(test88(), null); 1819 } 1820 1821 // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint) 1822 @Test(compLevel = CompLevel.C1_SIMPLE) 1823 public RefPoint test89(RefPoint p) { 1824 return test89_helper(p); 1825 } 1826 1827 @DontInline 1828 @ForceCompile(CompLevel.C2) 1829 private static RefPoint test89_helper(RefPoint p) { 1830 return p; 1831 } 1832 1833 @Run(test = "test89") 1834 public void test89_verifier() { 1835 Asserts.assertEQ(test89(null), null); 1836 Asserts.assertEQ(test89(refPointField1), refPointField1); 1837 } 1838 1839 //---------------------------------------------------------------------------------- 1840 // Tests for unverified entries: there are 6 cases: 1841 // C1 -> Unverified Value Entry compiled by C1 1842 // C1 -> Unverified Value Entry compiled by C2 1843 // C2 -> Unverified Entry compiled by C1 (target is NOT a value class) 1844 // C2 -> Unverified Entry compiled by C2 (target is NOT a value class) 1845 // C2 -> Unverified Entry compiled by C1 (target IS a value class, i.e., has VVEP_RO) 1846 // C2 -> Unverified Entry compiled by C2 (target IS a value class, i.e., has VVEP_RO) 1847 //---------------------------------------------------------------------------------- 1848 1849 // C1->C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by C1) 1850 @Test(compLevel = CompLevel.C1_SIMPLE) 1851 public int test90(Intf intf, int a, int b) { 1852 return intf.func2(a, b, pointField); 1853 } 1854 1855 static Intf test90_intfs[] = { 1856 new MyImplPojo1(), 1857 new MyImplPojo2(), 1858 }; 1859 1860 @Run(test = "test90") 1861 public void test90_verifier(RunInfo info) { 1862 int count = info.isWarmUp() ? 1 : 20; 1863 for (int i = 0; i < count; i++) { 1864 Intf intf = test90_intfs[i % test90_intfs.length]; 1865 int result = test90(intf, 123, 456) + i; 1866 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1867 } 1868 } 1869 1870 // C1->C2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by C2) 1871 @Test(compLevel = CompLevel.C1_SIMPLE) 1872 public int test91(Intf intf, int a, int b) { 1873 return intf.func2(a, b, pointField); 1874 } 1875 1876 static Intf test91_intfs[] = { 1877 new MyImplPojo2(), 1878 new MyImplPojo1(), 1879 }; 1880 1881 @Run(test = "test91") 1882 public void test91_verifier(RunInfo info) { 1883 int count = info.isWarmUp() ? 1 : 20; 1884 for (int i = 0; i < count; i++) { 1885 Intf intf = test91_intfs[i % test91_intfs.length]; 1886 int result = test91(intf, 123, 456) + i; 1887 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1888 } 1889 } 1890 1891 // C2->C1 invokeinterface -- call Unverified Entry of MyImplPojo1.func2 (compiled by C1) 1892 @Test(compLevel = CompLevel.C2) 1893 public int test92(Intf intf, int a, int b) { 1894 return intf.func2(a, b, pointField); 1895 } 1896 1897 static Intf test92_intfs[] = { 1898 new MyImplPojo1(), 1899 new MyImplPojo2(), 1900 }; 1901 1902 @Run(test = "test92") 1903 public void test92_verifier(RunInfo info) { 1904 int count = info.isWarmUp() ? 1 : 20; 1905 for (int i = 0; i < count; i++) { 1906 Intf intf = test92_intfs[i % test92_intfs.length]; 1907 int result = test92(intf, 123, 456) + i; 1908 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1909 } 1910 } 1911 1912 // C2->C2 invokeinterface -- call Unverified Entry of MyImplPojo2.func2 (compiled by C2) 1913 @Test(compLevel = CompLevel.C2) 1914 public int test93(Intf intf, int a, int b) { 1915 return intf.func2(a, b, pointField); 1916 } 1917 1918 static Intf test93_intfs[] = { 1919 new MyImplPojo2(), 1920 new MyImplPojo1(), 1921 }; 1922 1923 @Run(test = "test93") 1924 public void test93_verifier(RunInfo info) { 1925 int count = info.isWarmUp() ? 1 : 20; 1926 for (int i = 0; i < count; i++) { 1927 Intf intf = test93_intfs[i % test93_intfs.length]; 1928 int result = test93(intf, 123, 456) + i; 1929 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1930 } 1931 } 1932 1933 // C2->C1 invokeinterface -- call Unverified Entry of MyImplVal1.func2 (compiled by C1 - has VVEP_RO) 1934 @Test(compLevel = CompLevel.C2) 1935 public int test94(Intf intf, int a, int b) { 1936 return intf.func2(a, b, pointField); 1937 } 1938 1939 static Intf test94_intfs[] = { 1940 new MyImplVal1(), 1941 new MyImplVal2(), 1942 }; 1943 1944 @Run(test = "test94") 1945 public void test94_verifier(RunInfo info) { 1946 int count = info.isWarmUp() ? 1 : 20; 1947 for (int i = 0; i < count; i++) { 1948 Intf intf = test94_intfs[i % test94_intfs.length]; 1949 int result = test94(intf, 123, 456) + i; 1950 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1951 } 1952 } 1953 1954 // C2->C2 invokeinterface -- call Unverified Entry of MyImplVal2.func2 (compiled by C2 - has VVEP_RO) 1955 @Test(compLevel = CompLevel.C2) 1956 public int test95(Intf intf, int a, int b) { 1957 return intf.func2(a, b, pointField); 1958 } 1959 1960 static Intf test95_intfs[] = { 1961 new MyImplVal2(), 1962 new MyImplVal1(), 1963 }; 1964 1965 @Run(test = "test95") 1966 public void test95_verifier(RunInfo info) { 1967 int count = info.isWarmUp() ? 1 : 20; 1968 for (int i = 0; i < count; i++) { 1969 Intf intf = test95_intfs[i % test95_intfs.length]; 1970 int result = test95(intf, 123, 456) + i; 1971 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1972 } 1973 } 1974 1975 // C1->C2 GC handling in StubRoutines::store_inline_type_fields_to_buf() 1976 @Test(compLevel = CompLevel.C1_SIMPLE) 1977 public RefPoint test96(RefPoint rp, boolean b) { 1978 RefPoint p = test96_helper(rp); 1979 if (b) { 1980 return rp; 1981 } 1982 return p; 1983 } 1984 1985 @DontInline 1986 @ForceCompile(CompLevel.C2) 1987 public RefPoint test96_helper(RefPoint rp) { 1988 return rp; 1989 } 1990 1991 @Run(test = "test96") 1992 public void test96_verifier(RunInfo info) { 1993 int count = info.isWarmUp() ? 1 : 20000; // Do enough iteration to cause GC inside StubRoutines::store_inline_type_fields_to_buf 1994 Number x = new Number(10); // old object 1995 for (int i = 0; i < count; i++) { 1996 Number y = new Number(i); // new object for each iteraton 1997 RefPoint rp1 = new RefPoint(x, y); 1998 RefPoint rp2 = test96(rp1, info.isWarmUp()); 1999 2000 Asserts.assertEQ(rp1.x, x); 2001 Asserts.assertEQ(rp1.y, y); 2002 Asserts.assertEQ(rp1.y.n, i); 2003 } 2004 } 2005 2006 // C1->C1 - caller is compiled first. It invokes callee(test97) a few times while the 2007 // callee is executed by the interpreter. Then, callee is compiled 2008 // and SharedRuntime::fixup_callers_callsite is called to fix up the 2009 // callsite from test97_verifier->test97. 2010 @Test(compLevel = CompLevel.C1_SIMPLE) 2011 public int test97(Point p1, Point p2) { 2012 return test97_helper(p1, p2); 2013 } 2014 2015 @DontCompile 2016 public int test97_helper(Point p1, Point p2) { 2017 return p1.x + p1.y + p2.x + p2.y; 2018 } 2019 2020 @ForceCompile(CompLevel.C1_SIMPLE) 2021 public void test97_verifier(RunInfo info) { 2022 int count = info.isWarmUp() ? 1 : 20; 2023 for (int i = 0; i < count; i++) { 2024 int result = test97(pointField1, pointField2); 2025 int n = test97_helper(pointField1, pointField2); 2026 Asserts.assertEQ(result, n); 2027 } 2028 } 2029 2030 @Run(test = "test97") 2031 public void run_test97_verifier(RunInfo info) { 2032 test97_verifier(info); 2033 } 2034 2035 // C1->C2 - same as test97, except the callee is compiled by C2. 2036 @Test(compLevel = CompLevel.C2) 2037 public int test98(Point p1, Point p2) { 2038 return test98_helper(p1, p2); 2039 } 2040 2041 @DontCompile 2042 public int test98_helper(Point p1, Point p2) { 2043 return p1.x + p1.y + p2.x + p2.y; 2044 } 2045 2046 @ForceCompile(CompLevel.C1_SIMPLE) 2047 public void test98_verifier(RunInfo info) { 2048 int count = info.isWarmUp() ? 1 : 20; 2049 for (int i = 0; i < count; i++) { 2050 int result = test98(pointField1, pointField2); 2051 int n = test98_helper(pointField1, pointField2); 2052 Asserts.assertEQ(result, n); 2053 } 2054 } 2055 2056 @Run(test = "test98") 2057 public void run_test98_verifier(RunInfo info) { 2058 test98_verifier(info); 2059 } 2060 2061 // C1->C2 - same as test97, except the callee is a static method. 2062 @Test(compLevel = CompLevel.C1_SIMPLE) 2063 public static int test99(Point p1, Point p2) { 2064 return test99_helper(p1, p2); 2065 } 2066 2067 @DontCompile 2068 public static int test99_helper(Point p1, Point p2) { 2069 return p1.x + p1.y + p2.x + p2.y; 2070 } 2071 2072 @ForceCompile(CompLevel.C1_SIMPLE) 2073 public void test99_verifier(RunInfo info) { 2074 int count = info.isWarmUp() ? 1 : 20; 2075 for (int i = 0; i < count; i++) { 2076 int result = test99(pointField1, pointField2); 2077 int n = test99_helper(pointField1, pointField2); 2078 Asserts.assertEQ(result, n); 2079 } 2080 } 2081 2082 @Run(test = "test99") 2083 public void run_test99_verifier(RunInfo info) { 2084 test99_verifier(info); 2085 } 2086 2087 // C2->C1 invokestatic, packing causes stack growth (1 extra stack word). 2088 // Make sure stack frame is set up properly for GC. 2089 @Test(compLevel = CompLevel.C2) 2090 public float test100(FloatPoint fp1, FloatPoint fp2, RefPoint rp, int a1, int a2, int a3, int a4) { 2091 return test100_helper(fp1, fp2, rp, a1, a2, a3, a4); 2092 } 2093 2094 @DontInline 2095 @ForceCompile(CompLevel.C1_SIMPLE) 2096 private static float test100_helper(FloatPoint fp1, FloatPoint fp2, RefPoint rp, int a1, int a2, int a3, int a4) { 2097 // On x64: 2098 // Scalarized entry -- all parameters are passed in registers 2099 // xmm0 = fp1.x 2100 // xmm1 = fp1.y 2101 // xmm2 = fp2.x 2102 // xmm3 = fp2.y 2103 // rsi = rp.x (oop) 2104 // rdx = rp.y (oop) 2105 // cx = a1 2106 // r8 = a2 2107 // r9 = a3 2108 // di = a4 2109 // Non-scalarized entry -- a6 is passed on stack[0] 2110 // rsi = fp1 2111 // rdx = fp2 2112 // rcx = rp 2113 // r8 = a1 2114 // r9 = a2 2115 // di = a3 2116 // [sp + ??] = a4 2117 return fp1.x + fp1.y + fp2.x + fp2.y + rp.x.n + rp.y.n + a1 + a2 + a3 + a4; 2118 } 2119 2120 @Run(test = "test100") 2121 public void test100_verifier(RunInfo info) { 2122 int count = info.isWarmUp() ? 1 : 4; 2123 for (int i = 0; i < count; i++) { 2124 FloatPoint fp1 = new FloatPoint(i+0, i+11); 2125 FloatPoint fp2 = new FloatPoint(i+222, i+3333); 2126 RefPoint rp = new RefPoint(i+44444, i+555555); 2127 float result; 2128 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 2129 result = test100(fp1, fp2, rp, 1, 2, 3, 4); 2130 } 2131 float n = test100_helper(fp1, fp2, rp, 1, 2, 3, 4); 2132 Asserts.assertEQ(result, n); 2133 } 2134 } 2135 2136 // C1->C2 force GC for every allocation when storing the returned 2137 // fields back into a buffered object. 2138 @Test(compLevel = CompLevel.C1_SIMPLE) 2139 public RefPoint test101(RefPoint rp) { 2140 return test101_helper(rp); 2141 } 2142 2143 @DontInline 2144 @ForceCompile(CompLevel.C2) 2145 public RefPoint test101_helper(RefPoint rp) { 2146 return rp; 2147 } 2148 2149 @Run(test = "test101") 2150 public void test101_verifier(RunInfo info) { 2151 int count = info.isWarmUp() ? 1 : 5; 2152 for (int i = 0; i < count; i++) { 2153 RefPoint rp = new RefPoint(1, 2); 2154 Object x = rp.x; 2155 Object y = rp.y; 2156 RefPoint result = new RefPoint(3, 4); 2157 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 2158 result = test101(rp); 2159 } 2160 Asserts.assertEQ(rp.x, result.x); 2161 Asserts.assertEQ(rp.y, result.y); 2162 Asserts.assertEQ(x, result.x); 2163 Asserts.assertEQ(y, result.y); 2164 } 2165 } 2166 2167 // Same as test101, except we have Interpreter->C2 instead. 2168 @Test(compLevel = CompLevel.C1_SIMPLE) 2169 public RefPoint test102(RefPoint rp) { 2170 return test102_interp(rp); 2171 } 2172 2173 @DontInline 2174 public RefPoint test102_interp(RefPoint rp) { 2175 return test102_helper(rp); 2176 } 2177 2178 @DontInline 2179 @ForceCompile(CompLevel.C2) 2180 public RefPoint test102_helper(RefPoint rp) { 2181 return rp; 2182 } 2183 2184 @Run(test = "test102") 2185 public void test102_verifier(RunInfo info) { 2186 int count = info.isWarmUp() ? 1 : 5; 2187 for (int i = 0; i < count; i++) { 2188 RefPoint rp = new RefPoint(11, 22); 2189 Object x = rp.x; 2190 Object y = rp.y; 2191 RefPoint result = new RefPoint(333, 444); 2192 try (ForceGCMarker m = ForceGCMarker.mark(info.isWarmUp())) { 2193 result = test102(rp); 2194 } 2195 Asserts.assertEQ(rp.x, result.x); 2196 Asserts.assertEQ(rp.y, result.y); 2197 Asserts.assertEQ(x, result.x); 2198 Asserts.assertEQ(y, result.y); 2199 } 2200 } 2201 2202 @Test(compLevel = CompLevel.C1_SIMPLE) 2203 public void test103() { 2204 // when this method is compiled by C1, the Test103Value class is not yet loaded. 2205 test103_v = new Test103Value(); // invokestatic "Test103Value.<init>()QTest103Value;" 2206 } 2207 2208 @ImplicitlyConstructible 2209 @LooselyConsistentValue 2210 static value class Test103Value { 2211 int x = rI; 2212 } 2213 2214 static Object test103_v; 2215 2216 @Run(test = "test103") 2217 public void test103_verifier(RunInfo info) { 2218 if (info.isWarmUp()) { 2219 // Make sure test103() is compiled before Test103Value is loaded 2220 return; 2221 } 2222 test103(); 2223 Test103Value v = (Test103Value)test103_v; 2224 Asserts.assertEQ(v.x, rI); 2225 } 2226 2227 2228 // Same as test103, but with a value class that's too big to return as fields. 2229 @Test(compLevel = CompLevel.C1_SIMPLE) 2230 public void test104() { 2231 // when this method is compiled by C1, the Test104Value class is not yet loaded. 2232 test104_v = new Test104Value(); // invokestatic "Test104Value.<init>()QTest104Value;" 2233 } 2234 2235 @ImplicitlyConstructible 2236 @LooselyConsistentValue 2237 static value class Test104Value { 2238 long x0 = rL; 2239 long x1 = rL; 2240 long x2 = rL; 2241 long x3 = rL; 2242 long x4 = rL; 2243 long x5 = rL; 2244 long x6 = rL; 2245 long x7 = rL; 2246 long x8 = rL; 2247 long x9 = rL; 2248 long xa = rL; 2249 long xb = rL; 2250 long xc = rL; 2251 long xd = rL; 2252 long xe = rL; 2253 long xf = rL; 2254 } 2255 2256 static Object test104_v; 2257 2258 @Run(test = "test104") 2259 public void test104_verifier(RunInfo info) { 2260 if (info.isWarmUp()) { 2261 // Make sure test104() is compiled before Test104Value is loaded 2262 return; 2263 } 2264 test104(); 2265 Test104Value v = (Test104Value)test104_v; 2266 Asserts.assertEQ(v.x0, rL); 2267 } 2268 2269 // C2->C1 invokeinterface -- call Unverified Entry of MyImplVal1.func1 (compiled by C1 - has VVEP_RO) 2270 /// (same as test94, except we are calling func1, which shares VVEP and VVEP_RO 2271 @Test(compLevel = CompLevel.C2) 2272 public int test105(Intf intf, int a, int b) { 2273 return intf.func1(a, b); 2274 } 2275 2276 static Intf test105_intfs[] = { 2277 new MyImplVal1(), 2278 new MyImplVal2(), 2279 }; 2280 2281 @Run(test = "test105") 2282 public void test105_verifier(RunInfo info) { 2283 int count = info.isWarmUp() ? 1 : 20; 2284 for (int i = 0; i < count; i++) { 2285 Intf intf = test105_intfs[i % test105_intfs.length]; 2286 int result = test105(intf, 123, 456) + i; 2287 Asserts.assertEQ(result, intf.func1(123, 456) + i); 2288 } 2289 } 2290 2291 // C2->C2 invokeinterface -- call Unverified Entry of MyImplVal2.func1 (compiled by C2 - has VVEP_RO) 2292 /// (same as test95, except we are calling func1, which shares VVEP and VVEP_RO 2293 @Test(compLevel = CompLevel.C2) 2294 public int test106(Intf intf, int a, int b) { 2295 return intf.func1(a, b); 2296 } 2297 2298 static Intf test106_intfs[] = { 2299 new MyImplVal2(), 2300 new MyImplVal1(), 2301 }; 2302 2303 @Run(test = "test106") 2304 public void test106_verifier(RunInfo info) { 2305 int count = info.isWarmUp() ? 1 : 20; 2306 for (int i = 0; i < count; i++) { 2307 Intf intf = test106_intfs[i % test106_intfs.length]; 2308 int result = test106(intf, 123, 456) + i; 2309 Asserts.assertEQ(result, intf.func1(123, 456) + i); 2310 } 2311 } 2312 2313 // C2->C1 invokeinterface -- C2 calls call Unverified Entry of MyImplVal2X.func1 (compiled by 2314 // C1, with VVEP_RO==VVEP) 2315 // This test is developed to validate JDK-8230325. 2316 @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) 2317 public int test107(Intf intf, int a, int b) { 2318 return intf.func1(a, b); 2319 } 2320 2321 @ForceCompile 2322 public void test107_verifier() { 2323 Intf intf1 = new MyImplVal1X(); 2324 Intf intf2 = new MyImplVal2X(); 2325 2326 for (int i = 0; i < 1000; i++) { 2327 test107(intf1, 123, 456); 2328 } 2329 for (int i = 0; i < 500_000; i++) { 2330 // Run enough loops so that test107 will be compiled by C2. 2331 if (i % 30 == 0) { 2332 // This will indirectly call MyImplVal2X.func1, but the call frequency is low, so 2333 // test107 will be compiled by C2, but MyImplVal2X.func1 will compiled by C1 only. 2334 int result = test107(intf2, 123, 456) + i; 2335 Asserts.assertEQ(result, intf2.func1(123, 456) + i); 2336 } else { 2337 // Call test107 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) 2338 // for the invokeinterface bytecode in test107. 2339 test107(intf1, 123, 456); 2340 } 2341 } 2342 } 2343 2344 @Run(test = "test107") 2345 @Warmup(0) 2346 public void run_test107_verifier() { 2347 test107_verifier(); 2348 } 2349 2350 // Same as test107, except we call MyImplVal2X.func2 (compiled by C1, VVEP_RO != VVEP) 2351 @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) 2352 public int test108(Intf intf, int a, int b) { 2353 return intf.func2(a, b, pointField); 2354 } 2355 2356 @ForceCompile 2357 public void test108_verifier() { 2358 Intf intf1 = new MyImplVal1X(); 2359 Intf intf2 = new MyImplVal2X(); 2360 2361 for (int i = 0; i < 1000; i++) { 2362 test108(intf1, 123, 456); 2363 } 2364 for (int i = 0; i < 500_000; i++) { 2365 // Run enough loops so that test108 will be compiled by C2. 2366 if (i % 30 == 0) { 2367 // This will indirectly call MyImplVal2X.func2, but the call frequency is low, so 2368 // test108 will be compiled by C2, but MyImplVal2X.func2 will compiled by C1 only. 2369 int result = test108(intf2, 123, 456) + i; 2370 Asserts.assertEQ(result, intf2.func2(123, 456, pointField) + i); 2371 } else { 2372 // Call test108 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) 2373 // for the invokeinterface bytecode in test108. 2374 test108(intf1, 123, 456); 2375 } 2376 } 2377 } 2378 2379 @Run(test = "test108") 2380 @Warmup(0) 2381 public void run_test108_verifier() { 2382 test108_verifier(); 2383 } 2384 2385 // Same as test107, except we call MyImplPojo3.func2 (compiled by C1, VVEP_RO == VEP) 2386 @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) 2387 public int test109(Intf intf, int a, int b) { 2388 return intf.func2(a, b, pointField); 2389 } 2390 2391 @ForceCompile 2392 public void test109_verifier() { 2393 Intf intf1 = new MyImplPojo0(); 2394 Intf intf2 = new MyImplPojo3(); 2395 2396 for (int i = 0; i < 1000; i++) { 2397 test109(intf1, 123, 456); 2398 } 2399 for (int i = 0; i < 500_000; i++) { 2400 // Run enough loops so that test109 will be compiled by C2. 2401 if (i % 30 == 0) { 2402 // This will indirectly call MyImplPojo3.func2, but the call frequency is low, so 2403 // test109 will be compiled by C2, but MyImplPojo3.func2 will compiled by C1 only. 2404 int result = test109(intf2, 123, 456) + i; 2405 Asserts.assertEQ(result, intf2.func2(123, 456, pointField) + i); 2406 } else { 2407 // Call test109 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) 2408 // for the invokeinterface bytecode in test109. 2409 test109(intf1, 123, 456); 2410 } 2411 } 2412 } 2413 2414 @Run(test = "test109") 2415 @Warmup(0) 2416 public void run_test109_verifier() { 2417 test109_verifier(); 2418 } 2419 }