8035828: Turn on @Stable support in VM

Fri, 28 Mar 2014 10:13:37 -0700

author
vlivanov
date
Fri, 28 Mar 2014 10:13:37 -0700
changeset 6528
248ff38d2950
parent 6527
f47fa50d9b9c
child 6529
758ee76af3cd

8035828: Turn on @Stable support in VM
Reviewed-by: jrose, twisti

src/share/vm/opto/c2_globals.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableBoolean.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableByte.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableChar.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableDouble.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableFloat.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableInt.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableLong.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableObject.java file | annotate | diff | comparison | revisions
test/compiler/stable/TestStableShort.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/c2_globals.hpp	Fri Mar 28 10:12:48 2014 -0700
     1.2 +++ b/src/share/vm/opto/c2_globals.hpp	Fri Mar 28 10:13:37 2014 -0700
     1.3 @@ -458,7 +458,7 @@
     1.4    product(bool, EliminateAutoBox, false,                                    \
     1.5            "Control optimizations for autobox elimination")                  \
     1.6                                                                              \
     1.7 -  experimental(bool, UseImplicitStableValues, false,                        \
     1.8 +  diagnostic(bool, UseImplicitStableValues, true,                           \
     1.9            "Mark well-known stable fields as such (e.g. String.value)")      \
    1.10                                                                              \
    1.11    product(intx, AutoBoxCacheMax, 128,                                       \
     2.1 --- a/src/share/vm/runtime/globals.hpp	Fri Mar 28 10:12:48 2014 -0700
     2.2 +++ b/src/share/vm/runtime/globals.hpp	Fri Mar 28 10:13:37 2014 -0700
     2.3 @@ -3798,8 +3798,8 @@
     2.4    experimental(bool, TrustFinalNonStaticFields, false,                      \
     2.5            "trust final non-static declarations for constant folding")       \
     2.6                                                                              \
     2.7 -  experimental(bool, FoldStableValues, false,                               \
     2.8 -          "Private flag to control optimizations for stable variables")     \
     2.9 +  diagnostic(bool, FoldStableValues, true,                                  \
    2.10 +          "Optimize loads from stable fields (marked w/ @Stable)")          \
    2.11                                                                              \
    2.12    develop(bool, TraceInvokeDynamic, false,                                  \
    2.13            "trace internal invoke dynamic operations")                       \
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/compiler/stable/TestStableBoolean.java	Fri Mar 28 10:13:37 2014 -0700
     3.3 @@ -0,0 +1,627 @@
     3.4 +/*
     3.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.  Oracle designates this
    3.11 + * particular file as subject to the "Classpath" exception as provided
    3.12 + * by Oracle in the LICENSE file that accompanied this code.
    3.13 + *
    3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 + * version 2 for more details (a copy is included in the LICENSE file that
    3.18 + * accompanied this code).
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License version
    3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.23 + *
    3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.25 + * or visit www.oracle.com if you need additional information or have any
    3.26 + * questions.
    3.27 + */
    3.28 +
    3.29 +/*
    3.30 + * @test TestStableBoolean
    3.31 + * @summary tests on stable fields and arrays
    3.32 + * @library /testlibrary
    3.33 + * @compile -XDignore.symbol.file TestStableBoolean.java
    3.34 + * @run main ClassFileInstaller
    3.35 + *           java/lang/invoke/TestStableBoolean
    3.36 + *           java/lang/invoke/TestStableBoolean$BooleanStable
    3.37 + *           java/lang/invoke/TestStableBoolean$StaticBooleanStable
    3.38 + *           java/lang/invoke/TestStableBoolean$VolatileBooleanStable
    3.39 + *           java/lang/invoke/TestStableBoolean$BooleanArrayDim1
    3.40 + *           java/lang/invoke/TestStableBoolean$BooleanArrayDim2
    3.41 + *           java/lang/invoke/TestStableBoolean$BooleanArrayDim3
    3.42 + *           java/lang/invoke/TestStableBoolean$BooleanArrayDim4
    3.43 + *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim0
    3.44 + *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim1
    3.45 + *           java/lang/invoke/TestStableBoolean$NestedStableField
    3.46 + *           java/lang/invoke/TestStableBoolean$NestedStableField$A
    3.47 + *           java/lang/invoke/TestStableBoolean$NestedStableField1
    3.48 + *           java/lang/invoke/TestStableBoolean$NestedStableField1$A
    3.49 + *           java/lang/invoke/TestStableBoolean$NestedStableField2
    3.50 + *           java/lang/invoke/TestStableBoolean$NestedStableField2$A
    3.51 + *           java/lang/invoke/TestStableBoolean$NestedStableField3
    3.52 + *           java/lang/invoke/TestStableBoolean$NestedStableField3$A
    3.53 + *           java/lang/invoke/TestStableBoolean$DefaultValue
    3.54 + *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim2
    3.55 + *
    3.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    3.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
    3.58 + *                   -server -XX:-TieredCompilation -Xcomp
    3.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    3.60 + *                   java.lang.invoke.TestStableBoolean
    3.61 + *
    3.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    3.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
    3.64 + *                   -server -XX:-TieredCompilation -Xcomp
    3.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    3.66 + *                   java.lang.invoke.TestStableBoolean
    3.67 + *
    3.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    3.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
    3.70 + *                   -server -XX:-TieredCompilation -Xcomp
    3.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    3.72 + *                   java.lang.invoke.TestStableBoolean
    3.73 + *
    3.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    3.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
    3.76 + *                   -server -XX:-TieredCompilation -Xcomp
    3.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    3.78 + *                   java.lang.invoke.TestStableBoolean
    3.79 + */
    3.80 +package java.lang.invoke;
    3.81 +
    3.82 +import com.sun.management.HotSpotDiagnosticMXBean;
    3.83 +import com.sun.management.VMOption;
    3.84 +import sun.management.ManagementFactoryHelper;
    3.85 +import java.lang.reflect.InvocationTargetException;
    3.86 +
    3.87 +public class TestStableBoolean {
    3.88 +    public static void main(String[] args) throws Exception {
    3.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
    3.90 +        System.out.println();
    3.91 +
    3.92 +        run(DefaultValue.class);
    3.93 +        run(BooleanStable.class);
    3.94 +        run(StaticBooleanStable.class);
    3.95 +        run(VolatileBooleanStable.class);
    3.96 +
    3.97 +        // @Stable arrays: Dim 1-4
    3.98 +        run(BooleanArrayDim1.class);
    3.99 +        run(BooleanArrayDim2.class);
   3.100 +        run(BooleanArrayDim3.class);
   3.101 +        run(BooleanArrayDim4.class);
   3.102 +
   3.103 +        // @Stable Object field: dynamic arrays
   3.104 +        run(ObjectArrayLowerDim0.class);
   3.105 +        run(ObjectArrayLowerDim1.class);
   3.106 +        run(ObjectArrayLowerDim2.class);
   3.107 +
   3.108 +        // Nested @Stable fields
   3.109 +        run(NestedStableField.class);
   3.110 +        run(NestedStableField1.class);
   3.111 +        run(NestedStableField2.class);
   3.112 +        run(NestedStableField3.class);
   3.113 +
   3.114 +        if (failed) {
   3.115 +            throw new Error("TEST FAILED");
   3.116 +        }
   3.117 +    }
   3.118 +
   3.119 +    /* ==================================================== */
   3.120 +
   3.121 +    static class DefaultValue {
   3.122 +        public @Stable boolean v;
   3.123 +
   3.124 +        public static final DefaultValue c = new DefaultValue();
   3.125 +        public static boolean get() { return c.v; }
   3.126 +        public static void test() throws Exception {
   3.127 +                        boolean val1 = get();
   3.128 +            c.v = true; boolean val2 = get();
   3.129 +            assertEquals(val1, false);
   3.130 +            assertEquals(val2, true);
   3.131 +        }
   3.132 +    }
   3.133 +
   3.134 +    /* ==================================================== */
   3.135 +
   3.136 +    static class BooleanStable {
   3.137 +        public @Stable boolean v;
   3.138 +
   3.139 +        public static final BooleanStable c = new BooleanStable();
   3.140 +        public static boolean get() { return c.v; }
   3.141 +        public static void test() throws Exception {
   3.142 +            c.v = true; boolean val1 = get();
   3.143 +            c.v = false; boolean val2 = get();
   3.144 +            assertEquals(val1, true);
   3.145 +            assertEquals(val2, (isStableEnabled ? true : false));
   3.146 +        }
   3.147 +    }
   3.148 +
   3.149 +    /* ==================================================== */
   3.150 +
   3.151 +    static class StaticBooleanStable {
   3.152 +        public static @Stable boolean v;
   3.153 +
   3.154 +        public static final StaticBooleanStable c = new StaticBooleanStable();
   3.155 +        public static boolean get() { return c.v; }
   3.156 +        public static void test() throws Exception {
   3.157 +            c.v = true; boolean val1 = get();
   3.158 +            c.v = false; boolean val2 = get();
   3.159 +            assertEquals(val1, true);
   3.160 +            assertEquals(val2, (isStableEnabled ? true : false));
   3.161 +        }
   3.162 +    }
   3.163 +
   3.164 +    /* ==================================================== */
   3.165 +
   3.166 +    static class VolatileBooleanStable {
   3.167 +        public @Stable volatile boolean v;
   3.168 +
   3.169 +        public static final VolatileBooleanStable c = new VolatileBooleanStable();
   3.170 +        public static boolean get() { return c.v; }
   3.171 +        public static void test() throws Exception {
   3.172 +            c.v = true; boolean val1 = get();
   3.173 +            c.v = false; boolean val2 = get();
   3.174 +            assertEquals(val1, true);
   3.175 +            assertEquals(val2, (isStableEnabled ? true : false));
   3.176 +        }
   3.177 +    }
   3.178 +
   3.179 +    /* ==================================================== */
   3.180 +    // @Stable array == field && all components are stable
   3.181 +
   3.182 +    static class BooleanArrayDim1 {
   3.183 +        public @Stable boolean[] v;
   3.184 +
   3.185 +        public static final BooleanArrayDim1 c = new BooleanArrayDim1();
   3.186 +        public static boolean get() { return c.v[0]; }
   3.187 +        public static boolean get1() { return c.v[10]; }
   3.188 +        public static boolean[] get2() { return c.v; }
   3.189 +        public static void test() throws Exception {
   3.190 +            {
   3.191 +                c.v = new boolean[1]; c.v[0] = true;  boolean val1 = get();
   3.192 +                                      c.v[0] = false; boolean val2 = get();
   3.193 +                assertEquals(val1, true);
   3.194 +                assertEquals(val2, (isStableEnabled ? true : false));
   3.195 +            }
   3.196 +
   3.197 +            {
   3.198 +                c.v = new boolean[20]; c.v[10] = true;  boolean val1 = get1();
   3.199 +                                       c.v[10] = false; boolean val2 = get1();
   3.200 +                assertEquals(val1, true);
   3.201 +                assertEquals(val2, (isStableEnabled ? true : false));
   3.202 +            }
   3.203 +
   3.204 +            {
   3.205 +                c.v = new boolean[1]; boolean[] val1 = get2();
   3.206 +                c.v = new boolean[1]; boolean[] val2 = get2();
   3.207 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.208 +            }
   3.209 +        }
   3.210 +    }
   3.211 +
   3.212 +    /* ==================================================== */
   3.213 +
   3.214 +    static class BooleanArrayDim2 {
   3.215 +        public @Stable boolean[][] v;
   3.216 +
   3.217 +        public static final BooleanArrayDim2 c = new BooleanArrayDim2();
   3.218 +        public static boolean get() { return c.v[0][0]; }
   3.219 +        public static boolean[] get1() { return c.v[0]; }
   3.220 +        public static boolean[][] get2() { return c.v; }
   3.221 +        public static void test() throws Exception {
   3.222 +            {
   3.223 +                c.v = new boolean[1][1]; c.v[0][0] = true;  boolean val1 = get();
   3.224 +                                         c.v[0][0] = false; boolean val2 = get();
   3.225 +                assertEquals(val1, true);
   3.226 +                assertEquals(val2, (isStableEnabled ? true : false));
   3.227 +
   3.228 +                c.v = new boolean[1][1]; c.v[0][0] = false; boolean val3 = get();
   3.229 +                assertEquals(val3, (isStableEnabled ? true : false));
   3.230 +
   3.231 +                c.v[0] = new boolean[1]; c.v[0][0] = false; boolean val4 = get();
   3.232 +                assertEquals(val4, (isStableEnabled ? true : false));
   3.233 +            }
   3.234 +
   3.235 +            {
   3.236 +                c.v = new boolean[1][1]; boolean[] val1 = get1();
   3.237 +                c.v[0] = new boolean[1]; boolean[] val2 = get1();
   3.238 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.239 +            }
   3.240 +
   3.241 +            {
   3.242 +                c.v = new boolean[1][1]; boolean[][] val1 = get2();
   3.243 +                c.v = new boolean[1][1]; boolean[][] val2 = get2();
   3.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.245 +            }
   3.246 +        }
   3.247 +    }
   3.248 +
   3.249 +    /* ==================================================== */
   3.250 +
   3.251 +    static class BooleanArrayDim3 {
   3.252 +        public @Stable boolean[][][] v;
   3.253 +
   3.254 +        public static final BooleanArrayDim3 c = new BooleanArrayDim3();
   3.255 +        public static boolean get() { return c.v[0][0][0]; }
   3.256 +        public static boolean[] get1() { return c.v[0][0]; }
   3.257 +        public static boolean[][] get2() { return c.v[0]; }
   3.258 +        public static boolean[][][] get3() { return c.v; }
   3.259 +        public static void test() throws Exception {
   3.260 +            {
   3.261 +                c.v = new boolean[1][1][1]; c.v[0][0][0] = true;  boolean val1 = get();
   3.262 +                                            c.v[0][0][0] = false; boolean val2 = get();
   3.263 +                assertEquals(val1, true);
   3.264 +                assertEquals(val2, (isStableEnabled ? true : false));
   3.265 +
   3.266 +                c.v = new boolean[1][1][1]; c.v[0][0][0] = false; boolean val3 = get();
   3.267 +                assertEquals(val3, (isStableEnabled ? true : false));
   3.268 +
   3.269 +                c.v[0] = new boolean[1][1]; c.v[0][0][0] = false; boolean val4 = get();
   3.270 +                assertEquals(val4, (isStableEnabled ? true : false));
   3.271 +
   3.272 +                c.v[0][0] = new boolean[1]; c.v[0][0][0] = false; boolean val5 = get();
   3.273 +                assertEquals(val5, (isStableEnabled ? true : false));
   3.274 +            }
   3.275 +
   3.276 +            {
   3.277 +                c.v = new boolean[1][1][1]; boolean[] val1 = get1();
   3.278 +                c.v[0][0] = new boolean[1]; boolean[] val2 = get1();
   3.279 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.280 +            }
   3.281 +
   3.282 +            {
   3.283 +                c.v = new boolean[1][1][1]; boolean[][] val1 = get2();
   3.284 +                c.v[0] = new boolean[1][1]; boolean[][] val2 = get2();
   3.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.286 +            }
   3.287 +
   3.288 +            {
   3.289 +                c.v = new boolean[1][1][1]; boolean[][][] val1 = get3();
   3.290 +                c.v = new boolean[1][1][1]; boolean[][][] val2 = get3();
   3.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.292 +            }
   3.293 +        }
   3.294 +    }
   3.295 +
   3.296 +    /* ==================================================== */
   3.297 +
   3.298 +    static class BooleanArrayDim4 {
   3.299 +        public @Stable boolean[][][][] v;
   3.300 +
   3.301 +        public static final BooleanArrayDim4 c = new BooleanArrayDim4();
   3.302 +        public static boolean get() { return c.v[0][0][0][0]; }
   3.303 +        public static boolean[] get1() { return c.v[0][0][0]; }
   3.304 +        public static boolean[][] get2() { return c.v[0][0]; }
   3.305 +        public static boolean[][][] get3() { return c.v[0]; }
   3.306 +        public static boolean[][][][] get4() { return c.v; }
   3.307 +        public static void test() throws Exception {
   3.308 +            {
   3.309 +                c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = true;  boolean val1 = get();
   3.310 +                                               c.v[0][0][0][0] = false; boolean val2 = get();
   3.311 +                assertEquals(val1, true);
   3.312 +                assertEquals(val2, (isStableEnabled ? true : false));
   3.313 +
   3.314 +                c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = false; boolean val3 = get();
   3.315 +                assertEquals(val3, (isStableEnabled ? true : false));
   3.316 +
   3.317 +                c.v[0] = new boolean[1][1][1]; c.v[0][0][0][0] = false; boolean val4 = get();
   3.318 +                assertEquals(val4, (isStableEnabled ? true : false));
   3.319 +
   3.320 +                c.v[0][0] = new boolean[1][1]; c.v[0][0][0][0] = false; boolean val5 = get();
   3.321 +                assertEquals(val5, (isStableEnabled ? true : false));
   3.322 +
   3.323 +                c.v[0][0][0] = new boolean[1]; c.v[0][0][0][0] = false; boolean val6 = get();
   3.324 +                assertEquals(val6, (isStableEnabled ? true : false));
   3.325 +            }
   3.326 +
   3.327 +            {
   3.328 +                c.v = new boolean[1][1][1][1]; boolean[] val1 = get1();
   3.329 +                c.v[0][0][0] = new boolean[1]; boolean[] val2 = get1();
   3.330 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.331 +            }
   3.332 +
   3.333 +            {
   3.334 +                c.v = new boolean[1][1][1][1]; boolean[][] val1 = get2();
   3.335 +                c.v[0][0] = new boolean[1][1]; boolean[][] val2 = get2();
   3.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.337 +            }
   3.338 +
   3.339 +            {
   3.340 +                c.v = new boolean[1][1][1][1]; boolean[][][] val1 = get3();
   3.341 +                c.v[0] = new boolean[1][1][1]; boolean[][][] val2 = get3();
   3.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.343 +            }
   3.344 +
   3.345 +            {
   3.346 +                c.v = new boolean[1][1][1][1]; boolean[][][][] val1 = get4();
   3.347 +                c.v = new boolean[1][1][1][1]; boolean[][][][] val2 = get4();
   3.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.349 +            }
   3.350 +
   3.351 +        }
   3.352 +    }
   3.353 +
   3.354 +    /* ==================================================== */
   3.355 +    // Dynamic Dim is higher than static
   3.356 +
   3.357 +    static class ObjectArrayLowerDim0 {
   3.358 +        public @Stable Object v;
   3.359 +
   3.360 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
   3.361 +        public static boolean get() { return ((boolean[])c.v)[0]; }
   3.362 +        public static boolean[] get1() { return (boolean[])c.v; }
   3.363 +        public static boolean[] get2() { return (boolean[])c.v; }
   3.364 +
   3.365 +        public static void test() throws Exception {
   3.366 +            {
   3.367 +                c.v = new boolean[1]; ((boolean[])c.v)[0] = true;  boolean val1 = get();
   3.368 +                                      ((boolean[])c.v)[0] = false; boolean val2 = get();
   3.369 +
   3.370 +                assertEquals(val1, true);
   3.371 +                assertEquals(val2, false);
   3.372 +            }
   3.373 +
   3.374 +            {
   3.375 +                c.v = new boolean[1]; boolean[] val1 = get1();
   3.376 +                c.v = new boolean[1]; boolean[] val2 = get1();
   3.377 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.378 +            }
   3.379 +        }
   3.380 +    }
   3.381 +
   3.382 +    /* ==================================================== */
   3.383 +
   3.384 +    static class ObjectArrayLowerDim1 {
   3.385 +        public @Stable Object[] v;
   3.386 +
   3.387 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
   3.388 +        public static boolean get() { return ((boolean[][])c.v)[0][0]; }
   3.389 +        public static boolean[] get1() { return (boolean[])(c.v[0]); }
   3.390 +        public static Object[] get2() { return c.v; }
   3.391 +
   3.392 +        public static void test() throws Exception {
   3.393 +            {
   3.394 +                c.v = new boolean[1][1]; ((boolean[][])c.v)[0][0] = true;  boolean val1 = get();
   3.395 +                                         ((boolean[][])c.v)[0][0] = false; boolean val2 = get();
   3.396 +
   3.397 +                assertEquals(val1, true);
   3.398 +                assertEquals(val2, false);
   3.399 +            }
   3.400 +
   3.401 +            {
   3.402 +                c.v = new boolean[1][1]; c.v[0] = new boolean[0]; boolean[] val1 = get1();
   3.403 +                                         c.v[0] = new boolean[0]; boolean[] val2 = get1();
   3.404 +
   3.405 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.406 +            }
   3.407 +
   3.408 +            {
   3.409 +                c.v = new boolean[0][0]; Object[] val1 = get2();
   3.410 +                c.v = new boolean[0][0]; Object[] val2 = get2();
   3.411 +
   3.412 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.413 +            }
   3.414 +        }
   3.415 +    }
   3.416 +
   3.417 +    /* ==================================================== */
   3.418 +
   3.419 +    static class ObjectArrayLowerDim2 {
   3.420 +        public @Stable Object[][] v;
   3.421 +
   3.422 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
   3.423 +        public static boolean get() { return ((boolean[][][])c.v)[0][0][0]; }
   3.424 +        public static boolean[] get1() { return (boolean[])(c.v[0][0]); }
   3.425 +        public static boolean[][] get2() { return (boolean[][])(c.v[0]); }
   3.426 +        public static Object[][] get3() { return c.v; }
   3.427 +
   3.428 +        public static void test() throws Exception {
   3.429 +            {
   3.430 +                c.v = new boolean[1][1][1]; ((boolean[][][])c.v)[0][0][0] = true;  boolean val1 = get();
   3.431 +                                            ((boolean[][][])c.v)[0][0][0] = false; boolean val2 = get();
   3.432 +
   3.433 +                assertEquals(val1, true);
   3.434 +                assertEquals(val2, false);
   3.435 +            }
   3.436 +
   3.437 +            {
   3.438 +                c.v = new boolean[1][1][1]; c.v[0][0] = new boolean[0]; boolean[] val1 = get1();
   3.439 +                                            c.v[0][0] = new boolean[0]; boolean[] val2 = get1();
   3.440 +
   3.441 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.442 +            }
   3.443 +
   3.444 +            {
   3.445 +                c.v = new boolean[1][1][1]; c.v[0] = new boolean[0][0]; boolean[][] val1 = get2();
   3.446 +                                            c.v[0] = new boolean[0][0]; boolean[][] val2 = get2();
   3.447 +
   3.448 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.449 +            }
   3.450 +
   3.451 +            {
   3.452 +                c.v = new boolean[0][0][0]; Object[][] val1 = get3();
   3.453 +                c.v = new boolean[0][0][0]; Object[][] val2 = get3();
   3.454 +
   3.455 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   3.456 +            }
   3.457 +        }
   3.458 +    }
   3.459 +
   3.460 +    /* ==================================================== */
   3.461 +
   3.462 +    static class NestedStableField {
   3.463 +        static class A {
   3.464 +            public @Stable boolean a;
   3.465 +
   3.466 +        }
   3.467 +        public @Stable A v;
   3.468 +
   3.469 +        public static final NestedStableField c = new NestedStableField();
   3.470 +        public static A get() { return c.v; }
   3.471 +        public static boolean get1() { return get().a; }
   3.472 +
   3.473 +        public static void test() throws Exception {
   3.474 +            {
   3.475 +                c.v = new A(); c.v.a = true;  A val1 = get();
   3.476 +                               c.v.a = false; A val2 = get();
   3.477 +
   3.478 +                assertEquals(val1.a, false);
   3.479 +                assertEquals(val2.a, false);
   3.480 +            }
   3.481 +
   3.482 +            {
   3.483 +                c.v = new A(); c.v.a = true;  boolean val1 = get1();
   3.484 +                               c.v.a = false; boolean val2 = get1();
   3.485 +                c.v = new A(); c.v.a = false; boolean val3 = get1();
   3.486 +
   3.487 +                assertEquals(val1, true);
   3.488 +                assertEquals(val2, (isStableEnabled ? true : false));
   3.489 +                assertEquals(val3, (isStableEnabled ? true : false));
   3.490 +            }
   3.491 +        }
   3.492 +    }
   3.493 +
   3.494 +    /* ==================================================== */
   3.495 +
   3.496 +    static class NestedStableField1 {
   3.497 +        static class A {
   3.498 +            public @Stable boolean a;
   3.499 +            public @Stable A next;
   3.500 +        }
   3.501 +        public @Stable A v;
   3.502 +
   3.503 +        public static final NestedStableField1 c = new NestedStableField1();
   3.504 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
   3.505 +        public static boolean get1() { return get().a; }
   3.506 +
   3.507 +        public static void test() throws Exception {
   3.508 +            {
   3.509 +                c.v = new A(); c.v.next = new A(); c.v.next.next  = c.v;
   3.510 +                               c.v.a = true;  c.v.next.a = true;  A val1 = get();
   3.511 +                               c.v.a = false; c.v.next.a = false; A val2 = get();
   3.512 +
   3.513 +                assertEquals(val1.a, false);
   3.514 +                assertEquals(val2.a, false);
   3.515 +            }
   3.516 +
   3.517 +            {
   3.518 +                c.v = new A(); c.v.next = c.v;
   3.519 +                               c.v.a = true;  boolean val1 = get1();
   3.520 +                               c.v.a = false; boolean val2 = get1();
   3.521 +                c.v = new A(); c.v.next = c.v;
   3.522 +                               c.v.a = false; boolean val3 = get1();
   3.523 +
   3.524 +                assertEquals(val1, true);
   3.525 +                assertEquals(val2, (isStableEnabled ? true : false));
   3.526 +                assertEquals(val3, (isStableEnabled ? true : false));
   3.527 +            }
   3.528 +        }
   3.529 +    }
   3.530 +   /* ==================================================== */
   3.531 +
   3.532 +    static class NestedStableField2 {
   3.533 +        static class A {
   3.534 +            public @Stable boolean a;
   3.535 +            public @Stable A left;
   3.536 +            public         A right;
   3.537 +        }
   3.538 +
   3.539 +        public @Stable A v;
   3.540 +
   3.541 +        public static final NestedStableField2 c = new NestedStableField2();
   3.542 +        public static boolean get() { return c.v.left.left.left.a; }
   3.543 +        public static boolean get1() { return c.v.left.left.right.left.a; }
   3.544 +
   3.545 +        public static void test() throws Exception {
   3.546 +            {
   3.547 +                c.v = new A(); c.v.left = c.v.right = c.v;
   3.548 +                               c.v.a = true;  boolean val1 = get(); boolean val2 = get1();
   3.549 +                               c.v.a = false; boolean val3 = get(); boolean val4 = get1();
   3.550 +
   3.551 +                assertEquals(val1, true);
   3.552 +                assertEquals(val3, (isStableEnabled ? true : false));
   3.553 +
   3.554 +                assertEquals(val2, true);
   3.555 +                assertEquals(val4, false);
   3.556 +            }
   3.557 +        }
   3.558 +    }
   3.559 +
   3.560 +    /* ==================================================== */
   3.561 +
   3.562 +    static class NestedStableField3 {
   3.563 +        static class A {
   3.564 +            public @Stable boolean a;
   3.565 +            public @Stable A[] left;
   3.566 +            public         A[] right;
   3.567 +        }
   3.568 +
   3.569 +        public @Stable A[] v;
   3.570 +
   3.571 +        public static final NestedStableField3 c = new NestedStableField3();
   3.572 +        public static boolean get() { return c.v[0].left[1].left[0].left[1].a; }
   3.573 +        public static boolean get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
   3.574 +
   3.575 +        public static void test() throws Exception {
   3.576 +            {
   3.577 +                A elem = new A();
   3.578 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
   3.579 +                               elem.a = true;  boolean val1 = get(); boolean val2 = get1();
   3.580 +                               elem.a = false; boolean val3 = get(); boolean val4 = get1();
   3.581 +
   3.582 +                assertEquals(val1, true);
   3.583 +                assertEquals(val3, (isStableEnabled ? true : false));
   3.584 +
   3.585 +                assertEquals(val2, true);
   3.586 +                assertEquals(val4, false);
   3.587 +            }
   3.588 +        }
   3.589 +    }
   3.590 +
   3.591 +    /* ==================================================== */
   3.592 +    // Auxiliary methods
   3.593 +    static void assertEquals(boolean i, boolean j) { if (i != j)  throw new AssertionError(i + " != " + j); }
   3.594 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
   3.595 +
   3.596 +    static boolean failed = false;
   3.597 +
   3.598 +    public static void run(Class<?> test) {
   3.599 +        Throwable ex = null;
   3.600 +        System.out.print(test.getName()+": ");
   3.601 +        try {
   3.602 +            test.getMethod("test").invoke(null);
   3.603 +        } catch (InvocationTargetException e) {
   3.604 +            ex = e.getCause();
   3.605 +        } catch (Throwable e) {
   3.606 +            ex = e;
   3.607 +        } finally {
   3.608 +            if (ex == null) {
   3.609 +                System.out.println("PASSED");
   3.610 +            } else {
   3.611 +                failed = true;
   3.612 +                System.out.println("FAILED");
   3.613 +                ex.printStackTrace(System.out);
   3.614 +            }
   3.615 +        }
   3.616 +    }
   3.617 +
   3.618 +    static final boolean isStableEnabled;
   3.619 +    static {
   3.620 +        HotSpotDiagnosticMXBean diagnostic
   3.621 +                = ManagementFactoryHelper.getDiagnosticMXBean();
   3.622 +        VMOption tmp;
   3.623 +        try {
   3.624 +            tmp = diagnostic.getVMOption("FoldStableValues");
   3.625 +        } catch (IllegalArgumentException e) {
   3.626 +            tmp = null;
   3.627 +        }
   3.628 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
   3.629 +    }
   3.630 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/compiler/stable/TestStableByte.java	Fri Mar 28 10:13:37 2014 -0700
     4.3 @@ -0,0 +1,632 @@
     4.4 +/*
     4.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.  Oracle designates this
    4.11 + * particular file as subject to the "Classpath" exception as provided
    4.12 + * by Oracle in the LICENSE file that accompanied this code.
    4.13 + *
    4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 + * version 2 for more details (a copy is included in the LICENSE file that
    4.18 + * accompanied this code).
    4.19 + *
    4.20 + * You should have received a copy of the GNU General Public License version
    4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 + *
    4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.25 + * or visit www.oracle.com if you need additional information or have any
    4.26 + * questions.
    4.27 + */
    4.28 +
    4.29 +/*
    4.30 + * @test TestStableByte
    4.31 + * @summary tests on stable fields and arrays
    4.32 + * @library /testlibrary
    4.33 + * @compile -XDignore.symbol.file TestStableByte.java
    4.34 + * @run main ClassFileInstaller
    4.35 + *           java/lang/invoke/TestStableByte
    4.36 + *           java/lang/invoke/TestStableByte$ByteStable
    4.37 + *           java/lang/invoke/TestStableByte$StaticByteStable
    4.38 + *           java/lang/invoke/TestStableByte$VolatileByteStable
    4.39 + *           java/lang/invoke/TestStableByte$ByteArrayDim1
    4.40 + *           java/lang/invoke/TestStableByte$ByteArrayDim2
    4.41 + *           java/lang/invoke/TestStableByte$ByteArrayDim3
    4.42 + *           java/lang/invoke/TestStableByte$ByteArrayDim4
    4.43 + *           java/lang/invoke/TestStableByte$ObjectArrayLowerDim0
    4.44 + *           java/lang/invoke/TestStableByte$ObjectArrayLowerDim1
    4.45 + *           java/lang/invoke/TestStableByte$NestedStableField
    4.46 + *           java/lang/invoke/TestStableByte$NestedStableField$A
    4.47 + *           java/lang/invoke/TestStableByte$NestedStableField1
    4.48 + *           java/lang/invoke/TestStableByte$NestedStableField1$A
    4.49 + *           java/lang/invoke/TestStableByte$NestedStableField2
    4.50 + *           java/lang/invoke/TestStableByte$NestedStableField2$A
    4.51 + *           java/lang/invoke/TestStableByte$NestedStableField3
    4.52 + *           java/lang/invoke/TestStableByte$NestedStableField3$A
    4.53 + *           java/lang/invoke/TestStableByte$DefaultValue
    4.54 + *           java/lang/invoke/TestStableByte$ObjectArrayLowerDim2
    4.55 + *
    4.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    4.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
    4.58 + *                   -server -XX:-TieredCompilation -Xcomp
    4.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    4.60 + *                   java.lang.invoke.TestStableByte
    4.61 + *
    4.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    4.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
    4.64 + *                   -server -XX:-TieredCompilation -Xcomp
    4.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    4.66 + *                   java.lang.invoke.TestStableByte
    4.67 + *
    4.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    4.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
    4.70 + *                   -server -XX:-TieredCompilation -Xcomp
    4.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    4.72 + *                   java.lang.invoke.TestStableByte
    4.73 + *
    4.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    4.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
    4.76 + *                   -server -XX:-TieredCompilation -Xcomp
    4.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    4.78 + *                   java.lang.invoke.TestStableByte
    4.79 + */
    4.80 +package java.lang.invoke;
    4.81 +
    4.82 +import com.sun.management.HotSpotDiagnosticMXBean;
    4.83 +import com.sun.management.VMOption;
    4.84 +import sun.management.ManagementFactoryHelper;
    4.85 +import java.lang.reflect.InvocationTargetException;
    4.86 +
    4.87 +public class TestStableByte {
    4.88 +    public static void main(String[] args) throws Exception {
    4.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
    4.90 +        System.out.println();
    4.91 +
    4.92 +        run(DefaultValue.class);
    4.93 +        run(ByteStable.class);
    4.94 +        run(StaticByteStable.class);
    4.95 +        run(VolatileByteStable.class);
    4.96 +
    4.97 +        // @Stable arrays: Dim 1-4
    4.98 +        run(ByteArrayDim1.class);
    4.99 +        run(ByteArrayDim2.class);
   4.100 +        run(ByteArrayDim3.class);
   4.101 +        run(ByteArrayDim4.class);
   4.102 +
   4.103 +        // @Stable Object field: dynamic arrays
   4.104 +        run(ObjectArrayLowerDim0.class);
   4.105 +        run(ObjectArrayLowerDim1.class);
   4.106 +        run(ObjectArrayLowerDim2.class);
   4.107 +
   4.108 +        // Nested @Stable fields
   4.109 +        run(NestedStableField.class);
   4.110 +        run(NestedStableField1.class);
   4.111 +        run(NestedStableField2.class);
   4.112 +        run(NestedStableField3.class);
   4.113 +
   4.114 +        if (failed) {
   4.115 +            throw new Error("TEST FAILED");
   4.116 +        }
   4.117 +    }
   4.118 +
   4.119 +    /* ==================================================== */
   4.120 +
   4.121 +    static class DefaultValue {
   4.122 +        public @Stable byte v;
   4.123 +
   4.124 +        public static final DefaultValue c = new DefaultValue();
   4.125 +        public static byte get() { return c.v; }
   4.126 +        public static void test() throws Exception {
   4.127 +                     byte val1 = get();
   4.128 +            c.v = 1; byte val2 = get();
   4.129 +            assertEquals(val1, 0);
   4.130 +            assertEquals(val2, 1);
   4.131 +        }
   4.132 +    }
   4.133 +
   4.134 +    /* ==================================================== */
   4.135 +
   4.136 +    static class ByteStable {
   4.137 +        public @Stable byte v;
   4.138 +
   4.139 +        public static final ByteStable c = new ByteStable();
   4.140 +        public static byte get() { return c.v; }
   4.141 +        public static void test() throws Exception {
   4.142 +            c.v = 5;   byte val1 = get();
   4.143 +            c.v = 127; byte val2 = get();
   4.144 +            assertEquals(val1, 5);
   4.145 +            assertEquals(val2, (isStableEnabled ? 5 : 127));
   4.146 +        }
   4.147 +    }
   4.148 +
   4.149 +    /* ==================================================== */
   4.150 +
   4.151 +    static class StaticByteStable {
   4.152 +        public static @Stable byte v;
   4.153 +
   4.154 +        public static final StaticByteStable c = new StaticByteStable();
   4.155 +        public static byte get() { return c.v; }
   4.156 +        public static void test() throws Exception {
   4.157 +            c.v = 5;   byte val1 = get();
   4.158 +            c.v = 127; byte val2 = get();
   4.159 +            assertEquals(val1, 5);
   4.160 +            assertEquals(val2, (isStableEnabled ? 5 : 127));
   4.161 +        }
   4.162 +    }
   4.163 +
   4.164 +    /* ==================================================== */
   4.165 +
   4.166 +    static class VolatileByteStable {
   4.167 +        public @Stable volatile byte v;
   4.168 +
   4.169 +        public static final VolatileByteStable c = new VolatileByteStable();
   4.170 +        public static byte get() { return c.v; }
   4.171 +        public static void test() throws Exception {
   4.172 +            c.v = 5;   byte val1 = get();
   4.173 +            c.v = 127; byte val2 = get();
   4.174 +            assertEquals(val1, 5);
   4.175 +            assertEquals(val2, (isStableEnabled ? 5 : 127));
   4.176 +        }
   4.177 +    }
   4.178 +
   4.179 +    /* ==================================================== */
   4.180 +    // @Stable array == field && all components are stable
   4.181 +
   4.182 +    static class ByteArrayDim1 {
   4.183 +        public @Stable byte[] v;
   4.184 +
   4.185 +        public static final ByteArrayDim1 c = new ByteArrayDim1();
   4.186 +        public static byte get() { return c.v[0]; }
   4.187 +        public static byte get1() { return c.v[10]; }
   4.188 +        public static byte[] get2() { return c.v; }
   4.189 +        public static void test() throws Exception {
   4.190 +            {
   4.191 +                c.v = new byte[1]; c.v[0] = 1; byte val1 = get();
   4.192 +                                   c.v[0] = 2; byte val2 = get();
   4.193 +                assertEquals(val1, 1);
   4.194 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   4.195 +
   4.196 +                c.v = new byte[1]; c.v[0] = 3; byte val3 = get();
   4.197 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   4.198 +            }
   4.199 +
   4.200 +            {
   4.201 +                c.v = new byte[20]; c.v[10] = 1; byte val1 = get1();
   4.202 +                                    c.v[10] = 2; byte val2 = get1();
   4.203 +                assertEquals(val1, 1);
   4.204 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   4.205 +
   4.206 +                c.v = new byte[20]; c.v[10] = 3; byte val3 = get1();
   4.207 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   4.208 +            }
   4.209 +
   4.210 +            {
   4.211 +                c.v = new byte[1]; byte[] val1 = get2();
   4.212 +                c.v = new byte[1]; byte[] val2 = get2();
   4.213 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.214 +            }
   4.215 +        }
   4.216 +    }
   4.217 +
   4.218 +    /* ==================================================== */
   4.219 +
   4.220 +    static class ByteArrayDim2 {
   4.221 +        public @Stable byte[][] v;
   4.222 +
   4.223 +        public static final ByteArrayDim2 c = new ByteArrayDim2();
   4.224 +        public static byte get() { return c.v[0][0]; }
   4.225 +        public static byte[] get1() { return c.v[0]; }
   4.226 +        public static byte[][] get2() { return c.v; }
   4.227 +        public static void test() throws Exception {
   4.228 +            {
   4.229 +                c.v = new byte[1][1]; c.v[0][0] = 1; byte val1 = get();
   4.230 +                                      c.v[0][0] = 2; byte val2 = get();
   4.231 +                assertEquals(val1, 1);
   4.232 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   4.233 +
   4.234 +                c.v = new byte[1][1]; c.v[0][0] = 3; byte val3 = get();
   4.235 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   4.236 +
   4.237 +                c.v[0] = new byte[1]; c.v[0][0] = 4; byte val4 = get();
   4.238 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   4.239 +            }
   4.240 +
   4.241 +            {
   4.242 +                c.v = new byte[1][1]; byte[] val1 = get1();
   4.243 +                c.v[0] = new byte[1]; byte[] val2 = get1();
   4.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.245 +            }
   4.246 +
   4.247 +            {
   4.248 +                c.v = new byte[1][1]; byte[][] val1 = get2();
   4.249 +                c.v = new byte[1][1]; byte[][] val2 = get2();
   4.250 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.251 +            }
   4.252 +        }
   4.253 +    }
   4.254 +
   4.255 +    /* ==================================================== */
   4.256 +
   4.257 +    static class ByteArrayDim3 {
   4.258 +        public @Stable byte[][][] v;
   4.259 +
   4.260 +        public static final ByteArrayDim3 c = new ByteArrayDim3();
   4.261 +        public static byte get() { return c.v[0][0][0]; }
   4.262 +        public static byte[] get1() { return c.v[0][0]; }
   4.263 +        public static byte[][] get2() { return c.v[0]; }
   4.264 +        public static byte[][][] get3() { return c.v; }
   4.265 +        public static void test() throws Exception {
   4.266 +            {
   4.267 +                c.v = new byte[1][1][1]; c.v[0][0][0] = 1; byte val1 = get();
   4.268 +                                         c.v[0][0][0] = 2; byte val2 = get();
   4.269 +                assertEquals(val1, 1);
   4.270 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   4.271 +
   4.272 +                c.v = new byte[1][1][1]; c.v[0][0][0] = 3; byte val3 = get();
   4.273 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   4.274 +
   4.275 +                c.v[0] = new byte[1][1]; c.v[0][0][0] = 4; byte val4 = get();
   4.276 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   4.277 +
   4.278 +                c.v[0][0] = new byte[1]; c.v[0][0][0] = 5; byte val5 = get();
   4.279 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
   4.280 +            }
   4.281 +
   4.282 +            {
   4.283 +                c.v = new byte[1][1][1]; byte[] val1 = get1();
   4.284 +                c.v[0][0] = new byte[1]; byte[] val2 = get1();
   4.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.286 +            }
   4.287 +
   4.288 +            {
   4.289 +                c.v = new byte[1][1][1]; byte[][] val1 = get2();
   4.290 +                c.v[0] = new byte[1][1]; byte[][] val2 = get2();
   4.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.292 +            }
   4.293 +
   4.294 +            {
   4.295 +                c.v = new byte[1][1][1]; byte[][][] val1 = get3();
   4.296 +                c.v = new byte[1][1][1]; byte[][][] val2 = get3();
   4.297 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.298 +            }
   4.299 +        }
   4.300 +    }
   4.301 +
   4.302 +    /* ==================================================== */
   4.303 +
   4.304 +    static class ByteArrayDim4 {
   4.305 +        public @Stable byte[][][][] v;
   4.306 +
   4.307 +        public static final ByteArrayDim4 c = new ByteArrayDim4();
   4.308 +        public static byte get() { return c.v[0][0][0][0]; }
   4.309 +        public static byte[] get1() { return c.v[0][0][0]; }
   4.310 +        public static byte[][] get2() { return c.v[0][0]; }
   4.311 +        public static byte[][][] get3() { return c.v[0]; }
   4.312 +        public static byte[][][][] get4() { return c.v; }
   4.313 +        public static void test() throws Exception {
   4.314 +            {
   4.315 +                c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 1; byte val1 = get();
   4.316 +                                            c.v[0][0][0][0] = 2; byte val2 = get();
   4.317 +                assertEquals(val1, 1);
   4.318 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   4.319 +
   4.320 +                c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 3; byte val3 = get();
   4.321 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   4.322 +
   4.323 +                c.v[0] = new byte[1][1][1]; c.v[0][0][0][0] = 4; byte val4 = get();
   4.324 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   4.325 +
   4.326 +                c.v[0][0] = new byte[1][1]; c.v[0][0][0][0] = 5; byte val5 = get();
   4.327 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
   4.328 +
   4.329 +                c.v[0][0][0] = new byte[1]; c.v[0][0][0][0] = 6; byte val6 = get();
   4.330 +                assertEquals(val6, (isStableEnabled ? 1 : 6));
   4.331 +            }
   4.332 +
   4.333 +            {
   4.334 +                c.v = new byte[1][1][1][1]; byte[] val1 = get1();
   4.335 +                c.v[0][0][0] = new byte[1]; byte[] val2 = get1();
   4.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.337 +            }
   4.338 +
   4.339 +            {
   4.340 +                c.v = new byte[1][1][1][1]; byte[][] val1 = get2();
   4.341 +                c.v[0][0] = new byte[1][1]; byte[][] val2 = get2();
   4.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.343 +            }
   4.344 +
   4.345 +            {
   4.346 +                c.v = new byte[1][1][1][1]; byte[][][] val1 = get3();
   4.347 +                c.v[0] = new byte[1][1][1]; byte[][][] val2 = get3();
   4.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.349 +            }
   4.350 +
   4.351 +            {
   4.352 +                c.v = new byte[1][1][1][1]; byte[][][][] val1 = get4();
   4.353 +                c.v = new byte[1][1][1][1]; byte[][][][] val2 = get4();
   4.354 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.355 +            }
   4.356 +
   4.357 +        }
   4.358 +    }
   4.359 +
   4.360 +    /* ==================================================== */
   4.361 +    // Dynamic Dim is higher than static
   4.362 +
   4.363 +    static class ObjectArrayLowerDim0 {
   4.364 +        public @Stable Object v;
   4.365 +
   4.366 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
   4.367 +        public static byte get() { return ((byte[])c.v)[0]; }
   4.368 +        public static byte[] get1() { return (byte[])c.v; }
   4.369 +
   4.370 +        public static void test() throws Exception {
   4.371 +            {
   4.372 +                c.v = new byte[1]; ((byte[])c.v)[0] = 1; byte val1 = get();
   4.373 +                                   ((byte[])c.v)[0] = 2; byte val2 = get();
   4.374 +
   4.375 +                assertEquals(val1, 1);
   4.376 +                assertEquals(val2, 2);
   4.377 +            }
   4.378 +
   4.379 +            {
   4.380 +                c.v = new byte[1]; byte[] val1 = get1();
   4.381 +                c.v = new byte[1]; byte[] val2 = get1();
   4.382 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.383 +            }
   4.384 +        }
   4.385 +    }
   4.386 +
   4.387 +    /* ==================================================== */
   4.388 +
   4.389 +    static class ObjectArrayLowerDim1 {
   4.390 +        public @Stable Object[] v;
   4.391 +
   4.392 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
   4.393 +        public static byte get() { return ((byte[][])c.v)[0][0]; }
   4.394 +        public static byte[] get1() { return (byte[])(c.v[0]); }
   4.395 +        public static Object[] get2() { return c.v; }
   4.396 +
   4.397 +        public static void test() throws Exception {
   4.398 +            {
   4.399 +                c.v = new byte[1][1]; ((byte[][])c.v)[0][0] = 1; byte val1 = get();
   4.400 +                                      ((byte[][])c.v)[0][0] = 2; byte val2 = get();
   4.401 +
   4.402 +                assertEquals(val1, 1);
   4.403 +                assertEquals(val2, 2);
   4.404 +            }
   4.405 +
   4.406 +            {
   4.407 +                c.v = new byte[1][1]; c.v[0] = new byte[0]; byte[] val1 = get1();
   4.408 +                                     c.v[0] = new byte[0]; byte[] val2 = get1();
   4.409 +
   4.410 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.411 +            }
   4.412 +
   4.413 +            {
   4.414 +                c.v = new byte[0][0]; Object[] val1 = get2();
   4.415 +                c.v = new byte[0][0]; Object[] val2 = get2();
   4.416 +
   4.417 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.418 +            }
   4.419 +        }
   4.420 +    }
   4.421 +
   4.422 +    /* ==================================================== */
   4.423 +
   4.424 +    static class ObjectArrayLowerDim2 {
   4.425 +        public @Stable Object[][] v;
   4.426 +
   4.427 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
   4.428 +        public static byte get() { return ((byte[][][])c.v)[0][0][0]; }
   4.429 +        public static byte[] get1() { return (byte[])(c.v[0][0]); }
   4.430 +        public static byte[][] get2() { return (byte[][])(c.v[0]); }
   4.431 +        public static Object[][] get3() { return c.v; }
   4.432 +
   4.433 +        public static void test() throws Exception {
   4.434 +            {
   4.435 +                c.v = new byte[1][1][1]; ((byte[][][])c.v)[0][0][0] = 1;  byte val1 = get();
   4.436 +                                         ((byte[][][])c.v)[0][0][0] = 2; byte val2 = get();
   4.437 +
   4.438 +                assertEquals(val1, 1);
   4.439 +                assertEquals(val2, 2);
   4.440 +            }
   4.441 +
   4.442 +            {
   4.443 +                c.v = new byte[1][1][1]; c.v[0][0] = new byte[0]; byte[] val1 = get1();
   4.444 +                                         c.v[0][0] = new byte[0]; byte[] val2 = get1();
   4.445 +
   4.446 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.447 +            }
   4.448 +
   4.449 +            {
   4.450 +                c.v = new byte[1][1][1]; c.v[0] = new byte[0][0]; byte[][] val1 = get2();
   4.451 +                                         c.v[0] = new byte[0][0]; byte[][] val2 = get2();
   4.452 +
   4.453 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.454 +            }
   4.455 +
   4.456 +            {
   4.457 +                c.v = new byte[0][0][0]; Object[][] val1 = get3();
   4.458 +                c.v = new byte[0][0][0]; Object[][] val2 = get3();
   4.459 +
   4.460 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   4.461 +            }
   4.462 +        }
   4.463 +    }
   4.464 +
   4.465 +    /* ==================================================== */
   4.466 +
   4.467 +    static class NestedStableField {
   4.468 +        static class A {
   4.469 +            public @Stable byte a;
   4.470 +
   4.471 +        }
   4.472 +        public @Stable A v;
   4.473 +
   4.474 +        public static final NestedStableField c = new NestedStableField();
   4.475 +        public static A get() { return c.v; }
   4.476 +        public static byte get1() { return get().a; }
   4.477 +
   4.478 +        public static void test() throws Exception {
   4.479 +            {
   4.480 +                c.v = new A(); c.v.a = 1; A val1 = get();
   4.481 +                               c.v.a = 2; A val2 = get();
   4.482 +
   4.483 +                assertEquals(val1.a, 2);
   4.484 +                assertEquals(val2.a, 2);
   4.485 +            }
   4.486 +
   4.487 +            {
   4.488 +                c.v = new A(); c.v.a = 1; byte val1 = get1();
   4.489 +                               c.v.a = 2; byte val2 = get1();
   4.490 +                c.v = new A(); c.v.a = 3; byte val3 = get1();
   4.491 +
   4.492 +                assertEquals(val1, 1);
   4.493 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   4.494 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   4.495 +            }
   4.496 +        }
   4.497 +    }
   4.498 +
   4.499 +    /* ==================================================== */
   4.500 +
   4.501 +    static class NestedStableField1 {
   4.502 +        static class A {
   4.503 +            public @Stable byte a;
   4.504 +            public @Stable A next;
   4.505 +        }
   4.506 +        public @Stable A v;
   4.507 +
   4.508 +        public static final NestedStableField1 c = new NestedStableField1();
   4.509 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
   4.510 +        public static byte get1() { return get().a; }
   4.511 +
   4.512 +        public static void test() throws Exception {
   4.513 +            {
   4.514 +                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
   4.515 +                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
   4.516 +                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
   4.517 +
   4.518 +                assertEquals(val1.a, 2);
   4.519 +                assertEquals(val2.a, 2);
   4.520 +            }
   4.521 +
   4.522 +            {
   4.523 +                c.v = new A(); c.v.next = c.v;
   4.524 +                               c.v.a = 1; byte val1 = get1();
   4.525 +                               c.v.a = 2; byte val2 = get1();
   4.526 +                c.v = new A(); c.v.next = c.v;
   4.527 +                               c.v.a = 3; byte val3 = get1();
   4.528 +
   4.529 +                assertEquals(val1, 1);
   4.530 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   4.531 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   4.532 +            }
   4.533 +        }
   4.534 +    }
   4.535 +   /* ==================================================== */
   4.536 +
   4.537 +    static class NestedStableField2 {
   4.538 +        static class A {
   4.539 +            public @Stable byte a;
   4.540 +            public @Stable A left;
   4.541 +            public         A right;
   4.542 +        }
   4.543 +
   4.544 +        public @Stable A v;
   4.545 +
   4.546 +        public static final NestedStableField2 c = new NestedStableField2();
   4.547 +        public static byte get() { return c.v.left.left.left.a; }
   4.548 +        public static byte get1() { return c.v.left.left.right.left.a; }
   4.549 +
   4.550 +        public static void test() throws Exception {
   4.551 +            {
   4.552 +                c.v = new A(); c.v.left = c.v.right = c.v;
   4.553 +                               c.v.a = 1; byte val1 = get(); byte val2 = get1();
   4.554 +                               c.v.a = 2; byte val3 = get(); byte val4 = get1();
   4.555 +
   4.556 +                assertEquals(val1, 1);
   4.557 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
   4.558 +
   4.559 +                assertEquals(val2, 1);
   4.560 +                assertEquals(val4, 2);
   4.561 +            }
   4.562 +        }
   4.563 +    }
   4.564 +
   4.565 +    /* ==================================================== */
   4.566 +
   4.567 +    static class NestedStableField3 {
   4.568 +        static class A {
   4.569 +            public @Stable byte a;
   4.570 +            public @Stable A[] left;
   4.571 +            public         A[] right;
   4.572 +        }
   4.573 +
   4.574 +        public @Stable A[] v;
   4.575 +
   4.576 +        public static final NestedStableField3 c = new NestedStableField3();
   4.577 +        public static byte get() { return c.v[0].left[1].left[0].left[1].a; }
   4.578 +        public static byte get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
   4.579 +
   4.580 +        public static void test() throws Exception {
   4.581 +            {
   4.582 +                A elem = new A();
   4.583 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
   4.584 +                               elem.a = 1; byte val1 = get(); byte val2 = get1();
   4.585 +                               elem.a = 2; byte val3 = get(); byte val4 = get1();
   4.586 +
   4.587 +                assertEquals(val1, 1);
   4.588 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
   4.589 +
   4.590 +                assertEquals(val2, 1);
   4.591 +                assertEquals(val4, 2);
   4.592 +            }
   4.593 +        }
   4.594 +    }
   4.595 +
   4.596 +    /* ==================================================== */
   4.597 +    // Auxiliary methods
   4.598 +    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
   4.599 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
   4.600 +
   4.601 +    static boolean failed = false;
   4.602 +
   4.603 +    public static void run(Class<?> test) {
   4.604 +        Throwable ex = null;
   4.605 +        System.out.print(test.getName()+": ");
   4.606 +        try {
   4.607 +            test.getMethod("test").invoke(null);
   4.608 +        } catch (InvocationTargetException e) {
   4.609 +            ex = e.getCause();
   4.610 +        } catch (Throwable e) {
   4.611 +            ex = e;
   4.612 +        } finally {
   4.613 +            if (ex == null) {
   4.614 +                System.out.println("PASSED");
   4.615 +            } else {
   4.616 +                failed = true;
   4.617 +                System.out.println("FAILED");
   4.618 +                ex.printStackTrace(System.out);
   4.619 +            }
   4.620 +        }
   4.621 +    }
   4.622 +
   4.623 +    static final boolean isStableEnabled;
   4.624 +    static {
   4.625 +        HotSpotDiagnosticMXBean diagnostic
   4.626 +                = ManagementFactoryHelper.getDiagnosticMXBean();
   4.627 +        VMOption tmp;
   4.628 +        try {
   4.629 +            tmp = diagnostic.getVMOption("FoldStableValues");
   4.630 +        } catch (IllegalArgumentException e) {
   4.631 +            tmp = null;
   4.632 +        }
   4.633 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
   4.634 +    }
   4.635 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/compiler/stable/TestStableChar.java	Fri Mar 28 10:13:37 2014 -0700
     5.3 @@ -0,0 +1,631 @@
     5.4 +/*
     5.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.  Oracle designates this
    5.11 + * particular file as subject to the "Classpath" exception as provided
    5.12 + * by Oracle in the LICENSE file that accompanied this code.
    5.13 + *
    5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.17 + * version 2 for more details (a copy is included in the LICENSE file that
    5.18 + * accompanied this code).
    5.19 + *
    5.20 + * You should have received a copy of the GNU General Public License version
    5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.23 + *
    5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.25 + * or visit www.oracle.com if you need additional information or have any
    5.26 + * questions.
    5.27 + */
    5.28 +
    5.29 +/*
    5.30 + * @test TestStableChar
    5.31 + * @summary tests on stable fields and arrays
    5.32 + * @library /testlibrary
    5.33 + * @compile -XDignore.symbol.file TestStableChar.java
    5.34 + * @run main ClassFileInstaller
    5.35 + *           java/lang/invoke/TestStableChar
    5.36 + *           java/lang/invoke/TestStableChar$CharStable
    5.37 + *           java/lang/invoke/TestStableChar$StaticCharStable
    5.38 + *           java/lang/invoke/TestStableChar$VolatileCharStable
    5.39 + *           java/lang/invoke/TestStableChar$CharArrayDim1
    5.40 + *           java/lang/invoke/TestStableChar$CharArrayDim2
    5.41 + *           java/lang/invoke/TestStableChar$CharArrayDim3
    5.42 + *           java/lang/invoke/TestStableChar$CharArrayDim4
    5.43 + *           java/lang/invoke/TestStableChar$ObjectArrayLowerDim0
    5.44 + *           java/lang/invoke/TestStableChar$ObjectArrayLowerDim1
    5.45 + *           java/lang/invoke/TestStableChar$NestedStableField
    5.46 + *           java/lang/invoke/TestStableChar$NestedStableField$A
    5.47 + *           java/lang/invoke/TestStableChar$NestedStableField1
    5.48 + *           java/lang/invoke/TestStableChar$NestedStableField1$A
    5.49 + *           java/lang/invoke/TestStableChar$NestedStableField2
    5.50 + *           java/lang/invoke/TestStableChar$NestedStableField2$A
    5.51 + *           java/lang/invoke/TestStableChar$NestedStableField3
    5.52 + *           java/lang/invoke/TestStableChar$NestedStableField3$A
    5.53 + *           java/lang/invoke/TestStableChar$DefaultValue
    5.54 + *           java/lang/invoke/TestStableChar$ObjectArrayLowerDim2
    5.55 + *
    5.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    5.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
    5.58 + *                   -server -XX:-TieredCompilation -Xcomp
    5.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    5.60 + *                   java.lang.invoke.TestStableChar
    5.61 + *
    5.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    5.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
    5.64 + *                   -server -XX:-TieredCompilation -Xcomp
    5.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    5.66 + *                   java.lang.invoke.TestStableChar
    5.67 + *
    5.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    5.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
    5.70 + *                   -server -XX:-TieredCompilation -Xcomp
    5.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    5.72 + *                   java.lang.invoke.TestStableChar
    5.73 + *
    5.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    5.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
    5.76 + *                   -server -XX:-TieredCompilation -Xcomp
    5.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    5.78 + *                   java.lang.invoke.TestStableChar
    5.79 + */
    5.80 +package java.lang.invoke;
    5.81 +
    5.82 +import com.sun.management.HotSpotDiagnosticMXBean;
    5.83 +import com.sun.management.VMOption;
    5.84 +import sun.management.ManagementFactoryHelper;
    5.85 +import java.lang.reflect.InvocationTargetException;
    5.86 +
    5.87 +public class TestStableChar {
    5.88 +    public static void main(String[] args) throws Exception {
    5.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
    5.90 +        System.out.println();
    5.91 +
    5.92 +        run(DefaultValue.class);
    5.93 +        run(CharStable.class);
    5.94 +        run(StaticCharStable.class);
    5.95 +        run(VolatileCharStable.class);
    5.96 +
    5.97 +        // @Stable arrays: Dim 1-4
    5.98 +        run(CharArrayDim1.class);
    5.99 +        run(CharArrayDim2.class);
   5.100 +        run(CharArrayDim3.class);
   5.101 +        run(CharArrayDim4.class);
   5.102 +
   5.103 +        // @Stable Object field: dynamic arrays
   5.104 +        run(ObjectArrayLowerDim0.class);
   5.105 +        run(ObjectArrayLowerDim1.class);
   5.106 +        run(ObjectArrayLowerDim2.class);
   5.107 +
   5.108 +        // Nested @Stable fields
   5.109 +        run(NestedStableField.class);
   5.110 +        run(NestedStableField1.class);
   5.111 +        run(NestedStableField2.class);
   5.112 +        run(NestedStableField3.class);
   5.113 +
   5.114 +        if (failed) {
   5.115 +            throw new Error("TEST FAILED");
   5.116 +        }
   5.117 +    }
   5.118 +
   5.119 +    /* ==================================================== */
   5.120 +
   5.121 +    static class DefaultValue {
   5.122 +        public @Stable char v;
   5.123 +
   5.124 +        public static final DefaultValue c = new DefaultValue();
   5.125 +        public static char get() { return c.v; }
   5.126 +        public static void test() throws Exception {
   5.127 +                       char val1 = get();
   5.128 +            c.v = 'a'; char val2 = get();
   5.129 +            assertEquals(val1, 0);
   5.130 +            assertEquals(val2, 'a');
   5.131 +        }
   5.132 +    }
   5.133 +
   5.134 +    /* ==================================================== */
   5.135 +
   5.136 +    static class CharStable {
   5.137 +        public @Stable char v;
   5.138 +
   5.139 +        public static final CharStable c = new CharStable();
   5.140 +        public static char get() { return c.v; }
   5.141 +        public static void test() throws Exception {
   5.142 +            c.v = 'a'; char val1 = get();
   5.143 +            c.v = 'b'; char val2 = get();
   5.144 +            assertEquals(val1, 'a');
   5.145 +            assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.146 +        }
   5.147 +    }
   5.148 +
   5.149 +    /* ==================================================== */
   5.150 +
   5.151 +    static class StaticCharStable {
   5.152 +        public @Stable char v;
   5.153 +
   5.154 +        public static final StaticCharStable c = new StaticCharStable();
   5.155 +        public static char get() { return c.v; }
   5.156 +        public static void test() throws Exception {
   5.157 +            c.v = 'a'; char val1 = get();
   5.158 +            c.v = 'b'; char val2 = get();
   5.159 +            assertEquals(val1, 'a');
   5.160 +            assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.161 +        }
   5.162 +    }
   5.163 +
   5.164 +    /* ==================================================== */
   5.165 +
   5.166 +    static class VolatileCharStable {
   5.167 +        public @Stable volatile char v;
   5.168 +
   5.169 +        public static final VolatileCharStable c = new VolatileCharStable();
   5.170 +        public static char get() { return c.v; }
   5.171 +        public static void test() throws Exception {
   5.172 +            c.v = 'a'; char val1 = get();
   5.173 +            c.v = 'b'; char val2 = get();
   5.174 +            assertEquals(val1, 'a');
   5.175 +            assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.176 +        }
   5.177 +    }
   5.178 +
   5.179 +    /* ==================================================== */
   5.180 +    // @Stable array == field && all components are stable
   5.181 +
   5.182 +    static class CharArrayDim1 {
   5.183 +        public @Stable char[] v;
   5.184 +
   5.185 +        public static final CharArrayDim1 c = new CharArrayDim1();
   5.186 +        public static char get() { return c.v[0]; }
   5.187 +        public static char get1() { return c.v[10]; }
   5.188 +        public static char[] get2() { return c.v; }
   5.189 +        public static void test() throws Exception {
   5.190 +            {
   5.191 +                c.v = new char[1]; c.v[0] = 'a'; char val1 = get();
   5.192 +                                   c.v[0] = 'b'; char val2 = get();
   5.193 +                assertEquals(val1, 'a');
   5.194 +                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.195 +
   5.196 +                c.v = new char[1]; c.v[0] = 'c'; char val3 = get();
   5.197 +                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
   5.198 +            }
   5.199 +
   5.200 +            {
   5.201 +                c.v = new char[20]; c.v[10] = 'a'; char val1 = get1();
   5.202 +                                    c.v[10] = 'b'; char val2 = get1();
   5.203 +                assertEquals(val1, 'a');
   5.204 +                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.205 +
   5.206 +                c.v = new char[20]; c.v[10] = 'c'; char val3 = get1();
   5.207 +                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
   5.208 +            }
   5.209 +
   5.210 +            {
   5.211 +                c.v = new char[1]; char[] val1 = get2();
   5.212 +                c.v = new char[1]; char[] val2 = get2();
   5.213 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.214 +            }
   5.215 +        }
   5.216 +    }
   5.217 +
   5.218 +    /* ==================================================== */
   5.219 +
   5.220 +    static class CharArrayDim2 {
   5.221 +        public @Stable char[][] v;
   5.222 +
   5.223 +        public static final CharArrayDim2 c = new CharArrayDim2();
   5.224 +        public static char get() { return c.v[0][0]; }
   5.225 +        public static char[] get1() { return c.v[0]; }
   5.226 +        public static char[][] get2() { return c.v; }
   5.227 +        public static void test() throws Exception {
   5.228 +            {
   5.229 +                c.v = new char[1][1]; c.v[0][0] = 'a'; char val1 = get();
   5.230 +                                      c.v[0][0] = 'b'; char val2 = get();
   5.231 +                assertEquals(val1, 'a');
   5.232 +                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.233 +
   5.234 +                c.v = new char[1][1]; c.v[0][0] = 'c'; char val3 = get();
   5.235 +                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
   5.236 +
   5.237 +                c.v[0] = new char[1]; c.v[0][0] = 'd'; char val4 = get();
   5.238 +                assertEquals(val4, (isStableEnabled ? 'a' : 'd'));
   5.239 +            }
   5.240 +
   5.241 +            {
   5.242 +                c.v = new char[1][1]; char[] val1 = get1();
   5.243 +                c.v[0] = new char[1]; char[] val2 = get1();
   5.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.245 +            }
   5.246 +
   5.247 +            {
   5.248 +                c.v = new char[1][1]; char[][] val1 = get2();
   5.249 +                c.v = new char[1][1]; char[][] val2 = get2();
   5.250 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.251 +            }
   5.252 +        }
   5.253 +    }
   5.254 +
   5.255 +    /* ==================================================== */
   5.256 +
   5.257 +    static class CharArrayDim3 {
   5.258 +        public @Stable char[][][] v;
   5.259 +
   5.260 +        public static final CharArrayDim3 c = new CharArrayDim3();
   5.261 +        public static char get() { return c.v[0][0][0]; }
   5.262 +        public static char[] get1() { return c.v[0][0]; }
   5.263 +        public static char[][] get2() { return c.v[0]; }
   5.264 +        public static char[][][] get3() { return c.v; }
   5.265 +        public static void test() throws Exception {
   5.266 +            {
   5.267 +                c.v = new char[1][1][1]; c.v[0][0][0] = 'a'; char val1 = get();
   5.268 +                                         c.v[0][0][0] = 'b'; char val2 = get();
   5.269 +                assertEquals(val1, 'a');
   5.270 +                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.271 +
   5.272 +                c.v = new char[1][1][1]; c.v[0][0][0] = 'c'; char val3 = get();
   5.273 +                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
   5.274 +
   5.275 +                c.v[0] = new char[1][1]; c.v[0][0][0] = 'd'; char val4 = get();
   5.276 +                assertEquals(val4, (isStableEnabled ? 'a' : 'd'));
   5.277 +
   5.278 +                c.v[0][0] = new char[1]; c.v[0][0][0] = 'e'; char val5 = get();
   5.279 +                assertEquals(val5, (isStableEnabled ? 'a' : 'e'));
   5.280 +            }
   5.281 +
   5.282 +            {
   5.283 +                c.v = new char[1][1][1]; char[] val1 = get1();
   5.284 +                c.v[0][0] = new char[1]; char[] val2 = get1();
   5.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.286 +            }
   5.287 +
   5.288 +            {
   5.289 +                c.v = new char[1][1][1]; char[][] val1 = get2();
   5.290 +                c.v[0] = new char[1][1]; char[][] val2 = get2();
   5.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.292 +            }
   5.293 +
   5.294 +            {
   5.295 +                c.v = new char[1][1][1]; char[][][] val1 = get3();
   5.296 +                c.v = new char[1][1][1]; char[][][] val2 = get3();
   5.297 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.298 +            }
   5.299 +        }
   5.300 +    }
   5.301 +
   5.302 +    /* ==================================================== */
   5.303 +
   5.304 +    static class CharArrayDim4 {
   5.305 +        public @Stable char[][][][] v;
   5.306 +
   5.307 +        public static final CharArrayDim4 c = new CharArrayDim4();
   5.308 +        public static char get() { return c.v[0][0][0][0]; }
   5.309 +        public static char[] get1() { return c.v[0][0][0]; }
   5.310 +        public static char[][] get2() { return c.v[0][0]; }
   5.311 +        public static char[][][] get3() { return c.v[0]; }
   5.312 +        public static char[][][][] get4() { return c.v; }
   5.313 +        public static void test() throws Exception {
   5.314 +            {
   5.315 +                c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'a'; char val1 = get();
   5.316 +                                            c.v[0][0][0][0] = 'b'; char val2 = get();
   5.317 +                assertEquals(val1, 'a');
   5.318 +                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.319 +
   5.320 +                c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'c'; char val3 = get();
   5.321 +                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
   5.322 +
   5.323 +                c.v[0] = new char[1][1][1]; c.v[0][0][0][0] = 'd'; char val4 = get();
   5.324 +                assertEquals(val4, (isStableEnabled ? 'a' : 'd'));
   5.325 +
   5.326 +                c.v[0][0] = new char[1][1]; c.v[0][0][0][0] = 'e'; char val5 = get();
   5.327 +                assertEquals(val5, (isStableEnabled ? 'a' : 'e'));
   5.328 +
   5.329 +                c.v[0][0][0] = new char[1]; c.v[0][0][0][0] = 'f'; char val6 = get();
   5.330 +                assertEquals(val6, (isStableEnabled ? 'a' : 'f'));
   5.331 +            }
   5.332 +
   5.333 +            {
   5.334 +                c.v = new char[1][1][1][1]; char[] val1 = get1();
   5.335 +                c.v[0][0][0] = new char[1]; char[] val2 = get1();
   5.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.337 +            }
   5.338 +
   5.339 +            {
   5.340 +                c.v = new char[1][1][1][1]; char[][] val1 = get2();
   5.341 +                c.v[0][0] = new char[1][1]; char[][] val2 = get2();
   5.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.343 +            }
   5.344 +
   5.345 +            {
   5.346 +                c.v = new char[1][1][1][1]; char[][][] val1 = get3();
   5.347 +                c.v[0] = new char[1][1][1]; char[][][] val2 = get3();
   5.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.349 +            }
   5.350 +
   5.351 +            {
   5.352 +                c.v = new char[1][1][1][1]; char[][][][] val1 = get4();
   5.353 +                c.v = new char[1][1][1][1]; char[][][][] val2 = get4();
   5.354 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.355 +            }
   5.356 +
   5.357 +        }
   5.358 +    }
   5.359 +
   5.360 +    /* ==================================================== */
   5.361 +    // Dynamic Dim is higher than static
   5.362 +    static class ObjectArrayLowerDim0 {
   5.363 +        public @Stable Object v;
   5.364 +
   5.365 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
   5.366 +        public static char get() { return ((char[])c.v)[0]; }
   5.367 +        public static char[] get1() { return (char[])c.v; }
   5.368 +
   5.369 +        public static void test() throws Exception {
   5.370 +            {
   5.371 +                c.v = new char[1]; ((char[])c.v)[0] = 'a'; char val1 = get();
   5.372 +                                   ((char[])c.v)[0] = 'b'; char val2 = get();
   5.373 +
   5.374 +                assertEquals(val1, 'a');
   5.375 +                assertEquals(val2, 'b');
   5.376 +            }
   5.377 +
   5.378 +            {
   5.379 +                c.v = new char[1]; char[] val1 = get1();
   5.380 +                c.v = new char[1]; char[] val2 = get1();
   5.381 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.382 +            }
   5.383 +        }
   5.384 +    }
   5.385 +
   5.386 +    /* ==================================================== */
   5.387 +
   5.388 +    static class ObjectArrayLowerDim1 {
   5.389 +        public @Stable Object[] v;
   5.390 +
   5.391 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
   5.392 +        public static char get() { return ((char[][])c.v)[0][0]; }
   5.393 +        public static char[] get1() { return (char[])(c.v[0]); }
   5.394 +        public static Object[] get2() { return c.v; }
   5.395 +
   5.396 +        public static void test() throws Exception {
   5.397 +            {
   5.398 +                c.v = new char[1][1]; ((char[][])c.v)[0][0] = 'a'; char val1 = get();
   5.399 +                                      ((char[][])c.v)[0][0] = 'b'; char val2 = get();
   5.400 +
   5.401 +                assertEquals(val1, 'a');
   5.402 +                assertEquals(val2, 'b');
   5.403 +            }
   5.404 +
   5.405 +            {
   5.406 +                c.v = new char[1][1]; c.v[0] = new char[0]; char[] val1 = get1();
   5.407 +                                      c.v[0] = new char[0]; char[] val2 = get1();
   5.408 +
   5.409 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.410 +            }
   5.411 +
   5.412 +            {
   5.413 +                c.v = new char[0][0]; Object[] val1 = get2();
   5.414 +                c.v = new char[0][0]; Object[] val2 = get2();
   5.415 +
   5.416 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.417 +            }
   5.418 +        }
   5.419 +    }
   5.420 +
   5.421 +    /* ==================================================== */
   5.422 +
   5.423 +    static class ObjectArrayLowerDim2 {
   5.424 +        public @Stable Object[][] v;
   5.425 +
   5.426 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
   5.427 +        public static char get() { return ((char[][][])c.v)[0][0][0]; }
   5.428 +        public static char[] get1() { return (char[])(c.v[0][0]); }
   5.429 +        public static char[][] get2() { return (char[][])(c.v[0]); }
   5.430 +        public static Object[][] get3() { return c.v; }
   5.431 +
   5.432 +        public static void test() throws Exception {
   5.433 +            {
   5.434 +                c.v = new char[1][1][1]; ((char[][][])c.v)[0][0][0] = 'a';  char val1 = get();
   5.435 +                                         ((char[][][])c.v)[0][0][0] = 'b'; char val2 = get();
   5.436 +
   5.437 +                assertEquals(val1, 'a');
   5.438 +                assertEquals(val2, 'b');
   5.439 +            }
   5.440 +
   5.441 +            {
   5.442 +                c.v = new char[1][1][1]; c.v[0][0] = new char[0]; char[] val1 = get1();
   5.443 +                                         c.v[0][0] = new char[0]; char[] val2 = get1();
   5.444 +
   5.445 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.446 +            }
   5.447 +
   5.448 +            {
   5.449 +                c.v = new char[1][1][1]; c.v[0] = new char[0][0]; char[][] val1 = get2();
   5.450 +                                         c.v[0] = new char[0][0]; char[][] val2 = get2();
   5.451 +
   5.452 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.453 +            }
   5.454 +
   5.455 +            {
   5.456 +                c.v = new char[0][0][0]; Object[][] val1 = get3();
   5.457 +                c.v = new char[0][0][0]; Object[][] val2 = get3();
   5.458 +
   5.459 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   5.460 +            }
   5.461 +        }
   5.462 +    }
   5.463 +
   5.464 +    /* ==================================================== */
   5.465 +
   5.466 +    static class NestedStableField {
   5.467 +        static class A {
   5.468 +            public @Stable char a;
   5.469 +
   5.470 +        }
   5.471 +        public @Stable A v;
   5.472 +
   5.473 +        public static final NestedStableField c = new NestedStableField();
   5.474 +        public static A get() { return c.v; }
   5.475 +        public static char get1() { return get().a; }
   5.476 +
   5.477 +        public static void test() throws Exception {
   5.478 +            {
   5.479 +                c.v = new A(); c.v.a = 'a'; A val1 = get();
   5.480 +                               c.v.a = 'b'; A val2 = get();
   5.481 +
   5.482 +                assertEquals(val1.a, 'b');
   5.483 +                assertEquals(val2.a, 'b');
   5.484 +            }
   5.485 +
   5.486 +            {
   5.487 +                c.v = new A(); c.v.a = 'a'; char val1 = get1();
   5.488 +                               c.v.a = 'b'; char val2 = get1();
   5.489 +                c.v = new A(); c.v.a = 'c'; char val3 = get1();
   5.490 +
   5.491 +                assertEquals(val1, 'a');
   5.492 +                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.493 +                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
   5.494 +            }
   5.495 +        }
   5.496 +    }
   5.497 +
   5.498 +    /* ==================================================== */
   5.499 +
   5.500 +    static class NestedStableField1 {
   5.501 +        static class A {
   5.502 +            public @Stable char a;
   5.503 +            public @Stable A next;
   5.504 +        }
   5.505 +        public @Stable A v;
   5.506 +
   5.507 +        public static final NestedStableField1 c = new NestedStableField1();
   5.508 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
   5.509 +        public static char get1() { return get().a; }
   5.510 +
   5.511 +        public static void test() throws Exception {
   5.512 +            {
   5.513 +                c.v = new A(); c.v.next = new A(); c.v.next.next  = c.v;
   5.514 +                               c.v.a = 'a'; c.v.next.a = 'a'; A val1 = get();
   5.515 +                               c.v.a = 'b'; c.v.next.a = 'b'; A val2 = get();
   5.516 +
   5.517 +                assertEquals(val1.a, 'b');
   5.518 +                assertEquals(val2.a, 'b');
   5.519 +            }
   5.520 +
   5.521 +            {
   5.522 +                c.v = new A(); c.v.next = c.v;
   5.523 +                               c.v.a = 'a'; char val1 = get1();
   5.524 +                               c.v.a = 'b'; char val2 = get1();
   5.525 +                c.v = new A(); c.v.next = c.v;
   5.526 +                               c.v.a = 'c'; char val3 = get1();
   5.527 +
   5.528 +                assertEquals(val1, 'a');
   5.529 +                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
   5.530 +                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
   5.531 +            }
   5.532 +        }
   5.533 +    }
   5.534 +   /* ==================================================== */
   5.535 +
   5.536 +    static class NestedStableField2 {
   5.537 +        static class A {
   5.538 +            public @Stable char a;
   5.539 +            public @Stable A left;
   5.540 +            public         A right;
   5.541 +        }
   5.542 +
   5.543 +        public @Stable A v;
   5.544 +
   5.545 +        public static final NestedStableField2 c = new NestedStableField2();
   5.546 +        public static char get() { return c.v.left.left.left.a; }
   5.547 +        public static char get1() { return c.v.left.left.right.left.a; }
   5.548 +
   5.549 +        public static void test() throws Exception {
   5.550 +            {
   5.551 +                c.v = new A(); c.v.left = c.v.right = c.v;
   5.552 +                               c.v.a = 'a'; char val1 = get(); char val2 = get1();
   5.553 +                               c.v.a = 'b'; char val3 = get(); char val4 = get1();
   5.554 +
   5.555 +                assertEquals(val1, 'a');
   5.556 +                assertEquals(val3, (isStableEnabled ? 'a' : 'b'));
   5.557 +
   5.558 +                assertEquals(val2, 'a');
   5.559 +                assertEquals(val4, 'b');
   5.560 +            }
   5.561 +        }
   5.562 +    }
   5.563 +
   5.564 +    /* ==================================================== */
   5.565 +
   5.566 +    static class NestedStableField3 {
   5.567 +        static class A {
   5.568 +            public @Stable char a;
   5.569 +            public @Stable A[] left;
   5.570 +            public         A[] right;
   5.571 +        }
   5.572 +
   5.573 +        public @Stable A[] v;
   5.574 +
   5.575 +        public static final NestedStableField3 c = new NestedStableField3();
   5.576 +        public static char get() { return c.v[0].left[1].left[0].left[1].a; }
   5.577 +        public static char get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
   5.578 +
   5.579 +        public static void test() throws Exception {
   5.580 +            {
   5.581 +                A elem = new A();
   5.582 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
   5.583 +                               elem.a = 'a'; char val1 = get(); char val2 = get1();
   5.584 +                               elem.a = 'b'; char val3 = get(); char val4 = get1();
   5.585 +
   5.586 +                assertEquals(val1, 'a');
   5.587 +                assertEquals(val3, (isStableEnabled ? 'a' : 'b'));
   5.588 +
   5.589 +                assertEquals(val2, 'a');
   5.590 +                assertEquals(val4, 'b');
   5.591 +            }
   5.592 +        }
   5.593 +    }
   5.594 +
   5.595 +    /* ==================================================== */
   5.596 +    // Auxiliary methods
   5.597 +    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
   5.598 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
   5.599 +
   5.600 +    static boolean failed = false;
   5.601 +
   5.602 +    public static void run(Class<?> test) {
   5.603 +        Throwable ex = null;
   5.604 +        System.out.print(test.getName()+": ");
   5.605 +        try {
   5.606 +            test.getMethod("test").invoke(null);
   5.607 +        } catch (InvocationTargetException e) {
   5.608 +            ex = e.getCause();
   5.609 +        } catch (Throwable e) {
   5.610 +            ex = e;
   5.611 +        } finally {
   5.612 +            if (ex == null) {
   5.613 +                System.out.println("PASSED");
   5.614 +            } else {
   5.615 +                failed = true;
   5.616 +                System.out.println("FAILED");
   5.617 +                ex.printStackTrace(System.out);
   5.618 +            }
   5.619 +        }
   5.620 +    }
   5.621 +
   5.622 +    static final boolean isStableEnabled;
   5.623 +    static {
   5.624 +        HotSpotDiagnosticMXBean diagnostic
   5.625 +                = ManagementFactoryHelper.getDiagnosticMXBean();
   5.626 +        VMOption tmp;
   5.627 +        try {
   5.628 +            tmp = diagnostic.getVMOption("FoldStableValues");
   5.629 +        } catch (IllegalArgumentException e) {
   5.630 +            tmp = null;
   5.631 +        }
   5.632 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
   5.633 +    }
   5.634 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/compiler/stable/TestStableDouble.java	Fri Mar 28 10:13:37 2014 -0700
     6.3 @@ -0,0 +1,632 @@
     6.4 +/*
     6.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.  Oracle designates this
    6.11 + * particular file as subject to the "Classpath" exception as provided
    6.12 + * by Oracle in the LICENSE file that accompanied this code.
    6.13 + *
    6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.17 + * version 2 for more details (a copy is included in the LICENSE file that
    6.18 + * accompanied this code).
    6.19 + *
    6.20 + * You should have received a copy of the GNU General Public License version
    6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.23 + *
    6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.25 + * or visit www.oracle.com if you need additional information or have any
    6.26 + * questions.
    6.27 + */
    6.28 +
    6.29 +/*
    6.30 + * @test TestStableDouble
    6.31 + * @summary tests on stable fields and arrays
    6.32 + * @library /testlibrary
    6.33 + * @compile -XDignore.symbol.file TestStableDouble.java
    6.34 + * @run main ClassFileInstaller
    6.35 + *           java/lang/invoke/TestStableDouble
    6.36 + *           java/lang/invoke/TestStableDouble$DoubleStable
    6.37 + *           java/lang/invoke/TestStableDouble$StaticDoubleStable
    6.38 + *           java/lang/invoke/TestStableDouble$VolatileDoubleStable
    6.39 + *           java/lang/invoke/TestStableDouble$DoubleArrayDim1
    6.40 + *           java/lang/invoke/TestStableDouble$DoubleArrayDim2
    6.41 + *           java/lang/invoke/TestStableDouble$DoubleArrayDim3
    6.42 + *           java/lang/invoke/TestStableDouble$DoubleArrayDim4
    6.43 + *           java/lang/invoke/TestStableDouble$ObjectArrayLowerDim0
    6.44 + *           java/lang/invoke/TestStableDouble$ObjectArrayLowerDim1
    6.45 + *           java/lang/invoke/TestStableDouble$NestedStableField
    6.46 + *           java/lang/invoke/TestStableDouble$NestedStableField$A
    6.47 + *           java/lang/invoke/TestStableDouble$NestedStableField1
    6.48 + *           java/lang/invoke/TestStableDouble$NestedStableField1$A
    6.49 + *           java/lang/invoke/TestStableDouble$NestedStableField2
    6.50 + *           java/lang/invoke/TestStableDouble$NestedStableField2$A
    6.51 + *           java/lang/invoke/TestStableDouble$NestedStableField3
    6.52 + *           java/lang/invoke/TestStableDouble$NestedStableField3$A
    6.53 + *           java/lang/invoke/TestStableDouble$DefaultValue
    6.54 + *           java/lang/invoke/TestStableDouble$ObjectArrayLowerDim2
    6.55 + *
    6.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    6.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
    6.58 + *                   -server -XX:-TieredCompilation -Xcomp
    6.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    6.60 + *                   java.lang.invoke.TestStableDouble
    6.61 + *
    6.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    6.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
    6.64 + *                   -server -XX:-TieredCompilation -Xcomp
    6.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    6.66 + *                   java.lang.invoke.TestStableDouble
    6.67 + *
    6.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    6.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
    6.70 + *                   -server -XX:-TieredCompilation -Xcomp
    6.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    6.72 + *                   java.lang.invoke.TestStableDouble
    6.73 + *
    6.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    6.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
    6.76 + *                   -server -XX:-TieredCompilation -Xcomp
    6.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    6.78 + *                   java.lang.invoke.TestStableDouble
    6.79 + */
    6.80 +package java.lang.invoke;
    6.81 +
    6.82 +import com.sun.management.HotSpotDiagnosticMXBean;
    6.83 +import com.sun.management.VMOption;
    6.84 +import sun.management.ManagementFactoryHelper;
    6.85 +import java.lang.reflect.InvocationTargetException;
    6.86 +
    6.87 +public class TestStableDouble {
    6.88 +    public static void main(String[] args) throws Exception {
    6.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
    6.90 +        System.out.println();
    6.91 +
    6.92 +        run(DefaultValue.class);
    6.93 +        run(DoubleStable.class);
    6.94 +        run(StaticDoubleStable.class);
    6.95 +        run(VolatileDoubleStable.class);
    6.96 +
    6.97 +        // @Stable arrays: Dim 1-4
    6.98 +        run(DoubleArrayDim1.class);
    6.99 +        run(DoubleArrayDim2.class);
   6.100 +        run(DoubleArrayDim3.class);
   6.101 +        run(DoubleArrayDim4.class);
   6.102 +
   6.103 +        // @Stable Object field: dynamic arrays
   6.104 +        run(ObjectArrayLowerDim0.class);
   6.105 +        run(ObjectArrayLowerDim1.class);
   6.106 +        run(ObjectArrayLowerDim2.class);
   6.107 +
   6.108 +        // Nested @Stable fields
   6.109 +        run(NestedStableField.class);
   6.110 +        run(NestedStableField1.class);
   6.111 +        run(NestedStableField2.class);
   6.112 +        run(NestedStableField3.class);
   6.113 +
   6.114 +        if (failed) {
   6.115 +            throw new Error("TEST FAILED");
   6.116 +        }
   6.117 +    }
   6.118 +
   6.119 +    /* ==================================================== */
   6.120 +
   6.121 +    static class DefaultValue {
   6.122 +        public @Stable double v;
   6.123 +
   6.124 +        public static final DefaultValue c = new DefaultValue();
   6.125 +        public static double get() { return c.v; }
   6.126 +        public static void test() throws Exception {
   6.127 +                       double val1 = get();
   6.128 +            c.v = 1.0; double val2 = get();
   6.129 +            assertEquals(val1, 0);
   6.130 +            assertEquals(val2, 1.0);
   6.131 +        }
   6.132 +    }
   6.133 +
   6.134 +    /* ==================================================== */
   6.135 +
   6.136 +    static class DoubleStable {
   6.137 +        public @Stable double v;
   6.138 +
   6.139 +        public static final DoubleStable c = new DoubleStable();
   6.140 +        public static double get() { return c.v; }
   6.141 +        public static void test() throws Exception {
   6.142 +            c.v = 1.0; double val1 = get();
   6.143 +            c.v = Double.MAX_VALUE; double val2 = get();
   6.144 +            assertEquals(val1, 1.0);
   6.145 +            assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
   6.146 +        }
   6.147 +    }
   6.148 +
   6.149 +    /* ==================================================== */
   6.150 +
   6.151 +    static class StaticDoubleStable {
   6.152 +        public static @Stable double v;
   6.153 +
   6.154 +        public static final StaticDoubleStable c = new StaticDoubleStable();
   6.155 +        public static double get() { return c.v; }
   6.156 +        public static void test() throws Exception {
   6.157 +            c.v = 1.0; double val1 = get();
   6.158 +            c.v = Double.MAX_VALUE; double val2 = get();
   6.159 +            assertEquals(val1, 1.0);
   6.160 +            assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
   6.161 +        }
   6.162 +    }
   6.163 +
   6.164 +    /* ==================================================== */
   6.165 +
   6.166 +    static class VolatileDoubleStable {
   6.167 +        public @Stable double v;
   6.168 +
   6.169 +        public static final VolatileDoubleStable c = new VolatileDoubleStable();
   6.170 +        public static double get() { return c.v; }
   6.171 +        public static void test() throws Exception {
   6.172 +            c.v = 1.0; double val1 = get();
   6.173 +            c.v = Double.MAX_VALUE; double val2 = get();
   6.174 +            assertEquals(val1, 1.0);
   6.175 +            assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
   6.176 +        }
   6.177 +    }
   6.178 +
   6.179 +    /* ==================================================== */
   6.180 +    // @Stable array == field && all components are stable
   6.181 +
   6.182 +    static class DoubleArrayDim1 {
   6.183 +        public @Stable double[] v;
   6.184 +
   6.185 +        public static final DoubleArrayDim1 c = new DoubleArrayDim1();
   6.186 +        public static double get() { return c.v[0]; }
   6.187 +        public static double get1() { return c.v[10]; }
   6.188 +        public static double[] get2() { return c.v; }
   6.189 +        public static void test() throws Exception {
   6.190 +            {
   6.191 +                c.v = new double[1]; c.v[0] = 1.0; double val1 = get();
   6.192 +                                     c.v[0] = 2.0; double val2 = get();
   6.193 +                assertEquals(val1, 1.0);
   6.194 +                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
   6.195 +
   6.196 +                c.v = new double[1]; c.v[0] = 3.0; double val3 = get();
   6.197 +                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
   6.198 +            }
   6.199 +
   6.200 +            {
   6.201 +                c.v = new double[20]; c.v[10] = 1.0; double val1 = get1();
   6.202 +                                      c.v[10] = 2.0; double val2 = get1();
   6.203 +                assertEquals(val1, 1.0);
   6.204 +                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
   6.205 +
   6.206 +                c.v = new double[20]; c.v[10] = 3.0; double val3 = get1();
   6.207 +                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
   6.208 +            }
   6.209 +
   6.210 +            {
   6.211 +                c.v = new double[1]; double[] val1 = get2();
   6.212 +                c.v = new double[1]; double[] val2 = get2();
   6.213 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.214 +            }
   6.215 +        }
   6.216 +    }
   6.217 +
   6.218 +    /* ==================================================== */
   6.219 +
   6.220 +    static class DoubleArrayDim2 {
   6.221 +        public @Stable double[][] v;
   6.222 +
   6.223 +        public static final DoubleArrayDim2 c = new DoubleArrayDim2();
   6.224 +        public static double get() { return c.v[0][0]; }
   6.225 +        public static double[] get1() { return c.v[0]; }
   6.226 +        public static double[][] get2() { return c.v; }
   6.227 +        public static void test() throws Exception {
   6.228 +            {
   6.229 +                c.v = new double[1][1]; c.v[0][0] = 1.0; double val1 = get();
   6.230 +                                        c.v[0][0] = 2.0; double val2 = get();
   6.231 +                assertEquals(val1, 1.0);
   6.232 +                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
   6.233 +
   6.234 +                c.v = new double[1][1]; c.v[0][0] = 3.0; double val3 = get();
   6.235 +                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
   6.236 +
   6.237 +                c.v[0] = new double[1]; c.v[0][0] = 4.0; double val4 = get();
   6.238 +                assertEquals(val4, (isStableEnabled ? 1.0 : 4.0));
   6.239 +            }
   6.240 +
   6.241 +            {
   6.242 +                c.v = new double[1][1]; double[] val1 = get1();
   6.243 +                c.v[0] = new double[1]; double[] val2 = get1();
   6.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.245 +            }
   6.246 +
   6.247 +            {
   6.248 +                c.v = new double[1][1]; double[][] val1 = get2();
   6.249 +                c.v = new double[1][1]; double[][] val2 = get2();
   6.250 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.251 +            }
   6.252 +        }
   6.253 +    }
   6.254 +
   6.255 +    /* ==================================================== */
   6.256 +
   6.257 +    static class DoubleArrayDim3 {
   6.258 +        public @Stable double[][][] v;
   6.259 +
   6.260 +        public static final DoubleArrayDim3 c = new DoubleArrayDim3();
   6.261 +        public static double get() { return c.v[0][0][0]; }
   6.262 +        public static double[] get1() { return c.v[0][0]; }
   6.263 +        public static double[][] get2() { return c.v[0]; }
   6.264 +        public static double[][][] get3() { return c.v; }
   6.265 +        public static void test() throws Exception {
   6.266 +            {
   6.267 +                c.v = new double[1][1][1]; c.v[0][0][0] = 1.0; double val1 = get();
   6.268 +                                           c.v[0][0][0] = 2.0; double val2 = get();
   6.269 +                assertEquals(val1, 1.0);
   6.270 +                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
   6.271 +
   6.272 +                c.v = new double[1][1][1]; c.v[0][0][0] = 3.0; double val3 = get();
   6.273 +                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
   6.274 +
   6.275 +                c.v[0] = new double[1][1]; c.v[0][0][0] = 4.0; double val4 = get();
   6.276 +                assertEquals(val4, (isStableEnabled ? 1.0 : 4.0));
   6.277 +
   6.278 +                c.v[0][0] = new double[1]; c.v[0][0][0] = 5.0; double val5 = get();
   6.279 +                assertEquals(val5, (isStableEnabled ? 1.0 : 5.0));
   6.280 +            }
   6.281 +
   6.282 +            {
   6.283 +                c.v = new double[1][1][1]; double[] val1 = get1();
   6.284 +                c.v[0][0] = new double[1]; double[] val2 = get1();
   6.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.286 +            }
   6.287 +
   6.288 +            {
   6.289 +                c.v = new double[1][1][1]; double[][] val1 = get2();
   6.290 +                c.v[0] = new double[1][1]; double[][] val2 = get2();
   6.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.292 +            }
   6.293 +
   6.294 +            {
   6.295 +                c.v = new double[1][1][1]; double[][][] val1 = get3();
   6.296 +                c.v = new double[1][1][1]; double[][][] val2 = get3();
   6.297 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.298 +            }
   6.299 +        }
   6.300 +    }
   6.301 +
   6.302 +    /* ==================================================== */
   6.303 +
   6.304 +    static class DoubleArrayDim4 {
   6.305 +        public @Stable double[][][][] v;
   6.306 +
   6.307 +        public static final DoubleArrayDim4 c = new DoubleArrayDim4();
   6.308 +        public static double get() { return c.v[0][0][0][0]; }
   6.309 +        public static double[] get1() { return c.v[0][0][0]; }
   6.310 +        public static double[][] get2() { return c.v[0][0]; }
   6.311 +        public static double[][][] get3() { return c.v[0]; }
   6.312 +        public static double[][][][] get4() { return c.v; }
   6.313 +        public static void test() throws Exception {
   6.314 +            {
   6.315 +                c.v = new double[1][1][1][1]; c.v[0][0][0][0] = 1.0; double val1 = get();
   6.316 +                                              c.v[0][0][0][0] = 2.0; double val2 = get();
   6.317 +                assertEquals(val1, 1.0);
   6.318 +                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
   6.319 +
   6.320 +                c.v = new double[1][1][1][1]; c.v[0][0][0][0] = 3.0; double val3 = get();
   6.321 +                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
   6.322 +
   6.323 +                c.v[0] = new double[1][1][1]; c.v[0][0][0][0] = 4.0; double val4 = get();
   6.324 +                assertEquals(val4, (isStableEnabled ? 1.0 : 4.0));
   6.325 +
   6.326 +                c.v[0][0] = new double[1][1]; c.v[0][0][0][0] = 5.0; double val5 = get();
   6.327 +                assertEquals(val5, (isStableEnabled ? 1.0 : 5.0));
   6.328 +
   6.329 +                c.v[0][0][0] = new double[1]; c.v[0][0][0][0] = 6.0; double val6 = get();
   6.330 +                assertEquals(val6, (isStableEnabled ? 1.0 : 6.0));
   6.331 +            }
   6.332 +
   6.333 +            {
   6.334 +                c.v = new double[1][1][1][1]; double[] val1 = get1();
   6.335 +                c.v[0][0][0] = new double[1]; double[] val2 = get1();
   6.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.337 +            }
   6.338 +
   6.339 +            {
   6.340 +                c.v = new double[1][1][1][1]; double[][] val1 = get2();
   6.341 +                c.v[0][0] = new double[1][1]; double[][] val2 = get2();
   6.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.343 +            }
   6.344 +
   6.345 +            {
   6.346 +                c.v = new double[1][1][1][1]; double[][][] val1 = get3();
   6.347 +                c.v[0] = new double[1][1][1]; double[][][] val2 = get3();
   6.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.349 +            }
   6.350 +
   6.351 +            {
   6.352 +                c.v = new double[1][1][1][1]; double[][][][] val1 = get4();
   6.353 +                c.v = new double[1][1][1][1]; double[][][][] val2 = get4();
   6.354 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.355 +            }
   6.356 +
   6.357 +        }
   6.358 +    }
   6.359 +
   6.360 +    /* ==================================================== */
   6.361 +    // Dynamic Dim is higher than static
   6.362 +
   6.363 +    static class ObjectArrayLowerDim0 {
   6.364 +        public @Stable Object v;
   6.365 +
   6.366 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
   6.367 +        public static double get() { return ((double[])c.v)[0]; }
   6.368 +        public static double[] get1() { return (double[])c.v; }
   6.369 +
   6.370 +        public static void test() throws Exception {
   6.371 +            {
   6.372 +                c.v = new double[1]; ((double[])c.v)[0] = 1.0; double val1 = get();
   6.373 +                                     ((double[])c.v)[0] = 2.0; double val2 = get();
   6.374 +
   6.375 +                assertEquals(val1, 1.0);
   6.376 +                assertEquals(val2, 2.0);
   6.377 +            }
   6.378 +
   6.379 +            {
   6.380 +                c.v = new double[1]; double[] val1 = get1();
   6.381 +                c.v = new double[1]; double[] val2 = get1();
   6.382 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.383 +            }
   6.384 +        }
   6.385 +    }
   6.386 +
   6.387 +    /* ==================================================== */
   6.388 +
   6.389 +    static class ObjectArrayLowerDim1 {
   6.390 +        public @Stable Object[] v;
   6.391 +
   6.392 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
   6.393 +        public static double get() { return ((double[][])c.v)[0][0]; }
   6.394 +        public static double[] get1() { return (double[])(c.v[0]); }
   6.395 +        public static Object[] get2() { return c.v; }
   6.396 +
   6.397 +        public static void test() throws Exception {
   6.398 +            {
   6.399 +                c.v = new double[1][1]; ((double[][])c.v)[0][0] = 1.0; double val1 = get();
   6.400 +                                        ((double[][])c.v)[0][0] = 2.0; double val2 = get();
   6.401 +
   6.402 +                assertEquals(val1, 1.0);
   6.403 +                assertEquals(val2, 2.0);
   6.404 +            }
   6.405 +
   6.406 +            {
   6.407 +                c.v = new double[1][1]; c.v[0] = new double[0]; double[] val1 = get1();
   6.408 +                                        c.v[0] = new double[0]; double[] val2 = get1();
   6.409 +
   6.410 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.411 +            }
   6.412 +
   6.413 +            {
   6.414 +                c.v = new double[0][0]; Object[] val1 = get2();
   6.415 +                c.v = new double[0][0]; Object[] val2 = get2();
   6.416 +
   6.417 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.418 +            }
   6.419 +        }
   6.420 +    }
   6.421 +
   6.422 +    /* ==================================================== */
   6.423 +
   6.424 +    static class ObjectArrayLowerDim2 {
   6.425 +        public @Stable Object[][] v;
   6.426 +
   6.427 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
   6.428 +        public static double get() { return ((double[][][])c.v)[0][0][0]; }
   6.429 +        public static double[] get1() { return (double[])(c.v[0][0]); }
   6.430 +        public static double[][] get2() { return (double[][])(c.v[0]); }
   6.431 +        public static Object[][] get3() { return c.v; }
   6.432 +
   6.433 +        public static void test() throws Exception {
   6.434 +            {
   6.435 +                c.v = new double[1][1][1]; ((double[][][])c.v)[0][0][0] = 1.0; double val1 = get();
   6.436 +                                           ((double[][][])c.v)[0][0][0] = 2.0; double val2 = get();
   6.437 +
   6.438 +                assertEquals(val1, 1.0);
   6.439 +                assertEquals(val2, 2.0);
   6.440 +            }
   6.441 +
   6.442 +            {
   6.443 +                c.v = new double[1][1][1]; c.v[0][0] = new double[0]; double[] val1 = get1();
   6.444 +                                           c.v[0][0] = new double[0]; double[] val2 = get1();
   6.445 +
   6.446 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.447 +            }
   6.448 +
   6.449 +            {
   6.450 +                c.v = new double[1][1][1]; c.v[0] = new double[0][0]; double[][] val1 = get2();
   6.451 +                                           c.v[0] = new double[0][0]; double[][] val2 = get2();
   6.452 +
   6.453 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.454 +            }
   6.455 +
   6.456 +            {
   6.457 +                c.v = new double[0][0][0]; Object[][] val1 = get3();
   6.458 +                c.v = new double[0][0][0]; Object[][] val2 = get3();
   6.459 +
   6.460 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   6.461 +            }
   6.462 +        }
   6.463 +    }
   6.464 +
   6.465 +    /* ==================================================== */
   6.466 +
   6.467 +    static class NestedStableField {
   6.468 +        static class A {
   6.469 +            public @Stable double a;
   6.470 +
   6.471 +        }
   6.472 +        public @Stable A v;
   6.473 +
   6.474 +        public static final NestedStableField c = new NestedStableField();
   6.475 +        public static A get() { return c.v; }
   6.476 +        public static double get1() { return get().a; }
   6.477 +
   6.478 +        public static void test() throws Exception {
   6.479 +            {
   6.480 +                c.v = new A(); c.v.a = 1.0; A val1 = get();
   6.481 +                               c.v.a = 2.0; A val2 = get();
   6.482 +
   6.483 +                assertEquals(val1.a, 2.0);
   6.484 +                assertEquals(val2.a, 2.0);
   6.485 +            }
   6.486 +
   6.487 +            {
   6.488 +                c.v = new A(); c.v.a = 1.0; double val1 = get1();
   6.489 +                               c.v.a = 2.0; double val2 = get1();
   6.490 +                c.v = new A(); c.v.a = 3.0; double val3 = get1();
   6.491 +
   6.492 +                assertEquals(val1, 1.0);
   6.493 +                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
   6.494 +                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
   6.495 +            }
   6.496 +        }
   6.497 +    }
   6.498 +
   6.499 +    /* ==================================================== */
   6.500 +
   6.501 +    static class NestedStableField1 {
   6.502 +        static class A {
   6.503 +            public @Stable double a;
   6.504 +            public @Stable A next;
   6.505 +        }
   6.506 +        public @Stable A v;
   6.507 +
   6.508 +        public static final NestedStableField1 c = new NestedStableField1();
   6.509 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
   6.510 +        public static double get1() { return get().a; }
   6.511 +
   6.512 +        public static void test() throws Exception {
   6.513 +            {
   6.514 +                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
   6.515 +                               c.v.a = 1.0; c.v.next.a = 1.0; A val1 = get();
   6.516 +                               c.v.a = 2.0; c.v.next.a = 2.0; A val2 = get();
   6.517 +
   6.518 +                assertEquals(val1.a, 2.0);
   6.519 +                assertEquals(val2.a, 2.0);
   6.520 +            }
   6.521 +
   6.522 +            {
   6.523 +                c.v = new A(); c.v.next = c.v;
   6.524 +                               c.v.a = 1.0; double val1 = get1();
   6.525 +                               c.v.a = 2.0; double val2 = get1();
   6.526 +                c.v = new A(); c.v.next = c.v;
   6.527 +                               c.v.a = 3.0; double val3 = get1();
   6.528 +
   6.529 +                assertEquals(val1, 1.0);
   6.530 +                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
   6.531 +                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
   6.532 +            }
   6.533 +        }
   6.534 +    }
   6.535 +   /* ==================================================== */
   6.536 +
   6.537 +    static class NestedStableField2 {
   6.538 +        static class A {
   6.539 +            public @Stable double a;
   6.540 +            public @Stable A left;
   6.541 +            public         A right;
   6.542 +        }
   6.543 +
   6.544 +        public @Stable A v;
   6.545 +
   6.546 +        public static final NestedStableField2 c = new NestedStableField2();
   6.547 +        public static double get() { return c.v.left.left.left.a; }
   6.548 +        public static double get1() { return c.v.left.left.right.left.a; }
   6.549 +
   6.550 +        public static void test() throws Exception {
   6.551 +            {
   6.552 +                c.v = new A(); c.v.left = c.v.right = c.v;
   6.553 +                               c.v.a = 1.0; double val1 = get(); double val2 = get1();
   6.554 +                               c.v.a = 2.0; double val3 = get(); double val4 = get1();
   6.555 +
   6.556 +                assertEquals(val1, 1.0);
   6.557 +                assertEquals(val3, (isStableEnabled ? 1.0 : 2.0));
   6.558 +
   6.559 +                assertEquals(val2, 1.0);
   6.560 +                assertEquals(val4, 2.0);
   6.561 +            }
   6.562 +        }
   6.563 +    }
   6.564 +
   6.565 +    /* ==================================================== */
   6.566 +
   6.567 +    static class NestedStableField3 {
   6.568 +        static class A {
   6.569 +            public @Stable double a;
   6.570 +            public @Stable A[] left;
   6.571 +            public         A[] right;
   6.572 +        }
   6.573 +
   6.574 +        public @Stable A[] v;
   6.575 +
   6.576 +        public static final NestedStableField3 c = new NestedStableField3();
   6.577 +        public static double get() { return c.v[0].left[1].left[0].left[1].a; }
   6.578 +        public static double get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
   6.579 +
   6.580 +        public static void test() throws Exception {
   6.581 +            {
   6.582 +                A elem = new A();
   6.583 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
   6.584 +                               elem.a = 1.0; double val1 = get(); double val2 = get1();
   6.585 +                               elem.a = 2.0; double val3 = get(); double val4 = get1();
   6.586 +
   6.587 +                assertEquals(val1, 1.0);
   6.588 +                assertEquals(val3, (isStableEnabled ? 1.0 : 2.0));
   6.589 +
   6.590 +                assertEquals(val2, 1.0);
   6.591 +                assertEquals(val4, 2.0);
   6.592 +            }
   6.593 +        }
   6.594 +    }
   6.595 +
   6.596 +    /* ==================================================== */
   6.597 +    // Auxiliary methods
   6.598 +    static void assertEquals(double i, double j) { if (i != j)  throw new AssertionError(i + " != " + j); }
   6.599 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
   6.600 +
   6.601 +    static boolean failed = false;
   6.602 +
   6.603 +    public static void run(Class<?> test) {
   6.604 +        Throwable ex = null;
   6.605 +        System.out.print(test.getName()+": ");
   6.606 +        try {
   6.607 +            test.getMethod("test").invoke(null);
   6.608 +        } catch (InvocationTargetException e) {
   6.609 +            ex = e.getCause();
   6.610 +        } catch (Throwable e) {
   6.611 +            ex = e;
   6.612 +        } finally {
   6.613 +            if (ex == null) {
   6.614 +                System.out.println("PASSED");
   6.615 +            } else {
   6.616 +                failed = true;
   6.617 +                System.out.println("FAILED");
   6.618 +                ex.printStackTrace(System.out);
   6.619 +            }
   6.620 +        }
   6.621 +    }
   6.622 +
   6.623 +    static final boolean isStableEnabled;
   6.624 +    static {
   6.625 +        HotSpotDiagnosticMXBean diagnostic
   6.626 +                = ManagementFactoryHelper.getDiagnosticMXBean();
   6.627 +        VMOption tmp;
   6.628 +        try {
   6.629 +            tmp = diagnostic.getVMOption("FoldStableValues");
   6.630 +        } catch (IllegalArgumentException e) {
   6.631 +            tmp = null;
   6.632 +        }
   6.633 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
   6.634 +    }
   6.635 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/compiler/stable/TestStableFloat.java	Fri Mar 28 10:13:37 2014 -0700
     7.3 @@ -0,0 +1,632 @@
     7.4 +/*
     7.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.  Oracle designates this
    7.11 + * particular file as subject to the "Classpath" exception as provided
    7.12 + * by Oracle in the LICENSE file that accompanied this code.
    7.13 + *
    7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 + * version 2 for more details (a copy is included in the LICENSE file that
    7.18 + * accompanied this code).
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License version
    7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 + *
    7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.25 + * or visit www.oracle.com if you need additional information or have any
    7.26 + * questions.
    7.27 + */
    7.28 +
    7.29 +/*
    7.30 + * @test TestStableFloat
    7.31 + * @summary tests on stable fields and arrays
    7.32 + * @library /testlibrary
    7.33 + * @compile -XDignore.symbol.file TestStableFloat.java
    7.34 + * @run main ClassFileInstaller
    7.35 + *           java/lang/invoke/TestStableFloat
    7.36 + *           java/lang/invoke/TestStableFloat$FloatStable
    7.37 + *           java/lang/invoke/TestStableFloat$StaticFloatStable
    7.38 + *           java/lang/invoke/TestStableFloat$VolatileFloatStable
    7.39 + *           java/lang/invoke/TestStableFloat$FloatArrayDim1
    7.40 + *           java/lang/invoke/TestStableFloat$FloatArrayDim2
    7.41 + *           java/lang/invoke/TestStableFloat$FloatArrayDim3
    7.42 + *           java/lang/invoke/TestStableFloat$FloatArrayDim4
    7.43 + *           java/lang/invoke/TestStableFloat$ObjectArrayLowerDim0
    7.44 + *           java/lang/invoke/TestStableFloat$ObjectArrayLowerDim1
    7.45 + *           java/lang/invoke/TestStableFloat$NestedStableField
    7.46 + *           java/lang/invoke/TestStableFloat$NestedStableField$A
    7.47 + *           java/lang/invoke/TestStableFloat$NestedStableField1
    7.48 + *           java/lang/invoke/TestStableFloat$NestedStableField1$A
    7.49 + *           java/lang/invoke/TestStableFloat$NestedStableField2
    7.50 + *           java/lang/invoke/TestStableFloat$NestedStableField2$A
    7.51 + *           java/lang/invoke/TestStableFloat$NestedStableField3
    7.52 + *           java/lang/invoke/TestStableFloat$NestedStableField3$A
    7.53 + *           java/lang/invoke/TestStableFloat$DefaultValue
    7.54 + *           java/lang/invoke/TestStableFloat$ObjectArrayLowerDim2
    7.55 + *
    7.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    7.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
    7.58 + *                   -server -XX:-TieredCompilation -Xcomp
    7.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    7.60 + *                   java.lang.invoke.TestStableFloat
    7.61 + *
    7.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    7.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
    7.64 + *                   -server -XX:-TieredCompilation -Xcomp
    7.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    7.66 + *                   java.lang.invoke.TestStableFloat
    7.67 + *
    7.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    7.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
    7.70 + *                   -server -XX:-TieredCompilation -Xcomp
    7.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    7.72 + *                   java.lang.invoke.TestStableFloat
    7.73 + *
    7.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    7.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
    7.76 + *                   -server -XX:-TieredCompilation -Xcomp
    7.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    7.78 + *                   java.lang.invoke.TestStableFloat
    7.79 + */
    7.80 +package java.lang.invoke;
    7.81 +
    7.82 +import com.sun.management.HotSpotDiagnosticMXBean;
    7.83 +import com.sun.management.VMOption;
    7.84 +import sun.management.ManagementFactoryHelper;
    7.85 +import java.lang.reflect.InvocationTargetException;
    7.86 +
    7.87 +public class TestStableFloat {
    7.88 +    public static void main(String[] args) throws Exception {
    7.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
    7.90 +        System.out.println();
    7.91 +
    7.92 +        run(DefaultValue.class);
    7.93 +        run(FloatStable.class);
    7.94 +        run(StaticFloatStable.class);
    7.95 +        run(VolatileFloatStable.class);
    7.96 +
    7.97 +        // @Stable arrays: Dim 1-4
    7.98 +        run(FloatArrayDim1.class);
    7.99 +        run(FloatArrayDim2.class);
   7.100 +        run(FloatArrayDim3.class);
   7.101 +        run(FloatArrayDim4.class);
   7.102 +
   7.103 +        // @Stable Object field: dynamic arrays
   7.104 +        run(ObjectArrayLowerDim0.class);
   7.105 +        run(ObjectArrayLowerDim1.class);
   7.106 +        run(ObjectArrayLowerDim2.class);
   7.107 +
   7.108 +        // Nested @Stable fields
   7.109 +        run(NestedStableField.class);
   7.110 +        run(NestedStableField1.class);
   7.111 +        run(NestedStableField2.class);
   7.112 +        run(NestedStableField3.class);
   7.113 +
   7.114 +        if (failed) {
   7.115 +            throw new Error("TEST FAILED");
   7.116 +        }
   7.117 +    }
   7.118 +
   7.119 +    /* ==================================================== */
   7.120 +
   7.121 +    static class DefaultValue {
   7.122 +        public @Stable float v;
   7.123 +
   7.124 +        public static final DefaultValue c = new DefaultValue();
   7.125 +        public static float get() { return c.v; }
   7.126 +        public static void test() throws Exception {
   7.127 +                        float val1 = get();
   7.128 +            c.v = 1.0F; float val2 = get();
   7.129 +            assertEquals(val1, 0F);
   7.130 +            assertEquals(val2, 1.0F);
   7.131 +        }
   7.132 +    }
   7.133 +
   7.134 +    /* ==================================================== */
   7.135 +
   7.136 +    static class FloatStable {
   7.137 +        public @Stable float v;
   7.138 +
   7.139 +        public static final FloatStable c = new FloatStable();
   7.140 +        public static float get() { return c.v; }
   7.141 +        public static void test() throws Exception {
   7.142 +            c.v = 1.0F; float val1 = get();
   7.143 +            c.v = 2.0F; float val2 = get();
   7.144 +            assertEquals(val1, 1.0F);
   7.145 +            assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.146 +        }
   7.147 +    }
   7.148 +
   7.149 +    /* ==================================================== */
   7.150 +
   7.151 +    static class StaticFloatStable {
   7.152 +        public static @Stable float v;
   7.153 +
   7.154 +        public static final StaticFloatStable c = new StaticFloatStable();
   7.155 +        public static float get() { return c.v; }
   7.156 +        public static void test() throws Exception {
   7.157 +            c.v = 1.0F; float val1 = get();
   7.158 +            c.v = 2.0F; float val2 = get();
   7.159 +            assertEquals(val1, 1.0F);
   7.160 +            assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.161 +        }
   7.162 +    }
   7.163 +
   7.164 +    /* ==================================================== */
   7.165 +
   7.166 +    static class VolatileFloatStable {
   7.167 +        public @Stable volatile float v;
   7.168 +
   7.169 +        public static final VolatileFloatStable c = new VolatileFloatStable();
   7.170 +        public static float get() { return c.v; }
   7.171 +        public static void test() throws Exception {
   7.172 +            c.v = 1.0F; float val1 = get();
   7.173 +            c.v = 2.0F; float val2 = get();
   7.174 +            assertEquals(val1, 1.0F);
   7.175 +            assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.176 +        }
   7.177 +    }
   7.178 +
   7.179 +    /* ==================================================== */
   7.180 +    // @Stable array == field && all components are stable
   7.181 +
   7.182 +    static class FloatArrayDim1 {
   7.183 +        public @Stable float[] v;
   7.184 +
   7.185 +        public static final FloatArrayDim1 c = new FloatArrayDim1();
   7.186 +        public static float get() { return c.v[0]; }
   7.187 +        public static float get1() { return c.v[10]; }
   7.188 +        public static float[] get2() { return c.v; }
   7.189 +        public static void test() throws Exception {
   7.190 +            {
   7.191 +                c.v = new float[1]; c.v[0] = 1.0F; float val1 = get();
   7.192 +                                    c.v[0] = 2.0F; float val2 = get();
   7.193 +                assertEquals(val1, 1.0F);
   7.194 +                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.195 +
   7.196 +                c.v = new float[1]; c.v[0] = 3.0F; float val3 = get();
   7.197 +                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
   7.198 +            }
   7.199 +
   7.200 +            {
   7.201 +                c.v = new float[20]; c.v[10] = 1.0F; float val1 = get1();
   7.202 +                                     c.v[10] = 2.0F; float val2 = get1();
   7.203 +                assertEquals(val1, 1.0F);
   7.204 +                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.205 +
   7.206 +                c.v = new float[20]; c.v[10] = 3.0F; float val3 = get1();
   7.207 +                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
   7.208 +            }
   7.209 +
   7.210 +            {
   7.211 +                c.v = new float[1]; float[] val1 = get2();
   7.212 +                c.v = new float[1]; float[] val2 = get2();
   7.213 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.214 +            }
   7.215 +        }
   7.216 +    }
   7.217 +
   7.218 +    /* ==================================================== */
   7.219 +
   7.220 +    static class FloatArrayDim2 {
   7.221 +        public @Stable float[][] v;
   7.222 +
   7.223 +        public static final FloatArrayDim2 c = new FloatArrayDim2();
   7.224 +        public static float get() { return c.v[0][0]; }
   7.225 +        public static float[] get1() { return c.v[0]; }
   7.226 +        public static float[][] get2() { return c.v; }
   7.227 +        public static void test() throws Exception {
   7.228 +            {
   7.229 +                c.v = new float[1][1]; c.v[0][0] = 1.0F; float val1 = get();
   7.230 +                                       c.v[0][0] = 2.0F; float val2 = get();
   7.231 +                assertEquals(val1, 1.0F);
   7.232 +                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.233 +
   7.234 +                c.v = new float[1][1]; c.v[0][0] = 3.0F; float val3 = get();
   7.235 +                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
   7.236 +
   7.237 +                c.v[0] = new float[1]; c.v[0][0] = 4.0F; float val4 = get();
   7.238 +                assertEquals(val4, (isStableEnabled ? 1.0F : 4.0F));
   7.239 +            }
   7.240 +
   7.241 +            {
   7.242 +                c.v = new float[1][1]; float[] val1 = get1();
   7.243 +                c.v[0] = new float[1]; float[] val2 = get1();
   7.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.245 +            }
   7.246 +
   7.247 +            {
   7.248 +                c.v = new float[1][1]; float[][] val1 = get2();
   7.249 +                c.v = new float[1][1]; float[][] val2 = get2();
   7.250 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.251 +            }
   7.252 +        }
   7.253 +    }
   7.254 +
   7.255 +    /* ==================================================== */
   7.256 +
   7.257 +    static class FloatArrayDim3 {
   7.258 +        public @Stable float[][][] v;
   7.259 +
   7.260 +        public static final FloatArrayDim3 c = new FloatArrayDim3();
   7.261 +        public static float get() { return c.v[0][0][0]; }
   7.262 +        public static float[] get1() { return c.v[0][0]; }
   7.263 +        public static float[][] get2() { return c.v[0]; }
   7.264 +        public static float[][][] get3() { return c.v; }
   7.265 +        public static void test() throws Exception {
   7.266 +            {
   7.267 +                c.v = new float[1][1][1]; c.v[0][0][0] = 1.0F; float val1 = get();
   7.268 +                                          c.v[0][0][0] = 2.0F; float val2 = get();
   7.269 +                assertEquals(val1, 1.0F);
   7.270 +                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.271 +
   7.272 +                c.v = new float[1][1][1]; c.v[0][0][0] = 3.0F; float val3 = get();
   7.273 +                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
   7.274 +
   7.275 +                c.v[0] = new float[1][1]; c.v[0][0][0] = 4.0F; float val4 = get();
   7.276 +                assertEquals(val4, (isStableEnabled ? 1.0F : 4.0F));
   7.277 +
   7.278 +                c.v[0][0] = new float[1]; c.v[0][0][0] = 5.0F; float val5 = get();
   7.279 +                assertEquals(val5, (isStableEnabled ? 1.0F : 5.0F));
   7.280 +            }
   7.281 +
   7.282 +            {
   7.283 +                c.v = new float[1][1][1]; float[] val1 = get1();
   7.284 +                c.v[0][0] = new float[1]; float[] val2 = get1();
   7.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.286 +            }
   7.287 +
   7.288 +            {
   7.289 +                c.v = new float[1][1][1]; float[][] val1 = get2();
   7.290 +                c.v[0] = new float[1][1]; float[][] val2 = get2();
   7.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.292 +            }
   7.293 +
   7.294 +            {
   7.295 +                c.v = new float[1][1][1]; float[][][] val1 = get3();
   7.296 +                c.v = new float[1][1][1]; float[][][] val2 = get3();
   7.297 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.298 +            }
   7.299 +        }
   7.300 +    }
   7.301 +
   7.302 +    /* ==================================================== */
   7.303 +
   7.304 +    static class FloatArrayDim4 {
   7.305 +        public @Stable float[][][][] v;
   7.306 +
   7.307 +        public static final FloatArrayDim4 c = new FloatArrayDim4();
   7.308 +        public static float get() { return c.v[0][0][0][0]; }
   7.309 +        public static float[] get1() { return c.v[0][0][0]; }
   7.310 +        public static float[][] get2() { return c.v[0][0]; }
   7.311 +        public static float[][][] get3() { return c.v[0]; }
   7.312 +        public static float[][][][] get4() { return c.v; }
   7.313 +        public static void test() throws Exception {
   7.314 +            {
   7.315 +                c.v = new float[1][1][1][1]; c.v[0][0][0][0] = 1.0F; float val1 = get();
   7.316 +                                             c.v[0][0][0][0] = 2.0F; float val2 = get();
   7.317 +                assertEquals(val1, 1.0F);
   7.318 +                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.319 +
   7.320 +                c.v = new float[1][1][1][1]; c.v[0][0][0][0] = 3.0F; float val3 = get();
   7.321 +                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
   7.322 +
   7.323 +                c.v[0] = new float[1][1][1]; c.v[0][0][0][0] = 4.0F; float val4 = get();
   7.324 +                assertEquals(val4, (isStableEnabled ? 1.0F : 4.0F));
   7.325 +
   7.326 +                c.v[0][0] = new float[1][1]; c.v[0][0][0][0] = 5.0F; float val5 = get();
   7.327 +                assertEquals(val5, (isStableEnabled ? 1.0F : 5.0F));
   7.328 +
   7.329 +                c.v[0][0][0] = new float[1]; c.v[0][0][0][0] = 6.0F; float val6 = get();
   7.330 +                assertEquals(val6, (isStableEnabled ? 1.0F : 6.0F));
   7.331 +            }
   7.332 +
   7.333 +            {
   7.334 +                c.v = new float[1][1][1][1]; float[] val1 = get1();
   7.335 +                c.v[0][0][0] = new float[1]; float[] val2 = get1();
   7.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.337 +            }
   7.338 +
   7.339 +            {
   7.340 +                c.v = new float[1][1][1][1]; float[][] val1 = get2();
   7.341 +                c.v[0][0] = new float[1][1]; float[][] val2 = get2();
   7.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.343 +            }
   7.344 +
   7.345 +            {
   7.346 +                c.v = new float[1][1][1][1]; float[][][] val1 = get3();
   7.347 +                c.v[0] = new float[1][1][1]; float[][][] val2 = get3();
   7.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.349 +            }
   7.350 +
   7.351 +            {
   7.352 +                c.v = new float[1][1][1][1]; float[][][][] val1 = get4();
   7.353 +                c.v = new float[1][1][1][1]; float[][][][] val2 = get4();
   7.354 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.355 +            }
   7.356 +
   7.357 +        }
   7.358 +    }
   7.359 +
   7.360 +    /* ==================================================== */
   7.361 +    // Dynamic Dim is higher than static
   7.362 +
   7.363 +    static class ObjectArrayLowerDim0 {
   7.364 +        public @Stable Object v;
   7.365 +
   7.366 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
   7.367 +        public static float get() { return ((float[])c.v)[0]; }
   7.368 +        public static float[] get1() { return (float[])c.v; }
   7.369 +
   7.370 +        public static void test() throws Exception {
   7.371 +            {
   7.372 +                c.v = new float[1]; ((float[])c.v)[0] = 1.0F; float val1 = get();
   7.373 +                                    ((float[])c.v)[0] = 2.0F; float val2 = get();
   7.374 +
   7.375 +                assertEquals(val1, 1.0F);
   7.376 +                assertEquals(val2, 2.0F);
   7.377 +            }
   7.378 +
   7.379 +            {
   7.380 +                c.v = new float[1]; float[] val1 = get1();
   7.381 +                c.v = new float[1]; float[] val2 = get1();
   7.382 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.383 +            }
   7.384 +        }
   7.385 +    }
   7.386 +
   7.387 +    /* ==================================================== */
   7.388 +
   7.389 +    static class ObjectArrayLowerDim1 {
   7.390 +        public @Stable Object[] v;
   7.391 +
   7.392 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
   7.393 +        public static float get() { return ((float[][])c.v)[0][0]; }
   7.394 +        public static float[] get1() { return (float[])(c.v[0]); }
   7.395 +        public static Object[] get2() { return c.v; }
   7.396 +
   7.397 +        public static void test() throws Exception {
   7.398 +            {
   7.399 +                c.v = new float[1][1]; ((float[][])c.v)[0][0] = 1.0F; float val1 = get();
   7.400 +                                       ((float[][])c.v)[0][0] = 2.0F; float val2 = get();
   7.401 +
   7.402 +                assertEquals(val1, 1.0F);
   7.403 +                assertEquals(val2, 2.0F);
   7.404 +            }
   7.405 +
   7.406 +            {
   7.407 +                c.v = new float[1][1]; c.v[0] = new float[0]; float[] val1 = get1();
   7.408 +                                       c.v[0] = new float[0]; float[] val2 = get1();
   7.409 +
   7.410 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.411 +            }
   7.412 +
   7.413 +            {
   7.414 +                c.v = new float[0][0]; Object[] val1 = get2();
   7.415 +                c.v = new float[0][0]; Object[] val2 = get2();
   7.416 +
   7.417 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.418 +            }
   7.419 +        }
   7.420 +    }
   7.421 +
   7.422 +    /* ==================================================== */
   7.423 +
   7.424 +    static class ObjectArrayLowerDim2 {
   7.425 +        public @Stable Object[][] v;
   7.426 +
   7.427 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
   7.428 +        public static float get() { return ((float[][][])c.v)[0][0][0]; }
   7.429 +        public static float[] get1() { return (float[])(c.v[0][0]); }
   7.430 +        public static float[][] get2() { return (float[][])(c.v[0]); }
   7.431 +        public static Object[][] get3() { return c.v; }
   7.432 +
   7.433 +        public static void test() throws Exception {
   7.434 +            {
   7.435 +                c.v = new float[1][1][1]; ((float[][][])c.v)[0][0][0] = 1.0F; float val1 = get();
   7.436 +                                          ((float[][][])c.v)[0][0][0] = 2.0F; float val2 = get();
   7.437 +
   7.438 +                assertEquals(val1, 1.0F);
   7.439 +                assertEquals(val2, 2.0F);
   7.440 +            }
   7.441 +
   7.442 +            {
   7.443 +                c.v = new float[1][1][1]; c.v[0][0] = new float[0]; float[] val1 = get1();
   7.444 +                                          c.v[0][0] = new float[0]; float[] val2 = get1();
   7.445 +
   7.446 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.447 +            }
   7.448 +
   7.449 +            {
   7.450 +                c.v = new float[1][1][1]; c.v[0] = new float[0][0]; float[][] val1 = get2();
   7.451 +                                          c.v[0] = new float[0][0]; float[][] val2 = get2();
   7.452 +
   7.453 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.454 +            }
   7.455 +
   7.456 +            {
   7.457 +                c.v = new float[0][0][0]; Object[][] val1 = get3();
   7.458 +                c.v = new float[0][0][0]; Object[][] val2 = get3();
   7.459 +
   7.460 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   7.461 +            }
   7.462 +        }
   7.463 +    }
   7.464 +
   7.465 +    /* ==================================================== */
   7.466 +
   7.467 +    static class NestedStableField {
   7.468 +        static class A {
   7.469 +            public @Stable float a;
   7.470 +
   7.471 +        }
   7.472 +        public @Stable A v;
   7.473 +
   7.474 +        public static final NestedStableField c = new NestedStableField();
   7.475 +        public static A get() { return c.v; }
   7.476 +        public static float get1() { return get().a; }
   7.477 +
   7.478 +        public static void test() throws Exception {
   7.479 +            {
   7.480 +                c.v = new A(); c.v.a = 1.0F; A val1 = get();
   7.481 +                               c.v.a = 2.0F; A val2 = get();
   7.482 +
   7.483 +                assertEquals(val1.a, 2.0F);
   7.484 +                assertEquals(val2.a, 2.0F);
   7.485 +            }
   7.486 +
   7.487 +            {
   7.488 +                c.v = new A(); c.v.a = 1.0F; float val1 = get1();
   7.489 +                               c.v.a = 2.0F; float val2 = get1();
   7.490 +                c.v = new A(); c.v.a = 3.0F; float val3 = get1();
   7.491 +
   7.492 +                assertEquals(val1, 1.0F);
   7.493 +                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.494 +                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
   7.495 +            }
   7.496 +        }
   7.497 +    }
   7.498 +
   7.499 +    /* ==================================================== */
   7.500 +
   7.501 +    static class NestedStableField1 {
   7.502 +        static class A {
   7.503 +            public @Stable float a;
   7.504 +            public @Stable A next;
   7.505 +        }
   7.506 +        public @Stable A v;
   7.507 +
   7.508 +        public static final NestedStableField1 c = new NestedStableField1();
   7.509 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
   7.510 +        public static float get1() { return get().a; }
   7.511 +
   7.512 +        public static void test() throws Exception {
   7.513 +            {
   7.514 +                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
   7.515 +                               c.v.a = 1.0F; c.v.next.a = 1.0F; A val1 = get();
   7.516 +                               c.v.a = 2.0F; c.v.next.a = 2.0F; A val2 = get();
   7.517 +
   7.518 +                assertEquals(val1.a, 2.0F);
   7.519 +                assertEquals(val2.a, 2.0F);
   7.520 +            }
   7.521 +
   7.522 +            {
   7.523 +                c.v = new A(); c.v.next = c.v;
   7.524 +                               c.v.a = 1.0F; float val1 = get1();
   7.525 +                               c.v.a = 2.0F; float val2 = get1();
   7.526 +                c.v = new A(); c.v.next = c.v;
   7.527 +                               c.v.a = 3.0F; float val3 = get1();
   7.528 +
   7.529 +                assertEquals(val1, 1.0F);
   7.530 +                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
   7.531 +                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
   7.532 +            }
   7.533 +        }
   7.534 +    }
   7.535 +   /* ==================================================== */
   7.536 +
   7.537 +    static class NestedStableField2 {
   7.538 +        static class A {
   7.539 +            public @Stable float a;
   7.540 +            public @Stable A left;
   7.541 +            public         A right;
   7.542 +        }
   7.543 +
   7.544 +        public @Stable A v;
   7.545 +
   7.546 +        public static final NestedStableField2 c = new NestedStableField2();
   7.547 +        public static float get() { return c.v.left.left.left.a; }
   7.548 +        public static float get1() { return c.v.left.left.right.left.a; }
   7.549 +
   7.550 +        public static void test() throws Exception {
   7.551 +            {
   7.552 +                c.v = new A(); c.v.left = c.v.right = c.v;
   7.553 +                               c.v.a = 1.0F; float val1 = get(); float val2 = get1();
   7.554 +                               c.v.a = 2.0F; float val3 = get(); float val4 = get1();
   7.555 +
   7.556 +                assertEquals(val1, 1.0F);
   7.557 +                assertEquals(val3, (isStableEnabled ? 1.0F : 2.0F));
   7.558 +
   7.559 +                assertEquals(val2, 1.0F);
   7.560 +                assertEquals(val4, 2.0F);
   7.561 +            }
   7.562 +        }
   7.563 +    }
   7.564 +
   7.565 +    /* ==================================================== */
   7.566 +
   7.567 +    static class NestedStableField3 {
   7.568 +        static class A {
   7.569 +            public @Stable float a;
   7.570 +            public @Stable A[] left;
   7.571 +            public         A[] right;
   7.572 +        }
   7.573 +
   7.574 +        public @Stable A[] v;
   7.575 +
   7.576 +        public static final NestedStableField3 c = new NestedStableField3();
   7.577 +        public static float get() { return c.v[0].left[1].left[0].left[1].a; }
   7.578 +        public static float get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
   7.579 +
   7.580 +        public static void test() throws Exception {
   7.581 +            {
   7.582 +                A elem = new A();
   7.583 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
   7.584 +                               elem.a = 1.0F; float val1 = get(); float val2 = get1();
   7.585 +                               elem.a = 2.0F; float val3 = get(); float val4 = get1();
   7.586 +
   7.587 +                assertEquals(val1, 1.0F);
   7.588 +                assertEquals(val3, (isStableEnabled ? 1.0F : 2.0F));
   7.589 +
   7.590 +                assertEquals(val2, 1.0F);
   7.591 +                assertEquals(val4, 2.0F);
   7.592 +            }
   7.593 +        }
   7.594 +    }
   7.595 +
   7.596 +    /* ==================================================== */
   7.597 +    // Auxiliary methods
   7.598 +    static void assertEquals(float i, float j) { if (i != j)  throw new AssertionError(i + " != " + j); }
   7.599 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
   7.600 +
   7.601 +    static boolean failed = false;
   7.602 +
   7.603 +    public static void run(Class<?> test) {
   7.604 +        Throwable ex = null;
   7.605 +        System.out.print(test.getName()+": ");
   7.606 +        try {
   7.607 +            test.getMethod("test").invoke(null);
   7.608 +        } catch (InvocationTargetException e) {
   7.609 +            ex = e.getCause();
   7.610 +        } catch (Throwable e) {
   7.611 +            ex = e;
   7.612 +        } finally {
   7.613 +            if (ex == null) {
   7.614 +                System.out.println("PASSED");
   7.615 +            } else {
   7.616 +                failed = true;
   7.617 +                System.out.println("FAILED");
   7.618 +                ex.printStackTrace(System.out);
   7.619 +            }
   7.620 +        }
   7.621 +    }
   7.622 +
   7.623 +    static final boolean isStableEnabled;
   7.624 +    static {
   7.625 +        HotSpotDiagnosticMXBean diagnostic
   7.626 +                = ManagementFactoryHelper.getDiagnosticMXBean();
   7.627 +        VMOption tmp;
   7.628 +        try {
   7.629 +            tmp = diagnostic.getVMOption("FoldStableValues");
   7.630 +        } catch (IllegalArgumentException e) {
   7.631 +            tmp = null;
   7.632 +        }
   7.633 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
   7.634 +    }
   7.635 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/compiler/stable/TestStableInt.java	Fri Mar 28 10:13:37 2014 -0700
     8.3 @@ -0,0 +1,632 @@
     8.4 +/*
     8.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.  Oracle designates this
    8.11 + * particular file as subject to the "Classpath" exception as provided
    8.12 + * by Oracle in the LICENSE file that accompanied this code.
    8.13 + *
    8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.17 + * version 2 for more details (a copy is included in the LICENSE file that
    8.18 + * accompanied this code).
    8.19 + *
    8.20 + * You should have received a copy of the GNU General Public License version
    8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.23 + *
    8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.25 + * or visit www.oracle.com if you need additional information or have any
    8.26 + * questions.
    8.27 + */
    8.28 +
    8.29 +/*
    8.30 + * @test TestStableInt
    8.31 + * @summary tests on stable fields and arrays
    8.32 + * @library /testlibrary
    8.33 + * @compile -XDignore.symbol.file TestStableInt.java
    8.34 + * @run main ClassFileInstaller
    8.35 + *           java/lang/invoke/TestStableInt
    8.36 + *           java/lang/invoke/TestStableInt$IntStable
    8.37 + *           java/lang/invoke/TestStableInt$StaticIntStable
    8.38 + *           java/lang/invoke/TestStableInt$VolatileIntStable
    8.39 + *           java/lang/invoke/TestStableInt$IntArrayDim1
    8.40 + *           java/lang/invoke/TestStableInt$IntArrayDim2
    8.41 + *           java/lang/invoke/TestStableInt$IntArrayDim3
    8.42 + *           java/lang/invoke/TestStableInt$IntArrayDim4
    8.43 + *           java/lang/invoke/TestStableInt$ObjectArrayLowerDim0
    8.44 + *           java/lang/invoke/TestStableInt$ObjectArrayLowerDim1
    8.45 + *           java/lang/invoke/TestStableInt$NestedStableField
    8.46 + *           java/lang/invoke/TestStableInt$NestedStableField$A
    8.47 + *           java/lang/invoke/TestStableInt$NestedStableField1
    8.48 + *           java/lang/invoke/TestStableInt$NestedStableField1$A
    8.49 + *           java/lang/invoke/TestStableInt$NestedStableField2
    8.50 + *           java/lang/invoke/TestStableInt$NestedStableField2$A
    8.51 + *           java/lang/invoke/TestStableInt$NestedStableField3
    8.52 + *           java/lang/invoke/TestStableInt$NestedStableField3$A
    8.53 + *           java/lang/invoke/TestStableInt$DefaultValue
    8.54 + *           java/lang/invoke/TestStableInt$ObjectArrayLowerDim2
    8.55 + *
    8.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    8.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
    8.58 + *                   -server -XX:-TieredCompilation -Xcomp
    8.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    8.60 + *                   java.lang.invoke.TestStableInt
    8.61 + *
    8.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    8.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
    8.64 + *                   -server -XX:-TieredCompilation -Xcomp
    8.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    8.66 + *                   java.lang.invoke.TestStableInt
    8.67 + *
    8.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    8.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
    8.70 + *                   -server -XX:-TieredCompilation -Xcomp
    8.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    8.72 + *                   java.lang.invoke.TestStableInt
    8.73 + *
    8.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    8.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
    8.76 + *                   -server -XX:-TieredCompilation -Xcomp
    8.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    8.78 + *                   java.lang.invoke.TestStableInt
    8.79 + */
    8.80 +package java.lang.invoke;
    8.81 +
    8.82 +import com.sun.management.HotSpotDiagnosticMXBean;
    8.83 +import com.sun.management.VMOption;
    8.84 +import sun.management.ManagementFactoryHelper;
    8.85 +import java.lang.reflect.InvocationTargetException;
    8.86 +
    8.87 +public class TestStableInt {
    8.88 +    public static void main(String[] args) throws Exception {
    8.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
    8.90 +        System.out.println();
    8.91 +
    8.92 +        run(DefaultValue.class);
    8.93 +        run(IntStable.class);
    8.94 +        run(StaticIntStable.class);
    8.95 +        run(VolatileIntStable.class);
    8.96 +
    8.97 +        // @Stable arrays: Dim 1-4
    8.98 +        run(IntArrayDim1.class);
    8.99 +        run(IntArrayDim2.class);
   8.100 +        run(IntArrayDim3.class);
   8.101 +        run(IntArrayDim4.class);
   8.102 +
   8.103 +        // @Stable Object field: dynamic arrays
   8.104 +        run(ObjectArrayLowerDim0.class);
   8.105 +        run(ObjectArrayLowerDim1.class);
   8.106 +        run(ObjectArrayLowerDim2.class);
   8.107 +
   8.108 +        // Nested @Stable fields
   8.109 +        run(NestedStableField.class);
   8.110 +        run(NestedStableField1.class);
   8.111 +        run(NestedStableField2.class);
   8.112 +        run(NestedStableField3.class);
   8.113 +
   8.114 +        if (failed) {
   8.115 +            throw new Error("TEST FAILED");
   8.116 +        }
   8.117 +    }
   8.118 +
   8.119 +    /* ==================================================== */
   8.120 +
   8.121 +    static class DefaultValue {
   8.122 +        public @Stable int v;
   8.123 +
   8.124 +        public static final DefaultValue c = new DefaultValue();
   8.125 +        public static int get() { return c.v; }
   8.126 +        public static void test() throws Exception {
   8.127 +                        int val1 = get();
   8.128 +            c.v = 1; int val2 = get();
   8.129 +            assertEquals(val1, 0);
   8.130 +            assertEquals(val2, 1);
   8.131 +        }
   8.132 +    }
   8.133 +
   8.134 +    /* ==================================================== */
   8.135 +
   8.136 +    static class IntStable {
   8.137 +        public @Stable int v;
   8.138 +
   8.139 +        public static final IntStable c = new IntStable();
   8.140 +        public static int get() { return c.v; }
   8.141 +        public static void test() throws Exception {
   8.142 +            c.v = 1; int val1 = get();
   8.143 +            c.v = 2; int val2 = get();
   8.144 +            assertEquals(val1, 1);
   8.145 +            assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.146 +        }
   8.147 +    }
   8.148 +
   8.149 +    /* ==================================================== */
   8.150 +
   8.151 +    static class StaticIntStable {
   8.152 +        public static @Stable int v;
   8.153 +
   8.154 +        public static final StaticIntStable c = new StaticIntStable();
   8.155 +        public static int get() { return c.v; }
   8.156 +        public static void test() throws Exception {
   8.157 +            c.v = 1; int val1 = get();
   8.158 +            c.v = 2; int val2 = get();
   8.159 +            assertEquals(val1, 1);
   8.160 +            assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.161 +        }
   8.162 +    }
   8.163 +
   8.164 +    /* ==================================================== */
   8.165 +
   8.166 +    static class VolatileIntStable {
   8.167 +        public @Stable volatile int v;
   8.168 +
   8.169 +        public static final VolatileIntStable c = new VolatileIntStable();
   8.170 +        public static int get() { return c.v; }
   8.171 +        public static void test() throws Exception {
   8.172 +            c.v = 1; int val1 = get();
   8.173 +            c.v = 2; int val2 = get();
   8.174 +            assertEquals(val1, 1);
   8.175 +            assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.176 +        }
   8.177 +    }
   8.178 +
   8.179 +    /* ==================================================== */
   8.180 +    // @Stable array == field && all components are stable
   8.181 +
   8.182 +    static class IntArrayDim1 {
   8.183 +        public @Stable int[] v;
   8.184 +
   8.185 +        public static final IntArrayDim1 c = new IntArrayDim1();
   8.186 +        public static int get() { return c.v[0]; }
   8.187 +        public static int get1() { return c.v[10]; }
   8.188 +        public static int[] get2() { return c.v; }
   8.189 +        public static void test() throws Exception {
   8.190 +            {
   8.191 +                c.v = new int[1]; c.v[0] = 1; int val1 = get();
   8.192 +                                  c.v[0] = 2; int val2 = get();
   8.193 +                assertEquals(val1, 1);
   8.194 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.195 +
   8.196 +                c.v = new int[1]; c.v[0] = 3; int val3 = get();
   8.197 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   8.198 +            }
   8.199 +
   8.200 +            {
   8.201 +                c.v = new int[20]; c.v[10] = 1; int val1 = get1();
   8.202 +                                   c.v[10] = 2; int val2 = get1();
   8.203 +                assertEquals(val1, 1);
   8.204 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.205 +
   8.206 +                c.v = new int[20]; c.v[10] = 3; int val3 = get1();
   8.207 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   8.208 +            }
   8.209 +
   8.210 +            {
   8.211 +                c.v = new int[1]; int[] val1 = get2();
   8.212 +                c.v = new int[1]; int[] val2 = get2();
   8.213 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.214 +            }
   8.215 +        }
   8.216 +    }
   8.217 +
   8.218 +    /* ==================================================== */
   8.219 +
   8.220 +    static class IntArrayDim2 {
   8.221 +        public @Stable int[][] v;
   8.222 +
   8.223 +        public static final IntArrayDim2 c = new IntArrayDim2();
   8.224 +        public static int get() { return c.v[0][0]; }
   8.225 +        public static int[] get1() { return c.v[0]; }
   8.226 +        public static int[][] get2() { return c.v; }
   8.227 +        public static void test() throws Exception {
   8.228 +            {
   8.229 +                c.v = new int[1][1]; c.v[0][0] = 1; int val1 = get();
   8.230 +                                     c.v[0][0] = 2; int val2 = get();
   8.231 +                assertEquals(val1, 1);
   8.232 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.233 +
   8.234 +                c.v = new int[1][1]; c.v[0][0] = 3; int val3 = get();
   8.235 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   8.236 +
   8.237 +                c.v[0] = new int[1]; c.v[0][0] = 4; int val4 = get();
   8.238 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   8.239 +            }
   8.240 +
   8.241 +            {
   8.242 +                c.v = new int[1][1]; int[] val1 = get1();
   8.243 +                c.v[0] = new int[1]; int[] val2 = get1();
   8.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.245 +            }
   8.246 +
   8.247 +            {
   8.248 +                c.v = new int[1][1]; int[][] val1 = get2();
   8.249 +                c.v = new int[1][1]; int[][] val2 = get2();
   8.250 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.251 +            }
   8.252 +        }
   8.253 +    }
   8.254 +
   8.255 +    /* ==================================================== */
   8.256 +
   8.257 +    static class IntArrayDim3 {
   8.258 +        public @Stable int[][][] v;
   8.259 +
   8.260 +        public static final IntArrayDim3 c = new IntArrayDim3();
   8.261 +        public static int get() { return c.v[0][0][0]; }
   8.262 +        public static int[] get1() { return c.v[0][0]; }
   8.263 +        public static int[][] get2() { return c.v[0]; }
   8.264 +        public static int[][][] get3() { return c.v; }
   8.265 +        public static void test() throws Exception {
   8.266 +            {
   8.267 +                c.v = new int[1][1][1]; c.v[0][0][0] = 1; int val1 = get();
   8.268 +                                        c.v[0][0][0] = 2; int val2 = get();
   8.269 +                assertEquals(val1, 1);
   8.270 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.271 +
   8.272 +                c.v = new int[1][1][1]; c.v[0][0][0] = 3; int val3 = get();
   8.273 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   8.274 +
   8.275 +                c.v[0] = new int[1][1]; c.v[0][0][0] = 4; int val4 = get();
   8.276 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   8.277 +
   8.278 +                c.v[0][0] = new int[1]; c.v[0][0][0] = 5; int val5 = get();
   8.279 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
   8.280 +            }
   8.281 +
   8.282 +            {
   8.283 +                c.v = new int[1][1][1]; int[] val1 = get1();
   8.284 +                c.v[0][0] = new int[1]; int[] val2 = get1();
   8.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.286 +            }
   8.287 +
   8.288 +            {
   8.289 +                c.v = new int[1][1][1]; int[][] val1 = get2();
   8.290 +                c.v[0] = new int[1][1]; int[][] val2 = get2();
   8.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.292 +            }
   8.293 +
   8.294 +            {
   8.295 +                c.v = new int[1][1][1]; int[][][] val1 = get3();
   8.296 +                c.v = new int[1][1][1]; int[][][] val2 = get3();
   8.297 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.298 +            }
   8.299 +        }
   8.300 +    }
   8.301 +
   8.302 +    /* ==================================================== */
   8.303 +
   8.304 +    static class IntArrayDim4 {
   8.305 +        public @Stable int[][][][] v;
   8.306 +
   8.307 +        public static final IntArrayDim4 c = new IntArrayDim4();
   8.308 +        public static int get() { return c.v[0][0][0][0]; }
   8.309 +        public static int[] get1() { return c.v[0][0][0]; }
   8.310 +        public static int[][] get2() { return c.v[0][0]; }
   8.311 +        public static int[][][] get3() { return c.v[0]; }
   8.312 +        public static int[][][][] get4() { return c.v; }
   8.313 +        public static void test() throws Exception {
   8.314 +            {
   8.315 +                c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 1; int val1 = get();
   8.316 +                                           c.v[0][0][0][0] = 2; int val2 = get();
   8.317 +                assertEquals(val1, 1);
   8.318 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.319 +
   8.320 +                c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 3; int val3 = get();
   8.321 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   8.322 +
   8.323 +                c.v[0] = new int[1][1][1]; c.v[0][0][0][0] = 4; int val4 = get();
   8.324 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   8.325 +
   8.326 +                c.v[0][0] = new int[1][1]; c.v[0][0][0][0] = 5; int val5 = get();
   8.327 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
   8.328 +
   8.329 +                c.v[0][0][0] = new int[1]; c.v[0][0][0][0] = 6; int val6 = get();
   8.330 +                assertEquals(val6, (isStableEnabled ? 1 : 6));
   8.331 +            }
   8.332 +
   8.333 +            {
   8.334 +                c.v = new int[1][1][1][1]; int[] val1 = get1();
   8.335 +                c.v[0][0][0] = new int[1]; int[] val2 = get1();
   8.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.337 +            }
   8.338 +
   8.339 +            {
   8.340 +                c.v = new int[1][1][1][1]; int[][] val1 = get2();
   8.341 +                c.v[0][0] = new int[1][1]; int[][] val2 = get2();
   8.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.343 +            }
   8.344 +
   8.345 +            {
   8.346 +                c.v = new int[1][1][1][1]; int[][][] val1 = get3();
   8.347 +                c.v[0] = new int[1][1][1]; int[][][] val2 = get3();
   8.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.349 +            }
   8.350 +
   8.351 +            {
   8.352 +                c.v = new int[1][1][1][1]; int[][][][] val1 = get4();
   8.353 +                c.v = new int[1][1][1][1]; int[][][][] val2 = get4();
   8.354 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.355 +            }
   8.356 +
   8.357 +        }
   8.358 +    }
   8.359 +
   8.360 +    /* ==================================================== */
   8.361 +    // Dynamic Dim is higher than static
   8.362 +
   8.363 +    static class ObjectArrayLowerDim0 {
   8.364 +        public @Stable Object v;
   8.365 +
   8.366 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
   8.367 +        public static int get() { return ((int[])c.v)[0]; }
   8.368 +        public static int[] get1() { return (int[])c.v; }
   8.369 +
   8.370 +        public static void test() throws Exception {
   8.371 +            {
   8.372 +                c.v = new int[1]; ((int[])c.v)[0] = 1; int val1 = get();
   8.373 +                                  ((int[])c.v)[0] = 2; int val2 = get();
   8.374 +
   8.375 +                assertEquals(val1, 1);
   8.376 +                assertEquals(val2, 2);
   8.377 +            }
   8.378 +
   8.379 +            {
   8.380 +                c.v = new int[1]; int[] val1 = get1();
   8.381 +                c.v = new int[1]; int[] val2 = get1();
   8.382 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.383 +            }
   8.384 +        }
   8.385 +    }
   8.386 +
   8.387 +    /* ==================================================== */
   8.388 +
   8.389 +    static class ObjectArrayLowerDim1 {
   8.390 +        public @Stable Object[] v;
   8.391 +
   8.392 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
   8.393 +        public static int get() { return ((int[][])c.v)[0][0]; }
   8.394 +        public static int[] get1() { return (int[])(c.v[0]); }
   8.395 +        public static Object[] get2() { return c.v; }
   8.396 +
   8.397 +        public static void test() throws Exception {
   8.398 +            {
   8.399 +                c.v = new int[1][1]; ((int[][])c.v)[0][0] = 1; int val1 = get();
   8.400 +                                     ((int[][])c.v)[0][0] = 2; int val2 = get();
   8.401 +
   8.402 +                assertEquals(val1, 1);
   8.403 +                assertEquals(val2, 2);
   8.404 +            }
   8.405 +
   8.406 +            {
   8.407 +                c.v = new int[1][1]; c.v[0] = new int[0]; int[] val1 = get1();
   8.408 +                                     c.v[0] = new int[0]; int[] val2 = get1();
   8.409 +
   8.410 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.411 +            }
   8.412 +
   8.413 +            {
   8.414 +                c.v = new int[0][0]; Object[] val1 = get2();
   8.415 +                c.v = new int[0][0]; Object[] val2 = get2();
   8.416 +
   8.417 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.418 +            }
   8.419 +        }
   8.420 +    }
   8.421 +
   8.422 +    /* ==================================================== */
   8.423 +
   8.424 +    static class ObjectArrayLowerDim2 {
   8.425 +        public @Stable Object[][] v;
   8.426 +
   8.427 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
   8.428 +        public static int get() { return ((int[][][])c.v)[0][0][0]; }
   8.429 +        public static int[] get1() { return (int[])(c.v[0][0]); }
   8.430 +        public static int[][] get2() { return (int[][])(c.v[0]); }
   8.431 +        public static Object[][] get3() { return c.v; }
   8.432 +
   8.433 +        public static void test() throws Exception {
   8.434 +            {
   8.435 +                c.v = new int[1][1][1]; ((int[][][])c.v)[0][0][0] = 1; int val1 = get();
   8.436 +                                        ((int[][][])c.v)[0][0][0] = 2; int val2 = get();
   8.437 +
   8.438 +                assertEquals(val1, 1);
   8.439 +                assertEquals(val2, 2);
   8.440 +            }
   8.441 +
   8.442 +            {
   8.443 +                c.v = new int[1][1][1]; c.v[0][0] = new int[0]; int[] val1 = get1();
   8.444 +                                        c.v[0][0] = new int[0]; int[] val2 = get1();
   8.445 +
   8.446 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.447 +            }
   8.448 +
   8.449 +            {
   8.450 +                c.v = new int[1][1][1]; c.v[0] = new int[0][0]; int[][] val1 = get2();
   8.451 +                                        c.v[0] = new int[0][0]; int[][] val2 = get2();
   8.452 +
   8.453 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.454 +            }
   8.455 +
   8.456 +            {
   8.457 +                c.v = new int[0][0][0]; Object[][] val1 = get3();
   8.458 +                c.v = new int[0][0][0]; Object[][] val2 = get3();
   8.459 +
   8.460 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   8.461 +            }
   8.462 +        }
   8.463 +    }
   8.464 +
   8.465 +    /* ==================================================== */
   8.466 +
   8.467 +    static class NestedStableField {
   8.468 +        static class A {
   8.469 +            public @Stable int a;
   8.470 +
   8.471 +        }
   8.472 +        public @Stable A v;
   8.473 +
   8.474 +        public static final NestedStableField c = new NestedStableField();
   8.475 +        public static A get() { return c.v; }
   8.476 +        public static int get1() { return get().a; }
   8.477 +
   8.478 +        public static void test() throws Exception {
   8.479 +            {
   8.480 +                c.v = new A(); c.v.a = 1; A val1 = get();
   8.481 +                               c.v.a = 2; A val2 = get();
   8.482 +
   8.483 +                assertEquals(val1.a, 2);
   8.484 +                assertEquals(val2.a, 2);
   8.485 +            }
   8.486 +
   8.487 +            {
   8.488 +                c.v = new A(); c.v.a = 1; int val1 = get1();
   8.489 +                               c.v.a = 2; int val2 = get1();
   8.490 +                c.v = new A(); c.v.a = 3; int val3 = get1();
   8.491 +
   8.492 +                assertEquals(val1, 1);
   8.493 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.494 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   8.495 +            }
   8.496 +        }
   8.497 +    }
   8.498 +
   8.499 +    /* ==================================================== */
   8.500 +
   8.501 +    static class NestedStableField1 {
   8.502 +        static class A {
   8.503 +            public @Stable int a;
   8.504 +            public @Stable A next;
   8.505 +        }
   8.506 +        public @Stable A v;
   8.507 +
   8.508 +        public static final NestedStableField1 c = new NestedStableField1();
   8.509 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
   8.510 +        public static int get1() { return get().a; }
   8.511 +
   8.512 +        public static void test() throws Exception {
   8.513 +            {
   8.514 +                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
   8.515 +                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
   8.516 +                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
   8.517 +
   8.518 +                assertEquals(val1.a, 2);
   8.519 +                assertEquals(val2.a, 2);
   8.520 +            }
   8.521 +
   8.522 +            {
   8.523 +                c.v = new A(); c.v.next = c.v;
   8.524 +                               c.v.a = 1; int val1 = get1();
   8.525 +                               c.v.a = 2; int val2 = get1();
   8.526 +                c.v = new A(); c.v.next = c.v;
   8.527 +                               c.v.a = 3; int val3 = get1();
   8.528 +
   8.529 +                assertEquals(val1, 1);
   8.530 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   8.531 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   8.532 +            }
   8.533 +        }
   8.534 +    }
   8.535 +   /* ==================================================== */
   8.536 +
   8.537 +    static class NestedStableField2 {
   8.538 +        static class A {
   8.539 +            public @Stable int a;
   8.540 +            public @Stable A left;
   8.541 +            public         A right;
   8.542 +        }
   8.543 +
   8.544 +        public @Stable A v;
   8.545 +
   8.546 +        public static final NestedStableField2 c = new NestedStableField2();
   8.547 +        public static int get() { return c.v.left.left.left.a; }
   8.548 +        public static int get1() { return c.v.left.left.right.left.a; }
   8.549 +
   8.550 +        public static void test() throws Exception {
   8.551 +            {
   8.552 +                c.v = new A(); c.v.left = c.v.right = c.v;
   8.553 +                               c.v.a = 1; int val1 = get(); int val2 = get1();
   8.554 +                               c.v.a = 2; int val3 = get(); int val4 = get1();
   8.555 +
   8.556 +                assertEquals(val1, 1);
   8.557 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
   8.558 +
   8.559 +                assertEquals(val2, 1);
   8.560 +                assertEquals(val4, 2);
   8.561 +            }
   8.562 +        }
   8.563 +    }
   8.564 +
   8.565 +    /* ==================================================== */
   8.566 +
   8.567 +    static class NestedStableField3 {
   8.568 +        static class A {
   8.569 +            public @Stable int a;
   8.570 +            public @Stable A[] left;
   8.571 +            public         A[] right;
   8.572 +        }
   8.573 +
   8.574 +        public @Stable A[] v;
   8.575 +
   8.576 +        public static final NestedStableField3 c = new NestedStableField3();
   8.577 +        public static int get() { return c.v[0].left[1].left[0].left[1].a; }
   8.578 +        public static int get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
   8.579 +
   8.580 +        public static void test() throws Exception {
   8.581 +            {
   8.582 +                A elem = new A();
   8.583 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
   8.584 +                               elem.a = 1; int val1 = get(); int val2 = get1();
   8.585 +                               elem.a = 2; int val3 = get(); int val4 = get1();
   8.586 +
   8.587 +                assertEquals(val1, 1);
   8.588 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
   8.589 +
   8.590 +                assertEquals(val2, 1);
   8.591 +                assertEquals(val4, 2);
   8.592 +            }
   8.593 +        }
   8.594 +    }
   8.595 +
   8.596 +    /* ==================================================== */
   8.597 +    // Auxiliary methods
   8.598 +    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
   8.599 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
   8.600 +
   8.601 +    static boolean failed = false;
   8.602 +
   8.603 +    public static void run(Class<?> test) {
   8.604 +        Throwable ex = null;
   8.605 +        System.out.print(test.getName()+": ");
   8.606 +        try {
   8.607 +            test.getMethod("test").invoke(null);
   8.608 +        } catch (InvocationTargetException e) {
   8.609 +            ex = e.getCause();
   8.610 +        } catch (Throwable e) {
   8.611 +            ex = e;
   8.612 +        } finally {
   8.613 +            if (ex == null) {
   8.614 +                System.out.println("PASSED");
   8.615 +            } else {
   8.616 +                failed = true;
   8.617 +                System.out.println("FAILED");
   8.618 +                ex.printStackTrace(System.out);
   8.619 +            }
   8.620 +        }
   8.621 +    }
   8.622 +
   8.623 +    static final boolean isStableEnabled;
   8.624 +    static {
   8.625 +        HotSpotDiagnosticMXBean diagnostic
   8.626 +                = ManagementFactoryHelper.getDiagnosticMXBean();
   8.627 +        VMOption tmp;
   8.628 +        try {
   8.629 +            tmp = diagnostic.getVMOption("FoldStableValues");
   8.630 +        } catch (IllegalArgumentException e) {
   8.631 +            tmp = null;
   8.632 +        }
   8.633 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
   8.634 +    }
   8.635 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/compiler/stable/TestStableLong.java	Fri Mar 28 10:13:37 2014 -0700
     9.3 @@ -0,0 +1,632 @@
     9.4 +/*
     9.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.  Oracle designates this
    9.11 + * particular file as subject to the "Classpath" exception as provided
    9.12 + * by Oracle in the LICENSE file that accompanied this code.
    9.13 + *
    9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.17 + * version 2 for more details (a copy is included in the LICENSE file that
    9.18 + * accompanied this code).
    9.19 + *
    9.20 + * You should have received a copy of the GNU General Public License version
    9.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.23 + *
    9.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.25 + * or visit www.oracle.com if you need additional information or have any
    9.26 + * questions.
    9.27 + */
    9.28 +
    9.29 +/*
    9.30 + * @test TestStableLong
    9.31 + * @summary tests on stable fields and arrays
    9.32 + * @library /testlibrary
    9.33 + * @compile -XDignore.symbol.file TestStableLong.java
    9.34 + * @run main ClassFileInstaller
    9.35 + *           java/lang/invoke/TestStableLong
    9.36 + *           java/lang/invoke/TestStableLong$LongStable
    9.37 + *           java/lang/invoke/TestStableLong$StaticLongStable
    9.38 + *           java/lang/invoke/TestStableLong$VolatileLongStable
    9.39 + *           java/lang/invoke/TestStableLong$LongArrayDim1
    9.40 + *           java/lang/invoke/TestStableLong$LongArrayDim2
    9.41 + *           java/lang/invoke/TestStableLong$LongArrayDim3
    9.42 + *           java/lang/invoke/TestStableLong$LongArrayDim4
    9.43 + *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim0
    9.44 + *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim1
    9.45 + *           java/lang/invoke/TestStableLong$NestedStableField
    9.46 + *           java/lang/invoke/TestStableLong$NestedStableField$A
    9.47 + *           java/lang/invoke/TestStableLong$NestedStableField1
    9.48 + *           java/lang/invoke/TestStableLong$NestedStableField1$A
    9.49 + *           java/lang/invoke/TestStableLong$NestedStableField2
    9.50 + *           java/lang/invoke/TestStableLong$NestedStableField2$A
    9.51 + *           java/lang/invoke/TestStableLong$NestedStableField3
    9.52 + *           java/lang/invoke/TestStableLong$NestedStableField3$A
    9.53 + *           java/lang/invoke/TestStableLong$DefaultValue
    9.54 + *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim2
    9.55 + *
    9.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    9.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
    9.58 + *                   -server -XX:-TieredCompilation -Xcomp
    9.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    9.60 + *                   java.lang.invoke.TestStableLong
    9.61 + *
    9.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    9.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
    9.64 + *                   -server -XX:-TieredCompilation -Xcomp
    9.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    9.66 + *                   java.lang.invoke.TestStableLong
    9.67 + *
    9.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    9.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
    9.70 + *                   -server -XX:-TieredCompilation -Xcomp
    9.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    9.72 + *                   java.lang.invoke.TestStableLong
    9.73 + *
    9.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
    9.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
    9.76 + *                   -server -XX:-TieredCompilation -Xcomp
    9.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
    9.78 + *                   java.lang.invoke.TestStableLong
    9.79 + */
    9.80 +package java.lang.invoke;
    9.81 +
    9.82 +import com.sun.management.HotSpotDiagnosticMXBean;
    9.83 +import com.sun.management.VMOption;
    9.84 +import sun.management.ManagementFactoryHelper;
    9.85 +import java.lang.reflect.InvocationTargetException;
    9.86 +
    9.87 +public class TestStableLong {
    9.88 +    public static void main(String[] args) throws Exception {
    9.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
    9.90 +        System.out.println();
    9.91 +
    9.92 +        run(DefaultValue.class);
    9.93 +        run(LongStable.class);
    9.94 +        run(StaticLongStable.class);
    9.95 +        run(VolatileLongStable.class);
    9.96 +
    9.97 +        // @Stable arrays: Dim 1-4
    9.98 +        run(LongArrayDim1.class);
    9.99 +        run(LongArrayDim2.class);
   9.100 +        run(LongArrayDim3.class);
   9.101 +        run(LongArrayDim4.class);
   9.102 +
   9.103 +        // @Stable Object field: dynamic arrays
   9.104 +        run(ObjectArrayLowerDim0.class);
   9.105 +        run(ObjectArrayLowerDim1.class);
   9.106 +        run(ObjectArrayLowerDim2.class);
   9.107 +
   9.108 +        // Nested @Stable fields
   9.109 +        run(NestedStableField.class);
   9.110 +        run(NestedStableField1.class);
   9.111 +        run(NestedStableField2.class);
   9.112 +        run(NestedStableField3.class);
   9.113 +
   9.114 +        if (failed) {
   9.115 +            throw new Error("TEST FAILED");
   9.116 +        }
   9.117 +    }
   9.118 +
   9.119 +    /* ==================================================== */
   9.120 +
   9.121 +    static class DefaultValue {
   9.122 +        public @Stable long v;
   9.123 +
   9.124 +        public static final DefaultValue c = new DefaultValue();
   9.125 +        public static long get() { return c.v; }
   9.126 +        public static void test() throws Exception {
   9.127 +                      long val1 = get();
   9.128 +            c.v = 1L; long val2 = get();
   9.129 +            assertEquals(val1, 0);
   9.130 +            assertEquals(val2, 1L);
   9.131 +        }
   9.132 +    }
   9.133 +
   9.134 +    /* ==================================================== */
   9.135 +
   9.136 +    static class LongStable {
   9.137 +        public @Stable long v;
   9.138 +
   9.139 +        public static final LongStable c = new LongStable();
   9.140 +        public static long get() { return c.v; }
   9.141 +        public static void test() throws Exception {
   9.142 +            c.v = 5;              long val1 = get();
   9.143 +            c.v = Long.MAX_VALUE; long val2 = get();
   9.144 +            assertEquals(val1, 5);
   9.145 +            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
   9.146 +        }
   9.147 +    }
   9.148 +
   9.149 +    /* ==================================================== */
   9.150 +
   9.151 +    static class StaticLongStable {
   9.152 +        public static @Stable long v;
   9.153 +
   9.154 +        public static final StaticLongStable c = new StaticLongStable();
   9.155 +        public static long get() { return c.v; }
   9.156 +        public static void test() throws Exception {
   9.157 +            c.v = 5;              long val1 = get();
   9.158 +            c.v = Long.MAX_VALUE; long val2 = get();
   9.159 +            assertEquals(val1, 5);
   9.160 +            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
   9.161 +        }
   9.162 +    }
   9.163 +
   9.164 +    /* ==================================================== */
   9.165 +
   9.166 +    static class VolatileLongStable {
   9.167 +        public @Stable volatile long v;
   9.168 +
   9.169 +        public static final VolatileLongStable c = new VolatileLongStable();
   9.170 +        public static long get() { return c.v; }
   9.171 +        public static void test() throws Exception {
   9.172 +            c.v = 5;              long val1 = get();
   9.173 +            c.v = Long.MAX_VALUE; long val2 = get();
   9.174 +            assertEquals(val1, 5);
   9.175 +            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
   9.176 +        }
   9.177 +    }
   9.178 +
   9.179 +    /* ==================================================== */
   9.180 +    // @Stable array == field && all components are stable
   9.181 +
   9.182 +    static class LongArrayDim1 {
   9.183 +        public @Stable long[] v;
   9.184 +
   9.185 +        public static final LongArrayDim1 c = new LongArrayDim1();
   9.186 +        public static long get() { return c.v[0]; }
   9.187 +        public static long get1() { return c.v[10]; }
   9.188 +        public static long[] get2() { return c.v; }
   9.189 +        public static void test() throws Exception {
   9.190 +            {
   9.191 +                c.v = new long[1]; c.v[0] = 1; long val1 = get();
   9.192 +                                   c.v[0] = 2; long val2 = get();
   9.193 +                assertEquals(val1, 1);
   9.194 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   9.195 +
   9.196 +                c.v = new long[1]; c.v[0] = 3; long val3 = get();
   9.197 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   9.198 +            }
   9.199 +
   9.200 +            {
   9.201 +                c.v = new long[20]; c.v[10] = 1; long val1 = get1();
   9.202 +                                    c.v[10] = 2; long val2 = get1();
   9.203 +                assertEquals(val1, 1);
   9.204 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   9.205 +
   9.206 +                c.v = new long[20]; c.v[10] = 3; long val3 = get1();
   9.207 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   9.208 +            }
   9.209 +
   9.210 +            {
   9.211 +                c.v = new long[1]; long[] val1 = get2();
   9.212 +                c.v = new long[1]; long[] val2 = get2();
   9.213 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.214 +            }
   9.215 +        }
   9.216 +    }
   9.217 +
   9.218 +    /* ==================================================== */
   9.219 +
   9.220 +    static class LongArrayDim2 {
   9.221 +        public @Stable long[][] v;
   9.222 +
   9.223 +        public static final LongArrayDim2 c = new LongArrayDim2();
   9.224 +        public static long get() { return c.v[0][0]; }
   9.225 +        public static long[] get1() { return c.v[0]; }
   9.226 +        public static long[][] get2() { return c.v; }
   9.227 +        public static void test() throws Exception {
   9.228 +            {
   9.229 +                c.v = new long[1][1]; c.v[0][0] = 1; long val1 = get();
   9.230 +                                      c.v[0][0] = 2; long val2 = get();
   9.231 +                assertEquals(val1, 1);
   9.232 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   9.233 +
   9.234 +                c.v = new long[1][1]; c.v[0][0] = 3; long val3 = get();
   9.235 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   9.236 +
   9.237 +                c.v[0] = new long[1]; c.v[0][0] = 4; long val4 = get();
   9.238 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   9.239 +            }
   9.240 +
   9.241 +            {
   9.242 +                c.v = new long[1][1]; long[] val1 = get1();
   9.243 +                c.v[0] = new long[1]; long[] val2 = get1();
   9.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.245 +            }
   9.246 +
   9.247 +            {
   9.248 +                c.v = new long[1][1]; long[][] val1 = get2();
   9.249 +                c.v = new long[1][1]; long[][] val2 = get2();
   9.250 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.251 +            }
   9.252 +        }
   9.253 +    }
   9.254 +
   9.255 +    /* ==================================================== */
   9.256 +
   9.257 +    static class LongArrayDim3 {
   9.258 +        public @Stable long[][][] v;
   9.259 +
   9.260 +        public static final LongArrayDim3 c = new LongArrayDim3();
   9.261 +        public static long get() { return c.v[0][0][0]; }
   9.262 +        public static long[] get1() { return c.v[0][0]; }
   9.263 +        public static long[][] get2() { return c.v[0]; }
   9.264 +        public static long[][][] get3() { return c.v; }
   9.265 +        public static void test() throws Exception {
   9.266 +            {
   9.267 +                c.v = new long[1][1][1]; c.v[0][0][0] = 1; long val1 = get();
   9.268 +                                         c.v[0][0][0] = 2; long val2 = get();
   9.269 +                assertEquals(val1, 1);
   9.270 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   9.271 +
   9.272 +                c.v = new long[1][1][1]; c.v[0][0][0] = 3; long val3 = get();
   9.273 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   9.274 +
   9.275 +                c.v[0] = new long[1][1]; c.v[0][0][0] = 4; long val4 = get();
   9.276 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   9.277 +
   9.278 +                c.v[0][0] = new long[1]; c.v[0][0][0] = 5; long val5 = get();
   9.279 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
   9.280 +            }
   9.281 +
   9.282 +            {
   9.283 +                c.v = new long[1][1][1]; long[] val1 = get1();
   9.284 +                c.v[0][0] = new long[1]; long[] val2 = get1();
   9.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.286 +            }
   9.287 +
   9.288 +            {
   9.289 +                c.v = new long[1][1][1]; long[][] val1 = get2();
   9.290 +                c.v[0] = new long[1][1]; long[][] val2 = get2();
   9.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.292 +            }
   9.293 +
   9.294 +            {
   9.295 +                c.v = new long[1][1][1]; long[][][] val1 = get3();
   9.296 +                c.v = new long[1][1][1]; long[][][] val2 = get3();
   9.297 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.298 +            }
   9.299 +        }
   9.300 +    }
   9.301 +
   9.302 +    /* ==================================================== */
   9.303 +
   9.304 +    static class LongArrayDim4 {
   9.305 +        public @Stable long[][][][] v;
   9.306 +
   9.307 +        public static final LongArrayDim4 c = new LongArrayDim4();
   9.308 +        public static long get() { return c.v[0][0][0][0]; }
   9.309 +        public static long[] get1() { return c.v[0][0][0]; }
   9.310 +        public static long[][] get2() { return c.v[0][0]; }
   9.311 +        public static long[][][] get3() { return c.v[0]; }
   9.312 +        public static long[][][][] get4() { return c.v; }
   9.313 +        public static void test() throws Exception {
   9.314 +            {
   9.315 +                c.v = new long[1][1][1][1]; c.v[0][0][0][0] = 1; long val1 = get();
   9.316 +                                            c.v[0][0][0][0] = 2; long val2 = get();
   9.317 +                assertEquals(val1, 1);
   9.318 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   9.319 +
   9.320 +                c.v = new long[1][1][1][1]; c.v[0][0][0][0] = 3; long val3 = get();
   9.321 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   9.322 +
   9.323 +                c.v[0] = new long[1][1][1]; c.v[0][0][0][0] = 4; long val4 = get();
   9.324 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
   9.325 +
   9.326 +                c.v[0][0] = new long[1][1]; c.v[0][0][0][0] = 5; long val5 = get();
   9.327 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
   9.328 +
   9.329 +                c.v[0][0][0] = new long[1]; c.v[0][0][0][0] = 6; long val6 = get();
   9.330 +                assertEquals(val6, (isStableEnabled ? 1 : 6));
   9.331 +            }
   9.332 +
   9.333 +            {
   9.334 +                c.v = new long[1][1][1][1]; long[] val1 = get1();
   9.335 +                c.v[0][0][0] = new long[1]; long[] val2 = get1();
   9.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.337 +            }
   9.338 +
   9.339 +            {
   9.340 +                c.v = new long[1][1][1][1]; long[][] val1 = get2();
   9.341 +                c.v[0][0] = new long[1][1]; long[][] val2 = get2();
   9.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.343 +            }
   9.344 +
   9.345 +            {
   9.346 +                c.v = new long[1][1][1][1]; long[][][] val1 = get3();
   9.347 +                c.v[0] = new long[1][1][1]; long[][][] val2 = get3();
   9.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.349 +            }
   9.350 +
   9.351 +            {
   9.352 +                c.v = new long[1][1][1][1]; long[][][][] val1 = get4();
   9.353 +                c.v = new long[1][1][1][1]; long[][][][] val2 = get4();
   9.354 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.355 +            }
   9.356 +
   9.357 +        }
   9.358 +    }
   9.359 +
   9.360 +    /* ==================================================== */
   9.361 +    // Dynamic Dim is higher than static
   9.362 +
   9.363 +    static class ObjectArrayLowerDim0 {
   9.364 +        public @Stable Object v;
   9.365 +
   9.366 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
   9.367 +        public static long get() { return ((long[])c.v)[0]; }
   9.368 +        public static long[] get1() { return (long[])c.v; }
   9.369 +
   9.370 +        public static void test() throws Exception {
   9.371 +            {
   9.372 +                c.v = new long[1]; ((long[])c.v)[0] = 1; long val1 = get();
   9.373 +                                   ((long[])c.v)[0] = 2; long val2 = get();
   9.374 +
   9.375 +                assertEquals(val1, 1);
   9.376 +                assertEquals(val2, 2);
   9.377 +            }
   9.378 +
   9.379 +            {
   9.380 +                c.v = new long[1]; long[] val1 = get1();
   9.381 +                c.v = new long[1]; long[] val2 = get1();
   9.382 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.383 +            }
   9.384 +        }
   9.385 +    }
   9.386 +
   9.387 +    /* ==================================================== */
   9.388 +
   9.389 +    static class ObjectArrayLowerDim1 {
   9.390 +        public @Stable Object[] v;
   9.391 +
   9.392 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
   9.393 +        public static long get() { return ((long[][])c.v)[0][0]; }
   9.394 +        public static long[] get1() { return (long[])(c.v[0]); }
   9.395 +        public static Object[] get2() { return c.v; }
   9.396 +
   9.397 +        public static void test() throws Exception {
   9.398 +            {
   9.399 +                c.v = new long[1][1]; ((long[][])c.v)[0][0] = 1; long val1 = get();
   9.400 +                                      ((long[][])c.v)[0][0] = 2; long val2 = get();
   9.401 +
   9.402 +                assertEquals(val1, 1);
   9.403 +                assertEquals(val2, 2);
   9.404 +            }
   9.405 +
   9.406 +            {
   9.407 +                c.v = new long[1][1]; c.v[0] = new long[0]; long[] val1 = get1();
   9.408 +                                     c.v[0] = new long[0]; long[] val2 = get1();
   9.409 +
   9.410 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.411 +            }
   9.412 +
   9.413 +            {
   9.414 +                c.v = new long[0][0]; Object[] val1 = get2();
   9.415 +                c.v = new long[0][0]; Object[] val2 = get2();
   9.416 +
   9.417 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.418 +            }
   9.419 +        }
   9.420 +    }
   9.421 +
   9.422 +    /* ==================================================== */
   9.423 +
   9.424 +    static class ObjectArrayLowerDim2 {
   9.425 +        public @Stable Object[][] v;
   9.426 +
   9.427 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
   9.428 +        public static long get() { return ((long[][][])c.v)[0][0][0]; }
   9.429 +        public static long[] get1() { return (long[])(c.v[0][0]); }
   9.430 +        public static long[][] get2() { return (long[][])(c.v[0]); }
   9.431 +        public static Object[][] get3() { return c.v; }
   9.432 +
   9.433 +        public static void test() throws Exception {
   9.434 +            {
   9.435 +                c.v = new long[1][1][1]; ((long[][][])c.v)[0][0][0] = 1L; long val1 = get();
   9.436 +                                         ((long[][][])c.v)[0][0][0] = 2L; long val2 = get();
   9.437 +
   9.438 +                assertEquals(val1, 1L);
   9.439 +                assertEquals(val2, 2L);
   9.440 +            }
   9.441 +
   9.442 +            {
   9.443 +                c.v = new long[1][1][1]; c.v[0][0] = new long[0]; long[] val1 = get1();
   9.444 +                                         c.v[0][0] = new long[0]; long[] val2 = get1();
   9.445 +
   9.446 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.447 +            }
   9.448 +
   9.449 +            {
   9.450 +                c.v = new long[1][1][1]; c.v[0] = new long[0][0]; long[][] val1 = get2();
   9.451 +                                         c.v[0] = new long[0][0]; long[][] val2 = get2();
   9.452 +
   9.453 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.454 +            }
   9.455 +
   9.456 +            {
   9.457 +                c.v = new long[0][0][0]; Object[][] val1 = get3();
   9.458 +                c.v = new long[0][0][0]; Object[][] val2 = get3();
   9.459 +
   9.460 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
   9.461 +            }
   9.462 +        }
   9.463 +    }
   9.464 +
   9.465 +    /* ==================================================== */
   9.466 +
   9.467 +    static class NestedStableField {
   9.468 +        static class A {
   9.469 +            public @Stable long a;
   9.470 +
   9.471 +        }
   9.472 +        public @Stable A v;
   9.473 +
   9.474 +        public static final NestedStableField c = new NestedStableField();
   9.475 +        public static A get() { return c.v; }
   9.476 +        public static long get1() { return get().a; }
   9.477 +
   9.478 +        public static void test() throws Exception {
   9.479 +            {
   9.480 +                c.v = new A(); c.v.a = 1; A val1 = get();
   9.481 +                               c.v.a = 2; A val2 = get();
   9.482 +
   9.483 +                assertEquals(val1.a, 2);
   9.484 +                assertEquals(val2.a, 2);
   9.485 +            }
   9.486 +
   9.487 +            {
   9.488 +                c.v = new A(); c.v.a = 1; long val1 = get1();
   9.489 +                               c.v.a = 2; long val2 = get1();
   9.490 +                c.v = new A(); c.v.a = 3; long val3 = get1();
   9.491 +
   9.492 +                assertEquals(val1, 1);
   9.493 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   9.494 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   9.495 +            }
   9.496 +        }
   9.497 +    }
   9.498 +
   9.499 +    /* ==================================================== */
   9.500 +
   9.501 +    static class NestedStableField1 {
   9.502 +        static class A {
   9.503 +            public @Stable long a;
   9.504 +            public @Stable A next;
   9.505 +        }
   9.506 +        public @Stable A v;
   9.507 +
   9.508 +        public static final NestedStableField1 c = new NestedStableField1();
   9.509 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
   9.510 +        public static long get1() { return get().a; }
   9.511 +
   9.512 +        public static void test() throws Exception {
   9.513 +            {
   9.514 +                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
   9.515 +                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
   9.516 +                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
   9.517 +
   9.518 +                assertEquals(val1.a, 2);
   9.519 +                assertEquals(val2.a, 2);
   9.520 +            }
   9.521 +
   9.522 +            {
   9.523 +                c.v = new A(); c.v.next = c.v;
   9.524 +                               c.v.a = 1; long val1 = get1();
   9.525 +                               c.v.a = 2; long val2 = get1();
   9.526 +                c.v = new A(); c.v.next = c.v;
   9.527 +                               c.v.a = 3; long val3 = get1();
   9.528 +
   9.529 +                assertEquals(val1, 1);
   9.530 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
   9.531 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
   9.532 +            }
   9.533 +        }
   9.534 +    }
   9.535 +   /* ==================================================== */
   9.536 +
   9.537 +    static class NestedStableField2 {
   9.538 +        static class A {
   9.539 +            public @Stable long a;
   9.540 +            public @Stable A left;
   9.541 +            public         A right;
   9.542 +        }
   9.543 +
   9.544 +        public @Stable A v;
   9.545 +
   9.546 +        public static final NestedStableField2 c = new NestedStableField2();
   9.547 +        public static long get() { return c.v.left.left.left.a; }
   9.548 +        public static long get1() { return c.v.left.left.right.left.a; }
   9.549 +
   9.550 +        public static void test() throws Exception {
   9.551 +            {
   9.552 +                c.v = new A(); c.v.left = c.v.right = c.v;
   9.553 +                               c.v.a = 1; long val1 = get(); long val2 = get1();
   9.554 +                               c.v.a = 2; long val3 = get(); long val4 = get1();
   9.555 +
   9.556 +                assertEquals(val1, 1);
   9.557 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
   9.558 +
   9.559 +                assertEquals(val2, 1);
   9.560 +                assertEquals(val4, 2);
   9.561 +            }
   9.562 +        }
   9.563 +    }
   9.564 +
   9.565 +    /* ==================================================== */
   9.566 +
   9.567 +    static class NestedStableField3 {
   9.568 +        static class A {
   9.569 +            public @Stable long a;
   9.570 +            public @Stable A[] left;
   9.571 +            public         A[] right;
   9.572 +        }
   9.573 +
   9.574 +        public @Stable A[] v;
   9.575 +
   9.576 +        public static final NestedStableField3 c = new NestedStableField3();
   9.577 +        public static long get() { return c.v[0].left[1].left[0].left[1].a; }
   9.578 +        public static long get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
   9.579 +
   9.580 +        public static void test() throws Exception {
   9.581 +            {
   9.582 +                A elem = new A();
   9.583 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
   9.584 +                               elem.a = 1; long val1 = get(); long val2 = get1();
   9.585 +                               elem.a = 2; long val3 = get(); long val4 = get1();
   9.586 +
   9.587 +                assertEquals(val1, 1);
   9.588 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
   9.589 +
   9.590 +                assertEquals(val2, 1);
   9.591 +                assertEquals(val4, 2);
   9.592 +            }
   9.593 +        }
   9.594 +    }
   9.595 +
   9.596 +    /* ==================================================== */
   9.597 +    // Auxiliary methods
   9.598 +    static void assertEquals(long i, long j) { if (i != j)  throw new AssertionError(i + " != " + j); }
   9.599 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
   9.600 +
   9.601 +    static boolean failed = false;
   9.602 +
   9.603 +    public static void run(Class<?> test) {
   9.604 +        Throwable ex = null;
   9.605 +        System.out.print(test.getName()+": ");
   9.606 +        try {
   9.607 +            test.getMethod("test").invoke(null);
   9.608 +        } catch (InvocationTargetException e) {
   9.609 +            ex = e.getCause();
   9.610 +        } catch (Throwable e) {
   9.611 +            ex = e;
   9.612 +        } finally {
   9.613 +            if (ex == null) {
   9.614 +                System.out.println("PASSED");
   9.615 +            } else {
   9.616 +                failed = true;
   9.617 +                System.out.println("FAILED");
   9.618 +                ex.printStackTrace(System.out);
   9.619 +            }
   9.620 +        }
   9.621 +    }
   9.622 +
   9.623 +    static final boolean isStableEnabled;
   9.624 +    static {
   9.625 +        HotSpotDiagnosticMXBean diagnostic
   9.626 +                = ManagementFactoryHelper.getDiagnosticMXBean();
   9.627 +        VMOption tmp;
   9.628 +        try {
   9.629 +            tmp = diagnostic.getVMOption("FoldStableValues");
   9.630 +        } catch (IllegalArgumentException e) {
   9.631 +            tmp = null;
   9.632 +        }
   9.633 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
   9.634 +    }
   9.635 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/compiler/stable/TestStableObject.java	Fri Mar 28 10:13:37 2014 -0700
    10.3 @@ -0,0 +1,635 @@
    10.4 +/*
    10.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.  Oracle designates this
   10.11 + * particular file as subject to the "Classpath" exception as provided
   10.12 + * by Oracle in the LICENSE file that accompanied this code.
   10.13 + *
   10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.17 + * version 2 for more details (a copy is included in the LICENSE file that
   10.18 + * accompanied this code).
   10.19 + *
   10.20 + * You should have received a copy of the GNU General Public License version
   10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.23 + *
   10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.25 + * or visit www.oracle.com if you need additional information or have any
   10.26 + * questions.
   10.27 + */
   10.28 +
   10.29 +/*
   10.30 + * @test TestStableObject
   10.31 + * @summary tests on stable fields and arrays
   10.32 + * @library /testlibrary
   10.33 + * @compile -XDignore.symbol.file TestStableObject.java
   10.34 + * @run main ClassFileInstaller
   10.35 + *           java/lang/invoke/TestStableObject
   10.36 + *           java/lang/invoke/TestStableObject$ObjectStable
   10.37 + *           java/lang/invoke/TestStableObject$StaticObjectStable
   10.38 + *           java/lang/invoke/TestStableObject$VolatileObjectStable
   10.39 + *           java/lang/invoke/TestStableObject$ObjectArrayDim1
   10.40 + *           java/lang/invoke/TestStableObject$ObjectArrayDim2
   10.41 + *           java/lang/invoke/TestStableObject$ObjectArrayDim3
   10.42 + *           java/lang/invoke/TestStableObject$ObjectArrayDim4
   10.43 + *           java/lang/invoke/TestStableObject$ObjectArrayLowerDim0
   10.44 + *           java/lang/invoke/TestStableObject$ObjectArrayLowerDim1
   10.45 + *           java/lang/invoke/TestStableObject$NestedStableField
   10.46 + *           java/lang/invoke/TestStableObject$NestedStableField$A
   10.47 + *           java/lang/invoke/TestStableObject$NestedStableField1
   10.48 + *           java/lang/invoke/TestStableObject$NestedStableField1$A
   10.49 + *           java/lang/invoke/TestStableObject$NestedStableField2
   10.50 + *           java/lang/invoke/TestStableObject$NestedStableField2$A
   10.51 + *           java/lang/invoke/TestStableObject$NestedStableField3
   10.52 + *           java/lang/invoke/TestStableObject$NestedStableField3$A
   10.53 + *           java/lang/invoke/TestStableObject$Values
   10.54 + *           java/lang/invoke/TestStableObject$DefaultValue
   10.55 + *           java/lang/invoke/TestStableObject$ObjectArrayLowerDim2
   10.56 + *
   10.57 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   10.58 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
   10.59 + *                   -server -XX:-TieredCompilation -Xcomp
   10.60 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   10.61 + *                   java.lang.invoke.TestStableObject
   10.62 + *
   10.63 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   10.64 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
   10.65 + *                   -server -XX:-TieredCompilation -Xcomp
   10.66 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   10.67 + *                   java.lang.invoke.TestStableObject
   10.68 + *
   10.69 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   10.70 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
   10.71 + *                   -server -XX:-TieredCompilation -Xcomp
   10.72 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   10.73 + *                   java.lang.invoke.TestStableObject
   10.74 + *
   10.75 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   10.76 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
   10.77 + *                   -server -XX:-TieredCompilation -Xcomp
   10.78 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   10.79 + *                   java.lang.invoke.TestStableObject
   10.80 + */
   10.81 +package java.lang.invoke;
   10.82 +
   10.83 +import com.sun.management.HotSpotDiagnosticMXBean;
   10.84 +import com.sun.management.VMOption;
   10.85 +import sun.management.ManagementFactoryHelper;
   10.86 +import java.lang.reflect.InvocationTargetException;
   10.87 +
   10.88 +public class TestStableObject {
   10.89 +    public static void main(String[] args) throws Exception {
   10.90 +        System.out.println("@Stable enabled: "+isStableEnabled);
   10.91 +        System.out.println();
   10.92 +
   10.93 +        run(DefaultValue.class);
   10.94 +        run(ObjectStable.class);
   10.95 +        run(StaticObjectStable.class);
   10.96 +        run(VolatileObjectStable.class);
   10.97 +
   10.98 +        // @Stable arrays: Dim 1-4
   10.99 +        run(ObjectArrayDim1.class);
  10.100 +        run(ObjectArrayDim2.class);
  10.101 +        run(ObjectArrayDim3.class);
  10.102 +        run(ObjectArrayDim4.class);
  10.103 +
  10.104 +        // @Stable Object field: dynamic arrays
  10.105 +        run(ObjectArrayLowerDim0.class);
  10.106 +        run(ObjectArrayLowerDim1.class);
  10.107 +        run(ObjectArrayLowerDim2.class);
  10.108 +
  10.109 +        // Nested @Stable fields
  10.110 +        run(NestedStableField.class);
  10.111 +        run(NestedStableField1.class);
  10.112 +        run(NestedStableField2.class);
  10.113 +        run(NestedStableField3.class);
  10.114 +
  10.115 +        if (failed) {
  10.116 +            throw new Error("TEST FAILED");
  10.117 +        }
  10.118 +    }
  10.119 +
  10.120 +    /* ==================================================== */
  10.121 +
  10.122 +    enum Values {A, B, C, D, E, F}
  10.123 +
  10.124 +    static class DefaultValue {
  10.125 +        public @Stable Object v;
  10.126 +
  10.127 +        public static final DefaultValue c = new DefaultValue();
  10.128 +        public static Object get() { return c.v; }
  10.129 +        public static void test() throws Exception {
  10.130 +                            Object val1 = get();
  10.131 +            c.v = Values.A; Object val2 = get();
  10.132 +            assertEquals(val1, null);
  10.133 +            assertEquals(val2, Values.A);
  10.134 +        }
  10.135 +    }
  10.136 +
  10.137 +    /* ==================================================== */
  10.138 +
  10.139 +    static class ObjectStable {
  10.140 +        public @Stable Values v;
  10.141 +
  10.142 +        public static final ObjectStable c = new ObjectStable ();
  10.143 +        public static Values get() { return c.v; }
  10.144 +        public static void test() throws Exception {
  10.145 +            c.v = Values.A; Values val1 = get();
  10.146 +            c.v = Values.B; Values val2 = get();
  10.147 +            assertEquals(val1, Values.A);
  10.148 +            assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.149 +        }
  10.150 +    }
  10.151 +
  10.152 +    /* ==================================================== */
  10.153 +
  10.154 +    static class StaticObjectStable {
  10.155 +        public static @Stable Values v;
  10.156 +
  10.157 +        public static final ObjectStable c = new ObjectStable ();
  10.158 +        public static Values get() { return c.v; }
  10.159 +        public static void test() throws Exception {
  10.160 +            c.v = Values.A; Values val1 = get();
  10.161 +            c.v = Values.B; Values val2 = get();
  10.162 +            assertEquals(val1, Values.A);
  10.163 +            assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.164 +        }
  10.165 +    }
  10.166 +
  10.167 +    /* ==================================================== */
  10.168 +
  10.169 +    static class VolatileObjectStable {
  10.170 +        public @Stable volatile Values v;
  10.171 +
  10.172 +        public static final VolatileObjectStable c = new VolatileObjectStable ();
  10.173 +        public static Values get() { return c.v; }
  10.174 +        public static void test() throws Exception {
  10.175 +            c.v = Values.A; Values val1 = get();
  10.176 +            c.v = Values.B; Values val2 = get();
  10.177 +            assertEquals(val1, Values.A);
  10.178 +            assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.179 +        }
  10.180 +    }
  10.181 +
  10.182 +    /* ==================================================== */
  10.183 +    // @Stable array == field && all components are stable
  10.184 +
  10.185 +    static class ObjectArrayDim1 {
  10.186 +        public @Stable Object[] v;
  10.187 +
  10.188 +        public static final ObjectArrayDim1 c = new ObjectArrayDim1();
  10.189 +        public static Object get() { return c.v[0]; }
  10.190 +        public static Object get1() { return c.v[10]; }
  10.191 +        public static Object[] get2() { return c.v; }
  10.192 +        public static void test() throws Exception {
  10.193 +            {
  10.194 +                c.v = new Object[1]; c.v[0] = Values.A; Object val1 = get();
  10.195 +                                     c.v[0] = Values.B; Object val2 = get();
  10.196 +                assertEquals(val1, Values.A);
  10.197 +                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.198 +
  10.199 +                c.v = new Object[1]; c.v[0] = Values.C; Object val3 = get();
  10.200 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
  10.201 +            }
  10.202 +
  10.203 +            {
  10.204 +                c.v = new Object[20]; c.v[10] = Values.A; Object val1 = get1();
  10.205 +                                      c.v[10] = Values.B; Object val2 = get1();
  10.206 +                assertEquals(val1, Values.A);
  10.207 +                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.208 +
  10.209 +                c.v = new Object[20]; c.v[10] = Values.C; Object val3 = get1();
  10.210 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
  10.211 +            }
  10.212 +
  10.213 +            {
  10.214 +                c.v = new Object[1]; Object[] val1 = get2();
  10.215 +                c.v = new Object[1]; Object[] val2 = get2();
  10.216 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.217 +            }
  10.218 +        }
  10.219 +    }
  10.220 +
  10.221 +    /* ==================================================== */
  10.222 +
  10.223 +    static class ObjectArrayDim2 {
  10.224 +        public @Stable Object[][] v;
  10.225 +
  10.226 +        public static final ObjectArrayDim2 c = new ObjectArrayDim2();
  10.227 +        public static Object get() { return c.v[0][0]; }
  10.228 +        public static Object[] get1() { return c.v[0]; }
  10.229 +        public static Object[][] get2() { return c.v; }
  10.230 +        public static void test() throws Exception {
  10.231 +            {
  10.232 +                c.v = new Object[1][1]; c.v[0][0] = Values.A; Object val1 = get();
  10.233 +                                        c.v[0][0] = Values.B; Object val2 = get();
  10.234 +                assertEquals(val1, Values.A);
  10.235 +                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.236 +
  10.237 +                c.v = new Object[1][1]; c.v[0][0] = Values.C; Object val3 = get();
  10.238 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
  10.239 +
  10.240 +                c.v[0] = new Object[1]; c.v[0][0] = Values.D; Object val4 = get();
  10.241 +                assertEquals(val4, (isStableEnabled ? Values.A : Values.D));
  10.242 +            }
  10.243 +
  10.244 +            {
  10.245 +                c.v = new Object[1][1]; Object[] val1 = get1();
  10.246 +                c.v[0] = new Object[1]; Object[] val2 = get1();
  10.247 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.248 +            }
  10.249 +
  10.250 +            {
  10.251 +                c.v = new Object[1][1]; Object[][] val1 = get2();
  10.252 +                c.v = new Object[1][1]; Object[][] val2 = get2();
  10.253 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.254 +            }
  10.255 +        }
  10.256 +    }
  10.257 +
  10.258 +    /* ==================================================== */
  10.259 +
  10.260 +    static class ObjectArrayDim3 {
  10.261 +        public @Stable Object[][][] v;
  10.262 +
  10.263 +        public static final ObjectArrayDim3 c = new ObjectArrayDim3();
  10.264 +        public static Object get() { return c.v[0][0][0]; }
  10.265 +        public static Object[] get1() { return c.v[0][0]; }
  10.266 +        public static Object[][] get2() { return c.v[0]; }
  10.267 +        public static Object[][][] get3() { return c.v; }
  10.268 +        public static void test() throws Exception {
  10.269 +            {
  10.270 +                c.v = new Object[1][1][1]; c.v[0][0][0] = Values.A; Object val1 = get();
  10.271 +                                           c.v[0][0][0] = Values.B; Object val2 = get();
  10.272 +                assertEquals(val1, Values.A);
  10.273 +                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.274 +
  10.275 +                c.v = new Object[1][1][1]; c.v[0][0][0] = Values.C; Object val3 = get();
  10.276 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
  10.277 +
  10.278 +                c.v[0] = new Object[1][1]; c.v[0][0][0] = Values.D; Object val4 = get();
  10.279 +                assertEquals(val4, (isStableEnabled ? Values.A : Values.D));
  10.280 +
  10.281 +                c.v[0][0] = new Object[1]; c.v[0][0][0] = Values.E; Object val5 = get();
  10.282 +                assertEquals(val5, (isStableEnabled ? Values.A : Values.E));
  10.283 +            }
  10.284 +
  10.285 +            {
  10.286 +                c.v = new Object[1][1][1]; Object[] val1 = get1();
  10.287 +                c.v[0][0] = new Object[1]; Object[] val2 = get1();
  10.288 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.289 +            }
  10.290 +
  10.291 +            {
  10.292 +                c.v = new Object[1][1][1]; Object[][] val1 = get2();
  10.293 +                c.v[0] = new Object[1][1]; Object[][] val2 = get2();
  10.294 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.295 +            }
  10.296 +
  10.297 +            {
  10.298 +                c.v = new Object[1][1][1]; Object[][][] val1 = get3();
  10.299 +                c.v = new Object[1][1][1]; Object[][][] val2 = get3();
  10.300 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.301 +            }
  10.302 +        }
  10.303 +    }
  10.304 +
  10.305 +    /* ==================================================== */
  10.306 +
  10.307 +    static class ObjectArrayDim4 {
  10.308 +        public @Stable Object[][][][] v;
  10.309 +
  10.310 +        public static final ObjectArrayDim4 c = new ObjectArrayDim4();
  10.311 +        public static Object get() { return c.v[0][0][0][0]; }
  10.312 +        public static Object[] get1() { return c.v[0][0][0]; }
  10.313 +        public static Object[][] get2() { return c.v[0][0]; }
  10.314 +        public static Object[][][] get3() { return c.v[0]; }
  10.315 +        public static Object[][][][] get4() { return c.v; }
  10.316 +        public static void test() throws Exception {
  10.317 +            {
  10.318 +                c.v = new Object[1][1][1][1]; c.v[0][0][0][0] = Values.A; Object val1 = get();
  10.319 +                                              c.v[0][0][0][0] = Values.B; Object val2 = get();
  10.320 +                assertEquals(val1, Values.A);
  10.321 +                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.322 +
  10.323 +                c.v = new Object[1][1][1][1]; c.v[0][0][0][0] = Values.C; Object val3 = get();
  10.324 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
  10.325 +
  10.326 +                c.v[0] = new Object[1][1][1]; c.v[0][0][0][0] = Values.D; Object val4 = get();
  10.327 +                assertEquals(val4, (isStableEnabled ? Values.A : Values.D));
  10.328 +
  10.329 +                c.v[0][0] = new Object[1][1]; c.v[0][0][0][0] = Values.E; Object val5 = get();
  10.330 +                assertEquals(val5, (isStableEnabled ? Values.A : Values.E));
  10.331 +
  10.332 +                c.v[0][0][0] = new Object[1]; c.v[0][0][0][0] = Values.F; Object val6 = get();
  10.333 +                assertEquals(val6, (isStableEnabled ? Values.A : Values.F));
  10.334 +            }
  10.335 +
  10.336 +            {
  10.337 +                c.v = new Object[1][1][1][1]; Object[] val1 = get1();
  10.338 +                c.v[0][0][0] = new Object[1]; Object[] val2 = get1();
  10.339 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.340 +            }
  10.341 +
  10.342 +            {
  10.343 +                c.v = new Object[1][1][1][1]; Object[][] val1 = get2();
  10.344 +                c.v[0][0] = new Object[1][1]; Object[][] val2 = get2();
  10.345 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.346 +            }
  10.347 +
  10.348 +            {
  10.349 +                c.v = new Object[1][1][1][1]; Object[][][] val1 = get3();
  10.350 +                c.v[0] = new Object[1][1][1]; Object[][][] val2 = get3();
  10.351 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.352 +            }
  10.353 +
  10.354 +            {
  10.355 +                c.v = new Object[1][1][1][1]; Object[][][][] val1 = get4();
  10.356 +                c.v = new Object[1][1][1][1]; Object[][][][] val2 = get4();
  10.357 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.358 +            }
  10.359 +
  10.360 +        }
  10.361 +    }
  10.362 +
  10.363 +    /* ==================================================== */
  10.364 +    // Dynamic Dim is higher than static
  10.365 +
  10.366 +    static class ObjectArrayLowerDim0 {
  10.367 +        public @Stable Object v;
  10.368 +
  10.369 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
  10.370 +        public static Object get() { return ((Object[])c.v)[0]; }
  10.371 +        public static Object[] get1() { return (Object[])c.v; }
  10.372 +
  10.373 +        public static void test() throws Exception {
  10.374 +            {
  10.375 +                c.v = new Object[1]; ((Object[])c.v)[0] = Values.A; Object val1 = get();
  10.376 +                                     ((Object[])c.v)[0] = Values.B; Object val2 = get();
  10.377 +
  10.378 +                assertEquals(val1, Values.A);
  10.379 +                assertEquals(val2, Values.B);
  10.380 +            }
  10.381 +
  10.382 +            {
  10.383 +                c.v = new Object[1]; Object[] val1 = get1();
  10.384 +                c.v = new Object[1]; Object[] val2 = get1();
  10.385 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.386 +            }
  10.387 +        }
  10.388 +    }
  10.389 +
  10.390 +    /* ==================================================== */
  10.391 +
  10.392 +    static class ObjectArrayLowerDim1 {
  10.393 +        public @Stable Object[] v;
  10.394 +
  10.395 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
  10.396 +        public static Object get() { return ((Object[][])c.v)[0][0]; }
  10.397 +        public static Object[] get1() { return (Object[])(c.v[0]); }
  10.398 +        public static Object[] get2() { return c.v; }
  10.399 +
  10.400 +        public static void test() throws Exception {
  10.401 +            {
  10.402 +                c.v = new Object[1][1]; ((Object[][])c.v)[0][0] = Values.A; Object val1 = get();
  10.403 +                                        ((Object[][])c.v)[0][0] = Values.B; Object val2 = get();
  10.404 +
  10.405 +                assertEquals(val1, Values.A);
  10.406 +                assertEquals(val2, Values.B);
  10.407 +            }
  10.408 +
  10.409 +            {
  10.410 +                c.v = new Object[1][1]; c.v[0] = new Object[0]; Object[] val1 = get1();
  10.411 +                                     c.v[0] = new Object[0]; Object[] val2 = get1();
  10.412 +
  10.413 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.414 +            }
  10.415 +
  10.416 +            {
  10.417 +                c.v = new Object[0][0]; Object[] val1 = get2();
  10.418 +                c.v = new Object[0][0]; Object[] val2 = get2();
  10.419 +
  10.420 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.421 +            }
  10.422 +        }
  10.423 +    }
  10.424 +
  10.425 +    /* ==================================================== */
  10.426 +
  10.427 +    static class ObjectArrayLowerDim2 {
  10.428 +        public @Stable Object[][] v;
  10.429 +
  10.430 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
  10.431 +        public static Object get() { return ((Object[][][])c.v)[0][0][0]; }
  10.432 +        public static Object[] get1() { return (Object[])(c.v[0][0]); }
  10.433 +        public static Object[][] get2() { return (Object[][])(c.v[0]); }
  10.434 +        public static Object[][] get3() { return c.v; }
  10.435 +
  10.436 +        public static void test() throws Exception {
  10.437 +            {
  10.438 +                c.v = new Object[1][1][1]; ((Object[][][])c.v)[0][0][0] = Values.A; Object val1 = get();
  10.439 +                                           ((Object[][][])c.v)[0][0][0] = Values.B; Object val2 = get();
  10.440 +
  10.441 +                assertEquals(val1, Values.A);
  10.442 +                assertEquals(val2, Values.B);
  10.443 +            }
  10.444 +
  10.445 +            {
  10.446 +                c.v = new Object[1][1][1]; c.v[0][0] = new Object[0]; Object[] val1 = get1();
  10.447 +                                           c.v[0][0] = new Object[0]; Object[] val2 = get1();
  10.448 +
  10.449 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.450 +            }
  10.451 +
  10.452 +            {
  10.453 +                c.v = new Object[1][1][1]; c.v[0] = new Object[0][0]; Object[][] val1 = get2();
  10.454 +                                           c.v[0] = new Object[0][0]; Object[][] val2 = get2();
  10.455 +
  10.456 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.457 +            }
  10.458 +
  10.459 +            {
  10.460 +                c.v = new Object[0][0][0]; Object[][] val1 = get3();
  10.461 +                c.v = new Object[0][0][0]; Object[][] val2 = get3();
  10.462 +
  10.463 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  10.464 +            }
  10.465 +        }
  10.466 +    }
  10.467 +
  10.468 +    /* ==================================================== */
  10.469 +
  10.470 +    static class NestedStableField {
  10.471 +        static class A {
  10.472 +            public @Stable Object a;
  10.473 +
  10.474 +        }
  10.475 +        public @Stable A v;
  10.476 +
  10.477 +        public static final NestedStableField c = new NestedStableField();
  10.478 +        public static A get() { return c.v; }
  10.479 +        public static Object get1() { return get().a; }
  10.480 +
  10.481 +        public static void test() throws Exception {
  10.482 +            {
  10.483 +                c.v = new A(); c.v.a = Values.A; A val1 = get();
  10.484 +                               c.v.a = Values.B; A val2 = get();
  10.485 +
  10.486 +                assertEquals(val1.a, Values.B);
  10.487 +                assertEquals(val2.a, Values.B);
  10.488 +            }
  10.489 +
  10.490 +            {
  10.491 +                c.v = new A(); c.v.a = Values.A; Object val1 = get1();
  10.492 +                               c.v.a = Values.B; Object val2 = get1();
  10.493 +                c.v = new A(); c.v.a = Values.C; Object val3 = get1();
  10.494 +
  10.495 +                assertEquals(val1, Values.A);
  10.496 +                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.497 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
  10.498 +            }
  10.499 +        }
  10.500 +    }
  10.501 +
  10.502 +    /* ==================================================== */
  10.503 +
  10.504 +    static class NestedStableField1 {
  10.505 +        static class A {
  10.506 +            public @Stable Object a;
  10.507 +            public @Stable A next;
  10.508 +        }
  10.509 +        public @Stable A v;
  10.510 +
  10.511 +        public static final NestedStableField1 c = new NestedStableField1();
  10.512 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
  10.513 +        public static Object get1() { return get().a; }
  10.514 +
  10.515 +        public static void test() throws Exception {
  10.516 +            {
  10.517 +                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
  10.518 +                               c.v.a = Values.A; c.v.next.a = Values.A; A val1 = get();
  10.519 +                               c.v.a = Values.B; c.v.next.a = Values.B; A val2 = get();
  10.520 +
  10.521 +                assertEquals(val1.a, Values.B);
  10.522 +                assertEquals(val2.a, Values.B);
  10.523 +            }
  10.524 +
  10.525 +            {
  10.526 +                c.v = new A(); c.v.next = c.v;
  10.527 +                               c.v.a = Values.A; Object val1 = get1();
  10.528 +                               c.v.a = Values.B; Object val2 = get1();
  10.529 +                c.v = new A(); c.v.next = c.v;
  10.530 +                               c.v.a = Values.C; Object val3 = get1();
  10.531 +
  10.532 +                assertEquals(val1, Values.A);
  10.533 +                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
  10.534 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
  10.535 +            }
  10.536 +        }
  10.537 +    }
  10.538 +   /* ==================================================== */
  10.539 +
  10.540 +    static class NestedStableField2 {
  10.541 +        static class A {
  10.542 +            public @Stable Object a;
  10.543 +            public @Stable A left;
  10.544 +            public         A right;
  10.545 +        }
  10.546 +
  10.547 +        public @Stable A v;
  10.548 +
  10.549 +        public static final NestedStableField2 c = new NestedStableField2();
  10.550 +        public static Object get() { return c.v.left.left.left.a; }
  10.551 +        public static Object get1() { return c.v.left.left.right.left.a; }
  10.552 +
  10.553 +        public static void test() throws Exception {
  10.554 +            {
  10.555 +                c.v = new A(); c.v.left = c.v.right = c.v;
  10.556 +                               c.v.a = Values.A; Object val1 = get(); Object val2 = get1();
  10.557 +                               c.v.a = Values.B; Object val3 = get(); Object val4 = get1();
  10.558 +
  10.559 +                assertEquals(val1, Values.A);
  10.560 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.B));
  10.561 +
  10.562 +                assertEquals(val2, Values.A);
  10.563 +                assertEquals(val4, Values.B);
  10.564 +            }
  10.565 +        }
  10.566 +    }
  10.567 +
  10.568 +    /* ==================================================== */
  10.569 +
  10.570 +    static class NestedStableField3 {
  10.571 +        static class A {
  10.572 +            public @Stable Object a;
  10.573 +            public @Stable A[] left;
  10.574 +            public         A[] right;
  10.575 +        }
  10.576 +
  10.577 +        public @Stable A[] v;
  10.578 +
  10.579 +        public static final NestedStableField3 c = new NestedStableField3();
  10.580 +        public static Object get() { return c.v[0].left[1].left[0].left[1].a; }
  10.581 +        public static Object get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
  10.582 +
  10.583 +        public static void test() throws Exception {
  10.584 +            {
  10.585 +                A elem = new A();
  10.586 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
  10.587 +                               elem.a = Values.A; Object val1 = get(); Object val2 = get1();
  10.588 +                               elem.a = Values.B; Object val3 = get(); Object val4 = get1();
  10.589 +
  10.590 +                assertEquals(val1, Values.A);
  10.591 +                assertEquals(val3, (isStableEnabled ? Values.A : Values.B));
  10.592 +
  10.593 +                assertEquals(val2, Values.A);
  10.594 +                assertEquals(val4, Values.B);
  10.595 +            }
  10.596 +        }
  10.597 +    }
  10.598 +
  10.599 +    /* ==================================================== */
  10.600 +    // Auxiliary methods
  10.601 +    static void assertEquals(Object i, Object j) { if (i != j)  throw new AssertionError(i + " != " + j); }
  10.602 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
  10.603 +
  10.604 +    static boolean failed = false;
  10.605 +
  10.606 +    public static void run(Class<?> test) {
  10.607 +        Throwable ex = null;
  10.608 +        System.out.print(test.getName()+": ");
  10.609 +        try {
  10.610 +            test.getMethod("test").invoke(null);
  10.611 +        } catch (InvocationTargetException e) {
  10.612 +            ex = e.getCause();
  10.613 +        } catch (Throwable e) {
  10.614 +            ex = e;
  10.615 +        } finally {
  10.616 +            if (ex == null) {
  10.617 +                System.out.println("PASSED");
  10.618 +            } else {
  10.619 +                failed = true;
  10.620 +                System.out.println("FAILED");
  10.621 +                ex.printStackTrace(System.out);
  10.622 +            }
  10.623 +        }
  10.624 +    }
  10.625 +
  10.626 +    static final boolean isStableEnabled;
  10.627 +    static {
  10.628 +        HotSpotDiagnosticMXBean diagnostic
  10.629 +                = ManagementFactoryHelper.getDiagnosticMXBean();
  10.630 +        VMOption tmp;
  10.631 +        try {
  10.632 +            tmp = diagnostic.getVMOption("FoldStableValues");
  10.633 +        } catch (IllegalArgumentException e) {
  10.634 +            tmp = null;
  10.635 +        }
  10.636 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
  10.637 +    }
  10.638 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/compiler/stable/TestStableShort.java	Fri Mar 28 10:13:37 2014 -0700
    11.3 @@ -0,0 +1,632 @@
    11.4 +/*
    11.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.  Oracle designates this
   11.11 + * particular file as subject to the "Classpath" exception as provided
   11.12 + * by Oracle in the LICENSE file that accompanied this code.
   11.13 + *
   11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.17 + * version 2 for more details (a copy is included in the LICENSE file that
   11.18 + * accompanied this code).
   11.19 + *
   11.20 + * You should have received a copy of the GNU General Public License version
   11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.23 + *
   11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.25 + * or visit www.oracle.com if you need additional information or have any
   11.26 + * questions.
   11.27 + */
   11.28 +
   11.29 +/*
   11.30 + * @test TestStableShort
   11.31 + * @summary tests on stable fields and arrays
   11.32 + * @library /testlibrary
   11.33 + * @compile -XDignore.symbol.file TestStableShort.java
   11.34 + * @run main ClassFileInstaller
   11.35 + *           java/lang/invoke/TestStableShort
   11.36 + *           java/lang/invoke/TestStableShort$ShortStable
   11.37 + *           java/lang/invoke/TestStableShort$StaticShortStable
   11.38 + *           java/lang/invoke/TestStableShort$VolatileShortStable
   11.39 + *           java/lang/invoke/TestStableShort$ShortArrayDim1
   11.40 + *           java/lang/invoke/TestStableShort$ShortArrayDim2
   11.41 + *           java/lang/invoke/TestStableShort$ShortArrayDim3
   11.42 + *           java/lang/invoke/TestStableShort$ShortArrayDim4
   11.43 + *           java/lang/invoke/TestStableShort$ObjectArrayLowerDim0
   11.44 + *           java/lang/invoke/TestStableShort$ObjectArrayLowerDim1
   11.45 + *           java/lang/invoke/TestStableShort$NestedStableField
   11.46 + *           java/lang/invoke/TestStableShort$NestedStableField$A
   11.47 + *           java/lang/invoke/TestStableShort$NestedStableField1
   11.48 + *           java/lang/invoke/TestStableShort$NestedStableField1$A
   11.49 + *           java/lang/invoke/TestStableShort$NestedStableField2
   11.50 + *           java/lang/invoke/TestStableShort$NestedStableField2$A
   11.51 + *           java/lang/invoke/TestStableShort$NestedStableField3
   11.52 + *           java/lang/invoke/TestStableShort$NestedStableField3$A
   11.53 + *           java/lang/invoke/TestStableShort$DefaultValue
   11.54 + *           java/lang/invoke/TestStableShort$ObjectArrayLowerDim2
   11.55 + *
   11.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   11.57 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
   11.58 + *                   -server -XX:-TieredCompilation -Xcomp
   11.59 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   11.60 + *                   java.lang.invoke.TestStableShort
   11.61 + *
   11.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   11.63 + *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
   11.64 + *                   -server -XX:-TieredCompilation -Xcomp
   11.65 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   11.66 + *                   java.lang.invoke.TestStableShort
   11.67 + *
   11.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   11.69 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
   11.70 + *                   -server -XX:-TieredCompilation -Xcomp
   11.71 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   11.72 + *                   java.lang.invoke.TestStableShort
   11.73 + *
   11.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
   11.75 + *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
   11.76 + *                   -server -XX:-TieredCompilation -Xcomp
   11.77 + *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
   11.78 + *                   java.lang.invoke.TestStableShort
   11.79 + */
   11.80 +package java.lang.invoke;
   11.81 +
   11.82 +import com.sun.management.HotSpotDiagnosticMXBean;
   11.83 +import com.sun.management.VMOption;
   11.84 +import sun.management.ManagementFactoryHelper;
   11.85 +import java.lang.reflect.InvocationTargetException;
   11.86 +
   11.87 +public class TestStableShort {
   11.88 +    public static void main(String[] args) throws Exception {
   11.89 +        System.out.println("@Stable enabled: "+isStableEnabled);
   11.90 +        System.out.println();
   11.91 +
   11.92 +        run(DefaultValue.class);
   11.93 +        run(ShortStable.class);
   11.94 +        run(StaticShortStable.class);
   11.95 +        run(VolatileShortStable.class);
   11.96 +
   11.97 +        // @Stable arrays: Dim 1-4
   11.98 +        run(ShortArrayDim1.class);
   11.99 +        run(ShortArrayDim2.class);
  11.100 +        run(ShortArrayDim3.class);
  11.101 +        run(ShortArrayDim4.class);
  11.102 +
  11.103 +        // @Stable Object field: dynamic arrays
  11.104 +        run(ObjectArrayLowerDim0.class);
  11.105 +        run(ObjectArrayLowerDim1.class);
  11.106 +        run(ObjectArrayLowerDim2.class);
  11.107 +
  11.108 +        // Nested @Stable fields
  11.109 +        run(NestedStableField.class);
  11.110 +        run(NestedStableField1.class);
  11.111 +        run(NestedStableField2.class);
  11.112 +        run(NestedStableField3.class);
  11.113 +
  11.114 +        if (failed) {
  11.115 +            throw new Error("TEST FAILED");
  11.116 +        }
  11.117 +    }
  11.118 +
  11.119 +    /* ==================================================== */
  11.120 +
  11.121 +    static class DefaultValue {
  11.122 +        public @Stable short v;
  11.123 +
  11.124 +        public static final DefaultValue c = new DefaultValue();
  11.125 +        public static short get() { return c.v; }
  11.126 +        public static void test() throws Exception {
  11.127 +                     short val1 = get();
  11.128 +            c.v = 1; short val2 = get();
  11.129 +            assertEquals(val1, 0);
  11.130 +            assertEquals(val2, 1);
  11.131 +        }
  11.132 +    }
  11.133 +
  11.134 +    /* ==================================================== */
  11.135 +
  11.136 +    static class ShortStable {
  11.137 +        public @Stable short v;
  11.138 +
  11.139 +        public static final ShortStable c = new ShortStable();
  11.140 +        public static short get() { return c.v; }
  11.141 +        public static void test() throws Exception {
  11.142 +            c.v = 1;     short val1 = get();
  11.143 +            c.v = 32767; short val2 = get();
  11.144 +            assertEquals(val1, 1);
  11.145 +            assertEquals(val2, (isStableEnabled ? 1 : 32767));
  11.146 +        }
  11.147 +    }
  11.148 +
  11.149 +    /* ==================================================== */
  11.150 +
  11.151 +    static class StaticShortStable {
  11.152 +        public static @Stable short v;
  11.153 +
  11.154 +        public static final StaticShortStable c = new StaticShortStable();
  11.155 +        public static short get() { return c.v; }
  11.156 +        public static void test() throws Exception {
  11.157 +            c.v = 1;     short val1 = get();
  11.158 +            c.v = 32767; short val2 = get();
  11.159 +            assertEquals(val1, 1);
  11.160 +            assertEquals(val2, (isStableEnabled ? 1 : 32767));
  11.161 +        }
  11.162 +    }
  11.163 +
  11.164 +    /* ==================================================== */
  11.165 +
  11.166 +    static class VolatileShortStable {
  11.167 +        public @Stable volatile short v;
  11.168 +
  11.169 +        public static final VolatileShortStable c = new VolatileShortStable();
  11.170 +        public static short get() { return c.v; }
  11.171 +        public static void test() throws Exception {
  11.172 +            c.v = 1;     short val1 = get();
  11.173 +            c.v = 32767; short val2 = get();
  11.174 +            assertEquals(val1, 1);
  11.175 +            assertEquals(val2, (isStableEnabled ? 1 : 32767));
  11.176 +        }
  11.177 +    }
  11.178 +
  11.179 +    /* ==================================================== */
  11.180 +    // @Stable array == field && all components are stable
  11.181 +
  11.182 +    static class ShortArrayDim1 {
  11.183 +        public @Stable short[] v;
  11.184 +
  11.185 +        public static final ShortArrayDim1 c = new ShortArrayDim1();
  11.186 +        public static short get() { return c.v[0]; }
  11.187 +        public static short get1() { return c.v[10]; }
  11.188 +        public static short[] get2() { return c.v; }
  11.189 +        public static void test() throws Exception {
  11.190 +            {
  11.191 +                c.v = new short[1]; c.v[0] = 1; short val1 = get();
  11.192 +                                    c.v[0] = 2; short val2 = get();
  11.193 +                assertEquals(val1, 1);
  11.194 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
  11.195 +
  11.196 +                c.v = new short[1]; c.v[0] = 3; short val3 = get();
  11.197 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
  11.198 +            }
  11.199 +
  11.200 +            {
  11.201 +                c.v = new short[20]; c.v[10] = 1; short val1 = get1();
  11.202 +                                     c.v[10] = 2; short val2 = get1();
  11.203 +                assertEquals(val1, 1);
  11.204 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
  11.205 +
  11.206 +                c.v = new short[20]; c.v[10] = 3; short val3 = get1();
  11.207 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
  11.208 +            }
  11.209 +
  11.210 +            {
  11.211 +                c.v = new short[1]; short[] val1 = get2();
  11.212 +                c.v = new short[1]; short[] val2 = get2();
  11.213 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.214 +            }
  11.215 +        }
  11.216 +    }
  11.217 +
  11.218 +    /* ==================================================== */
  11.219 +
  11.220 +    static class ShortArrayDim2 {
  11.221 +        public @Stable short[][] v;
  11.222 +
  11.223 +        public static final ShortArrayDim2 c = new ShortArrayDim2();
  11.224 +        public static short get() { return c.v[0][0]; }
  11.225 +        public static short[] get1() { return c.v[0]; }
  11.226 +        public static short[][] get2() { return c.v; }
  11.227 +        public static void test() throws Exception {
  11.228 +            {
  11.229 +                c.v = new short[1][1]; c.v[0][0] = 1; short val1 = get();
  11.230 +                                       c.v[0][0] = 2; short val2 = get();
  11.231 +                assertEquals(val1, 1);
  11.232 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
  11.233 +
  11.234 +                c.v = new short[1][1]; c.v[0][0] = 3; short val3 = get();
  11.235 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
  11.236 +
  11.237 +                c.v[0] = new short[1]; c.v[0][0] = 4; short val4 = get();
  11.238 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
  11.239 +            }
  11.240 +
  11.241 +            {
  11.242 +                c.v = new short[1][1]; short[] val1 = get1();
  11.243 +                c.v[0] = new short[1]; short[] val2 = get1();
  11.244 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.245 +            }
  11.246 +
  11.247 +            {
  11.248 +                c.v = new short[1][1]; short[][] val1 = get2();
  11.249 +                c.v = new short[1][1]; short[][] val2 = get2();
  11.250 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.251 +            }
  11.252 +        }
  11.253 +    }
  11.254 +
  11.255 +    /* ==================================================== */
  11.256 +
  11.257 +    static class ShortArrayDim3 {
  11.258 +        public @Stable short[][][] v;
  11.259 +
  11.260 +        public static final ShortArrayDim3 c = new ShortArrayDim3();
  11.261 +        public static short get() { return c.v[0][0][0]; }
  11.262 +        public static short[] get1() { return c.v[0][0]; }
  11.263 +        public static short[][] get2() { return c.v[0]; }
  11.264 +        public static short[][][] get3() { return c.v; }
  11.265 +        public static void test() throws Exception {
  11.266 +            {
  11.267 +                c.v = new short[1][1][1]; c.v[0][0][0] = 1; short val1 = get();
  11.268 +                                          c.v[0][0][0] = 2; short val2 = get();
  11.269 +                assertEquals(val1, 1);
  11.270 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
  11.271 +
  11.272 +                c.v = new short[1][1][1]; c.v[0][0][0] = 3; short val3 = get();
  11.273 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
  11.274 +
  11.275 +                c.v[0] = new short[1][1]; c.v[0][0][0] = 4; short val4 = get();
  11.276 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
  11.277 +
  11.278 +                c.v[0][0] = new short[1]; c.v[0][0][0] = 5; short val5 = get();
  11.279 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
  11.280 +            }
  11.281 +
  11.282 +            {
  11.283 +                c.v = new short[1][1][1]; short[] val1 = get1();
  11.284 +                c.v[0][0] = new short[1]; short[] val2 = get1();
  11.285 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.286 +            }
  11.287 +
  11.288 +            {
  11.289 +                c.v = new short[1][1][1]; short[][] val1 = get2();
  11.290 +                c.v[0] = new short[1][1]; short[][] val2 = get2();
  11.291 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.292 +            }
  11.293 +
  11.294 +            {
  11.295 +                c.v = new short[1][1][1]; short[][][] val1 = get3();
  11.296 +                c.v = new short[1][1][1]; short[][][] val2 = get3();
  11.297 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.298 +            }
  11.299 +        }
  11.300 +    }
  11.301 +
  11.302 +    /* ==================================================== */
  11.303 +
  11.304 +    static class ShortArrayDim4 {
  11.305 +        public @Stable short[][][][] v;
  11.306 +
  11.307 +        public static final ShortArrayDim4 c = new ShortArrayDim4();
  11.308 +        public static short get() { return c.v[0][0][0][0]; }
  11.309 +        public static short[] get1() { return c.v[0][0][0]; }
  11.310 +        public static short[][] get2() { return c.v[0][0]; }
  11.311 +        public static short[][][] get3() { return c.v[0]; }
  11.312 +        public static short[][][][] get4() { return c.v; }
  11.313 +        public static void test() throws Exception {
  11.314 +            {
  11.315 +                c.v = new short[1][1][1][1]; c.v[0][0][0][0] = 1; short val1 = get();
  11.316 +                                             c.v[0][0][0][0] = 2; short val2 = get();
  11.317 +                assertEquals(val1, 1);
  11.318 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
  11.319 +
  11.320 +                c.v = new short[1][1][1][1]; c.v[0][0][0][0] = 3; short val3 = get();
  11.321 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
  11.322 +
  11.323 +                c.v[0] = new short[1][1][1]; c.v[0][0][0][0] = 4; short val4 = get();
  11.324 +                assertEquals(val4, (isStableEnabled ? 1 : 4));
  11.325 +
  11.326 +                c.v[0][0] = new short[1][1]; c.v[0][0][0][0] = 5; short val5 = get();
  11.327 +                assertEquals(val5, (isStableEnabled ? 1 : 5));
  11.328 +
  11.329 +                c.v[0][0][0] = new short[1]; c.v[0][0][0][0] = 6; short val6 = get();
  11.330 +                assertEquals(val6, (isStableEnabled ? 1 : 6));
  11.331 +            }
  11.332 +
  11.333 +            {
  11.334 +                c.v = new short[1][1][1][1]; short[] val1 = get1();
  11.335 +                c.v[0][0][0] = new short[1]; short[] val2 = get1();
  11.336 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.337 +            }
  11.338 +
  11.339 +            {
  11.340 +                c.v = new short[1][1][1][1]; short[][] val1 = get2();
  11.341 +                c.v[0][0] = new short[1][1]; short[][] val2 = get2();
  11.342 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.343 +            }
  11.344 +
  11.345 +            {
  11.346 +                c.v = new short[1][1][1][1]; short[][][] val1 = get3();
  11.347 +                c.v[0] = new short[1][1][1]; short[][][] val2 = get3();
  11.348 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.349 +            }
  11.350 +
  11.351 +            {
  11.352 +                c.v = new short[1][1][1][1]; short[][][][] val1 = get4();
  11.353 +                c.v = new short[1][1][1][1]; short[][][][] val2 = get4();
  11.354 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.355 +            }
  11.356 +
  11.357 +        }
  11.358 +    }
  11.359 +
  11.360 +    /* ==================================================== */
  11.361 +    // Dynamic Dim is higher than static
  11.362 +
  11.363 +    static class ObjectArrayLowerDim0 {
  11.364 +        public @Stable Object v;
  11.365 +
  11.366 +        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
  11.367 +        public static short get() { return ((short[])c.v)[0]; }
  11.368 +        public static short[] get1() { return (short[])c.v; }
  11.369 +
  11.370 +        public static void test() throws Exception {
  11.371 +            {
  11.372 +                c.v = new short[1]; ((short[])c.v)[0] = 1; short val1 = get();
  11.373 +                                    ((short[])c.v)[0] = 2; short val2 = get();
  11.374 +
  11.375 +                assertEquals(val1, 1);
  11.376 +                assertEquals(val2, 2);
  11.377 +            }
  11.378 +
  11.379 +            {
  11.380 +                c.v = new short[1]; short[] val1 = get1();
  11.381 +                c.v = new short[1]; short[] val2 = get1();
  11.382 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.383 +            }
  11.384 +        }
  11.385 +    }
  11.386 +
  11.387 +    /* ==================================================== */
  11.388 +
  11.389 +    static class ObjectArrayLowerDim1 {
  11.390 +        public @Stable Object[] v;
  11.391 +
  11.392 +        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
  11.393 +        public static short get() { return ((short[][])c.v)[0][0]; }
  11.394 +        public static short[] get1() { return (short[])(c.v[0]); }
  11.395 +        public static Object[] get2() { return c.v; }
  11.396 +
  11.397 +        public static void test() throws Exception {
  11.398 +            {
  11.399 +                c.v = new short[1][1]; ((short[][])c.v)[0][0] = 1; short val1 = get();
  11.400 +                                       ((short[][])c.v)[0][0] = 2; short val2 = get();
  11.401 +
  11.402 +                assertEquals(val1, 1);
  11.403 +                assertEquals(val2, 2);
  11.404 +            }
  11.405 +
  11.406 +            {
  11.407 +                c.v = new short[1][1]; c.v[0] = new short[0]; short[] val1 = get1();
  11.408 +                                       c.v[0] = new short[0]; short[] val2 = get1();
  11.409 +
  11.410 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.411 +            }
  11.412 +
  11.413 +            {
  11.414 +                c.v = new short[0][0]; Object[] val1 = get2();
  11.415 +                c.v = new short[0][0]; Object[] val2 = get2();
  11.416 +
  11.417 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.418 +            }
  11.419 +        }
  11.420 +    }
  11.421 +
  11.422 +    /* ==================================================== */
  11.423 +
  11.424 +    static class ObjectArrayLowerDim2 {
  11.425 +        public @Stable Object[][] v;
  11.426 +
  11.427 +        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
  11.428 +        public static short get() { return ((short[][][])c.v)[0][0][0]; }
  11.429 +        public static short[] get1() { return (short[])(c.v[0][0]); }
  11.430 +        public static short[][] get2() { return (short[][])(c.v[0]); }
  11.431 +        public static Object[][] get3() { return c.v; }
  11.432 +
  11.433 +        public static void test() throws Exception {
  11.434 +            {
  11.435 +                c.v = new short[1][1][1]; ((short[][][])c.v)[0][0][0] = 1; short val1 = get();
  11.436 +                                          ((short[][][])c.v)[0][0][0] = 2; short val2 = get();
  11.437 +
  11.438 +                assertEquals(val1, 1);
  11.439 +                assertEquals(val2, 2);
  11.440 +            }
  11.441 +
  11.442 +            {
  11.443 +                c.v = new short[1][1][1]; c.v[0][0] = new short[0]; short[] val1 = get1();
  11.444 +                                          c.v[0][0] = new short[0]; short[] val2 = get1();
  11.445 +
  11.446 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.447 +            }
  11.448 +
  11.449 +            {
  11.450 +                c.v = new short[1][1][1]; c.v[0] = new short[0][0]; short[][] val1 = get2();
  11.451 +                                          c.v[0] = new short[0][0]; short[][] val2 = get2();
  11.452 +
  11.453 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.454 +            }
  11.455 +
  11.456 +            {
  11.457 +                c.v = new short[0][0][0]; Object[][] val1 = get3();
  11.458 +                c.v = new short[0][0][0]; Object[][] val2 = get3();
  11.459 +
  11.460 +                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
  11.461 +            }
  11.462 +        }
  11.463 +    }
  11.464 +
  11.465 +    /* ==================================================== */
  11.466 +
  11.467 +    static class NestedStableField {
  11.468 +        static class A {
  11.469 +            public @Stable short a;
  11.470 +
  11.471 +        }
  11.472 +        public @Stable A v;
  11.473 +
  11.474 +        public static final NestedStableField c = new NestedStableField();
  11.475 +        public static A get() { return c.v; }
  11.476 +        public static short get1() { return get().a; }
  11.477 +
  11.478 +        public static void test() throws Exception {
  11.479 +            {
  11.480 +                c.v = new A(); c.v.a = 1; A val1 = get();
  11.481 +                               c.v.a = 2; A val2 = get();
  11.482 +
  11.483 +                assertEquals(val1.a, 2);
  11.484 +                assertEquals(val2.a, 2);
  11.485 +            }
  11.486 +
  11.487 +            {
  11.488 +                c.v = new A(); c.v.a = 1; short val1 = get1();
  11.489 +                               c.v.a = 2; short val2 = get1();
  11.490 +                c.v = new A(); c.v.a = 3; short val3 = get1();
  11.491 +
  11.492 +                assertEquals(val1, 1);
  11.493 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
  11.494 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
  11.495 +            }
  11.496 +        }
  11.497 +    }
  11.498 +
  11.499 +    /* ==================================================== */
  11.500 +
  11.501 +    static class NestedStableField1 {
  11.502 +        static class A {
  11.503 +            public @Stable short a;
  11.504 +            public @Stable A next;
  11.505 +        }
  11.506 +        public @Stable A v;
  11.507 +
  11.508 +        public static final NestedStableField1 c = new NestedStableField1();
  11.509 +        public static A get() { return c.v.next.next.next.next.next.next.next; }
  11.510 +        public static short get1() { return get().a; }
  11.511 +
  11.512 +        public static void test() throws Exception {
  11.513 +            {
  11.514 +                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
  11.515 +                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
  11.516 +                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
  11.517 +
  11.518 +                assertEquals(val1.a, 2);
  11.519 +                assertEquals(val2.a, 2);
  11.520 +            }
  11.521 +
  11.522 +            {
  11.523 +                c.v = new A(); c.v.next = c.v;
  11.524 +                               c.v.a = 1; short val1 = get1();
  11.525 +                               c.v.a = 2; short val2 = get1();
  11.526 +                c.v = new A(); c.v.next = c.v;
  11.527 +                               c.v.a = 3; short val3 = get1();
  11.528 +
  11.529 +                assertEquals(val1, 1);
  11.530 +                assertEquals(val2, (isStableEnabled ? 1 : 2));
  11.531 +                assertEquals(val3, (isStableEnabled ? 1 : 3));
  11.532 +            }
  11.533 +        }
  11.534 +    }
  11.535 +   /* ==================================================== */
  11.536 +
  11.537 +    static class NestedStableField2 {
  11.538 +        static class A {
  11.539 +            public @Stable short a;
  11.540 +            public @Stable A left;
  11.541 +            public         A right;
  11.542 +        }
  11.543 +
  11.544 +        public @Stable A v;
  11.545 +
  11.546 +        public static final NestedStableField2 c = new NestedStableField2();
  11.547 +        public static short get() { return c.v.left.left.left.a; }
  11.548 +        public static short get1() { return c.v.left.left.right.left.a; }
  11.549 +
  11.550 +        public static void test() throws Exception {
  11.551 +            {
  11.552 +                c.v = new A(); c.v.left = c.v.right = c.v;
  11.553 +                               c.v.a = 1; short val1 = get(); short val2 = get1();
  11.554 +                               c.v.a = 2; short val3 = get(); short val4 = get1();
  11.555 +
  11.556 +                assertEquals(val1, 1);
  11.557 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
  11.558 +
  11.559 +                assertEquals(val2, 1);
  11.560 +                assertEquals(val4, 2);
  11.561 +            }
  11.562 +        }
  11.563 +    }
  11.564 +
  11.565 +    /* ==================================================== */
  11.566 +
  11.567 +    static class NestedStableField3 {
  11.568 +        static class A {
  11.569 +            public @Stable short a;
  11.570 +            public @Stable A[] left;
  11.571 +            public         A[] right;
  11.572 +        }
  11.573 +
  11.574 +        public @Stable A[] v;
  11.575 +
  11.576 +        public static final NestedStableField3 c = new NestedStableField3();
  11.577 +        public static short get() { return c.v[0].left[1].left[0].left[1].a; }
  11.578 +        public static short get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
  11.579 +
  11.580 +        public static void test() throws Exception {
  11.581 +            {
  11.582 +                A elem = new A();
  11.583 +                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
  11.584 +                               elem.a = 1; short val1 = get(); short val2 = get1();
  11.585 +                               elem.a = 2; short val3 = get(); short val4 = get1();
  11.586 +
  11.587 +                assertEquals(val1, 1);
  11.588 +                assertEquals(val3, (isStableEnabled ? 1 : 2));
  11.589 +
  11.590 +                assertEquals(val2, 1);
  11.591 +                assertEquals(val4, 2);
  11.592 +            }
  11.593 +        }
  11.594 +    }
  11.595 +
  11.596 +    /* ==================================================== */
  11.597 +    // Auxiliary methods
  11.598 +    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
  11.599 +    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
  11.600 +
  11.601 +    static boolean failed = false;
  11.602 +
  11.603 +    public static void run(Class<?> test) {
  11.604 +        Throwable ex = null;
  11.605 +        System.out.print(test.getName()+": ");
  11.606 +        try {
  11.607 +            test.getMethod("test").invoke(null);
  11.608 +        } catch (InvocationTargetException e) {
  11.609 +            ex = e.getCause();
  11.610 +        } catch (Throwable e) {
  11.611 +            ex = e;
  11.612 +        } finally {
  11.613 +            if (ex == null) {
  11.614 +                System.out.println("PASSED");
  11.615 +            } else {
  11.616 +                failed = true;
  11.617 +                System.out.println("FAILED");
  11.618 +                ex.printStackTrace(System.out);
  11.619 +            }
  11.620 +        }
  11.621 +    }
  11.622 +
  11.623 +    static final boolean isStableEnabled;
  11.624 +    static {
  11.625 +        HotSpotDiagnosticMXBean diagnostic
  11.626 +                = ManagementFactoryHelper.getDiagnosticMXBean();
  11.627 +        VMOption tmp;
  11.628 +        try {
  11.629 +            tmp = diagnostic.getVMOption("FoldStableValues");
  11.630 +        } catch (IllegalArgumentException e) {
  11.631 +            tmp = null;
  11.632 +        }
  11.633 +        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
  11.634 +    }
  11.635 +}

mercurial