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 jdk.test.lib.Asserts; 27 28 /* 29 * @test 30 * @summary Test calls from {C1} to {C2, Interpreter}, and vice versa. 31 * @library /testlibrary /test/lib /compiler/whitebox / 32 * @requires os.simpleArch == "x64" 33 * @compile TestCallingConventionC1.java 34 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 35 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 36 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla 37 * compiler.valhalla.valuetypes.ValueTypeTest 38 * compiler.valhalla.valuetypes.TestCallingConventionC1 39 */ 40 public class TestCallingConventionC1 extends ValueTypeTest { 41 public static final int C1 = COMP_LEVEL_SIMPLE; 42 public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION; 43 44 @Override 45 public int getNumScenarios() { 46 return 2; 47 } 48 49 @Override 50 public String[] getVMParameters(int scenario) { 51 switch (scenario) { 52 53 // Default: both C1 and C2 are enabled, tierd compilation enabled 54 case 0: return new String[] {"-XX:+EnableValhallaC1", "-XX:CICompilerCount=2" 55 , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test52_helper" 56 //, "-XX:CompileCommand=print,*::func_c1" 57 }; 58 // Only C1. Tierd compilation disabled. 59 case 1: return new String[] {"-XX:+EnableValhallaC1", "-XX:TieredStopAtLevel=1" 60 , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test32*" 61 }; 62 } 63 return null; 64 } 65 66 public static void main(String[] args) throws Throwable { 67 TestCallingConventionC1 test = new TestCallingConventionC1(); 68 test.run(args, 69 Point.class, 70 Functor.class, 71 Functor1.class, 72 Functor2.class, 73 Functor3.class, 74 Functor4.class, 75 MyImplPojo1.class, 76 MyImplPojo2.class, 77 MyImplVal.class, 78 FixedPoints.class, 79 FloatPoint.class); 80 } 81 82 static inline class Point { 83 final int x; 84 final int y; 85 public Point(int x, int y) { 86 this.x = x; 87 this.y = y; 88 } 89 90 @DontCompile 91 @DontInline 92 public int func() { 93 return x + y; 94 } 95 96 @ForceCompile(compLevel = C1) 97 @DontInline 98 public int func_c1(Point p) { 99 return x + y + p.x + p.y; 100 } 101 } 102 103 static interface FunctorInterface { 104 public int apply_interp(Point p); 105 } 106 107 static class Functor implements FunctorInterface { 108 @DontCompile 109 @DontInline 110 public int apply_interp(Point p) { 111 return p.func() + 0; 112 } 113 } 114 static class Functor1 extends Functor { 115 @DontCompile 116 @DontInline 117 public int apply_interp(Point p) { 118 return p.func() + 10000; 119 } 120 } 121 static class Functor2 extends Functor { 122 @DontCompile 123 @DontInline 124 public int apply_interp(Point p) { 125 return p.func() + 20000; 126 } 127 } 128 static class Functor3 extends Functor { 129 @DontCompile 130 @DontInline 131 public int apply_interp(Point p) { 132 return p.func() + 30000; 133 } 134 } 135 static class Functor4 extends Functor { 136 @DontCompile 137 @DontInline 138 public int apply_interp(Point p) { 139 return p.func() + 40000; 140 } 141 } 142 143 static Functor functors[] = { 144 new Functor(), 145 new Functor1(), 146 new Functor2(), 147 new Functor3(), 148 new Functor4() 149 }; 150 static int functorCounter = 0; 151 static Functor getFunctor() { 152 int n = (++ functorCounter) % functors.length; 153 return functors[n]; 154 } 155 156 static Point pointField = new Point(123, 456); 157 static Point pointField1 = new Point(1123, 1456); 158 static Point pointField2 = new Point(2123, 2456); 159 160 static interface Intf { 161 public int func1(int a, int b); 162 public int func2(int a, int b, Point p); 163 } 164 165 static class MyImplPojo1 implements Intf { 166 int field = 1000; 167 @DontInline @DontCompile 168 public int func1(int a, int b) { return field + a + b + 1; } 169 @DontInline @DontCompile 170 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } 171 } 172 173 static class MyImplPojo2 implements Intf { 174 int field = 2000; 175 176 @DontInline @ForceCompile(compLevel = C1) 177 public int func1(int a, int b) { return field + a + b + 20; } 178 @DontInline @ForceCompile(compLevel = C1) 179 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } 180 } 181 182 static inline class MyImplVal implements Intf { 183 final int field; 184 MyImplVal(int f) { 185 field = f; 186 } 187 MyImplVal() { 188 field = 3000; 189 } 190 191 @DontInline @ForceCompile(compLevel = C1) 192 public int func1(int a, int b) { return field + a + b + 300; } 193 194 @DontInline @ForceCompile(compLevel = C1) 195 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } 196 } 197 198 static Intf intfs[] = { 199 new MyImplPojo1(), 200 new MyImplPojo2(), 201 new MyImplVal() 202 }; 203 static int intfCounter = 0; 204 static Intf getIntf() { 205 int n = (++ intfCounter) % intfs.length; 206 return intfs[n]; 207 } 208 209 static inline class FixedPoints { 210 final boolean Z0 = false; 211 final boolean Z1 = true; 212 final byte B = (byte)2; 213 final char C = (char)34; 214 final short S = (short)456; 215 final int I = 5678; 216 final long J = 0x1234567800abcdefL; 217 } 218 static FixedPoints fixedPointsField = new FixedPoints(); 219 220 static inline class FloatPoint { 221 final float x; 222 final float y; 223 public FloatPoint(float x, float y) { 224 this.x = x; 225 this.y = y; 226 } 227 } 228 static inline class DoublePoint { 229 final double x; 230 final double y; 231 public DoublePoint(double x, double y) { 232 this.x = x; 233 this.y = y; 234 } 235 } 236 static FloatPoint floatPointField = new FloatPoint(123.456f, 789.012f); 237 static DoublePoint doublePointField = new DoublePoint(123.456, 789.012); 238 239 static inline class EightFloats { 240 float f1, f2, f3, f4, f5, f6, f7, f8; 241 public EightFloats() { 242 f1 = 1.1f; 243 f2 = 2.2f; 244 f3 = 3.3f; 245 f4 = 4.4f; 246 f5 = 5.5f; 247 f6 = 6.6f; 248 f7 = 7.7f; 249 f8 = 8.8f; 250 } 251 } 252 static EightFloats eightFloatsField = new EightFloats(); 253 254 static class Number { 255 int n; 256 Number(int v) { 257 n = v; 258 } 259 void set(int v) { 260 n = v; 261 } 262 } 263 static inline class RefPoint { 264 final Number x; 265 final Number y; 266 public RefPoint(int x, int y) { 267 this.x = new Number(x); 268 this.y = new Number(y); 269 } 270 } 271 272 static RefPoint refPointField1 = new RefPoint(12, 34); 273 static RefPoint refPointField2 = new RefPoint(56789, 0x12345678); 274 275 //********************************************************************** 276 // PART 1 - C1 calls interpreted code 277 //********************************************************************** 278 279 280 //** C1 passes value to interpreter (static) 281 @Test(compLevel = C1) 282 public int test1() { 283 return test1_helper(pointField); 284 } 285 286 @DontInline 287 @DontCompile 288 private static int test1_helper(Point p) { 289 return p.func(); 290 } 291 292 @DontCompile 293 public void test1_verifier(boolean warmup) { 294 int count = warmup ? 1 : 10; 295 for (int i=0; i<count; i++) { // need a loop to test inline cache 296 int result = test1() + i; 297 Asserts.assertEQ(result, pointField.func() + i); 298 } 299 } 300 301 302 //** C1 passes value to interpreter (monomorphic) 303 @Test(compLevel = C1) 304 public int test2() { 305 return test2_helper(pointField); 306 } 307 308 @DontInline 309 @DontCompile 310 private int test2_helper(Point p) { 311 return p.func(); 312 } 313 314 @DontCompile 315 public void test2_verifier(boolean warmup) { 316 int count = warmup ? 1 : 10; 317 for (int i=0; i<count; i++) { // need a loop to test inline cache 318 int result = test2() + i; 319 Asserts.assertEQ(result, pointField.func() + i); 320 } 321 } 322 323 // C1 passes value to interpreter (megamorphic: vtable) 324 @Test(compLevel = C1) 325 public int test3(Functor functor) { 326 return functor.apply_interp(pointField); 327 } 328 329 @DontCompile 330 public void test3_verifier(boolean warmup) { 331 int count = warmup ? 1 : 100; 332 for (int i=0; i<count; i++) { // need a loop to test inline cache and vtable indexing 333 Functor functor = warmup ? functors[0] : getFunctor(); 334 int result = test3(functor) + i; 335 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 336 } 337 } 338 339 // Same as test3, but compiled with C2. Test the hastable of VtableStubs 340 @Test(compLevel = C2) 341 public int test3b(Functor functor) { 342 return functor.apply_interp(pointField); 343 } 344 345 @DontCompile 346 public void test3b_verifier(boolean warmup) { 347 int count = warmup ? 1 : 100; 348 for (int i=0; i<count; i++) { // need a loop to test inline cache and vtable indexing 349 Functor functor = warmup ? functors[0] : getFunctor(); 350 int result = test3b(functor) + i; 351 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 352 } 353 } 354 355 // C1 passes value to interpreter (megamorphic: itable) 356 @Test(compLevel = C1) 357 public int test4(FunctorInterface fi) { 358 return fi.apply_interp(pointField); 359 } 360 361 @DontCompile 362 public void test4_verifier(boolean warmup) { 363 int count = warmup ? 1 : 100; 364 for (int i=0; i<count; i++) { // need a loop to test inline cache and itable indexing 365 Functor functor = warmup ? functors[0] : getFunctor(); 366 int result = test4(functor) + i; 367 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 368 } 369 } 370 371 //********************************************************************** 372 // PART 2 - interpreter calls C1 373 //********************************************************************** 374 375 // Interpreter passes value to C1 (static) 376 @Test(compLevel = C1) 377 static public int test20(Point p1, long l, Point p2) { 378 return p1.x + p2.y; 379 } 380 381 @DontCompile 382 public void test20_verifier(boolean warmup) { 383 int result = test20(pointField1, 0, pointField2); 384 int n = pointField1.x + pointField2.y; 385 Asserts.assertEQ(result, n); 386 } 387 388 // Interpreter passes value to C1 (instance method in inline class) 389 @Test 390 public int test21(Point p) { 391 return test21_helper(p); 392 } 393 394 @DontCompile 395 @DontInline 396 int test21_helper(Point p) { 397 return p.func_c1(p); 398 } 399 400 @DontCompile 401 public void test21_verifier(boolean warmup) { 402 int result = test21(pointField); 403 int n = 2 * (pointField.x + pointField.y); 404 Asserts.assertEQ(result, n); 405 } 406 407 408 //********************************************************************** 409 // PART 3 - C2 calls C1 410 //********************************************************************** 411 412 // C2->C1 invokestatic, single value arg 413 @Test(compLevel = C2) 414 public int test30() { 415 return test30_helper(pointField); 416 } 417 418 @DontInline 419 @ForceCompile(compLevel = C1) 420 private static int test30_helper(Point p) { 421 return p.x + p.y; 422 } 423 424 @DontCompile 425 public void test30_verifier(boolean warmup) { 426 int count = warmup ? 1 : 2; 427 for (int i=0; i<count; i++) { // need a loop to test inline cache 428 int result = test30(); 429 int n = pointField.x + pointField.y; 430 Asserts.assertEQ(result, n); 431 } 432 } 433 434 // C2->C1 invokestatic, two single value args 435 @Test(compLevel = C2) 436 public int test31() { 437 return test31_helper(pointField1, pointField2); 438 } 439 440 @DontInline 441 @ForceCompile(compLevel = C1) 442 private static int test31_helper(Point p1, Point p2) { 443 return p1.x + p2.y; 444 } 445 446 @DontCompile 447 public void test31_verifier(boolean warmup) { 448 int count = warmup ? 1 : 2; 449 for (int i=0; i<count; i++) { // need a loop to test inline cache 450 int result = test31(); 451 int n = pointField1.x + pointField2.y; 452 Asserts.assertEQ(result, n); 453 } 454 } 455 456 // C2->C1 invokestatic, two single value args and interleaving ints (all passed in registers on x64) 457 @Test(compLevel = C2) 458 public int test32() { 459 return test32_helper(0, pointField1, 1, pointField2); 460 } 461 462 @DontInline 463 @ForceCompile(compLevel = C1) 464 private static int test32_helper(int x, Point p1, int y, Point p2) { 465 return p1.x + p2.y + x + y; 466 } 467 468 @DontCompile 469 public void test32_verifier(boolean warmup) { 470 int count = warmup ? 1 : 2; 471 for (int i=0; i<count; i++) { // need a loop to test inline cache 472 int result = test32(); 473 int n = pointField1.x + pointField2.y + 0 + 1; 474 Asserts.assertEQ(result, n); 475 } 476 } 477 478 // C2->C1 invokeinterface -- no verified_ro_entry (no value args except for receiver) 479 @Test(compLevel = C2) 480 public int test33(Intf intf, int a, int b) { 481 return intf.func1(a, b); 482 } 483 484 @DontCompile 485 public void test33_verifier(boolean warmup) { 486 int count = warmup ? 1 : 20; 487 for (int i=0; i<count; i++) { 488 Intf intf = warmup ? intfs[0] : getIntf(); 489 int result = test33(intf, 123, 456) + i; 490 Asserts.assertEQ(result, intf.func1(123, 456) + i); 491 } 492 } 493 494 // C2->C1 invokeinterface -- use verified_ro_entry (has value args other than receiver) 495 @Test(compLevel = C2) 496 public int test34(Intf intf, int a, int b) { 497 return intf.func2(a, b, pointField); 498 } 499 500 @DontCompile 501 public void test34_verifier(boolean warmup) { 502 int count = warmup ? 1 : 20; 503 for (int i=0; i<count; i++) { 504 Intf intf = warmup ? intfs[0] : getIntf(); 505 int result = test34(intf, 123, 456) + i; 506 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 507 } 508 } 509 510 // C2->C1 invokestatic, Point.y is on stack (x64) 511 @Test(compLevel = C2) 512 public int test35() { 513 return test35_helper(1, 2, 3, 4, 5, pointField); 514 } 515 516 @DontInline 517 @ForceCompile(compLevel = C1) 518 private static int test35_helper(int a1, int a2, int a3, int a4, int a5, Point p) { 519 return a1 + a2 + a3 + a4 + a5 + p.x + p.y; 520 } 521 522 @DontCompile 523 public void test35_verifier(boolean warmup) { 524 int count = warmup ? 1 : 2; 525 for (int i=0; i<count; i++) { // need a loop to test inline cache 526 int result = test35(); 527 int n = 1 + 2 + 3 + 4 + 5 + pointField.x + pointField.y; 528 Asserts.assertEQ(result, n); 529 } 530 } 531 532 // C2->C1 invokestatic, shuffling arguments that are passed on stack 533 @Test(compLevel = C2) 534 public int test36() { 535 return test36_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); 536 } 537 538 @DontInline 539 @ForceCompile(compLevel = C1) 540 private static int test36_helper(Point p, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { 541 return a6 + a8; 542 } 543 544 @DontCompile 545 public void test36_verifier(boolean warmup) { 546 int count = warmup ? 1 : 2; 547 for (int i=0; i<count; i++) { // need a loop to test inline cache 548 int result = test36(); 549 int n = 6 + 8; 550 Asserts.assertEQ(result, n); 551 } 552 } 553 554 // C2->C1 invokestatic, shuffling long arguments 555 @Test(compLevel = C2) 556 public int test37() { 557 return test37_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); 558 } 559 560 @DontInline 561 @ForceCompile(compLevel = C1) 562 private static int test37_helper(Point p, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { 563 return (int)(a6 + a8); 564 } 565 566 @DontCompile 567 public void test37_verifier(boolean warmup) { 568 int count = warmup ? 1 : 2; 569 for (int i=0; i<count; i++) { // need a loop to test inline cache 570 int result = test37(); 571 int n = 6 + 8; 572 Asserts.assertEQ(result, n); 573 } 574 } 575 576 // C2->C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments 577 @Test(compLevel = C2) 578 public int test38() { 579 return test38_helper(pointField, true, (byte)1, (char)2, (short)3, 4, 5, (byte)6, (short)7, 8); 580 } 581 582 @DontInline 583 @ForceCompile(compLevel = C1) 584 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) { 585 if (a0) { 586 return (int)(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8); 587 } else { 588 return -1; 589 } 590 } 591 592 @DontCompile 593 public void test38_verifier(boolean warmup) { 594 int count = warmup ? 1 : 2; 595 for (int i=0; i<count; i++) { // need a loop to test inline cache 596 int result = test38(); 597 int n = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8; 598 Asserts.assertEQ(result, n); 599 } 600 } 601 602 // C2->C1 invokestatic, packing a value object with all types of fixed point primitive fields. 603 @Test(compLevel = C2) 604 public long test39() { 605 return test39_helper(1, fixedPointsField, 2, fixedPointsField); 606 } 607 608 @DontInline 609 @ForceCompile(compLevel = C1) 610 private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2) { 611 if (f1.Z0 == false && f1.Z1 == true && f2.Z0 == false && f2.Z1 == true) { 612 return f1.B + f2.C + f1.S + f2.I + f1.J; 613 } else { 614 return -1; 615 } 616 } 617 618 @DontCompile 619 public void test39_verifier(boolean warmup) { 620 int count = warmup ? 1 : 2; 621 for (int i=0; i<count; i++) { // need a loop to test inline cache 622 long result = test39(); 623 long n = test39_helper(1, fixedPointsField, 2, fixedPointsField); 624 Asserts.assertEQ(result, n); 625 } 626 } 627 628 // C2->C1 invokestatic, shuffling floating point args 629 @Test(compLevel = C2) 630 public double test40() { 631 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); 632 } 633 634 @DontInline 635 @ForceCompile(compLevel = C1) 636 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) { 637 return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + fp.x + fp.y - dp.x - dp.y; 638 } 639 640 @DontCompile 641 public void test40_verifier(boolean warmup) { 642 int count = warmup ? 1 : 2; 643 for (int i=0; i<count; i++) { // need a loop to test inline cache 644 double result = test40(); 645 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); 646 Asserts.assertEQ(result, n); 647 } 648 } 649 650 // C2->C1 invokestatic, mixing floats and ints 651 @Test(compLevel = C2) 652 public double test41() { 653 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); 654 } 655 656 @DontInline 657 @ForceCompile(compLevel = C1) 658 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) { 659 return a1 + a2 + fp.x + fp.y - dp.x - dp.y + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12; 660 } 661 662 @DontCompile 663 public void test41_verifier(boolean warmup) { 664 int count = warmup ? 1 : 2; 665 for (int i=0; i<count; i++) { // need a loop to test inline cache 666 double result = test41(); 667 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); 668 Asserts.assertEQ(result, n); 669 } 670 } 671 672 // C2->C1 invokestatic, circular dependency (between rdi and first stack slot on x64) 673 @Test(compLevel = C2) 674 public float test42() { 675 return test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); 676 } 677 678 @DontInline 679 @ForceCompile(compLevel = C1) 680 private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi 681 Point p2, // (rsi, rdx) -> rdx 682 int i3, // rcx -> rcx 683 int i4, // r8 -> r8 684 int i5, // r9 -> r9 685 FloatPoint fp6, // (stk[0], stk[1]) -> rdi ** circ depend 686 int i7) // rdi -> stk[0] ** circ depend 687 { 688 return ep1.f1 + ep1.f2 + ep1.f3 + ep1.f4 + ep1.f5 + ep1.f6 + ep1.f7 + ep1.f8 + 689 p2.x + p2.y + i3 + i4 + i5 + fp6.x + fp6.y + i7; 690 } 691 692 @DontCompile 693 public void test42_verifier(boolean warmup) { 694 int count = warmup ? 1 : 2; 695 for (int i=0; i<count; i++) { // need a loop to test inline cache 696 float result = test42(); 697 float n = test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); 698 Asserts.assertEQ(result, n); 699 } 700 } 701 702 // C2->C1 invokestatic, packing causes stack growth (1 extra stack word) 703 @Test(compLevel = C2) 704 public float test43() { 705 return test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); 706 } 707 708 @DontInline 709 @ForceCompile(compLevel = C1) 710 private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 711 // On x64: 712 // Scalarized entry -- all parameters are passed in registers 713 // Non-scalarized entry -- a6 is passed on stack[0] 714 return fp.x + fp.y + a1 + a2 + a3 + a4 + a5 + a6; 715 } 716 717 @DontCompile 718 public void test43_verifier(boolean warmup) { 719 int count = warmup ? 1 : 2; 720 for (int i=0; i<count; i++) { // need a loop to test inline cache 721 float result = test43(); 722 float n = test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); 723 Asserts.assertEQ(result, n); 724 } 725 } 726 727 // C2->C1 invokestatic, packing causes stack growth (2 extra stack words) 728 @Test(compLevel = C2) 729 public float test44() { 730 return test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); 731 } 732 733 @DontInline 734 @ForceCompile(compLevel = C1) 735 private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a2, int a3, int a4, int a5, int a6) { 736 // On x64: 737 // Scalarized entry -- all parameters are passed in registers 738 // Non-scalarized entry -- a5 is passed on stack[0] 739 // Non-scalarized entry -- a6 is passed on stack[1] 740 return fp1.x + fp1.y + 741 fp2.x + fp2.y + 742 a1 + a2 + a3 + a4 + a5 + a6; 743 } 744 745 @DontCompile 746 public void test44_verifier(boolean warmup) { 747 int count = warmup ? 1 : 2; 748 for (int i=0; i<count; i++) { // need a loop to test inline cache 749 float result = test44(); 750 float n = test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); 751 Asserts.assertEQ(result, n); 752 } 753 } 754 755 // C2->C1 invokestatic, packing causes stack growth (5 extra stack words) 756 @Test(compLevel = C2) 757 public float test45() { 758 return test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 759 } 760 761 @DontInline 762 @ForceCompile(compLevel = C1) 763 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) { 764 return fp1.x + fp1.y + 765 fp2.x + fp2.y + 766 fp3.x + fp3.y + 767 fp4.x + fp4.y + 768 fp5.x + fp5.y + 769 a1 + a2 + a3 + a4 + a5 + a6 + a7; 770 } 771 772 @DontCompile 773 public void test45_verifier(boolean warmup) { 774 int count = warmup ? 1 : 2; 775 for (int i=0; i<count; i++) { // need a loop to test inline cache 776 float result = test45(); 777 float n = test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 778 Asserts.assertEQ(result, n); 779 } 780 } 781 782 // C2->C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint) 783 @Test(compLevel = C2) 784 public float test46() { 785 return test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 786 } 787 788 @DontInline 789 @ForceCompile(compLevel = C1) 790 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) { 791 return p1.x + p1.y + 792 p2.x + p2.y + 793 fp1.x + fp1.y + 794 fp2.x + fp2.y + 795 fp3.x + fp3.y + 796 fp4.x + fp4.y + 797 fp5.x + fp5.y + 798 a1 + a2 + a3 + a4 + a5 + a6 + a7; 799 } 800 801 @DontCompile 802 public void test46_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 float result = test46(); 806 float n = test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 807 Asserts.assertEQ(result, n); 808 } 809 } 810 811 static class MyRuntimeException extends RuntimeException { 812 MyRuntimeException(String s) { 813 super(s); 814 } 815 } 816 817 static void checkStackTrace(Throwable t, String... methodNames) { 818 StackTraceElement[] trace = t.getStackTrace(); 819 for (int i=0; i<methodNames.length; i++) { 820 if (!methodNames[i].equals(trace[i].getMethodName())) { 821 String error = "Unexpected stack trace: level " + i + " should be " + methodNames[i]; 822 System.out.println(error); 823 t.printStackTrace(System.out); 824 throw new RuntimeException(error, t); 825 } 826 } 827 } 828 //* 829 830 // C2->C1 invokestatic, make sure stack walking works (with static variable) 831 @Test(compLevel = C2) 832 public void test47(int n) { 833 try { 834 test47_helper(floatPointField, 1, 2, 3, 4, 5); 835 test47_value = 666; 836 } catch (MyRuntimeException e) { 837 // expected; 838 } 839 test47_value = n; 840 } 841 842 @DontInline 843 @ForceCompile(compLevel = C1) 844 private static float test47_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { 845 test47_thrower(); 846 return 0.0f; 847 } 848 849 @DontInline @DontCompile 850 private static void test47_thrower() { 851 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 852 checkStackTrace(e, "test47_thrower", "test47_helper", "test47", "test47_verifier"); 853 throw e; 854 } 855 856 static int test47_value = 999; 857 858 @DontCompile 859 public void test47_verifier(boolean warmup) { 860 int count = warmup ? 1 : 5; 861 for (int i=0; i<count; i++) { // need a loop to test inline cache 862 test47_value = 777 + i; 863 test47(i); 864 Asserts.assertEQ(test47_value, i); 865 } 866 } 867 868 // C2->C1 invokestatic, make sure stack walking works (with returned value) 869 @Test(compLevel = C2) 870 public int test48(int n) { 871 try { 872 test48_helper(floatPointField, 1, 2, 3, 4, 5); 873 return 666; 874 } catch (MyRuntimeException e) { 875 // expected; 876 } 877 return n; 878 } 879 880 @DontInline 881 @ForceCompile(compLevel = C1) 882 private static float test48_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { 883 test48_thrower(); 884 return 0.0f; 885 } 886 887 @DontInline @DontCompile 888 private static void test48_thrower() { 889 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 890 checkStackTrace(e, "test48_thrower", "test48_helper", "test48", "test48_verifier"); 891 throw e; 892 } 893 894 @DontCompile 895 public void test48_verifier(boolean warmup) { 896 int count = warmup ? 1 : 5; 897 for (int i=0; i<count; i++) { // need a loop to test inline cache 898 int n = test48(i); 899 Asserts.assertEQ(n, i); 900 } 901 } 902 903 // C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) 904 // (this is the baseline for test50 -- 905 // the only difference is: test49_helper is interpreted but test50_helper is compiled by C1). 906 @Test(compLevel = C2) 907 public int test49(int n) { 908 try { 909 test49_helper(floatPointField, 1, 2, 3, 4, 5, 6); 910 return 666; 911 } catch (MyRuntimeException e) { 912 // expected; 913 } 914 return n; 915 } 916 917 @DontInline @DontCompile 918 private static float test49_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 919 test49_thrower(); 920 return 0.0f; 921 } 922 923 @DontInline @DontCompile 924 private static void test49_thrower() { 925 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 926 checkStackTrace(e, "test49_thrower", "test49_helper", "test49", "test49_verifier"); 927 throw e; 928 } 929 930 @DontCompile 931 public void test49_verifier(boolean warmup) { 932 int count = warmup ? 1 : 5; 933 for (int i=0; i<count; i++) { // need a loop to test inline cache 934 int n = test49(i); 935 Asserts.assertEQ(n, i); 936 } 937 } 938 939 // C2->C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) 940 @Test(compLevel = C2) 941 public int test50(int n) { 942 try { 943 test50_helper(floatPointField, 1, 2, 3, 4, 5, 6); 944 return 666; 945 } catch (MyRuntimeException e) { 946 // expected; 947 } 948 return n; 949 } 950 951 @DontInline 952 @ForceCompile(compLevel = C1) 953 private static float test50_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 954 test50_thrower(); 955 return 0.0f; 956 } 957 958 @DontInline @DontCompile 959 private static void test50_thrower() { 960 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 961 checkStackTrace(e, "test50_thrower", "test50_helper", "test50", "test50_verifier"); 962 throw e; 963 } 964 965 @DontCompile 966 public void test50_verifier(boolean warmup) { 967 int count = warmup ? 1 : 5; 968 for (int i=0; i<count; i++) { // need a loop to test inline cache 969 int n = test50(i); 970 Asserts.assertEQ(n, i); 971 } 972 } 973 974 975 // C2->C1 invokestatic, inline class with ref fields (RefPoint) 976 @Test(compLevel = C2) 977 public int test51() { 978 return test51_helper(refPointField1); 979 } 980 981 @DontInline 982 @ForceCompile(compLevel = C1) 983 private static int test51_helper(RefPoint rp1) { 984 return rp1.x.n + rp1.y.n; 985 } 986 987 @DontCompile 988 public void test51_verifier(boolean warmup) { 989 int count = warmup ? 1 : 5; 990 for (int i=0; i<count; i++) { // need a loop to test inline cache 991 int result = test51(); 992 int n = test51_helper(refPointField1); 993 Asserts.assertEQ(result, n); 994 } 995 } 996 997 // C2->C1 invokestatic, inline class with ref fields (Point, RefPoint) 998 @Test(compLevel = C2) 999 public int test52() { 1000 return test52_helper(pointField, refPointField1); 1001 } 1002 1003 @DontInline 1004 @ForceCompile(compLevel = C1) 1005 private static int test52_helper(Point p1, RefPoint rp1) { 1006 return p1.x + p1.y + rp1.x.n + rp1.y.n; 1007 } 1008 1009 @DontCompile 1010 public void test52_verifier(boolean warmup) { 1011 int count = warmup ? 1 : 5; 1012 for (int i=0; i<count; i++) { // need a loop to test inline cache 1013 int result = test52(); 1014 int n = test52_helper(pointField, refPointField1); 1015 Asserts.assertEQ(result, n); 1016 } 1017 } 1018 1019 // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint) 1020 @Test(compLevel = C2) 1021 public int test53() { 1022 return test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); 1023 } 1024 1025 @DontInline 1026 @ForceCompile(compLevel = C1) 1027 private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPoint rp4) { 1028 return rp1.x.n + rp1.y.n + 1029 rp2.x.n + rp2.y.n + 1030 rp3.x.n + rp3.y.n + 1031 rp4.x.n + rp4.y.n; 1032 } 1033 1034 @DontCompile 1035 public void test53_verifier(boolean warmup) { 1036 int count = warmup ? 1 : 5; 1037 for (int i=0; i<count; i++) { // need a loop to test inline cache 1038 int result = test53(); 1039 int n = test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); 1040 Asserts.assertEQ(result, n); 1041 } 1042 } 1043 1044 // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint) 1045 @Test(compLevel = C2) 1046 public int test54() { 1047 return test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); 1048 } 1049 1050 @DontInline 1051 @ForceCompile(compLevel = C1) 1052 private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, RefPoint rp3, RefPoint rp4) { 1053 return rp1.x.n + rp1.y.n + 1054 rp2.x.n + rp2.y.n + 1055 (int)(f) + i + 1056 rp3.x.n + rp3.y.n + 1057 rp4.x.n + rp4.y.n; 1058 } 1059 1060 @DontCompile 1061 public void test54_verifier(boolean warmup) { 1062 int count = warmup ? 1 : 5; 1063 for (int i=0; i<count; i++) { // need a loop to test inline cache 1064 int result = test54(); 1065 int n = test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); 1066 Asserts.assertEQ(result, n); 1067 } 1068 } 1069 }