1 /*
   2  * Copyright (c) 2014, 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 TestStableBoolean
  28  * @summary tests on stable fields and arrays
  29  * @library /testlibrary
  30  * @compile -XDignore.symbol.file TestStableBoolean.java
  31  * @run main ClassFileInstaller
  32  *           java/lang/invoke/TestStableBoolean
  33  *           java/lang/invoke/TestStableBoolean$BooleanStable
  34  *           java/lang/invoke/TestStableBoolean$StaticBooleanStable
  35  *           java/lang/invoke/TestStableBoolean$VolatileBooleanStable
  36  *           java/lang/invoke/TestStableBoolean$BooleanArrayDim1
  37  *           java/lang/invoke/TestStableBoolean$BooleanArrayDim2
  38  *           java/lang/invoke/TestStableBoolean$BooleanArrayDim3
  39  *           java/lang/invoke/TestStableBoolean$BooleanArrayDim4
  40  *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim0
  41  *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim1
  42  *           java/lang/invoke/TestStableBoolean$NestedStableField
  43  *           java/lang/invoke/TestStableBoolean$NestedStableField$A
  44  *           java/lang/invoke/TestStableBoolean$NestedStableField1
  45  *           java/lang/invoke/TestStableBoolean$NestedStableField1$A
  46  *           java/lang/invoke/TestStableBoolean$NestedStableField2
  47  *           java/lang/invoke/TestStableBoolean$NestedStableField2$A
  48  *           java/lang/invoke/TestStableBoolean$NestedStableField3
  49  *           java/lang/invoke/TestStableBoolean$NestedStableField3$A
  50  *           java/lang/invoke/TestStableBoolean$DefaultValue
  51  *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim2
  52  *
  53  * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
  54  *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
  55  *                   -server -XX:-TieredCompilation -Xcomp
  56  *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  57  *                   java.lang.invoke.TestStableBoolean
  58  *
  59  * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
  60  *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
  61  *                   -server -XX:-TieredCompilation -Xcomp
  62  *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  63  *                   java.lang.invoke.TestStableBoolean
  64  *
  65  * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
  66  *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
  67  *                   -server -XX:-TieredCompilation -Xcomp
  68  *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  69  *                   java.lang.invoke.TestStableBoolean
  70  *
  71  * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
  72  *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
  73  *                   -server -XX:-TieredCompilation -Xcomp
  74  *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  75  *                   java.lang.invoke.TestStableBoolean
  76  */
  77 package java.lang.invoke;
  78 
  79 import com.sun.management.HotSpotDiagnosticMXBean;
  80 import com.sun.management.VMOption;
  81 import sun.management.ManagementFactoryHelper;
  82 import java.lang.reflect.InvocationTargetException;
  83 
  84 public class TestStableBoolean {
  85     public static void main(String[] args) throws Exception {
  86         System.out.println("@Stable enabled: "+isStableEnabled);
  87         System.out.println();
  88 
  89         run(DefaultValue.class);
  90         run(BooleanStable.class);
  91         run(StaticBooleanStable.class);
  92         run(VolatileBooleanStable.class);
  93 
  94         // @Stable arrays: Dim 1-4
  95         run(BooleanArrayDim1.class);
  96         run(BooleanArrayDim2.class);
  97         run(BooleanArrayDim3.class);
  98         run(BooleanArrayDim4.class);
  99 
 100         // @Stable Object field: dynamic arrays
 101         run(ObjectArrayLowerDim0.class);
 102         run(ObjectArrayLowerDim1.class);
 103         run(ObjectArrayLowerDim2.class);
 104 
 105         // Nested @Stable fields
 106         run(NestedStableField.class);
 107         run(NestedStableField1.class);
 108         run(NestedStableField2.class);
 109         run(NestedStableField3.class);
 110 
 111         if (failed) {
 112             throw new Error("TEST FAILED");
 113         }
 114     }
 115 
 116     /* ==================================================== */
 117 
 118     static class DefaultValue {
 119         public @Stable boolean v;
 120 
 121         public static final DefaultValue c = new DefaultValue();
 122         public static boolean get() { return c.v; }
 123         public static void test() throws Exception {
 124                         boolean val1 = get();
 125             c.v = true; boolean val2 = get();
 126             assertEquals(val1, false);
 127             assertEquals(val2, true);
 128         }
 129     }
 130 
 131     /* ==================================================== */
 132 
 133     static class BooleanStable {
 134         public @Stable boolean v;
 135 
 136         public static final BooleanStable c = new BooleanStable();
 137         public static boolean get() { return c.v; }
 138         public static void test() throws Exception {
 139             c.v = true; boolean val1 = get();
 140             c.v = false; boolean val2 = get();
 141             assertEquals(val1, true);
 142             assertEquals(val2, (isStableEnabled ? true : false));
 143         }
 144     }
 145 
 146     /* ==================================================== */
 147 
 148     static class StaticBooleanStable {
 149         public static @Stable boolean v;
 150 
 151         public static final StaticBooleanStable c = new StaticBooleanStable();
 152         public static boolean get() { return c.v; }
 153         public static void test() throws Exception {
 154             c.v = true; boolean val1 = get();
 155             c.v = false; boolean val2 = get();
 156             assertEquals(val1, true);
 157             assertEquals(val2, (isStableEnabled ? true : false));
 158         }
 159     }
 160 
 161     /* ==================================================== */
 162 
 163     static class VolatileBooleanStable {
 164         public @Stable volatile boolean v;
 165 
 166         public static final VolatileBooleanStable c = new VolatileBooleanStable();
 167         public static boolean get() { return c.v; }
 168         public static void test() throws Exception {
 169             c.v = true; boolean val1 = get();
 170             c.v = false; boolean val2 = get();
 171             assertEquals(val1, true);
 172             assertEquals(val2, (isStableEnabled ? true : false));
 173         }
 174     }
 175 
 176     /* ==================================================== */
 177     // @Stable array == field && all components are stable
 178 
 179     static class BooleanArrayDim1 {
 180         public @Stable boolean[] v;
 181 
 182         public static final BooleanArrayDim1 c = new BooleanArrayDim1();
 183         public static boolean get() { return c.v[0]; }
 184         public static boolean get1() { return c.v[10]; }
 185         public static boolean[] get2() { return c.v; }
 186         public static void test() throws Exception {
 187             {
 188                 c.v = new boolean[1]; c.v[0] = true;  boolean val1 = get();
 189                                       c.v[0] = false; boolean val2 = get();
 190                 assertEquals(val1, true);
 191                 assertEquals(val2, (isStableEnabled ? true : false));
 192             }
 193 
 194             {
 195                 c.v = new boolean[20]; c.v[10] = true;  boolean val1 = get1();
 196                                        c.v[10] = false; boolean val2 = get1();
 197                 assertEquals(val1, true);
 198                 assertEquals(val2, (isStableEnabled ? true : false));
 199             }
 200 
 201             {
 202                 c.v = new boolean[1]; boolean[] val1 = get2();
 203                 c.v = new boolean[1]; boolean[] val2 = get2();
 204                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 205             }
 206         }
 207     }
 208 
 209     /* ==================================================== */
 210 
 211     static class BooleanArrayDim2 {
 212         public @Stable boolean[][] v;
 213 
 214         public static final BooleanArrayDim2 c = new BooleanArrayDim2();
 215         public static boolean get() { return c.v[0][0]; }
 216         public static boolean[] get1() { return c.v[0]; }
 217         public static boolean[][] get2() { return c.v; }
 218         public static void test() throws Exception {
 219             {
 220                 c.v = new boolean[1][1]; c.v[0][0] = true;  boolean val1 = get();
 221                                          c.v[0][0] = false; boolean val2 = get();
 222                 assertEquals(val1, true);
 223                 assertEquals(val2, (isStableEnabled ? true : false));
 224 
 225                 c.v = new boolean[1][1]; c.v[0][0] = false; boolean val3 = get();
 226                 assertEquals(val3, (isStableEnabled ? true : false));
 227 
 228                 c.v[0] = new boolean[1]; c.v[0][0] = false; boolean val4 = get();
 229                 assertEquals(val4, (isStableEnabled ? true : false));
 230             }
 231 
 232             {
 233                 c.v = new boolean[1][1]; boolean[] val1 = get1();
 234                 c.v[0] = new boolean[1]; boolean[] val2 = get1();
 235                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 236             }
 237 
 238             {
 239                 c.v = new boolean[1][1]; boolean[][] val1 = get2();
 240                 c.v = new boolean[1][1]; boolean[][] val2 = get2();
 241                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 242             }
 243         }
 244     }
 245 
 246     /* ==================================================== */
 247 
 248     static class BooleanArrayDim3 {
 249         public @Stable boolean[][][] v;
 250 
 251         public static final BooleanArrayDim3 c = new BooleanArrayDim3();
 252         public static boolean get() { return c.v[0][0][0]; }
 253         public static boolean[] get1() { return c.v[0][0]; }
 254         public static boolean[][] get2() { return c.v[0]; }
 255         public static boolean[][][] get3() { return c.v; }
 256         public static void test() throws Exception {
 257             {
 258                 c.v = new boolean[1][1][1]; c.v[0][0][0] = true;  boolean val1 = get();
 259                                             c.v[0][0][0] = false; boolean val2 = get();
 260                 assertEquals(val1, true);
 261                 assertEquals(val2, (isStableEnabled ? true : false));
 262 
 263                 c.v = new boolean[1][1][1]; c.v[0][0][0] = false; boolean val3 = get();
 264                 assertEquals(val3, (isStableEnabled ? true : false));
 265 
 266                 c.v[0] = new boolean[1][1]; c.v[0][0][0] = false; boolean val4 = get();
 267                 assertEquals(val4, (isStableEnabled ? true : false));
 268 
 269                 c.v[0][0] = new boolean[1]; c.v[0][0][0] = false; boolean val5 = get();
 270                 assertEquals(val5, (isStableEnabled ? true : false));
 271             }
 272 
 273             {
 274                 c.v = new boolean[1][1][1]; boolean[] val1 = get1();
 275                 c.v[0][0] = new boolean[1]; boolean[] val2 = get1();
 276                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 277             }
 278 
 279             {
 280                 c.v = new boolean[1][1][1]; boolean[][] val1 = get2();
 281                 c.v[0] = new boolean[1][1]; boolean[][] val2 = get2();
 282                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 283             }
 284 
 285             {
 286                 c.v = new boolean[1][1][1]; boolean[][][] val1 = get3();
 287                 c.v = new boolean[1][1][1]; boolean[][][] val2 = get3();
 288                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 289             }
 290         }
 291     }
 292 
 293     /* ==================================================== */
 294 
 295     static class BooleanArrayDim4 {
 296         public @Stable boolean[][][][] v;
 297 
 298         public static final BooleanArrayDim4 c = new BooleanArrayDim4();
 299         public static boolean get() { return c.v[0][0][0][0]; }
 300         public static boolean[] get1() { return c.v[0][0][0]; }
 301         public static boolean[][] get2() { return c.v[0][0]; }
 302         public static boolean[][][] get3() { return c.v[0]; }
 303         public static boolean[][][][] get4() { return c.v; }
 304         public static void test() throws Exception {
 305             {
 306                 c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = true;  boolean val1 = get();
 307                                                c.v[0][0][0][0] = false; boolean val2 = get();
 308                 assertEquals(val1, true);
 309                 assertEquals(val2, (isStableEnabled ? true : false));
 310 
 311                 c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = false; boolean val3 = get();
 312                 assertEquals(val3, (isStableEnabled ? true : false));
 313 
 314                 c.v[0] = new boolean[1][1][1]; c.v[0][0][0][0] = false; boolean val4 = get();
 315                 assertEquals(val4, (isStableEnabled ? true : false));
 316 
 317                 c.v[0][0] = new boolean[1][1]; c.v[0][0][0][0] = false; boolean val5 = get();
 318                 assertEquals(val5, (isStableEnabled ? true : false));
 319 
 320                 c.v[0][0][0] = new boolean[1]; c.v[0][0][0][0] = false; boolean val6 = get();
 321                 assertEquals(val6, (isStableEnabled ? true : false));
 322             }
 323 
 324             {
 325                 c.v = new boolean[1][1][1][1]; boolean[] val1 = get1();
 326                 c.v[0][0][0] = new boolean[1]; boolean[] val2 = get1();
 327                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 328             }
 329 
 330             {
 331                 c.v = new boolean[1][1][1][1]; boolean[][] val1 = get2();
 332                 c.v[0][0] = new boolean[1][1]; boolean[][] val2 = get2();
 333                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 334             }
 335 
 336             {
 337                 c.v = new boolean[1][1][1][1]; boolean[][][] val1 = get3();
 338                 c.v[0] = new boolean[1][1][1]; boolean[][][] val2 = get3();
 339                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 340             }
 341 
 342             {
 343                 c.v = new boolean[1][1][1][1]; boolean[][][][] val1 = get4();
 344                 c.v = new boolean[1][1][1][1]; boolean[][][][] val2 = get4();
 345                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 346             }
 347 
 348         }
 349     }
 350 
 351     /* ==================================================== */
 352     // Dynamic Dim is higher than static
 353 
 354     static class ObjectArrayLowerDim0 {
 355         public @Stable Object v;
 356 
 357         public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
 358         public static boolean get() { return ((boolean[])c.v)[0]; }
 359         public static boolean[] get1() { return (boolean[])c.v; }
 360         public static boolean[] get2() { return (boolean[])c.v; }
 361 
 362         public static void test() throws Exception {
 363             {
 364                 c.v = new boolean[1]; ((boolean[])c.v)[0] = true;  boolean val1 = get();
 365                                       ((boolean[])c.v)[0] = false; boolean val2 = get();
 366 
 367                 assertEquals(val1, true);
 368                 assertEquals(val2, false);
 369             }
 370 
 371             {
 372                 c.v = new boolean[1]; boolean[] val1 = get1();
 373                 c.v = new boolean[1]; boolean[] val2 = get1();
 374                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 375             }
 376         }
 377     }
 378 
 379     /* ==================================================== */
 380 
 381     static class ObjectArrayLowerDim1 {
 382         public @Stable Object[] v;
 383 
 384         public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
 385         public static boolean get() { return ((boolean[][])c.v)[0][0]; }
 386         public static boolean[] get1() { return (boolean[])(c.v[0]); }
 387         public static Object[] get2() { return c.v; }
 388 
 389         public static void test() throws Exception {
 390             {
 391                 c.v = new boolean[1][1]; ((boolean[][])c.v)[0][0] = true;  boolean val1 = get();
 392                                          ((boolean[][])c.v)[0][0] = false; boolean val2 = get();
 393 
 394                 assertEquals(val1, true);
 395                 assertEquals(val2, false);
 396             }
 397 
 398             {
 399                 c.v = new boolean[1][1]; c.v[0] = new boolean[0]; boolean[] val1 = get1();
 400                                          c.v[0] = new boolean[0]; boolean[] val2 = get1();
 401 
 402                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 403             }
 404 
 405             {
 406                 c.v = new boolean[0][0]; Object[] val1 = get2();
 407                 c.v = new boolean[0][0]; Object[] val2 = get2();
 408 
 409                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 410             }
 411         }
 412     }
 413 
 414     /* ==================================================== */
 415 
 416     static class ObjectArrayLowerDim2 {
 417         public @Stable Object[][] v;
 418 
 419         public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
 420         public static boolean get() { return ((boolean[][][])c.v)[0][0][0]; }
 421         public static boolean[] get1() { return (boolean[])(c.v[0][0]); }
 422         public static boolean[][] get2() { return (boolean[][])(c.v[0]); }
 423         public static Object[][] get3() { return c.v; }
 424 
 425         public static void test() throws Exception {
 426             {
 427                 c.v = new boolean[1][1][1]; ((boolean[][][])c.v)[0][0][0] = true;  boolean val1 = get();
 428                                             ((boolean[][][])c.v)[0][0][0] = false; boolean val2 = get();
 429 
 430                 assertEquals(val1, true);
 431                 assertEquals(val2, false);
 432             }
 433 
 434             {
 435                 c.v = new boolean[1][1][1]; c.v[0][0] = new boolean[0]; boolean[] val1 = get1();
 436                                             c.v[0][0] = new boolean[0]; boolean[] val2 = get1();
 437 
 438                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 439             }
 440 
 441             {
 442                 c.v = new boolean[1][1][1]; c.v[0] = new boolean[0][0]; boolean[][] val1 = get2();
 443                                             c.v[0] = new boolean[0][0]; boolean[][] val2 = get2();
 444 
 445                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 446             }
 447 
 448             {
 449                 c.v = new boolean[0][0][0]; Object[][] val1 = get3();
 450                 c.v = new boolean[0][0][0]; Object[][] val2 = get3();
 451 
 452                 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
 453             }
 454         }
 455     }
 456 
 457     /* ==================================================== */
 458 
 459     static class NestedStableField {
 460         static class A {
 461             public @Stable boolean a;
 462 
 463         }
 464         public @Stable A v;
 465 
 466         public static final NestedStableField c = new NestedStableField();
 467         public static A get() { return c.v; }
 468         public static boolean get1() { return get().a; }
 469 
 470         public static void test() throws Exception {
 471             {
 472                 c.v = new A(); c.v.a = true;  A val1 = get();
 473                                c.v.a = false; A val2 = get();
 474 
 475                 assertEquals(val1.a, false);
 476                 assertEquals(val2.a, false);
 477             }
 478 
 479             {
 480                 c.v = new A(); c.v.a = true;  boolean val1 = get1();
 481                                c.v.a = false; boolean val2 = get1();
 482                 c.v = new A(); c.v.a = false; boolean val3 = get1();
 483 
 484                 assertEquals(val1, true);
 485                 assertEquals(val2, (isStableEnabled ? true : false));
 486                 assertEquals(val3, (isStableEnabled ? true : false));
 487             }
 488         }
 489     }
 490 
 491     /* ==================================================== */
 492 
 493     static class NestedStableField1 {
 494         static class A {
 495             public @Stable boolean a;
 496             public @Stable A next;
 497         }
 498         public @Stable A v;
 499 
 500         public static final NestedStableField1 c = new NestedStableField1();
 501         public static A get() { return c.v.next.next.next.next.next.next.next; }
 502         public static boolean get1() { return get().a; }
 503 
 504         public static void test() throws Exception {
 505             {
 506                 c.v = new A(); c.v.next = new A(); c.v.next.next  = c.v;
 507                                c.v.a = true;  c.v.next.a = true;  A val1 = get();
 508                                c.v.a = false; c.v.next.a = false; A val2 = get();
 509 
 510                 assertEquals(val1.a, false);
 511                 assertEquals(val2.a, false);
 512             }
 513 
 514             {
 515                 c.v = new A(); c.v.next = c.v;
 516                                c.v.a = true;  boolean val1 = get1();
 517                                c.v.a = false; boolean val2 = get1();
 518                 c.v = new A(); c.v.next = c.v;
 519                                c.v.a = false; boolean val3 = get1();
 520 
 521                 assertEquals(val1, true);
 522                 assertEquals(val2, (isStableEnabled ? true : false));
 523                 assertEquals(val3, (isStableEnabled ? true : false));
 524             }
 525         }
 526     }
 527    /* ==================================================== */
 528 
 529     static class NestedStableField2 {
 530         static class A {
 531             public @Stable boolean a;
 532             public @Stable A left;
 533             public         A right;
 534         }
 535 
 536         public @Stable A v;
 537 
 538         public static final NestedStableField2 c = new NestedStableField2();
 539         public static boolean get() { return c.v.left.left.left.a; }
 540         public static boolean get1() { return c.v.left.left.right.left.a; }
 541 
 542         public static void test() throws Exception {
 543             {
 544                 c.v = new A(); c.v.left = c.v.right = c.v;
 545                                c.v.a = true;  boolean val1 = get(); boolean val2 = get1();
 546                                c.v.a = false; boolean val3 = get(); boolean val4 = get1();
 547 
 548                 assertEquals(val1, true);
 549                 assertEquals(val3, (isStableEnabled ? true : false));
 550 
 551                 assertEquals(val2, true);
 552                 assertEquals(val4, false);
 553             }
 554         }
 555     }
 556 
 557     /* ==================================================== */
 558 
 559     static class NestedStableField3 {
 560         static class A {
 561             public @Stable boolean a;
 562             public @Stable A[] left;
 563             public         A[] right;
 564         }
 565 
 566         public @Stable A[] v;
 567 
 568         public static final NestedStableField3 c = new NestedStableField3();
 569         public static boolean get() { return c.v[0].left[1].left[0].left[1].a; }
 570         public static boolean get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
 571 
 572         public static void test() throws Exception {
 573             {
 574                 A elem = new A();
 575                 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
 576                                elem.a = true;  boolean val1 = get(); boolean val2 = get1();
 577                                elem.a = false; boolean val3 = get(); boolean val4 = get1();
 578 
 579                 assertEquals(val1, true);
 580                 assertEquals(val3, (isStableEnabled ? true : false));
 581 
 582                 assertEquals(val2, true);
 583                 assertEquals(val4, false);
 584             }
 585         }
 586     }
 587 
 588     /* ==================================================== */
 589     // Auxiliary methods
 590     static void assertEquals(boolean i, boolean j) { if (i != j)  throw new AssertionError(i + " != " + j); }
 591     static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
 592 
 593     static boolean failed = false;
 594 
 595     public static void run(Class<?> test) {
 596         Throwable ex = null;
 597         System.out.print(test.getName()+": ");
 598         try {
 599             test.getMethod("test").invoke(null);
 600         } catch (InvocationTargetException e) {
 601             ex = e.getCause();
 602         } catch (Throwable e) {
 603             ex = e;
 604         } finally {
 605             if (ex == null) {
 606                 System.out.println("PASSED");
 607             } else {
 608                 failed = true;
 609                 System.out.println("FAILED");
 610                 ex.printStackTrace(System.out);
 611             }
 612         }
 613     }
 614 
 615     static final boolean isStableEnabled;
 616     static {
 617         HotSpotDiagnosticMXBean diagnostic
 618                 = ManagementFactoryHelper.getDiagnosticMXBean();
 619         VMOption tmp;
 620         try {
 621             tmp = diagnostic.getVMOption("FoldStableValues");
 622         } catch (IllegalArgumentException e) {
 623             tmp = null;
 624         }
 625         isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
 626     }
 627 }