hotspot/test/compiler/stable/TestStableBoolean.java
changeset 23192 f6a1c8866065
child 25641 d99065e4572b
equal deleted inserted replaced
23191:5f3c5592f0e8 23192:f6a1c8866065
       
     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 }