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"
  34  * @requires vm.compMode != "Xcomp"
  35  * @compile TestCallingConventionC1.java
  36  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  37  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  38  *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla
  39  *                               compiler.valhalla.valuetypes.ValueTypeTest
  40  *                               compiler.valhalla.valuetypes.TestCallingConventionC1
  41  */
  42 public class TestCallingConventionC1 extends ValueTypeTest {
  43     public static final int C1 = COMP_LEVEL_SIMPLE;
  44     public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION;
  45 
  46     @Override
  47     public int getNumScenarios() {
  48         return 2;
  49     }
  50 
  51     @Override
  52     public String[] getVMParameters(int scenario) {
  53         switch (scenario) {
  54 
  55         // Default: both C1 and C2 are enabled, tierd compilation enabled
  56         case 0: return new String[] {"-XX:+EnableValhallaC1", "-XX:CICompilerCount=2"
  57                                    //  , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test78*"
  58                                    //, "-XX:CompileCommand=print,*::func_c1"
  59                                      };
  60         // Only C1. Tierd compilation disabled.
  61         case 1: return new String[] {"-XX:+EnableValhallaC1", "-XX:TieredStopAtLevel=1"
  62                                    //  , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test76*"
  63                                      };
  64         }
  65         return null;
  66     }
  67 
  68     public static void main(String[] args) throws Throwable {
  69         System.gc(); // Resolve this call, to avoid C1 code patching in the test cases.
  70         TestCallingConventionC1 test = new TestCallingConventionC1();
  71         test.run(args,
  72                  Point.class,
  73                  Functor.class,
  74                  Functor1.class,
  75                  Functor2.class,
  76                  Functor3.class,
  77                  Functor4.class,
  78                  MyImplPojo0.class,
  79                  MyImplPojo1.class,
  80                  MyImplPojo2.class,
  81                  MyImplVal1.class,
  82                  MyImplVal2.class,
  83                  FixedPoints.class,
  84                  FloatPoint.class,
  85                  RefPoint.class);
  86     }
  87 
  88     static inline class Point {
  89         final int x;
  90         final int y;
  91         public Point(int x, int y) {
  92             this.x = x;
  93             this.y = y;
  94         }
  95 
  96         @DontCompile
  97         @DontInline
  98         public int func() {
  99             return x + y;
 100         }
 101 
 102         @ForceCompile(compLevel = C1)
 103         @DontInline
 104         public int func_c1(Point p) {
 105             return x + y + p.x + p.y;
 106         }
 107     }
 108 
 109     static interface FunctorInterface {
 110         public int apply_interp(Point p);
 111     }
 112 
 113     static class Functor implements FunctorInterface {
 114         @DontCompile
 115         @DontInline
 116         public int apply_interp(Point p) {
 117             return p.func() + 0;
 118         }
 119     }
 120     static class Functor1 extends Functor {
 121         @DontCompile
 122         @DontInline
 123         public int apply_interp(Point p) {
 124             return p.func() + 10000;
 125         }
 126     }
 127     static class Functor2 extends Functor {
 128         @DontCompile
 129         @DontInline
 130         public int apply_interp(Point p) {
 131             return p.func() + 20000;
 132         }
 133     }
 134     static class Functor3 extends Functor {
 135         @DontCompile
 136         @DontInline
 137         public int apply_interp(Point p) {
 138             return p.func() + 30000;
 139         }
 140     }
 141     static class Functor4 extends Functor {
 142         @DontCompile
 143         @DontInline
 144         public int apply_interp(Point p) {
 145             return p.func() + 40000;
 146         }
 147     }
 148 
 149     static Functor functors[] = {
 150         new Functor(),
 151         new Functor1(),
 152         new Functor2(),
 153         new Functor3(),
 154         new Functor4()
 155     };
 156     static int functorCounter = 0;
 157     static Functor getFunctor() {
 158         int n = (++ functorCounter) % functors.length;
 159         return functors[n];
 160     }
 161 
 162     static Point pointField  = new Point(123, 456);
 163     static Point pointField1 = new Point(1123, 1456);
 164     static Point pointField2 = new Point(2123, 2456);
 165 
 166     static interface Intf {
 167         public int func1(int a, int b);
 168         public int func2(int a, int b, Point p);
 169     }
 170 
 171     static class MyImplPojo0 implements Intf {
 172         int field = 0;
 173         @DontInline @DontCompile
 174         public int func1(int a, int b)             { return field + a + b + 1; }
 175         @DontInline @DontCompile
 176         public int func2(int a, int b, Point p)     { return field + a + b + p.x + p.y + 1; }
 177     }
 178 
 179     static class MyImplPojo1 implements Intf {
 180         int field = 1000;
 181 
 182         @DontInline @ForceCompile(compLevel = C1)
 183         public int func1(int a, int b)             { return field + a + b + 20; }
 184         @DontInline @ForceCompile(compLevel = C1)
 185         public int func2(int a, int b, Point p)    { return field + a + b + p.x + p.y + 20; }
 186     }
 187 
 188     static class MyImplPojo2 implements Intf {
 189         int field = 2000;
 190 
 191         @DontInline @ForceCompile(compLevel = C2)
 192         public int func1(int a, int b)             { return field + a + b + 20; }
 193         @DontInline @ForceCompile(compLevel = C2)
 194         public int func2(int a, int b, Point p)    { return field + a + b + p.x + p.y + 20; }
 195     }
 196 
 197     static inline class MyImplVal1 implements Intf {
 198         final int field;
 199         MyImplVal1() {
 200             field = 11000;
 201         }
 202 
 203         @DontInline @ForceCompile(compLevel = C1)
 204         public int func1(int a, int b)             { return field + a + b + 300; }
 205 
 206         @DontInline @ForceCompile(compLevel = C1)
 207         public int func2(int a, int b, Point p)    { return field + a + b + p.x + p.y + 300; }
 208     }
 209 
 210     static inline class MyImplVal2 implements Intf {
 211         final int field;
 212         MyImplVal2() {
 213             field = 12000;
 214         }
 215 
 216         @DontInline @ForceCompile(compLevel = C2)
 217         public int func1(int a, int b)             { return field + a + b + 300; }
 218 
 219         @DontInline @ForceCompile(compLevel = C2)
 220         public int func2(int a, int b, Point p)    { return field + a + b + p.x + p.y + 300; }
 221     }
 222 
 223     static Intf intfs[] = {
 224         new MyImplPojo0(), // methods not compiled
 225         new MyImplPojo1(), // methods compiled by C1
 226         new MyImplPojo2(), // methods compiled by C2
 227         new MyImplVal1(),  // methods compiled by C1
 228         new MyImplVal2()   // methods compiled by C2
 229     };
 230     static Intf getIntf(int i) {
 231         int n = i % intfs.length;
 232         return intfs[n];
 233     }
 234 
 235     static inline class FixedPoints {
 236         final boolean Z0 = false;
 237         final boolean Z1 = true;
 238         final byte    B  = (byte)2;
 239         final char    C  = (char)34;
 240         final short   S  = (short)456;
 241         final int     I  = 5678;
 242         final long    J  = 0x1234567800abcdefL;
 243     }
 244     static FixedPoints fixedPointsField = new FixedPoints();
 245 
 246     static inline class FloatPoint {
 247         final float x;
 248         final float y;
 249         public FloatPoint(float x, float y) {
 250             this.x = x;
 251             this.y = y;
 252         }
 253     }
 254     static inline class DoublePoint {
 255         final double x;
 256         final double y;
 257         public DoublePoint(double x, double y) {
 258             this.x = x;
 259             this.y = y;
 260         }
 261     }
 262     static FloatPoint floatPointField = new FloatPoint(123.456f, 789.012f);
 263     static DoublePoint doublePointField = new DoublePoint(123.456, 789.012);
 264 
 265     static inline class EightFloats {
 266         float f1, f2, f3, f4, f5, f6, f7, f8;
 267         public EightFloats() {
 268             f1 = 1.1f;
 269             f2 = 2.2f;
 270             f3 = 3.3f;
 271             f4 = 4.4f;
 272             f5 = 5.5f;
 273             f6 = 6.6f;
 274             f7 = 7.7f;
 275             f8 = 8.8f;
 276         }
 277     }
 278     static EightFloats eightFloatsField = new EightFloats();
 279 
 280     static class Number {
 281         int n;
 282         Number(int v) {
 283             n = v;
 284         }
 285         void set(int v) {
 286             n = v;
 287         }
 288     }
 289 
 290     static interface RefPoint_Access {
 291         public int func1(RefPoint rp2);
 292         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2);
 293     }
 294 
 295     static inline class RefPoint implements RefPoint_Access {
 296         final Number x;
 297         final Number y;
 298         public RefPoint(int x, int y) {
 299             this.x = new Number(x);
 300             this.y = new Number(y);
 301         }
 302 
 303         @DontInline
 304         @ForceCompile(compLevel = C1)
 305         public final int final_func(RefPoint rp2) { // opt_virtual_call
 306             return this.x.n + this.y.n + rp2.x.n + rp2.y.n;
 307         }
 308 
 309         @DontInline
 310         @ForceCompile(compLevel = C1)
 311         public int func1(RefPoint rp2) {
 312             return this.x.n + this.y.n + rp2.x.n + rp2.y.n;
 313         }
 314 
 315         @DontInline
 316         @ForceCompile(compLevel = C1)
 317         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
 318             return x.n + y.n +
 319                    rp1.x.n + rp1.y.n +
 320                    rp2.x.n + rp2.y.n +
 321                    n1.n +
 322                    rp3.x.n + rp3.y.n +
 323                    rp4.x.n + rp4.y.n +
 324                    n2.n;
 325         }
 326     }
 327 
 328     static class RefPoint_Access_Impl1 implements RefPoint_Access {
 329         @DontInline @DontCompile
 330         public int func1(RefPoint rp2) {
 331             return rp2.x.n + rp2.y.n + 1111111;
 332         }
 333         @DontInline @DontCompile
 334         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
 335             return 111111 +
 336                    rp1.x.n + rp1.y.n +
 337                    rp2.x.n + rp2.y.n +
 338                    n1.n +
 339                    rp3.x.n + rp3.y.n +
 340                    rp4.x.n + rp4.y.n +
 341                    n2.n;
 342         }
 343     }
 344     static class RefPoint_Access_Impl2 implements RefPoint_Access {
 345         @DontInline @DontCompile
 346         public int func1(RefPoint rp2) {
 347             return rp2.x.n + rp2.y.n + 2222222;
 348         }
 349         @DontInline @DontCompile
 350         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
 351             return 222222 +
 352                    rp1.x.n + rp1.y.n +
 353                    rp2.x.n + rp2.y.n +
 354                    n1.n +
 355                    rp3.x.n + rp3.y.n +
 356                    rp4.x.n + rp4.y.n +
 357                    n2.n;
 358         }
 359     }
 360 
 361     static RefPoint_Access refPoint_Access_impls[] = {
 362         new RefPoint_Access_Impl1(),
 363         new RefPoint_Access_Impl2(),
 364         new RefPoint(0x12345, 0x6789a)
 365     };
 366 
 367     static int next_RefPoint_Access = 0;
 368     static RefPoint_Access get_RefPoint_Access() {
 369         int i = next_RefPoint_Access ++;
 370         return refPoint_Access_impls[i % refPoint_Access_impls.length];
 371     }
 372 
 373     static RefPoint refPointField1 = new RefPoint(12, 34);
 374     static RefPoint refPointField2 = new RefPoint(56789, 0x12345678);
 375 
 376     // This inline class has too many fields to fit in registers on x64 for
 377     // ValueTypeReturnedAsFields.
 378     static inline class TooBigToReturnAsFields {
 379         int a0 = 0;
 380         int a1 = 1;
 381         int a2 = 2;
 382         int a3 = 3;
 383         int a4 = 4;
 384         int a5 = 5;
 385         int a6 = 6;
 386         int a7 = 7;
 387         int a8 = 8;
 388         int a9 = 9;
 389     }
 390 
 391     static TooBigToReturnAsFields tooBig = new TooBigToReturnAsFields();
 392 
 393     //**********************************************************************
 394     // PART 1 - C1 calls interpreted code
 395     //**********************************************************************
 396 
 397 
 398     //** C1 passes value to interpreter (static)
 399     @Test(compLevel = C1)
 400     public int test1() {
 401         return test1_helper(pointField);
 402     }
 403 
 404     @DontInline
 405     @DontCompile
 406     private static int test1_helper(Point p) {
 407         return p.func();
 408     }
 409 
 410     @DontCompile
 411     public void test1_verifier(boolean warmup) {
 412         int count = warmup ? 1 : 10;
 413         for (int i=0; i<count; i++) { // need a loop to test inline cache
 414             int result = test1() + i;
 415             Asserts.assertEQ(result, pointField.func() + i);
 416         }
 417     }
 418 
 419 
 420     //** C1 passes value to interpreter (monomorphic)
 421     @Test(compLevel = C1)
 422     public int test2() {
 423         return test2_helper(pointField);
 424     }
 425 
 426     @DontInline
 427     @DontCompile
 428     private int test2_helper(Point p) {
 429         return p.func();
 430     }
 431 
 432     @DontCompile
 433     public void test2_verifier(boolean warmup) {
 434         int count = warmup ? 1 : 10;
 435         for (int i=0; i<count; i++) { // need a loop to test inline cache
 436             int result = test2() + i;
 437             Asserts.assertEQ(result, pointField.func() + i);
 438         }
 439     }
 440 
 441     // C1 passes value to interpreter (megamorphic: vtable)
 442     @Test(compLevel = C1)
 443     public int test3(Functor functor) {
 444         return functor.apply_interp(pointField);
 445     }
 446 
 447     @DontCompile
 448     public void test3_verifier(boolean warmup) {
 449         int count = warmup ? 1 : 100;
 450         for (int i=0; i<count; i++) {  // need a loop to test inline cache and vtable indexing
 451             Functor functor = warmup ? functors[0] : getFunctor();
 452             int result = test3(functor) + i;
 453             Asserts.assertEQ(result, functor.apply_interp(pointField) + i);
 454         }
 455     }
 456 
 457     // Same as test3, but compiled with C2. Test the hastable of VtableStubs
 458     @Test(compLevel = C2)
 459     public int test3b(Functor functor) {
 460         return functor.apply_interp(pointField);
 461     }
 462 
 463     @DontCompile
 464     public void test3b_verifier(boolean warmup) {
 465         int count = warmup ? 1 : 100;
 466         for (int i=0; i<count; i++) {  // need a loop to test inline cache and vtable indexing
 467             Functor functor = warmup ? functors[0] : getFunctor();
 468             int result = test3b(functor) + i;
 469             Asserts.assertEQ(result, functor.apply_interp(pointField) + i);
 470         }
 471     }
 472 
 473     // C1 passes value to interpreter (megamorphic: itable)
 474     @Test(compLevel = C1)
 475     public int test4(FunctorInterface fi) {
 476         return fi.apply_interp(pointField);
 477     }
 478 
 479     @DontCompile
 480     public void test4_verifier(boolean warmup) {
 481         int count = warmup ? 1 : 100;
 482         for (int i=0; i<count; i++) {  // need a loop to test inline cache and itable indexing
 483             Functor functor = warmup ? functors[0] : getFunctor();
 484             int result = test4(functor) + i;
 485             Asserts.assertEQ(result, functor.apply_interp(pointField) + i);
 486         }
 487     }
 488 
 489     //**********************************************************************
 490     // PART 2 - interpreter calls C1
 491     //**********************************************************************
 492 
 493     // Interpreter passes value to C1 (static)
 494     @Test(compLevel = C1)
 495     static public int test20(Point p1, long l, Point p2) {
 496         return p1.x + p2.y;
 497     }
 498 
 499     @DontCompile
 500     public void test20_verifier(boolean warmup) {
 501         int result = test20(pointField1, 0, pointField2);
 502         int n = pointField1.x + pointField2.y;
 503         Asserts.assertEQ(result, n);
 504     }
 505 
 506     // Interpreter passes value to C1 (instance method in inline class)
 507     @Test
 508     public int test21(Point p) {
 509         return test21_helper(p);
 510     }
 511 
 512     @DontCompile
 513     @DontInline
 514     int test21_helper(Point p) {
 515         return p.func_c1(p);
 516     }
 517 
 518     @DontCompile
 519     public void test21_verifier(boolean warmup) {
 520         int result = test21(pointField);
 521         int n = 2 * (pointField.x + pointField.y);
 522         Asserts.assertEQ(result, n);
 523     }
 524 
 525 
 526     //**********************************************************************
 527     // PART 3 - C2 calls C1
 528     //**********************************************************************
 529 
 530     // C2->C1 invokestatic, single value arg
 531     @Test(compLevel = C2)
 532     public int test30() {
 533         return test30_helper(pointField);
 534     }
 535 
 536     @DontInline
 537     @ForceCompile(compLevel = C1)
 538     private static int test30_helper(Point p) {
 539         return p.x + p.y;
 540     }
 541 
 542     @DontCompile
 543     public void test30_verifier(boolean warmup) {
 544         int count = warmup ? 1 : 2;
 545         for (int i=0; i<count; i++) { // need a loop to test inline cache
 546             int result = test30();
 547             int n = pointField.x + pointField.y;
 548             Asserts.assertEQ(result, n);
 549         }
 550     }
 551 
 552     // C2->C1 invokestatic, two single value args
 553     @Test(compLevel = C2)
 554       public int test31() {
 555       return test31_helper(pointField1, pointField2);
 556     }
 557 
 558     @DontInline
 559     @ForceCompile(compLevel = C1)
 560       private static int test31_helper(Point p1, Point p2) {
 561         return p1.x + p2.y;
 562     }
 563 
 564     @DontCompile
 565     public void test31_verifier(boolean warmup) {
 566         int count = warmup ? 1 : 2;
 567         for (int i=0; i<count; i++) { // need a loop to test inline cache
 568             int result = test31();
 569             int n = pointField1.x + pointField2.y;
 570             Asserts.assertEQ(result, n);
 571         }
 572     }
 573 
 574     // C2->C1 invokestatic, two single value args and interleaving ints (all passed in registers on x64)
 575     @Test(compLevel = C2)
 576     public int test32() {
 577       return test32_helper(0, pointField1, 1, pointField2);
 578     }
 579 
 580     @DontInline
 581     @ForceCompile(compLevel = C1)
 582     private static int test32_helper(int x, Point p1, int y, Point p2) {
 583         return p1.x + p2.y + x + y;
 584     }
 585 
 586     @DontCompile
 587     public void test32_verifier(boolean warmup) {
 588         int count = warmup ? 1 : 2;
 589         for (int i=0; i<count; i++) { // need a loop to test inline cache
 590             int result = test32();
 591             int n = pointField1.x + pointField2.y + 0 + 1;
 592             Asserts.assertEQ(result, n);
 593         }
 594     }
 595 
 596     // C2->C1 invokeinterface -- no verified_ro_entry (no value args except for receiver)
 597     @Test(compLevel = C2)
 598     public int test33(Intf intf, int a, int b) {
 599         return intf.func1(a, b);
 600     }
 601 
 602     @DontCompile
 603     public void test33_verifier(boolean warmup) {
 604         int count = warmup ? 1 : 20;
 605         for (int i=0; i<count; i++) {
 606             Intf intf = warmup ? intfs[0] : getIntf(i+1);
 607             int result = test33(intf, 123, 456) + i;
 608             Asserts.assertEQ(result, intf.func1(123, 456) + i);
 609         }
 610     }
 611 
 612     // C2->C1 invokeinterface -- use verified_ro_entry (has value args other than receiver)
 613     @Test(compLevel = C2)
 614     public int test34(Intf intf, int a, int b) {
 615         return intf.func2(a, b, pointField);
 616     }
 617 
 618     @DontCompile
 619     public void test34_verifier(boolean warmup) {
 620       int count = warmup ? 1 : 20;
 621         for (int i=0; i<count; i++) {
 622             Intf intf = warmup ? intfs[0] : getIntf(i+1);
 623             int result = test34(intf, 123, 456) + i;
 624             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
 625         }
 626     }
 627 
 628     // C2->C1 invokestatic, Point.y is on stack (x64)
 629     @Test(compLevel = C2)
 630     public int test35() {
 631         return test35_helper(1, 2, 3, 4, 5, pointField);
 632     }
 633 
 634     @DontInline
 635     @ForceCompile(compLevel = C1)
 636     private static int test35_helper(int a1, int a2, int a3, int a4, int a5, Point p) {
 637         return a1 + a2 + a3 + a4 + a5 + p.x + p.y;
 638     }
 639 
 640     @DontCompile
 641     public void test35_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             int result = test35();
 645             int n = 1 + 2 + 3  + 4 + 5 + pointField.x + pointField.y;
 646             Asserts.assertEQ(result, n);
 647         }
 648     }
 649 
 650     // C2->C1 invokestatic, shuffling arguments that are passed on stack
 651     @Test(compLevel = C2)
 652     public int test36() {
 653         return test36_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8);
 654     }
 655 
 656     @DontInline
 657     @ForceCompile(compLevel = C1)
 658     private static int test36_helper(Point p, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
 659         return a6 + a8;
 660     }
 661 
 662     @DontCompile
 663     public void test36_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             int result = test36();
 667             int n = 6 + 8;
 668             Asserts.assertEQ(result, n);
 669         }
 670     }
 671 
 672     // C2->C1 invokestatic, shuffling long arguments
 673     @Test(compLevel = C2)
 674     public int test37() {
 675         return test37_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8);
 676     }
 677 
 678     @DontInline
 679     @ForceCompile(compLevel = C1)
 680     private static int test37_helper(Point p, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) {
 681         return (int)(a6 + a8);
 682     }
 683 
 684     @DontCompile
 685     public void test37_verifier(boolean warmup) {
 686         int count = warmup ? 1 : 2;
 687         for (int i=0; i<count; i++) { // need a loop to test inline cache
 688             int result = test37();
 689             int n = 6 + 8;
 690             Asserts.assertEQ(result, n);
 691         }
 692     }
 693 
 694     // C2->C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments
 695     @Test(compLevel = C2)
 696     public int test38() {
 697         return test38_helper(pointField, true, (byte)1, (char)2, (short)3, 4, 5, (byte)6, (short)7, 8);
 698     }
 699 
 700     @DontInline
 701     @ForceCompile(compLevel = C1)
 702     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) {
 703         if (a0) {
 704             return (int)(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8);
 705         } else {
 706             return -1;
 707         }
 708     }
 709 
 710     @DontCompile
 711     public void test38_verifier(boolean warmup) {
 712         int count = warmup ? 1 : 2;
 713         for (int i=0; i<count; i++) { // need a loop to test inline cache
 714             int result = test38();
 715             int n = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8;
 716             Asserts.assertEQ(result, n);
 717         }
 718     }
 719 
 720     // C2->C1 invokestatic, packing a value object with all types of fixed point primitive fields.
 721     @Test(compLevel = C2)
 722     public long test39() {
 723         return test39_helper(1, fixedPointsField, 2, fixedPointsField);
 724     }
 725 
 726     @DontInline
 727     @ForceCompile(compLevel = C1)
 728     private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2) {
 729         if (f1.Z0 == false && f1.Z1 == true && f2.Z0 == false && f2.Z1 == true) {
 730             return f1.B + f2.C + f1.S + f2.I + f1.J;
 731         } else {
 732             return -1;
 733         }
 734     }
 735 
 736     @DontCompile
 737     public void test39_verifier(boolean warmup) {
 738         int count = warmup ? 1 : 2;
 739         for (int i=0; i<count; i++) { // need a loop to test inline cache
 740             long result = test39();
 741             long n = test39_helper(1, fixedPointsField, 2, fixedPointsField);
 742             Asserts.assertEQ(result, n);
 743         }
 744     }
 745 
 746     // C2->C1 invokestatic, shuffling floating point args
 747     @Test(compLevel = C2)
 748     public double test40() {
 749         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);
 750     }
 751 
 752     @DontInline
 753     @ForceCompile(compLevel = C1)
 754     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) {
 755         return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + fp.x + fp.y - dp.x - dp.y;
 756     }
 757 
 758     @DontCompile
 759     public void test40_verifier(boolean warmup) {
 760         int count = warmup ? 1 : 2;
 761         for (int i=0; i<count; i++) { // need a loop to test inline cache
 762             double result = test40();
 763             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);
 764             Asserts.assertEQ(result, n);
 765         }
 766     }
 767 
 768     // C2->C1 invokestatic, mixing floats and ints
 769     @Test(compLevel = C2)
 770     public double test41() {
 771         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);
 772     }
 773 
 774     @DontInline
 775     @ForceCompile(compLevel = C1)
 776     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) {
 777       return a1 + a2  + fp.x + fp.y - dp.x - dp.y + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12;
 778     }
 779 
 780     @DontCompile
 781     public void test41_verifier(boolean warmup) {
 782         int count = warmup ? 1 : 2;
 783         for (int i=0; i<count; i++) { // need a loop to test inline cache
 784             double result = test41();
 785             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);
 786             Asserts.assertEQ(result, n);
 787         }
 788     }
 789 
 790     // C2->C1 invokestatic, circular dependency (between rdi and first stack slot on x64)
 791     @Test(compLevel = C2)
 792     public float test42() {
 793         return test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7);
 794     }
 795 
 796     @DontInline
 797     @ForceCompile(compLevel = C1)
 798     private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi
 799                                        Point p2,        // (rsi, rdx) -> rdx
 800                                        int i3,          // rcx -> rcx
 801                                        int i4,          // r8 -> r8
 802                                        int i5,          // r9 -> r9
 803                                        FloatPoint fp6,  // (stk[0], stk[1]) -> rdi   ** circ depend
 804                                        int i7)          // rdi -> stk[0]             ** circ depend
 805     {
 806         return ep1.f1 + ep1.f2 + ep1.f3 + ep1.f4 + ep1.f5 + ep1.f6 + ep1.f7 + ep1.f8 +
 807             p2.x + p2.y + i3 + i4 + i5 + fp6.x + fp6.y + i7;
 808     }
 809 
 810     @DontCompile
 811     public void test42_verifier(boolean warmup) {
 812         int count = warmup ? 1 : 2;
 813         for (int i=0; i<count; i++) { // need a loop to test inline cache
 814             float result = test42();
 815             float n = test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7);
 816             Asserts.assertEQ(result, n);
 817         }
 818     }
 819 
 820     // C2->C1 invokestatic, packing causes stack growth (1 extra stack word)
 821     @Test(compLevel = C2)
 822     public float test43() {
 823         return test43_helper(floatPointField, 1, 2, 3, 4, 5, 6);
 824     }
 825 
 826     @DontInline
 827     @ForceCompile(compLevel = C1)
 828     private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) {
 829         // On x64:
 830         //    Scalarized entry -- all parameters are passed in registers
 831         //    Non-scalarized entry -- a6 is passed on stack[0]
 832         return fp.x + fp.y + a1 + a2 + a3 + a4 + a5 + a6;
 833     }
 834 
 835     @DontCompile
 836     public void test43_verifier(boolean warmup) {
 837         int count = warmup ? 1 : 2;
 838         for (int i=0; i<count; i++) { // need a loop to test inline cache
 839             float result = test43();
 840             float n = test43_helper(floatPointField, 1, 2, 3, 4, 5, 6);
 841             Asserts.assertEQ(result, n);
 842         }
 843     }
 844 
 845     // C2->C1 invokestatic, packing causes stack growth (2 extra stack words)
 846     @Test(compLevel = C2)
 847     public float test44() {
 848       return test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6);
 849     }
 850 
 851     @DontInline
 852     @ForceCompile(compLevel = C1)
 853       private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a2, int a3, int a4, int a5, int a6) {
 854         // On x64:
 855         //    Scalarized entry -- all parameters are passed in registers
 856         //    Non-scalarized entry -- a5 is passed on stack[0]
 857         //    Non-scalarized entry -- a6 is passed on stack[1]
 858         return fp1.x + fp1.y +
 859                fp2.x + fp2.y +
 860                a1 + a2 + a3 + a4 + a5 + a6;
 861     }
 862 
 863     @DontCompile
 864     public void test44_verifier(boolean warmup) {
 865         int count = warmup ? 1 : 2;
 866         for (int i=0; i<count; i++) { // need a loop to test inline cache
 867             float result = test44();
 868             float n = test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6);
 869             Asserts.assertEQ(result, n);
 870         }
 871     }
 872 
 873     // C2->C1 invokestatic, packing causes stack growth (5 extra stack words)
 874     @Test(compLevel = C2)
 875     public float test45() {
 876       return test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 877     }
 878 
 879     @DontInline
 880     @ForceCompile(compLevel = C1)
 881     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) {
 882         return fp1.x + fp1.y +
 883                fp2.x + fp2.y +
 884                fp3.x + fp3.y +
 885                fp4.x + fp4.y +
 886                fp5.x + fp5.y +
 887                a1 + a2 + a3 + a4 + a5 + a6 + a7;
 888     }
 889 
 890     @DontCompile
 891     public void test45_verifier(boolean warmup) {
 892         int count = warmup ? 1 : 2;
 893         for (int i=0; i<count; i++) { // need a loop to test inline cache
 894             float result = test45();
 895             float n = test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 896             Asserts.assertEQ(result, n);
 897         }
 898     }
 899 
 900     // C2->C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint)
 901     @Test(compLevel = C2)
 902     public float test46() {
 903       return test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 904     }
 905 
 906     @DontInline
 907     @ForceCompile(compLevel = C1)
 908       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) {
 909         return p1.x + p1.y +
 910                p2.x + p2.y +
 911                fp1.x + fp1.y +
 912                fp2.x + fp2.y +
 913                fp3.x + fp3.y +
 914                fp4.x + fp4.y +
 915                fp5.x + fp5.y +
 916                a1 + a2 + a3 + a4 + a5 + a6 + a7;
 917     }
 918 
 919     @DontCompile
 920     public void test46_verifier(boolean warmup) {
 921         int count = warmup ? 1 : 2;
 922         for (int i=0; i<count; i++) { // need a loop to test inline cache
 923             float result = test46();
 924             float n = test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 925             Asserts.assertEQ(result, n);
 926         }
 927     }
 928 
 929     static class MyRuntimeException extends RuntimeException {
 930         MyRuntimeException(String s) {
 931             super(s);
 932         }
 933     }
 934 
 935     static void checkStackTrace(Throwable t, String... methodNames) {
 936         StackTraceElement[] trace = t.getStackTrace();
 937         for (int i=0; i<methodNames.length; i++) {
 938             if (!methodNames[i].equals(trace[i].getMethodName())) {
 939                 String error = "Unexpected stack trace: level " + i + " should be " + methodNames[i];
 940                 System.out.println(error);
 941                 t.printStackTrace(System.out);
 942                 throw new RuntimeException(error, t);
 943             }
 944         }
 945     }
 946     //*
 947 
 948     // C2->C1 invokestatic, make sure stack walking works (with static variable)
 949     @Test(compLevel = C2)
 950     public void test47(int n) {
 951         try {
 952             test47_helper(floatPointField, 1, 2, 3, 4, 5);
 953             test47_value = 666;
 954         } catch (MyRuntimeException e) {
 955             // expected;
 956         }
 957         test47_value = n;
 958     }
 959 
 960     @DontInline
 961     @ForceCompile(compLevel = C1)
 962     private static float test47_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) {
 963         test47_thrower();
 964         return 0.0f;
 965     }
 966 
 967     @DontInline @DontCompile
 968     private static void test47_thrower() {
 969         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
 970         checkStackTrace(e, "test47_thrower", "test47_helper", "test47", "test47_verifier");
 971         throw e;
 972     }
 973 
 974     static int test47_value = 999;
 975 
 976     @DontCompile
 977     public void test47_verifier(boolean warmup) {
 978         int count = warmup ? 1 : 5;
 979         for (int i=0; i<count; i++) { // need a loop to test inline cache
 980             test47_value = 777 + i;
 981             test47(i);
 982             Asserts.assertEQ(test47_value, i);
 983         }
 984     }
 985 
 986     // C2->C1 invokestatic, make sure stack walking works (with returned value)
 987     @Test(compLevel = C2)
 988     public int test48(int n) {
 989         try {
 990             test48_helper(floatPointField, 1, 2, 3, 4, 5);
 991             return 666;
 992         } catch (MyRuntimeException e) {
 993             // expected;
 994         }
 995         return n;
 996     }
 997 
 998     @DontInline
 999     @ForceCompile(compLevel = C1)
