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