1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/compiler/stable/TestStableChar.java Fri Mar 28 10:13:37 2014 -0700 1.3 @@ -0,0 +1,631 @@ 1.4 +/* 1.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +/* 1.30 + * @test TestStableChar 1.31 + * @summary tests on stable fields and arrays 1.32 + * @library /testlibrary 1.33 + * @compile -XDignore.symbol.file TestStableChar.java 1.34 + * @run main ClassFileInstaller 1.35 + * java/lang/invoke/TestStableChar 1.36 + * java/lang/invoke/TestStableChar$CharStable 1.37 + * java/lang/invoke/TestStableChar$StaticCharStable 1.38 + * java/lang/invoke/TestStableChar$VolatileCharStable 1.39 + * java/lang/invoke/TestStableChar$CharArrayDim1 1.40 + * java/lang/invoke/TestStableChar$CharArrayDim2 1.41 + * java/lang/invoke/TestStableChar$CharArrayDim3 1.42 + * java/lang/invoke/TestStableChar$CharArrayDim4 1.43 + * java/lang/invoke/TestStableChar$ObjectArrayLowerDim0 1.44 + * java/lang/invoke/TestStableChar$ObjectArrayLowerDim1 1.45 + * java/lang/invoke/TestStableChar$NestedStableField 1.46 + * java/lang/invoke/TestStableChar$NestedStableField$A 1.47 + * java/lang/invoke/TestStableChar$NestedStableField1 1.48 + * java/lang/invoke/TestStableChar$NestedStableField1$A 1.49 + * java/lang/invoke/TestStableChar$NestedStableField2 1.50 + * java/lang/invoke/TestStableChar$NestedStableField2$A 1.51 + * java/lang/invoke/TestStableChar$NestedStableField3 1.52 + * java/lang/invoke/TestStableChar$NestedStableField3$A 1.53 + * java/lang/invoke/TestStableChar$DefaultValue 1.54 + * java/lang/invoke/TestStableChar$ObjectArrayLowerDim2 1.55 + * 1.56 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 1.57 + * -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop 1.58 + * -server -XX:-TieredCompilation -Xcomp 1.59 + * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 1.60 + * java.lang.invoke.TestStableChar 1.61 + * 1.62 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 1.63 + * -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop 1.64 + * -server -XX:-TieredCompilation -Xcomp 1.65 + * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 1.66 + * java.lang.invoke.TestStableChar 1.67 + * 1.68 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 1.69 + * -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop 1.70 + * -server -XX:-TieredCompilation -Xcomp 1.71 + * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 1.72 + * java.lang.invoke.TestStableChar 1.73 + * 1.74 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 1.75 + * -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop 1.76 + * -server -XX:-TieredCompilation -Xcomp 1.77 + * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 1.78 + * java.lang.invoke.TestStableChar 1.79 + */ 1.80 +package java.lang.invoke; 1.81 + 1.82 +import com.sun.management.HotSpotDiagnosticMXBean; 1.83 +import com.sun.management.VMOption; 1.84 +import sun.management.ManagementFactoryHelper; 1.85 +import java.lang.reflect.InvocationTargetException; 1.86 + 1.87 +public class TestStableChar { 1.88 + public static void main(String[] args) throws Exception { 1.89 + System.out.println("@Stable enabled: "+isStableEnabled); 1.90 + System.out.println(); 1.91 + 1.92 + run(DefaultValue.class); 1.93 + run(CharStable.class); 1.94 + run(StaticCharStable.class); 1.95 + run(VolatileCharStable.class); 1.96 + 1.97 + // @Stable arrays: Dim 1-4 1.98 + run(CharArrayDim1.class); 1.99 + run(CharArrayDim2.class); 1.100 + run(CharArrayDim3.class); 1.101 + run(CharArrayDim4.class); 1.102 + 1.103 + // @Stable Object field: dynamic arrays 1.104 + run(ObjectArrayLowerDim0.class); 1.105 + run(ObjectArrayLowerDim1.class); 1.106 + run(ObjectArrayLowerDim2.class); 1.107 + 1.108 + // Nested @Stable fields 1.109 + run(NestedStableField.class); 1.110 + run(NestedStableField1.class); 1.111 + run(NestedStableField2.class); 1.112 + run(NestedStableField3.class); 1.113 + 1.114 + if (failed) { 1.115 + throw new Error("TEST FAILED"); 1.116 + } 1.117 + } 1.118 + 1.119 + /* ==================================================== */ 1.120 + 1.121 + static class DefaultValue { 1.122 + public @Stable char v; 1.123 + 1.124 + public static final DefaultValue c = new DefaultValue(); 1.125 + public static char get() { return c.v; } 1.126 + public static void test() throws Exception { 1.127 + char val1 = get(); 1.128 + c.v = 'a'; char val2 = get(); 1.129 + assertEquals(val1, 0); 1.130 + assertEquals(val2, 'a'); 1.131 + } 1.132 + } 1.133 + 1.134 + /* ==================================================== */ 1.135 + 1.136 + static class CharStable { 1.137 + public @Stable char v; 1.138 + 1.139 + public static final CharStable c = new CharStable(); 1.140 + public static char get() { return c.v; } 1.141 + public static void test() throws Exception { 1.142 + c.v = 'a'; char val1 = get(); 1.143 + c.v = 'b'; char val2 = get(); 1.144 + assertEquals(val1, 'a'); 1.145 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.146 + } 1.147 + } 1.148 + 1.149 + /* ==================================================== */ 1.150 + 1.151 + static class StaticCharStable { 1.152 + public @Stable char v; 1.153 + 1.154 + public static final StaticCharStable c = new StaticCharStable(); 1.155 + public static char get() { return c.v; } 1.156 + public static void test() throws Exception { 1.157 + c.v = 'a'; char val1 = get(); 1.158 + c.v = 'b'; char val2 = get(); 1.159 + assertEquals(val1, 'a'); 1.160 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.161 + } 1.162 + } 1.163 + 1.164 + /* ==================================================== */ 1.165 + 1.166 + static class VolatileCharStable { 1.167 + public @Stable volatile char v; 1.168 + 1.169 + public static final VolatileCharStable c = new VolatileCharStable(); 1.170 + public static char get() { return c.v; } 1.171 + public static void test() throws Exception { 1.172 + c.v = 'a'; char val1 = get(); 1.173 + c.v = 'b'; char val2 = get(); 1.174 + assertEquals(val1, 'a'); 1.175 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.176 + } 1.177 + } 1.178 + 1.179 + /* ==================================================== */ 1.180 + // @Stable array == field && all components are stable 1.181 + 1.182 + static class CharArrayDim1 { 1.183 + public @Stable char[] v; 1.184 + 1.185 + public static final CharArrayDim1 c = new CharArrayDim1(); 1.186 + public static char get() { return c.v[0]; } 1.187 + public static char get1() { return c.v[10]; } 1.188 + public static char[] get2() { return c.v; } 1.189 + public static void test() throws Exception { 1.190 + { 1.191 + c.v = new char[1]; c.v[0] = 'a'; char val1 = get(); 1.192 + c.v[0] = 'b'; char val2 = get(); 1.193 + assertEquals(val1, 'a'); 1.194 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.195 + 1.196 + c.v = new char[1]; c.v[0] = 'c'; char val3 = get(); 1.197 + assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 1.198 + } 1.199 + 1.200 + { 1.201 + c.v = new char[20]; c.v[10] = 'a'; char val1 = get1(); 1.202 + c.v[10] = 'b'; char val2 = get1(); 1.203 + assertEquals(val1, 'a'); 1.204 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.205 + 1.206 + c.v = new char[20]; c.v[10] = 'c'; char val3 = get1(); 1.207 + assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 1.208 + } 1.209 + 1.210 + { 1.211 + c.v = new char[1]; char[] val1 = get2(); 1.212 + c.v = new char[1]; char[] val2 = get2(); 1.213 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.214 + } 1.215 + } 1.216 + } 1.217 + 1.218 + /* ==================================================== */ 1.219 + 1.220 + static class CharArrayDim2 { 1.221 + public @Stable char[][] v; 1.222 + 1.223 + public static final CharArrayDim2 c = new CharArrayDim2(); 1.224 + public static char get() { return c.v[0][0]; } 1.225 + public static char[] get1() { return c.v[0]; } 1.226 + public static char[][] get2() { return c.v; } 1.227 + public static void test() throws Exception { 1.228 + { 1.229 + c.v = new char[1][1]; c.v[0][0] = 'a'; char val1 = get(); 1.230 + c.v[0][0] = 'b'; char val2 = get(); 1.231 + assertEquals(val1, 'a'); 1.232 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.233 + 1.234 + c.v = new char[1][1]; c.v[0][0] = 'c'; char val3 = get(); 1.235 + assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 1.236 + 1.237 + c.v[0] = new char[1]; c.v[0][0] = 'd'; char val4 = get(); 1.238 + assertEquals(val4, (isStableEnabled ? 'a' : 'd')); 1.239 + } 1.240 + 1.241 + { 1.242 + c.v = new char[1][1]; char[] val1 = get1(); 1.243 + c.v[0] = new char[1]; char[] val2 = get1(); 1.244 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.245 + } 1.246 + 1.247 + { 1.248 + c.v = new char[1][1]; char[][] val1 = get2(); 1.249 + c.v = new char[1][1]; char[][] val2 = get2(); 1.250 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.251 + } 1.252 + } 1.253 + } 1.254 + 1.255 + /* ==================================================== */ 1.256 + 1.257 + static class CharArrayDim3 { 1.258 + public @Stable char[][][] v; 1.259 + 1.260 + public static final CharArrayDim3 c = new CharArrayDim3(); 1.261 + public static char get() { return c.v[0][0][0]; } 1.262 + public static char[] get1() { return c.v[0][0]; } 1.263 + public static char[][] get2() { return c.v[0]; } 1.264 + public static char[][][] get3() { return c.v; } 1.265 + public static void test() throws Exception { 1.266 + { 1.267 + c.v = new char[1][1][1]; c.v[0][0][0] = 'a'; char val1 = get(); 1.268 + c.v[0][0][0] = 'b'; char val2 = get(); 1.269 + assertEquals(val1, 'a'); 1.270 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.271 + 1.272 + c.v = new char[1][1][1]; c.v[0][0][0] = 'c'; char val3 = get(); 1.273 + assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 1.274 + 1.275 + c.v[0] = new char[1][1]; c.v[0][0][0] = 'd'; char val4 = get(); 1.276 + assertEquals(val4, (isStableEnabled ? 'a' : 'd')); 1.277 + 1.278 + c.v[0][0] = new char[1]; c.v[0][0][0] = 'e'; char val5 = get(); 1.279 + assertEquals(val5, (isStableEnabled ? 'a' : 'e')); 1.280 + } 1.281 + 1.282 + { 1.283 + c.v = new char[1][1][1]; char[] val1 = get1(); 1.284 + c.v[0][0] = new char[1]; char[] val2 = get1(); 1.285 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.286 + } 1.287 + 1.288 + { 1.289 + c.v = new char[1][1][1]; char[][] val1 = get2(); 1.290 + c.v[0] = new char[1][1]; char[][] val2 = get2(); 1.291 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.292 + } 1.293 + 1.294 + { 1.295 + c.v = new char[1][1][1]; char[][][] val1 = get3(); 1.296 + c.v = new char[1][1][1]; char[][][] val2 = get3(); 1.297 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.298 + } 1.299 + } 1.300 + } 1.301 + 1.302 + /* ==================================================== */ 1.303 + 1.304 + static class CharArrayDim4 { 1.305 + public @Stable char[][][][] v; 1.306 + 1.307 + public static final CharArrayDim4 c = new CharArrayDim4(); 1.308 + public static char get() { return c.v[0][0][0][0]; } 1.309 + public static char[] get1() { return c.v[0][0][0]; } 1.310 + public static char[][] get2() { return c.v[0][0]; } 1.311 + public static char[][][] get3() { return c.v[0]; } 1.312 + public static char[][][][] get4() { return c.v; } 1.313 + public static void test() throws Exception { 1.314 + { 1.315 + c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'a'; char val1 = get(); 1.316 + c.v[0][0][0][0] = 'b'; char val2 = get(); 1.317 + assertEquals(val1, 'a'); 1.318 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.319 + 1.320 + c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'c'; char val3 = get(); 1.321 + assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 1.322 + 1.323 + c.v[0] = new char[1][1][1]; c.v[0][0][0][0] = 'd'; char val4 = get(); 1.324 + assertEquals(val4, (isStableEnabled ? 'a' : 'd')); 1.325 + 1.326 + c.v[0][0] = new char[1][1]; c.v[0][0][0][0] = 'e'; char val5 = get(); 1.327 + assertEquals(val5, (isStableEnabled ? 'a' : 'e')); 1.328 + 1.329 + c.v[0][0][0] = new char[1]; c.v[0][0][0][0] = 'f'; char val6 = get(); 1.330 + assertEquals(val6, (isStableEnabled ? 'a' : 'f')); 1.331 + } 1.332 + 1.333 + { 1.334 + c.v = new char[1][1][1][1]; char[] val1 = get1(); 1.335 + c.v[0][0][0] = new char[1]; char[] val2 = get1(); 1.336 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.337 + } 1.338 + 1.339 + { 1.340 + c.v = new char[1][1][1][1]; char[][] val1 = get2(); 1.341 + c.v[0][0] = new char[1][1]; char[][] val2 = get2(); 1.342 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.343 + } 1.344 + 1.345 + { 1.346 + c.v = new char[1][1][1][1]; char[][][] val1 = get3(); 1.347 + c.v[0] = new char[1][1][1]; char[][][] val2 = get3(); 1.348 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.349 + } 1.350 + 1.351 + { 1.352 + c.v = new char[1][1][1][1]; char[][][][] val1 = get4(); 1.353 + c.v = new char[1][1][1][1]; char[][][][] val2 = get4(); 1.354 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.355 + } 1.356 + 1.357 + } 1.358 + } 1.359 + 1.360 + /* ==================================================== */ 1.361 + // Dynamic Dim is higher than static 1.362 + static class ObjectArrayLowerDim0 { 1.363 + public @Stable Object v; 1.364 + 1.365 + public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0(); 1.366 + public static char get() { return ((char[])c.v)[0]; } 1.367 + public static char[] get1() { return (char[])c.v; } 1.368 + 1.369 + public static void test() throws Exception { 1.370 + { 1.371 + c.v = new char[1]; ((char[])c.v)[0] = 'a'; char val1 = get(); 1.372 + ((char[])c.v)[0] = 'b'; char val2 = get(); 1.373 + 1.374 + assertEquals(val1, 'a'); 1.375 + assertEquals(val2, 'b'); 1.376 + } 1.377 + 1.378 + { 1.379 + c.v = new char[1]; char[] val1 = get1(); 1.380 + c.v = new char[1]; char[] val2 = get1(); 1.381 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.382 + } 1.383 + } 1.384 + } 1.385 + 1.386 + /* ==================================================== */ 1.387 + 1.388 + static class ObjectArrayLowerDim1 { 1.389 + public @Stable Object[] v; 1.390 + 1.391 + public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1(); 1.392 + public static char get() { return ((char[][])c.v)[0][0]; } 1.393 + public static char[] get1() { return (char[])(c.v[0]); } 1.394 + public static Object[] get2() { return c.v; } 1.395 + 1.396 + public static void test() throws Exception { 1.397 + { 1.398 + c.v = new char[1][1]; ((char[][])c.v)[0][0] = 'a'; char val1 = get(); 1.399 + ((char[][])c.v)[0][0] = 'b'; char val2 = get(); 1.400 + 1.401 + assertEquals(val1, 'a'); 1.402 + assertEquals(val2, 'b'); 1.403 + } 1.404 + 1.405 + { 1.406 + c.v = new char[1][1]; c.v[0] = new char[0]; char[] val1 = get1(); 1.407 + c.v[0] = new char[0]; char[] val2 = get1(); 1.408 + 1.409 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.410 + } 1.411 + 1.412 + { 1.413 + c.v = new char[0][0]; Object[] val1 = get2(); 1.414 + c.v = new char[0][0]; Object[] val2 = get2(); 1.415 + 1.416 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.417 + } 1.418 + } 1.419 + } 1.420 + 1.421 + /* ==================================================== */ 1.422 + 1.423 + static class ObjectArrayLowerDim2 { 1.424 + public @Stable Object[][] v; 1.425 + 1.426 + public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2(); 1.427 + public static char get() { return ((char[][][])c.v)[0][0][0]; } 1.428 + public static char[] get1() { return (char[])(c.v[0][0]); } 1.429 + public static char[][] get2() { return (char[][])(c.v[0]); } 1.430 + public static Object[][] get3() { return c.v; } 1.431 + 1.432 + public static void test() throws Exception { 1.433 + { 1.434 + c.v = new char[1][1][1]; ((char[][][])c.v)[0][0][0] = 'a'; char val1 = get(); 1.435 + ((char[][][])c.v)[0][0][0] = 'b'; char val2 = get(); 1.436 + 1.437 + assertEquals(val1, 'a'); 1.438 + assertEquals(val2, 'b'); 1.439 + } 1.440 + 1.441 + { 1.442 + c.v = new char[1][1][1]; c.v[0][0] = new char[0]; char[] val1 = get1(); 1.443 + c.v[0][0] = new char[0]; char[] val2 = get1(); 1.444 + 1.445 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.446 + } 1.447 + 1.448 + { 1.449 + c.v = new char[1][1][1]; c.v[0] = new char[0][0]; char[][] val1 = get2(); 1.450 + c.v[0] = new char[0][0]; char[][] val2 = get2(); 1.451 + 1.452 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.453 + } 1.454 + 1.455 + { 1.456 + c.v = new char[0][0][0]; Object[][] val1 = get3(); 1.457 + c.v = new char[0][0][0]; Object[][] val2 = get3(); 1.458 + 1.459 + assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 1.460 + } 1.461 + } 1.462 + } 1.463 + 1.464 + /* ==================================================== */ 1.465 + 1.466 + static class NestedStableField { 1.467 + static class A { 1.468 + public @Stable char a; 1.469 + 1.470 + } 1.471 + public @Stable A v; 1.472 + 1.473 + public static final NestedStableField c = new NestedStableField(); 1.474 + public static A get() { return c.v; } 1.475 + public static char get1() { return get().a; } 1.476 + 1.477 + public static void test() throws Exception { 1.478 + { 1.479 + c.v = new A(); c.v.a = 'a'; A val1 = get(); 1.480 + c.v.a = 'b'; A val2 = get(); 1.481 + 1.482 + assertEquals(val1.a, 'b'); 1.483 + assertEquals(val2.a, 'b'); 1.484 + } 1.485 + 1.486 + { 1.487 + c.v = new A(); c.v.a = 'a'; char val1 = get1(); 1.488 + c.v.a = 'b'; char val2 = get1(); 1.489 + c.v = new A(); c.v.a = 'c'; char val3 = get1(); 1.490 + 1.491 + assertEquals(val1, 'a'); 1.492 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.493 + assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 1.494 + } 1.495 + } 1.496 + } 1.497 + 1.498 + /* ==================================================== */ 1.499 + 1.500 + static class NestedStableField1 { 1.501 + static class A { 1.502 + public @Stable char a; 1.503 + public @Stable A next; 1.504 + } 1.505 + public @Stable A v; 1.506 + 1.507 + public static final NestedStableField1 c = new NestedStableField1(); 1.508 + public static A get() { return c.v.next.next.next.next.next.next.next; } 1.509 + public static char get1() { return get().a; } 1.510 + 1.511 + public static void test() throws Exception { 1.512 + { 1.513 + c.v = new A(); c.v.next = new A(); c.v.next.next = c.v; 1.514 + c.v.a = 'a'; c.v.next.a = 'a'; A val1 = get(); 1.515 + c.v.a = 'b'; c.v.next.a = 'b'; A val2 = get(); 1.516 + 1.517 + assertEquals(val1.a, 'b'); 1.518 + assertEquals(val2.a, 'b'); 1.519 + } 1.520 + 1.521 + { 1.522 + c.v = new A(); c.v.next = c.v; 1.523 + c.v.a = 'a'; char val1 = get1(); 1.524 + c.v.a = 'b'; char val2 = get1(); 1.525 + c.v = new A(); c.v.next = c.v; 1.526 + c.v.a = 'c'; char val3 = get1(); 1.527 + 1.528 + assertEquals(val1, 'a'); 1.529 + assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 1.530 + assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 1.531 + } 1.532 + } 1.533 + } 1.534 + /* ==================================================== */ 1.535 + 1.536 + static class NestedStableField2 { 1.537 + static class A { 1.538 + public @Stable char a; 1.539 + public @Stable A left; 1.540 + public A right; 1.541 + } 1.542 + 1.543 + public @Stable A v; 1.544 + 1.545 + public static final NestedStableField2 c = new NestedStableField2(); 1.546 + public static char get() { return c.v.left.left.left.a; } 1.547 + public static char get1() { return c.v.left.left.right.left.a; } 1.548 + 1.549 + public static void test() throws Exception { 1.550 + { 1.551 + c.v = new A(); c.v.left = c.v.right = c.v; 1.552 + c.v.a = 'a'; char val1 = get(); char val2 = get1(); 1.553 + c.v.a = 'b'; char val3 = get(); char val4 = get1(); 1.554 + 1.555 + assertEquals(val1, 'a'); 1.556 + assertEquals(val3, (isStableEnabled ? 'a' : 'b')); 1.557 + 1.558 + assertEquals(val2, 'a'); 1.559 + assertEquals(val4, 'b'); 1.560 + } 1.561 + } 1.562 + } 1.563 + 1.564 + /* ==================================================== */ 1.565 + 1.566 + static class NestedStableField3 { 1.567 + static class A { 1.568 + public @Stable char a; 1.569 + public @Stable A[] left; 1.570 + public A[] right; 1.571 + } 1.572 + 1.573 + public @Stable A[] v; 1.574 + 1.575 + public static final NestedStableField3 c = new NestedStableField3(); 1.576 + public static char get() { return c.v[0].left[1].left[0].left[1].a; } 1.577 + public static char get1() { return c.v[1].left[0].left[1].right[0].left[1].a; } 1.578 + 1.579 + public static void test() throws Exception { 1.580 + { 1.581 + A elem = new A(); 1.582 + c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v; 1.583 + elem.a = 'a'; char val1 = get(); char val2 = get1(); 1.584 + elem.a = 'b'; char val3 = get(); char val4 = get1(); 1.585 + 1.586 + assertEquals(val1, 'a'); 1.587 + assertEquals(val3, (isStableEnabled ? 'a' : 'b')); 1.588 + 1.589 + assertEquals(val2, 'a'); 1.590 + assertEquals(val4, 'b'); 1.591 + } 1.592 + } 1.593 + } 1.594 + 1.595 + /* ==================================================== */ 1.596 + // Auxiliary methods 1.597 + static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } 1.598 + static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } 1.599 + 1.600 + static boolean failed = false; 1.601 + 1.602 + public static void run(Class<?> test) { 1.603 + Throwable ex = null; 1.604 + System.out.print(test.getName()+": "); 1.605 + try { 1.606 + test.getMethod("test").invoke(null); 1.607 + } catch (InvocationTargetException e) { 1.608 + ex = e.getCause(); 1.609 + } catch (Throwable e) { 1.610 + ex = e; 1.611 + } finally { 1.612 + if (ex == null) { 1.613 + System.out.println("PASSED"); 1.614 + } else { 1.615 + failed = true; 1.616 + System.out.println("FAILED"); 1.617 + ex.printStackTrace(System.out); 1.618 + } 1.619 + } 1.620 + } 1.621 + 1.622 + static final boolean isStableEnabled; 1.623 + static { 1.624 + HotSpotDiagnosticMXBean diagnostic 1.625 + = ManagementFactoryHelper.getDiagnosticMXBean(); 1.626 + VMOption tmp; 1.627 + try { 1.628 + tmp = diagnostic.getVMOption("FoldStableValues"); 1.629 + } catch (IllegalArgumentException e) { 1.630 + tmp = null; 1.631 + } 1.632 + isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue())); 1.633 + } 1.634 +}