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