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 }