1000     private static float test48_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) {
1001         test48_thrower();
1002         return 0.0f;
1003     }
1004 
1005     @DontInline @DontCompile
1006     private static void test48_thrower() {
1007         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
1008         checkStackTrace(e, "test48_thrower", "test48_helper", "test48", "test48_verifier");
1009         throw e;
1010     }
1011 
1012     @DontCompile
1013     public void test48_verifier(boolean warmup) {
1014         int count = warmup ? 1 : 5;
1015         for (int i=0; i<count; i++) { // need a loop to test inline cache
1016             int n = test48(i);
1017             Asserts.assertEQ(n, i);
1018         }
1019     }
1020 
1021     // C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair)
1022     // (this is the baseline for test50 --
1023     // the only difference is: test49_helper is interpreted but test50_helper is compiled by C1).
1024     @Test(compLevel = C2)
1025     public int test49(int n) {
1026         try {
1027             test49_helper(floatPointField, 1, 2, 3, 4, 5, 6);
1028             return 666;
1029         } catch (MyRuntimeException e) {
1030             // expected;
1031         }
1032         return n;
1033     }
1034 
1035     @DontInline @DontCompile
1036     private static float test49_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) {
1037         test49_thrower();
1038         return 0.0f;
1039     }
1040 
1041     @DontInline @DontCompile
1042     private static void test49_thrower() {
1043         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
1044         checkStackTrace(e, "test49_thrower", "test49_helper", "test49", "test49_verifier");
1045         throw e;
1046     }
1047 
1048     @DontCompile
1049     public void test49_verifier(boolean warmup) {
1050         int count = warmup ? 1 : 5;
1051         for (int i=0; i<count; i++) { // need a loop to test inline cache
1052             int n = test49(i);
1053             Asserts.assertEQ(n, i);
1054         }
1055     }
1056 
1057     // C2->C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair)
1058     @Test(compLevel = C2)
1059     public int test50(int n) {
1060         try {
1061             test50_helper(floatPointField, 1, 2, 3, 4, 5, 6);
1062             return 666;
1063         } catch (MyRuntimeException e) {
1064             // expected;
1065         }
1066         return n;
1067     }
1068 
1069     @DontInline
1070     @ForceCompile(compLevel = C1)
1071     private static float test50_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) {
1072         test50_thrower();
1073         return 0.0f;
1074     }
1075 
1076     @DontInline @DontCompile
1077     private static void test50_thrower() {
1078         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
1079         checkStackTrace(e, "test50_thrower", "test50_helper", "test50", "test50_verifier");
1080         throw e;
1081     }
1082 
1083     @DontCompile
1084     public void test50_verifier(boolean warmup) {
1085         int count = warmup ? 1 : 5;
1086         for (int i=0; i<count; i++) { // need a loop to test inline cache
1087             int n = test50(i);
1088             Asserts.assertEQ(n, i);
1089         }
1090     }
1091 
1092 
1093     // C2->C1 invokestatic, inline class with ref fields (RefPoint)
1094     @Test(compLevel = C2)
1095     public int test51() {
1096         return test51_helper(refPointField1);
1097     }
1098 
1099     @DontInline
1100     @ForceCompile(compLevel = C1)
1101     private static int test51_helper(RefPoint rp1) {
1102         return rp1.x.n + rp1.y.n;
1103     }
1104 
1105     @DontCompile
1106     public void test51_verifier(boolean warmup) {
1107         int count = warmup ? 1 : 5;
1108         for (int i=0; i<count; i++) { // need a loop to test inline cache
1109             int result = test51();
1110             int n = test51_helper(refPointField1);
1111             Asserts.assertEQ(result, n);
1112         }
1113     }
1114 
1115     // C2->C1 invokestatic, inline class with ref fields (Point, RefPoint)
1116     @Test(compLevel = C2)
1117     public int test52() {
1118         return test52_helper(pointField, refPointField1);
1119     }
1120 
1121     @DontInline
1122     @ForceCompile(compLevel = C1)
1123     private static int test52_helper(Point p1, RefPoint rp1) {
1124         return p1.x + p1.y + rp1.x.n + rp1.y.n;
1125     }
1126 
1127     @DontCompile
1128     public void test52_verifier(boolean warmup) {
1129         int count = warmup ? 1 : 5;
1130         for (int i=0; i<count; i++) { // need a loop to test inline cache
1131             int result = test52();
1132             int n = test52_helper(pointField, refPointField1);
1133             Asserts.assertEQ(result, n);
1134         }
1135     }
1136 
1137     // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint)
1138     @Test(compLevel = C2)
1139     public int test53() {
1140         return test53_helper(refPointField1, refPointField2, refPointField1, refPointField2);
1141     }
1142 
1143     @DontInline
1144     @ForceCompile(compLevel = C1)
1145     private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPoint rp4) {
1146         return rp1.x.n + rp1.y.n +
1147                rp2.x.n + rp2.y.n +
1148                rp3.x.n + rp3.y.n +
1149                rp4.x.n + rp4.y.n;
1150     }
1151 
1152     @DontCompile
1153     public void test53_verifier(boolean warmup) {
1154         int count = warmup ? 1 : 5;
1155         for (int i=0; i<count; i++) { // need a loop to test inline cache
1156             int result = test53();
1157             int n = test53_helper(refPointField1, refPointField2, refPointField1, refPointField2);
1158             Asserts.assertEQ(result, n);
1159         }
1160     }
1161 
1162     // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint)
1163     @Test(compLevel = C2)
1164     public int test54() {
1165         return test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2);
1166     }
1167 
1168     @DontInline
1169     @ForceCompile(compLevel = C1)
1170     private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, RefPoint rp3, RefPoint rp4) {
1171         return rp1.x.n + rp1.y.n +
1172                rp2.x.n + rp2.y.n +
1173                (int)(f) + i +
1174                rp3.x.n + rp3.y.n +
1175                rp4.x.n + rp4.y.n;
1176     }
1177 
1178     @DontCompile
1179     public void test54_verifier(boolean warmup) {
1180         int count = warmup ? 1 : 5;
1181         for (int i=0; i<count; i++) { // need a loop to test inline cache
1182             int result = test54();
1183             int n = test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2);
1184             Asserts.assertEQ(result, n);
1185         }
1186     }
1187 
1188     static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
1189     static final String ScavengeALot = "ScavengeALot";
1190 
1191 
1192     /**
1193      * Each allocation with a "try" block like this will cause a GC
1194      *
1195      *       try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1196      *           result = test55(p1);
1197      *       }
1198      */
1199     static class ForceGCMarker implements java.io.Closeable {
1200         static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
1201 
1202         ForceGCMarker() {
1203             WHITE_BOX.setBooleanVMFlag(ScavengeALot, true);
1204         }
1205         public void close() {
1206             WHITE_BOX.setBooleanVMFlag(ScavengeALot, false);
1207         }
1208 
1209         static ForceGCMarker mark(boolean warmup) {
1210             return warmup ? null : new ForceGCMarker();
1211         }
1212     }
1213 
1214     // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (Point)
1215     @Test(compLevel = C2)
1216     public int test55(Point p1) {
1217         return test55_helper(p1);
1218     }
1219 
1220     @DontInline
1221     @ForceCompile(compLevel = C1)
1222     private static int test55_helper(Point p1) {
1223         return p1.x + p1.y;
1224     }
1225 
1226     @DontCompile
1227     public void test55_verifier(boolean warmup) {
1228         int count = warmup ? 1 : 5;
1229         for (int i=0; i<count; i++) { // need a loop to test inline cache
1230             Point p1 = new Point(1, 2);
1231             int result;
1232             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1233                 result = test55(p1);
1234             }
1235             int n = test55_helper(p1);
1236             Asserts.assertEQ(result, n);
1237         }
1238     }
1239 
1240     // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (RefPoint)
1241     @Test(compLevel = C2)
1242     public int test56(RefPoint rp1) {
1243         return test56_helper(rp1);
1244     }
1245 
1246     @DontInline
1247     @ForceCompile(compLevel = C1)
1248     private static int test56_helper(RefPoint rp1) {
1249         return rp1.x.n + rp1.y.n;
1250     }
1251 
1252     @DontCompile
1253     public void test56_verifier(boolean warmup) {
1254         int count = warmup ? 1 : 5;
1255         for (int i=0; i<count; i++) { // need a loop to test inline cache
1256             RefPoint rp1 = new RefPoint(1, 2);
1257             int result;
1258             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1259                 result = test56(rp1);
1260             }
1261             int n = test56_helper(rp1);
1262             Asserts.assertEQ(result, n);
1263         }
1264     }
1265 
1266     // C2->Interpreter (same as test56, but test c2i entry instead of C1)
1267     @Test(compLevel = C2)
1268     public int test57(RefPoint rp1) {
1269         return test57_helper(rp1);
1270     }
1271 
1272     @DontInline @DontCompile
1273     private static int test57_helper(RefPoint rp1) {
1274         return rp1.x.n + rp1.y.n;
1275     }
1276 
1277     @DontCompile
1278     public void test57_verifier(boolean warmup) {
1279         int count = warmup ? 1 : 5;
1280         for (int i=0; i<count; i++) { // need a loop to test inline cache
1281             RefPoint rp1 = new RefPoint(1, 2);
1282             int result;
1283             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1284                 result = test57(rp1);
1285             }
1286             int n = test57_helper(rp1);
1287             Asserts.assertEQ(result, n);
1288         }
1289     }
1290 
1291     // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (a bunch of RefPoints and Numbers);
1292     @Test(compLevel = C2)
1293     public int test58(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
1294         return test58_helper(rp1, rp2, n1, rp3, rp4, n2);
1295     }
1296 
1297     @DontInline
1298     @ForceCompile(compLevel = C1)
1299     private static int test58_helper(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
1300         return rp1.x.n + rp1.y.n +
1301                rp2.x.n + rp2.y.n +
1302                n1.n +
1303                rp3.x.n + rp3.y.n +
1304                rp4.x.n + rp4.y.n +
1305                n2.n;
1306     }
1307 
1308     @DontCompile
1309     public void test58_verifier(boolean warmup) {
1310         int count = warmup ? 1 : 5;
1311         for (int i=0; i<count; i++) { // need a loop to test inline cache
1312             RefPoint rp1 = new RefPoint(1, 2);
1313             RefPoint rp2 = refPointField1;
1314             RefPoint rp3 = new RefPoint(222, 777);
1315             RefPoint rp4 = refPointField2;
1316             Number n1 = new Number(5878);
1317             Number n2 = new Number(1234);
1318             int result;
1319             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1320                 result = test58(rp1, rp2, n1, rp3, rp4, n2);
1321             }
1322             int n = test58_helper(rp1, rp2, n1, rp3, rp4, n2);
1323             Asserts.assertEQ(result, n);
1324         }
1325     }
1326 
1327     // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed).
1328     @Test(compLevel = C2)
1329     public int test59(RefPoint rp1, boolean doGC) {
1330       return test59_helper(rp1, 11, 222, 3333, 4444, doGC);
1331     }
1332 
1333     @DontInline
1334     @ForceCompile(compLevel = C1)
1335     private static int test59_helper(RefPoint rp1, int a1, int a2, int a3, int a4, boolean doGC) {
1336         if (doGC) {
1337             System.gc();
1338         }
1339         return rp1.x.n + rp1.y.n + a1 + a2 + a3 + a4;
1340     }
1341 
1342     @DontCompile
1343     public void test59_verifier(boolean warmup) {
1344         int count = warmup ? 1 : 5;
1345         boolean doGC = !warmup;
1346         for (int i=0; i<count; i++) { // need a loop to test inline cache
1347             RefPoint rp1 = new RefPoint(1, 2);
1348             int result = test59(rp1, doGC);
1349             int n = test59_helper(rp1, 11, 222, 3333, 4444, doGC);
1350             Asserts.assertEQ(result, n);
1351         }
1352     }
1353 
1354     // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed).
1355     // same as test59, but the incoming (scalarized) oops are passed in both registers and stack.
1356     @Test(compLevel = C2)
1357     public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) {
1358         return test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC);
1359     }
1360 
1361     @DontInline
1362     @ForceCompile(compLevel = C1)
1363     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) {
1364         // On x64, C2 passes:   reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y ....
1365         //         C1 expects:  reg0=x1, reg1=x1, reg2=x2, reg3=rp1,   reg4=rp2,   reg5=a1    stack0=a2 ...
1366         // When GC happens, make sure it does not treat reg5 and stack0 as oops!
1367         if (doGC) {
1368             System.gc();
1369         }
1370         return x0 + x1 + x2 + rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + a1 + a2 + a3 + a4;
1371     }
1372 
1373     @DontCompile
1374     public void test60_verifier(boolean warmup) {
1375         int count = warmup ? 1 : 5;
1376         boolean doGC = !warmup;
1377         for (int i=0; i<count; i++) { // need a loop to test inline cache
1378             RefPoint rp1 = new RefPoint(1, 2);
1379             RefPoint rp2 = new RefPoint(33, 44);
1380             int result = test60(rp1, rp2, doGC);
1381             int n = test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC);
1382             Asserts.assertEQ(result, n);
1383         }
1384     }
1385 
1386     // C2->C1 invokeinterface via VVEP(RO)
1387     @Test(compLevel = C2)
1388     public int test61(RefPoint_Access rpa, RefPoint rp2) {
1389         return rpa.func1(rp2);
1390     }
1391 
1392     @DontCompile
1393     public void test61_verifier(boolean warmup) {
1394         int count = warmup ? 1 : 20;
1395         for (int i=0; i<count; i++) { // need a loop to test inline cache
1396             RefPoint_Access rpa = get_RefPoint_Access();
1397             RefPoint rp2 = refPointField2;
1398             int result = test61(rpa, rp2);
1399             int n = rpa.func1(rp2);
1400             Asserts.assertEQ(result, n);
1401         }
1402     }
1403 
1404     // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (RefPoint)
1405     @Test(compLevel = C2)
1406     public int test62(RefPoint_Access rpa, RefPoint rp2) {
1407         return rpa.func1(rp2);
1408     }
1409 
1410     @DontCompile
1411     public void test62_verifier(boolean warmup) {
1412         int count = warmup ? 1 : 20;
1413         for (int i=0; i<count; i++) { // need a loop to test inline cache
1414             RefPoint_Access rpa = get_RefPoint_Access();
1415             RefPoint rp2 = new RefPoint(111, 2222);
1416             int result;
1417             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1418                 result = test62(rpa, rp2);
1419             }
1420             int n = rpa.func1(rp2);
1421             Asserts.assertEQ(result, n);
1422         }
1423     }
1424 
1425     /* disabled due to bug JDK-8224944
1426 
1427 
1428     // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (a bunch of RefPoints and Numbers)
1429     @Test(compLevel = C2)
1430     public int test63(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
1431         return rpa.func2(rp1, rp2, n1, rp3, rp4, n2);
1432     }
1433 
1434     @DontCompile
1435     public void test63_verifier(boolean warmup) {
1436         int count = warmup ? 1 : 20;
1437         for (int i=0; i<count; i++) { // need a loop to test inline cache
1438             RefPoint_Access rpa = get_RefPoint_Access();
1439             RefPoint rp1 = new RefPoint(1, 2);
1440             RefPoint rp2 = refPointField1;
1441             RefPoint rp3 = new RefPoint(222, 777);
1442             RefPoint rp4 = refPointField2;
1443             Number n1 = new Number(5878);
1444             Number n2 = new Number(1234);
1445             int result;
1446             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1447                 result = test63(rpa, rp1, rp2, n1, rp3, rp4, n2);
1448             }
1449             int n = rpa.func2(rp1, rp2, n1, rp3, rp4, n2);
1450             Asserts.assertEQ(result, n);
1451         }
1452     }
1453     /**/
1454 
1455     // C2->C1 invokevirtual via VVEP(RO) (opt_virtual_call)
1456     @Test(compLevel = C2)
1457     public int test76(RefPoint rp1, RefPoint rp2) {
1458         return rp1.final_func(rp2);
1459     }
1460 
1461     @DontCompile
1462     public void test76_verifier(boolean warmup) {
1463         int count = warmup ? 1 : 5;
1464         for (int i=0; i<count; i++) { // need a loop to test inline cache
1465             RefPoint rp1 = refPointField1;
1466             RefPoint rp2 = refPointField2;
1467             int result = test76(rp1, rp2);
1468             int n = rp1.final_func(rp2);
1469             Asserts.assertEQ(result, n);
1470         }
1471     }
1472 
1473     // C2->C1 invokevirtual, force GC for every allocation when entering a C1 VEP (RefPoint)
1474     // Same as test56, except we call the VVEP(RO) instead of VEP.
1475     @Test(compLevel = C2)
1476     public int test77(RefPoint rp1, RefPoint rp2) {
1477         return rp1.final_func(rp2);
1478     }
1479 
1480     @DontCompile
1481     public void test77_verifier(boolean warmup) {
1482         int count = warmup ? 1 : 5;
1483         for (int i=0; i<count; i++) { // need a loop to test inline cache
1484             RefPoint rp1 = new RefPoint(1, 2);
1485             RefPoint rp2 = new RefPoint(22, 33);
1486             int result;
1487             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1488                 result = test77(rp1, rp2);
1489             }
1490             int n = rp1.final_func(rp2);
1491             Asserts.assertEQ(result, n);
1492         }
1493     }
1494 
1495     //-------------------------------------------------------------------------------
1496     // Tests for how C1 handles ValueTypeReturnedAsFields in both calls and returns
1497     //-------------------------------------------------------------------------------
1498     // C2->C1 invokestatic with ValueTypeReturnedAsFields (Point)
1499     @Test(compLevel = C2)
1500     public int test78(Point p) {
1501         Point np = test78_helper(p);
1502         return np.x + np.y;
1503     }
1504 
1505     @DontInline
1506     @ForceCompile(compLevel = C1)
1507     private static Point test78_helper(Point p) {
1508         return p;
1509     }
1510 
1511     @DontCompile
1512     public void test78_verifier(boolean warmup) {
1513         int result = test78(pointField1);
1514         int n = pointField1.x + pointField1.y;
1515         Asserts.assertEQ(result, n);
1516     }
1517 
1518     // C2->C1 invokestatic with ValueTypeReturnedAsFields (RefPoint)
1519     @Test(compLevel = C2)
1520     public int test79(RefPoint p) {
1521         RefPoint np = test79_helper(p);
1522         return np.x.n + np.y.n;
1523     }
1524 
1525     @DontInline
1526     @ForceCompile(compLevel = C1)
1527     private static RefPoint test79_helper(RefPoint p) {
1528         return p;
1529     }
1530 
1531     @DontCompile
1532     public void test79_verifier(boolean warmup) {
1533         int result = test79(refPointField1);
1534         int n = refPointField1.x.n + refPointField1.y.n;
1535         Asserts.assertEQ(result, n);
1536     }
1537 
1538     // C1->C2 invokestatic with ValueTypeReturnedAsFields (RefPoint)
1539     @Test(compLevel = C1)
1540     public int test80(RefPoint p) {
1541         RefPoint np = test80_helper(p);
1542         return np.x.n + np.y.n;
1543     }
1544 
1545     @DontInline
1546     @ForceCompile(compLevel = C2)
1547     private static RefPoint test80_helper(RefPoint p) {
1548         return p;
1549     }
1550 
1551     @DontCompile
1552     public void test80_verifier(boolean warmup) {
1553         int result = test80(refPointField1);
1554         int n = refPointField1.x.n + refPointField1.y.n;
1555         Asserts.assertEQ(result, n);
1556     }
1557 
1558     // Interpreter->C1 invokestatic with ValueTypeReturnedAsFields (Point)
1559     @Test(compLevel = C1)
1560     public Point test81(Point p) {
1561         return p;
1562     }
1563 
1564     @DontCompile
1565     public void test81_verifier(boolean warmup) {
1566         Point p = test81(pointField1);
1567         Asserts.assertEQ(p.x, pointField1.x);
1568         Asserts.assertEQ(p.y, pointField1.y);
1569         p = test81(pointField2);
1570         Asserts.assertEQ(p.x, pointField2.x);
1571         Asserts.assertEQ(p.y, pointField2.y);
1572     }
1573 
1574     // C1->Interpreter invokestatic with ValueTypeReturnedAsFields (RefPoint)
1575     @Test(compLevel = C1)
1576     public int test82(RefPoint p) {
1577         RefPoint np = test82_helper(p);
1578         return np.x.n + np.y.n;
1579     }
1580 
1581     @DontInline @DontCompile
1582     private static RefPoint test82_helper(RefPoint p) {
1583         return p;
1584     }
1585 
1586     @DontCompile
1587     public void test82_verifier(boolean warmup) {
1588         int result = test82(refPointField1);
1589         int n = refPointField1.x.n + refPointField1.y.n;
1590         Asserts.assertEQ(result, n);
1591     }
1592 
1593     //-------------------------------------------------------------------------------
1594     // Tests for ValueTypeReturnedAsFields vs the inline class TooBigToReturnAsFields
1595     //-------------------------------------------------------------------------------
1596 
1597     // C2->C1 invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields)
1598     @Test(compLevel = C2)
1599     public int test83(TooBigToReturnAsFields p) {
1600         TooBigToReturnAsFields np = test83_helper(p);
1601         return p.a0 + p.a5;
1602     }
1603 
1604     @DontInline
1605     @ForceCompile(compLevel = C1)
1606     private static TooBigToReturnAsFields test83_helper(TooBigToReturnAsFields p) {
1607         return p;
1608     }
1609 
1610     @DontCompile
1611     public void test83_verifier(boolean warmup) {
1612         int result = test83(tooBig);
1613         int n = tooBig.a0 + tooBig.a5;
1614         Asserts.assertEQ(result, n);
1615     }
1616 
1617     // C1->C2 invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields)
1618     @Test(compLevel = C1)
1619     public int test84(TooBigToReturnAsFields p) {
1620         TooBigToReturnAsFields np = test84_helper(p);
1621         return p.a0 + p.a5;
1622     }
1623 
1624     @DontInline
1625     @ForceCompile(compLevel = C2)
1626     private static TooBigToReturnAsFields test84_helper(TooBigToReturnAsFields p) {
1627         return p;
1628     }
1629 
1630     @DontCompile
1631     public void test84_verifier(boolean warmup) {
1632         int result = test84(tooBig);
1633         int n = tooBig.a0 + tooBig.a5;
1634         Asserts.assertEQ(result, n);
1635     }
1636 
1637     // Interpreter->C1 invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields)
1638     @Test(compLevel = C1)
1639     public TooBigToReturnAsFields test85(TooBigToReturnAsFields p) {
1640         return p;
1641     }
1642 
1643     @DontCompile
1644     public void test85_verifier(boolean warmup) {
1645         TooBigToReturnAsFields p = test85(tooBig);
1646         Asserts.assertEQ(p.a0, tooBig.a0);
1647         Asserts.assertEQ(p.a2, tooBig.a2);
1648     }
1649 
1650     // C1->Interpreter invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields)
1651     @Test(compLevel = C1)
1652     public int test86(TooBigToReturnAsFields p) {
1653         TooBigToReturnAsFields np = test86_helper(p);
1654         return p.a0 + p.a5;
1655     }
1656 
1657     @DontInline @DontCompile
1658     private static TooBigToReturnAsFields test86_helper(TooBigToReturnAsFields p) {
1659         return p;
1660     }
1661 
1662     @DontCompile
1663     public void test86_verifier(boolean warmup) {
1664         int result = test86(tooBig);
1665         int n = tooBig.a0 + tooBig.a5;
1666         Asserts.assertEQ(result, n);
1667     }
1668 
1669     //-------------------------------------------------------------------------------
1670     // Tests for how C1 handles ValueTypeReturnedAsFields in both calls and returns (RefPoint?)
1671     //-------------------------------------------------------------------------------
1672 
1673     // C2->C1 invokestatic with ValueTypeReturnedAsFields (RefPoint?)
1674     @Test(compLevel = C2)
1675     public RefPoint? test87(RefPoint? p) {
1676         return test87_helper(p);
1677     }
1678 
1679     @DontInline
1680     @ForceCompile(compLevel = C1)
1681     private static RefPoint? test87_helper(RefPoint? p) {
1682         return p;
1683     }
1684 
1685     @DontCompile
1686     public void test87_verifier(boolean warmup) {
1687         Object result = test87(null);
1688         Asserts.assertEQ(result, null);
1689     }
1690 
1691     // C2->C1 invokestatic with ValueTypeReturnedAsFields (RefPoint? with constant null)
1692     @Test(compLevel = C2)
1693     public RefPoint? test88() {
1694         return test88_helper();
1695     }
1696 
1697     @DontInline
1698     @ForceCompile(compLevel = C1)
1699     private static RefPoint? test88_helper() {
1700         return null;
1701     }
1702 
1703     @DontCompile
1704     public void test88_verifier(boolean warmup) {
1705         Object result = test88();
1706         Asserts.assertEQ(result, null);
1707     }
1708 
1709     // C1->C2 invokestatic with ValueTypeReturnedAsFields (RefPoint?)
1710     @Test(compLevel = C1)
1711     public RefPoint? test89(RefPoint? p) {
1712         return test89_helper(p);
1713     }
1714 
1715     @DontInline
1716     @ForceCompile(compLevel = C2)
1717     private static RefPoint? test89_helper(RefPoint? p) {
1718         return p;
1719     }
1720 
1721     @DontCompile
1722     public void test89_verifier(boolean warmup) {
1723         Object result = test89(null);
1724         Asserts.assertEQ(result, null);
1725     }
1726 
1727     //----------------------------------------------------------------------------------
1728     // Tests for unverified entries: there are 6 cases:
1729     // C1 -> Unverified Value Entry compiled by C1
1730     // C1 -> Unverified Value Entry compiled by C2
1731     // C2 -> Unverified Entry compiled by C1 (target is NOT a value type)
1732     // C2 -> Unverified Entry compiled by C2 (target is NOT a value type)
1733     // C2 -> Unverified Entry compiled by C1 (target IS a value type, i.e., has VVEP_RO)
1734     // C2 -> Unverified Entry compiled by C2 (target IS a value type, i.e., has VVEP_RO)
1735     //----------------------------------------------------------------------------------
1736 
1737     // C1->C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by C1)
1738     @Test(compLevel = C1)
1739     public int test90(Intf intf, int a, int b) {
1740         return intf.func2(a, b, pointField);
1741     }
1742 
1743     static Intf test90_intfs[] = {
1744         new MyImplPojo1(),
1745         new MyImplPojo2(),
1746     };
1747 
1748     @DontCompile
1749     public void test90_verifier(boolean warmup) {
1750         int count = warmup ? 1 : 20;
1751         for (int i=0; i<count; i++) {
1752             Intf intf = test90_intfs[i % test90_intfs.length];
1753             int result = test90(intf, 123, 456) + i;
1754             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
1755         }
1756     }
1757 
1758     // C1->C2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by C2)
1759     @Test(compLevel = C1)
1760     public int test91(Intf intf, int a, int b) {
1761         return intf.func2(a, b, pointField);
1762     }
1763 
1764     static Intf test91_intfs[] = {
1765         new MyImplPojo2(),
1766         new MyImplPojo1(),
1767     };
1768 
1769     @DontCompile
1770     public void test91_verifier(boolean warmup) {
1771         int count = warmup ? 1 : 20;
1772         for (int i=0; i<count; i++) {
1773             Intf intf = test91_intfs[i % test91_intfs.length];
1774             int result = test91(intf, 123, 456) + i;
1775             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
1776         }
1777     }
1778 
1779     // C2->C1 invokeinterface -- call Unverified Entry of MyImplPojo1.func2 (compiled by C1)
1780     @Test(compLevel = C2)
1781     public int test92(Intf intf, int a, int b) {
1782         return intf.func2(a, b, pointField);
1783     }
1784 
1785     static Intf test92_intfs[] = {
1786         new MyImplPojo1(),
1787         new MyImplPojo2(),
1788     };
1789 
1790     @DontCompile
1791     public void test92_verifier(boolean warmup) {
1792         int count = warmup ? 1 : 20;
1793         for (int i=0; i<count; i++) {
1794             Intf intf = test92_intfs[i % test92_intfs.length];
1795             int result = test92(intf, 123, 456) + i;
1796             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
1797         }
1798     }
1799 
1800     // C2->C2 invokeinterface -- call Unverified Entry of MyImplPojo2.func2 (compiled by C2)
1801     @Test(compLevel = C2)
1802     public int test93(Intf intf, int a, int b) {
1803         return intf.func2(a, b, pointField);
1804     }
1805 
1806     static Intf test93_intfs[] = {
1807         new MyImplPojo2(),
1808         new MyImplPojo1(),
1809     };
1810 
1811     @DontCompile
1812     public void test93_verifier(boolean warmup) {
1813         int count = warmup ? 1 : 20;
1814         for (int i=0; i<count; i++) {
1815             Intf intf = test93_intfs[i % test93_intfs.length];
1816             int result = test93(intf, 123, 456) + i;
1817             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
1818         }
1819     }
1820 
1821     // C2->C1 invokeinterface -- call Unverified Entry of MyImplVal1.func2 (compiled by C1 - has VVEP_RO)
1822     @Test(compLevel = C2)
1823     public int test94(Intf intf, int a, int b) {
1824         return intf.func2(a, b, pointField);
1825     }
1826 
1827     static Intf test94_intfs[] = {
1828         new MyImplVal1(),
1829         new MyImplVal2(),
1830     };
1831 
1832     @DontCompile
1833     public void test94_verifier(boolean warmup) {
1834         int count = warmup ? 1 : 20;
1835         for (int i=0; i<count; i++) {
1836             Intf intf = test94_intfs[i % test94_intfs.length];
1837             int result = test94(intf, 123, 456) + i;
1838             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
1839         }
1840     }
1841 
1842     // C2->C2 invokeinterface -- call Unverified Entry of MyImplVal2.func2 (compiled by C2 - has VVEP_RO)
1843     @Test(compLevel = C2)
1844     public int test95(Intf intf, int a, int b) {
1845         return intf.func2(a, b, pointField);
1846     }
1847 
1848     static Intf test95_intfs[] = {
1849         new MyImplVal2(),
1850         new MyImplVal1(),
1851     };
1852 
1853     @DontCompile
1854     public void test95_verifier(boolean warmup) {
1855         int count = warmup ? 1 : 20;
1856         for (int i=0; i<count; i++) {
1857             Intf intf = test95_intfs[i % test95_intfs.length];
1858             int result = test95(intf, 123, 456) + i;
1859             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
1860         }
1861     }
1862 }