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