1 /*
   2  * Copyright (c) 2013, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * @test StableValueTest
  28  * @summary tests on stable fields and arrays
  29  * @library /testlibrary
  30  * @compile -XDignore.symbol.file StableValueTest.java
  31  * @run main ClassFileInstaller StableValueTest StableValueTest$BoolStable StableValueTest$ByteStable StableValueTest$CharStable
  32  *                              StableValueTest$DoubleStable StableValueTest$FloatStable StableValueTest$IntArrayArity1
  33  *                              StableValueTest$IntArrayArity2 StableValueTest$IntArrayArity3 StableValueTest$IntArrayArity4
  34  *                              StableValueTest$IntStable StableValueTest$LongStable StableValueTest$ObjectArrayArity0
  35  *                              StableValueTest$ObjectArrayArity1 StableValueTest$ObjectStable$Values StableValueTest$ObjectStable
  36  *                              StableValueTest$ShortStable StableValueTest$StaticBoolStable StableValueTest$StaticByteStable
  37  *                              StableValueTest$StaticCharStable StableValueTest$StaticDoubleStable StableValueTest$StaticFloatStable
  38  *                              StableValueTest$StaticIntStable StableValueTest$StaticLongStable StableValueTest$StaticShortStable
  39  *                              StableValueTest$VolatileBoolStable StableValueTest$VolatileByteStable StableValueTest$VolatileCharStable
  40  *                              StableValueTest$VolatileDoubleStable StableValueTest$VolatileFloatStable StableValueTest$VolatileIntStable
  41  *                              StableValueTest$VolatileLongStable StableValueTest$VolatileObjectStable$Values
  42  *                              StableValueTest$VolatileObjectStable StableValueTest$VolatileShortStable
  43  *                              StableValueTest$NestedStableField StableValueTest$NestedStableField$A
  44  *                              StableValueTest$NestedStableField1 StableValueTest$NestedStableField1$A
  45  *                              StableValueTest$NestedStableField2 StableValueTest$NestedStableField2$A
  46  *                              StableValueTest$NestedStableField3 StableValueTest$NestedStableField3$A
  47  *
  48  * @run main/othervm -Xbootclasspath/a:. -server -XX:-TieredCompilation -Xcomp -XX:+UnlockExperimentalVMOptions
  49  *                   -XX:+FoldStableValues -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 StableValueTest
  50  * @run main/othervm -Xbootclasspath/a:. -server -XX:-TieredCompilation -Xcomp -XX:+UnlockExperimentalVMOptions
  51  *                   -XX:-FoldStableValues -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 StableValueTest
  52  */
  53 import com.sun.management.HotSpotDiagnosticMXBean;
  54 import com.sun.management.VMOption;
  55 import sun.invoke.Stable;
  56 import sun.management.ManagementFactoryHelper;
  57 
  58 import java.lang.reflect.InvocationTargetException;
  59 
  60 public class StableValueTest {
  61     public static void main(String[] args) throws Exception {
  62         System.out.println("@Stable enabled: "+isStableEnabled);
  63         System.out.println();
  64 
  65         // @Stable primitive & raw Object fields
  66         run(ObjectStable.class);
  67         run(BoolStable.class);
  68         run(ByteStable.class);
  69         run(ShortStable.class);
  70         run(CharStable.class);
  71         run(IntStable.class);
  72         run(LongStable.class);
  73         run(FloatStable.class);
  74         run(DoubleStable.class);
  75 
  76         // @Stable primitive & raw Object static fields
  77         run(StaticBoolStable.class);
  78         run(StaticByteStable.class);
  79         run(StaticShortStable.class);
  80         run(StaticCharStable.class);
  81         run(StaticIntStable.class);
  82         run(StaticLongStable.class);
  83         run(StaticFloatStable.class);
  84         run(StaticDoubleStable.class);
  85 
  86         // @Stable primitive & raw Object volatile instance fields
  87         run(VolatileObjectStable.class);
  88         run(VolatileBoolStable.class);
  89         run(VolatileByteStable.class);
  90         run(VolatileShortStable.class);
  91         run(VolatileCharStable.class);
  92         run(VolatileIntStable.class);
  93         run(VolatileLongStable.class);
  94         run(VolatileFloatStable.class);
  95         run(VolatileDoubleStable.class);
  96 
  97         // @Stable arrays: arity 1-4
  98         run(IntArrayArity1.class);
  99         run(IntArrayArity2.class);
 100         run(IntArrayArity3.class);
 101         run(IntArrayArity4.class);
 102 
 103         // @Stable Object field: dynamic arrays
 104         run(ObjectArrayArity0.class);
 105         run(ObjectArrayArity1.class);
 106 
 107         // Nested @Stable fields
 108         run(NestedStableField.class);
 109         run(NestedStableField1.class);
 110         run(NestedStableField2.class);
 111         run(NestedStableField3.class);
 112 
 113         if (failed) {
 114             throw new Error("TEST FAILED");
 115         }
 116     }
 117 
 118     /* ==================================================== */
 119 
 120     static class ObjectStable {
 121         enum Values { A, B}
 122         public @Stable Values v;
 123 
 124         public static final ObjectStable c = new ObjectStable ();
 125         public static Values get() { return c.v; }
 126         public static void test() throws Exception {
 127             c.v = Values.A; Values val1 = get();
 128             c.v = Values.B; Values val2 = get();
 129             assertEquals(val1, Values.A);
 130             assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
 131         }
 132     }
 133 
 134     /* ==================================================== */
 135 
 136     static class BoolStable {
 137         public @Stable boolean v;
 138 
 139         public static final BoolStable c = new BoolStable();
 140         public static boolean get() { return c.v; }
 141         public static void test() throws Exception {
 142             c.v = true; boolean val1 = get();
 143             c.v = false; boolean val2 = get();
 144             assertEquals(val1, true);
 145             assertEquals(val2, (isStableEnabled ? true : false));
 146         }
 147     }
 148 
 149     /* ==================================================== */
 150 
 151     static class ByteStable {
 152         public @Stable byte v;
 153 
 154         public static final ByteStable c = new ByteStable();
 155         public static byte get() { return c.v; }
 156         public static void test() throws Exception {
 157             c.v = 5;   byte val1 = get();
 158             c.v = 127; byte val2 = get();
 159             assertEquals(val1, 5);
 160             assertEquals(val2, (isStableEnabled ? 5 : 127));
 161         }
 162     }
 163 
 164     /* ==================================================== */
 165 
 166     static class ShortStable {
 167         public @Stable short v;
 168 
 169         public static final ShortStable c = new ShortStable();
 170         public static short get() { return c.v; }
 171         public static void test() throws Exception {
 172             c.v = 1;     short val1 = get();
 173             c.v = 32767; short val2 = get();
 174             assertEquals(val1, 1);
 175             assertEquals(val2, (isStableEnabled ? 1 : 32767));
 176         }
 177     }
 178 
 179     /* ==================================================== */
 180 
 181     static class CharStable {
 182         public @Stable char v;
 183 
 184         public static final CharStable c = new CharStable();
 185         public static char get() { return c.v; }
 186         public static void test() throws Exception {
 187             c.v = 'a'; char val1 = get();
 188             c.v = 'b'; char val2 = get();
 189             assertEquals(val1, 'a');
 190             assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
 191         }
 192     }
 193 
 194     /* ==================================================== */
 195 
 196     static class IntStable {
 197         public @Stable int v;
 198 
 199         public static final IntStable c = new IntStable();
 200         public static int get() { return c.v; }
 201         public static void test() throws Exception {
 202             c.v = 1; int val1 = get();
 203             c.v = 2; int val2 = get();
 204             assertEquals(val1, 1);
 205             assertEquals(val2, (isStableEnabled ? 1 : 2));
 206         }
 207     }
 208 
 209     /* ==================================================== */
 210 
 211     static class FloatStable {
 212         public @Stable float v;
 213 
 214         public static final FloatStable c = new FloatStable();
 215         public static float get() { return c.v; }
 216         public static void test() throws Exception {
 217             c.v = 1.0F; float val1 = get();
 218             c.v = 2.0F; float val2 = get();
 219             assertEquals(val1, 1.0F);
 220             assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
 221         }
 222     }
 223 
 224     /* ==================================================== */
 225 
 226     static class LongStable {
 227         public @Stable long v;
 228 
 229         public static final LongStable c = new LongStable();
 230         public static long get() { return c.v; }
 231         public static void test() throws Exception {
 232             c.v = 5;              long val1 = get();
 233             c.v = Long.MAX_VALUE; long val2 = get();
 234             assertEquals(val1, 5);
 235             assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
 236         }
 237     }
 238 
 239     /* ==================================================== */
 240 
 241     static class DoubleStable {
 242         public @Stable double v;
 243 
 244         public static final DoubleStable c = new DoubleStable();
 245         public static double get() { return c.v; }
 246         public static void test() throws Exception {
 247             c.v = 1.0; double val1 = get();
 248             c.v = Double.MAX_VALUE; double val2 = get();
 249             assertEquals(val1, 1.0);
 250             assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
 251         }
 252     }
 253 
 254     /* ==================================================== */
 255 
 256     static class StaticBoolStable {
 257         public static @Stable boolean v;
 258 
 259         public static final StaticBoolStable c = new StaticBoolStable();
 260         public static boolean get() { return c.v; }
 261         public static void test() throws Exception {
 262             c.v = true; boolean val1 = get();
 263             c.v = false; boolean val2 = get();
 264             assertEquals(val1, true);
 265             assertEquals(val2, (isStableEnabled ? true : false));
 266         }
 267     }
 268 
 269     /* ==================================================== */
 270 
 271     static class StaticByteStable {
 272         public static @Stable byte v;
 273 
 274         public static final StaticByteStable c = new StaticByteStable();
 275         public static byte get() { return c.v; }
 276         public static void test() throws Exception {
 277             c.v = 5;   byte val1 = get();
 278             c.v = 127; byte val2 = get();
 279             assertEquals(val1, 5);
 280             assertEquals(val2, (isStableEnabled ? 5 : 127));
 281         }
 282     }
 283 
 284     /* ==================================================== */
 285 
 286     static class StaticShortStable {
 287         public static @Stable short v;
 288 
 289         public static final StaticShortStable c = new StaticShortStable();
 290         public static short get() { return c.v; }
 291         public static void test() throws Exception {
 292             c.v = 1;     short val1 = get();
 293             c.v = 32767; short val2 = get();
 294             assertEquals(val1, 1);
 295             assertEquals(val2, (isStableEnabled ? 1 : 32767));
 296         }
 297     }
 298 
 299     /* ==================================================== */
 300 
 301     static class StaticCharStable {
 302         public static @Stable char v;
 303 
 304         public static final StaticCharStable c = new StaticCharStable();
 305         public static char get() { return c.v; }
 306         public static void test() throws Exception {
 307             c.v = 'a'; char val1 = get();
 308             c.v = 'b'; char val2 = get();
 309             assertEquals(val1, 'a');
 310             assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
 311         }
 312     }
 313 
 314     /* ==================================================== */
 315 
 316     static class StaticIntStable {
 317         public static @Stable int v;
 318 
 319         public static final StaticIntStable c = new StaticIntStable();
 320         public static int get() { return c.v; }
 321         public static void test() throws Exception {
 322             c.v = 1; int val1 = get();
 323             c.v = 2; int val2 = get();
 324             assertEquals(val1, 1);
 325             assertEquals(val2, (isStableEnabled ? 1 : 2));
 326         }
 327     }
 328 
 329     /* ==================================================== */
 330 
 331     static class StaticFloatStable {
 332         public static @Stable float v;
 333 
 334         public static final StaticFloatStable c = new StaticFloatStable();
 335         public static float get() { return c.v; }
 336         public static void test() throws Exception {
 337             c.v = 1.0F; float val1 = get();
 338             c.v = 2.0F; float val2 = get();
 339             assertEquals(val1, 1.0F);
 340             assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
 341         }
 342     }
 343 
 344     /* ==================================================== */
 345 
 346     static class StaticLongStable {
 347         public static @Stable long v;
 348 
 349         public static final StaticLongStable c = new StaticLongStable();
 350         public static long get() { return c.v; }
 351         public static void test() throws Exception {
 352             c.v = 5;              long val1 = get();
 353             c.v = Long.MAX_VALUE; long val2 = get();
 354             assertEquals(val1, 5);
 355             assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
 356         }
 357     }
 358 
 359     /* ==================================================== */
 360 
 361     static class StaticDoubleStable {
 362         public static @Stable double v;
 363 
 364         public static final StaticDoubleStable c = new StaticDoubleStable();
 365         public static double get() { return c.v; }
 366         public static void test() throws Exception {
 367             c.v = 1.0; double val1 = get();
 368             c.v = Double.MAX_VALUE; double val2 = get();
 369             assertEquals(val1, 1.0);
 370             assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
 371         }
 372     }
 373 
 374     /* ==================================================== */
 375 
 376     static class VolatileObjectStable {
 377         enum Values { A, B}
 378         public @Stable volatile Values v;
 379 
 380         public static final VolatileObjectStable c = new VolatileObjectStable ();
 381         public static Values get() { return c.v; }
 382         public static void test() throws Exception {
 383             c.v = Values.A; Values val1 = get();
 384             c.v = Values.B; Values val2 = get();
 385             assertEquals(val1, Values.A);
 386             assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
 387         }
 388     }
 389 
 390     /* ==================================================== */
 391 
 392     static class VolatileBoolStable {
 393         public @Stable volatile boolean v;
 394 
 395         public static final VolatileBoolStable c = new VolatileBoolStable();
 396         public static boolean get() { return c.v; }
 397         public static void test() throws Exception {
 398             c.v = true; boolean val1 = get();
 399             c.v = false; boolean val2 = get();
 400             assertEquals(val1, true);
 401             assertEquals(val2, (isStableEnabled ? true : false));
 402         }
 403     }
 404 
 405     /* ==================================================== */
 406 
 407     static class VolatileByteStable {
 408         public @Stable volatile byte v;
 409 
 410         public static final VolatileByteStable c = new VolatileByteStable();
 411         public static byte get() { return c.v; }
 412         public static void test() throws Exception {
 413             c.v = 5;   byte val1 = get();
 414             c.v = 127; byte val2 = get();
 415             assertEquals(val1, 5);
 416             assertEquals(val2, (isStableEnabled ? 5 : 127));
 417         }
 418     }
 419 
 420     /* ==================================================== */
 421 
 422     static class VolatileShortStable {
 423         public @Stable volatile short v;
 424 
 425         public static final VolatileShortStable c = new VolatileShortStable();
 426         public static short get() { return c.v; }
 427         public static void test() throws Exception {
 428             c.v = 1;     short val1 = get();
 429             c.v = 32767; short val2 = get();
 430             assertEquals(val1, 1);
 431             assertEquals(val2, (isStableEnabled ? 1 : 32767));
 432         }
 433     }
 434 
 435     /* ==================================================== */
 436 
 437     static class VolatileCharStable {
 438         public @Stable volatile char v;
 439 
 440         public static final VolatileCharStable c = new VolatileCharStable();
 441         public static char get() { return c.v; }
 442         public static void test() throws Exception {
 443             c.v = 'a'; char val1 = get();
 444             c.v = 'b'; char val2 = get();
 445             assertEquals(val1, 'a');
 446             assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
 447         }
 448     }
 449 
 450     /* ==================================================== */
 451 
 452     static class VolatileIntStable {
 453         public @Stable volatile int v;
 454 
 455         public static final VolatileIntStable c = new VolatileIntStable();
 456         public static int get() { return c.v; }
 457         public static void test() throws Exception {
 458             c.v = 1; int val1 = get();
 459             c.v = 2; int val2 = get();
 460             assertEquals(val1, 1);
 461             assertEquals(val2, (isStableEnabled ? 1 : 2));
 462         }
 463     }
 464 
 465     /* ==================================================== */
 466 
 467     static class VolatileFloatStable {
 468         public @Stable volatile float v;
 469 
 470         public static final VolatileFloatStable c = new VolatileFloatStable();
 471         public static float get() { return c.v; }
 472         public static void test() throws Exception {
 473             c.v = 1.0F; float val1 = get();
 474             c.v = 2.0F; float val2 = get();
 475             assertEquals(val1, 1.0F);
 476             assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
 477         }
 478     }
 479 
 480     /* ==================================================== */
 481 
 482     static class VolatileLongStable {
 483         public @Stable volatile long v;
 484 
 485         public static final VolatileLongStable c = new VolatileLongStable();
 486         public static long get() { return c.v; }
 487         public static void test() throws Exception {
 488             c.v = 5;              long val1 = get();
 489             c.v = Long.MAX_VALUE; long val2 = get();
 490             assertEquals(val1, 5);
 491             assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
 492         }
 493     }
 494 
 495     /* ==================================================== */
 496 
 497     static class VolatileDoubleStable {
 498         public @Stable double v;
 499 
 500         public static final VolatileDoubleStable c = new VolatileDoubleStable();
 501         public static double get() { return c.v; }
 502         public static void test() throws Exception {
 503             c.v = 1.0; double val1 = get();
 504             c.v = Double.MAX_VALUE; double val2 = get();
 505             assertEquals(val1, 1.0);
 506             assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
 507         }
 508     }
 509 
 510     /* ==================================================== */
 511     // @Stable array == field && all components are stable
 512 
 513     static class IntArrayArity1 {
 514         public static @Stable int[] v;
 515 
 516         public static final IntArrayArity1 c = new IntArrayArity1();
 517         public static int get() { return c.v[0]; }
 518         public static int[] get1() { return c.v; }
 519         public static void test() throws Exception {
 520             {
 521                 c.v = new int[1]; c.v[0] = 1; int val1 = get();
 522                                   c.v[0] = 2; int val2 = get();
 523                 assertEquals(val1, 1);
 524                 assertEquals(val2, (isStableEnabled ? 1 : 2));
 525 
 526                 c.v = new int[1]; c.v[0] = 3; int val3 = get();
 527                 assertEquals(val3, (isStableEnabled ? 1 : 3));
 528             }
 529 
 530             {
 531                 c.v = new int[1]; int[] val1 = get1();
 532                 c.v = new int[1]; int[] val2 = get1();
 533                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 534             }
 535         }
 536     }
 537 
 538     /* ==================================================== */
 539 
 540     static class IntArrayArity2 {
 541         public static @Stable int[][] v;
 542 
 543         public static final IntArrayArity2 c = new IntArrayArity2();
 544         public static int get() { return c.v[0][0]; }
 545         public static int[] get1() { return c.v[0]; }
 546         public static int[][] get2() { return c.v; }
 547         public static void test() throws Exception {
 548             {
 549                 c.v = new int[1][1]; c.v[0][0] = 1; int val1 = get();
 550                                      c.v[0][0] = 2; int val2 = get();
 551                 assertEquals(val1, 1);
 552                 assertEquals(val2, (isStableEnabled ? 1 : 2));
 553 
 554                 c.v = new int[1][1]; c.v[0][0] = 3; int val3 = get();
 555                 assertEquals(val3, (isStableEnabled ? 1 : 3));
 556 
 557                 c.v[0] = new int[1]; c.v[0][0] = 4; int val4 = get();
 558                 assertEquals(val4, (isStableEnabled ? 1 : 4));
 559             }
 560 
 561             {
 562                 c.v = new int[1][1]; int[] val1 = get1();
 563                 c.v[0] = new int[1]; int[] val2 = get1();
 564                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 565             }
 566 
 567             {
 568                 c.v = new int[1][1]; int[][] val1 = get2();
 569                 c.v = new int[1][1]; int[][] val2 = get2();
 570                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 571             }
 572         }
 573     }
 574 
 575     /* ==================================================== */
 576 
 577     static class IntArrayArity3 {
 578         public static @Stable int[][][] v;
 579 
 580         public static final IntArrayArity3 c = new IntArrayArity3();
 581         public static int get() { return c.v[0][0][0]; }
 582         public static int[] get1() { return c.v[0][0]; }
 583         public static int[][] get2() { return c.v[0]; }
 584         public static int[][][] get3() { return c.v; }
 585         public static void test() throws Exception {
 586             {
 587                 c.v = new int[1][1][1]; c.v[0][0][0] = 1; int val1 = get();
 588                 c.v[0][0][0] = 2; int val2 = get();
 589                 assertEquals(val1, 1);
 590                 assertEquals(val2, (isStableEnabled ? 1 : 2));
 591 
 592                 c.v = new int[1][1][1]; c.v[0][0][0] = 3; int val3 = get();
 593                 assertEquals(val3, (isStableEnabled ? 1 : 3));
 594 
 595                 c.v[0] = new int[1][1]; c.v[0][0][0] = 4; int val4 = get();
 596                 assertEquals(val4, (isStableEnabled ? 1 : 4));
 597 
 598                 c.v[0][0] = new int[1]; c.v[0][0][0] = 5; int val5 = get();
 599                 assertEquals(val5, (isStableEnabled ? 1 : 5));
 600             }
 601 
 602             {
 603                 c.v = new int[1][1][1]; int[] val1 = get1();
 604                 c.v[0][0] = new int[1]; int[] val2 = get1();
 605                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 606             }
 607 
 608             {
 609                 c.v = new int[1][1][1]; int[][] val1 = get2();
 610                 c.v[0] = new int[1][1]; int[][] val2 = get2();
 611                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 612             }
 613 
 614             {
 615                 c.v = new int[1][1][1]; int[][][] val1 = get3();
 616                 c.v = new int[1][1][1]; int[][][] val2 = get3();
 617                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 618             }
 619         }
 620     }
 621 
 622     /* ==================================================== */
 623 
 624     static class IntArrayArity4 {
 625         public static @Stable int[][][][] v;
 626 
 627         public static final IntArrayArity4 c = new IntArrayArity4();
 628         public static int get() { return c.v[0][0][0][0]; }
 629         public static int[] get1() { return c.v[0][0][0]; }
 630         public static int[][] get2() { return c.v[0][0]; }
 631         public static int[][][] get3() { return c.v[0]; }
 632         public static int[][][][] get4() { return c.v; }
 633         public static void test() throws Exception {
 634             {
 635                 c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 1; int val1 = get();
 636                 c.v[0][0][0][0] = 2; int val2 = get();
 637                 assertEquals(val1, 1);
 638                 assertEquals(val2, (isStableEnabled ? 1 : 2));
 639 
 640                 c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 3; int val3 = get();
 641                 assertEquals(val3, (isStableEnabled ? 1 : 3));
 642 
 643                 c.v[0] = new int[1][1][1]; c.v[0][0][0][0] = 4; int val4 = get();
 644                 assertEquals(val4, (isStableEnabled ? 1 : 4));
 645 
 646                 c.v[0][0] = new int[1][1]; c.v[0][0][0][0] = 5; int val5 = get();
 647                 assertEquals(val5, (isStableEnabled ? 1 : 5));
 648 
 649                 c.v[0][0][0] = new int[1]; c.v[0][0][0][0] = 6; int val6 = get();
 650                 assertEquals(val6, (isStableEnabled ? 1 : 6));
 651             }
 652 
 653             {
 654                 c.v = new int[1][1][1][1]; int[] val1 = get1();
 655                 c.v[0][0][0] = new int[1]; int[] val2 = get1();
 656                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 657             }
 658 
 659             {
 660                 c.v = new int[1][1][1][1]; int[][] val1 = get2();
 661                 c.v[0][0] = new int[1][1]; int[][] val2 = get2();
 662                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 663             }
 664 
 665             {
 666                 c.v = new int[1][1][1][1]; int[][][] val1 = get3();
 667                 c.v[0] = new int[1][1][1]; int[][][] val2 = get3();
 668                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 669             }
 670 
 671             {
 672                 c.v = new int[1][1][1][1]; int[][][][] val1 = get4();
 673                 c.v = new int[1][1][1][1]; int[][][][] val2 = get4();
 674                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 675             }
 676 
 677         }
 678     }
 679 
 680     /* ==================================================== */
 681     // Dynamic arity is higher than static
 682 
 683     static class ObjectArrayArity0 {
 684         public static @Stable Object v;
 685 
 686         public static final ObjectArrayArity0 c = new ObjectArrayArity0();
 687         public static int get() { return ((int[])c.v)[0]; }
 688         public static int[] get1() { return (int[])c.v; }
 689 
 690         public static void test() throws Exception {
 691             {
 692                 c.v = new int[1]; ((int[])c.v)[0] = 1; int val1 = get();
 693                                   ((int[])c.v)[0] = 2; int val2 = get();
 694 
 695                 assertEquals(val1, 1);
 696                 assertEquals(val2, 2);
 697             }
 698 
 699             {
 700                 c.v = new int[1]; int[] val1 = get1();
 701                 c.v = new int[1]; int[] val2 = get1();
 702                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 703             }
 704         }
 705     }
 706 
 707     /* ==================================================== */
 708 
 709     static class ObjectArrayArity1 {
 710         public static @Stable Object[] v;
 711 
 712         public static final ObjectArrayArity1 c = new ObjectArrayArity1();
 713         public static int get() { return ((int[][])c.v)[0][0]; }
 714         public static int[] get1() { return (int[])(c.v[0]); }
 715         public static Object[] get2() { return c.v; }
 716 
 717         public static void test() throws Exception {
 718             {
 719                 c.v = new int[1][1]; ((int[][])c.v)[0][0] = 1; int val1 = get();
 720                                      ((int[][])c.v)[0][0] = 2; int val2 = get();
 721 
 722                 assertEquals(val1, 1);
 723                 assertEquals(val2, 2);
 724             }
 725 
 726             {
 727                 c.v = new int[1][1]; c.v[0] = new int[0]; int[] val1 = get1();
 728                                      c.v[0] = new int[0]; int[] val2 = get1();
 729 
 730                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 731             }
 732 
 733             {
 734                 c.v = new int[0][0]; Object[] val1 = get2();
 735                 c.v = new int[0][0]; Object[] val2 = get2();
 736 
 737                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 738             }
 739         }
 740     }
 741 
 742     /* ==================================================== */
 743 
 744     static class NestedStableField {
 745         static class A {
 746             public @Stable int a;
 747 
 748         }
 749         public static @Stable A v;
 750 
 751         public static final NestedStableField c = new NestedStableField();
 752         public static A get() { return c.v; }
 753         public static int get1() { return get().a; }
 754 
 755         public static void test() throws Exception {
 756             {
 757                 c.v = new A(); c.v.a = 1; A val1 = get();
 758                                c.v.a = 2; A val2 = get();
 759 
 760                 assertEquals(val1.a, 2);
 761                 assertEquals(val2.a, 2);
 762             }
 763 
 764             {
 765                 c.v = new A(); c.v.a = 1; int val1 = get1();
 766                                c.v.a = 2; int val2 = get1();
 767                 c.v = new A(); c.v.a = 3; int val3 = get1();
 768 
 769                 assertEquals(val1, 1);
 770                 assertEquals(val2, (isStableEnabled ? 1 : 2));
 771                 assertEquals(val3, (isStableEnabled ? 1 : 3));
 772             }
 773         }
 774     }
 775 
 776     /* ==================================================== */
 777 
 778     static class NestedStableField1 {
 779         static class A {
 780             public @Stable int a;
 781             public @Stable A next;
 782         }
 783         public static @Stable A v;
 784 
 785         public static final NestedStableField1 c = new NestedStableField1();
 786         public static A get() { return c.v.next.next.next.next.next.next.next; }
 787         public static int get1() { return get().a; }
 788 
 789         public static void test() throws Exception {
 790             {
 791                 c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
 792                                c.v.a = 1; c.v.next.a = 1; A val1 = get();
 793                                c.v.a = 2; c.v.next.a = 2; A val2 = get();
 794 
 795                 assertEquals(val1.a, 2);
 796                 assertEquals(val2.a, 2);
 797             }
 798 
 799             {
 800                 c.v = new A(); c.v.next = c.v;
 801                                c.v.a = 1; int val1 = get1();
 802                                c.v.a = 2; int val2 = get1();
 803                 c.v = new A(); c.v.next = c.v;
 804                                c.v.a = 3; int val3 = get1();
 805 
 806                 assertEquals(val1, 1);
 807                 assertEquals(val2, (isStableEnabled ? 1 : 2));
 808                 assertEquals(val3, (isStableEnabled ? 1 : 3));
 809             }
 810         }
 811     }
 812    /* ==================================================== */
 813 
 814     static class NestedStableField2 {
 815         static class A {
 816             public @Stable int a;
 817             public @Stable A left;
 818             public         A right;
 819         }
 820 
 821         public static @Stable A v;
 822 
 823         public static final NestedStableField2 c = new NestedStableField2();
 824         public static int get() { return c.v.left.left.left.a; }
 825         public static int get1() { return c.v.left.left.right.left.a; }
 826 
 827         public static void test() throws Exception {
 828             {
 829                 c.v = new A(); c.v.left = c.v.right = c.v;
 830                                c.v.a = 1; int val1 = get(); int val2 = get1();
 831                                c.v.a = 2; int val3 = get(); int val4 = get1();
 832 
 833                 assertEquals(val1, 1);
 834                 assertEquals(val3, (isStableEnabled ? 1 : 2));
 835 
 836                 assertEquals(val2, 1);
 837                 assertEquals(val4, 2);
 838             }
 839         }
 840     }
 841 
 842     /* ==================================================== */
 843 
 844     static class NestedStableField3 {
 845         static class A {
 846             public @Stable int a;
 847             public @Stable A[] left;
 848             public         A[] right;
 849         }
 850 
 851         public static @Stable A[] v;
 852 
 853         public static final NestedStableField3 c = new NestedStableField3();
 854         public static int get() { return c.v[0].left[1].left[0].left[1].a; }
 855         public static int get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
 856 
 857         public static void test() throws Exception {
 858             {
 859                 A elem = new A();
 860                 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
 861                                elem.a = 1; int val1 = get(); int val2 = get1();
 862                                elem.a = 2; int val3 = get(); int val4 = get1();
 863 
 864                 assertEquals(val1, 1);
 865                 assertEquals(val3, (isStableEnabled ? 1 : 2));
 866 
 867                 assertEquals(val2, 1);
 868                 assertEquals(val4, 2);
 869             }
 870         }
 871     }
 872 
 873     /* ==================================================== */
 874     // Auxiliary methods
 875     static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
 876     static void assertEquals(long i, long j) { if (i != j)  throw new AssertionError(i + " != " + j); }
 877     static void assertEquals(boolean i, boolean j) { if (i != j)  throw new AssertionError(i + " != " + j); }
 878     static void assertEquals(float i, float j) { if (i != j)  throw new AssertionError(i + " != " + j); }
 879     static void assertEquals(double i, double j) { if (i != j)  throw new AssertionError(i + " != " + j); }
 880     static void assertEquals(Object i, Object j) { if (!i.equals(j))  throw new AssertionError(i + " != " + j); }
 881     static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
 882 
 883     static boolean failed = false;
 884 
 885     public static void run(Class<?> test) {
 886         Throwable ex = null;
 887         System.out.print(test.getName()+": ");
 888         try {
 889             test.getMethod("test").invoke(null);
 890         } catch (InvocationTargetException e) {
 891             ex = e.getCause();
 892         } catch (Throwable e) {
 893             ex = e;
 894         } finally {
 895             if (ex == null) {
 896                 System.out.println("PASSED");
 897             } else {
 898                 failed = true;
 899                 System.out.println("FAILED");
 900                 ex.printStackTrace(System.out);
 901             }
 902         }
 903     }
 904 
 905     static final boolean isStableEnabled;
 906     static {
 907         HotSpotDiagnosticMXBean diagnostic
 908                 = ManagementFactoryHelper.getDiagnosticMXBean();
 909         VMOption tmp;
 910         try {
 911             tmp = diagnostic.getVMOption("FoldStableValues");
 912         } catch (IllegalArgumentException e) {
 913             tmp = null;
 914         }
 915         isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
 916     }
 917 }