Wed, 27 Aug 2014 08:19:12 -0400
8046598: Scalable Native memory tracking development
Summary: Enhance scalability of native memory tracking
Reviewed-by: coleenp, ctornqvi, gtriantafill
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 */
26 /*
27 * @test TestStableObject
28 * @summary tests on stable fields and arrays
29 * @library /testlibrary /testlibrary/whitebox
30 * @build TestStableObject StableConfiguration sun.hotspot.WhiteBox
31 * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
32 * @run main ClassFileInstaller
33 * java/lang/invoke/StableConfiguration
34 * java/lang/invoke/TestStableObject
35 * java/lang/invoke/TestStableObject$ObjectStable
36 * java/lang/invoke/TestStableObject$StaticObjectStable
37 * java/lang/invoke/TestStableObject$VolatileObjectStable
38 * java/lang/invoke/TestStableObject$ObjectArrayDim1
39 * java/lang/invoke/TestStableObject$ObjectArrayDim2
40 * java/lang/invoke/TestStableObject$ObjectArrayDim3
41 * java/lang/invoke/TestStableObject$ObjectArrayDim4
42 * java/lang/invoke/TestStableObject$ObjectArrayLowerDim0
43 * java/lang/invoke/TestStableObject$ObjectArrayLowerDim1
44 * java/lang/invoke/TestStableObject$NestedStableField
45 * java/lang/invoke/TestStableObject$NestedStableField$A
46 * java/lang/invoke/TestStableObject$NestedStableField1
47 * java/lang/invoke/TestStableObject$NestedStableField1$A
48 * java/lang/invoke/TestStableObject$NestedStableField2
49 * java/lang/invoke/TestStableObject$NestedStableField2$A
50 * java/lang/invoke/TestStableObject$NestedStableField3
51 * java/lang/invoke/TestStableObject$NestedStableField3$A
52 * java/lang/invoke/TestStableObject$Values
53 * java/lang/invoke/TestStableObject$DefaultValue
54 * java/lang/invoke/TestStableObject$DefaultStaticValue
55 * java/lang/invoke/TestStableObject$ObjectArrayLowerDim2
56 *
57 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
58 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
59 * -server -XX:-TieredCompilation
60 * -XX:+FoldStableValues
61 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
62 * java.lang.invoke.TestStableObject
63 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
64 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
65 * -server -XX:-TieredCompilation
66 * -XX:-FoldStableValues
67 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
68 * java.lang.invoke.TestStableObject
69 *
70 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
71 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
72 * -server -XX:+TieredCompilation -XX:TieredStopAtLevel=1
73 * -XX:+FoldStableValues
74 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
75 * java.lang.invoke.TestStableObject
76 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
77 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
78 * -server -XX:+TieredCompilation -XX:TieredStopAtLevel=1
79 * -XX:-FoldStableValues
80 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
81 * java.lang.invoke.TestStableObject
82 *
83 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
84 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
85 * -client -XX:-TieredCompilation
86 * -XX:+FoldStableValues
87 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
88 * java.lang.invoke.TestStableObject
89 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
90 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
91 * -client -XX:-TieredCompilation
92 * -XX:-FoldStableValues
93 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
94 * java.lang.invoke.TestStableObject
95 */
96 package java.lang.invoke;
98 import java.lang.reflect.InvocationTargetException;
100 public class TestStableObject {
101 static final boolean isStableEnabled = StableConfiguration.isStableEnabled;
102 static final boolean isServerWithStable = StableConfiguration.isServerWithStable;
104 public static void main(String[] args) throws Exception {
105 run(DefaultValue.class);
106 run(ObjectStable.class);
107 run(DefaultStaticValue.class);
108 run(StaticObjectStable.class);
109 run(VolatileObjectStable.class);
111 // @Stable arrays: Dim 1-4
112 run(ObjectArrayDim1.class);
113 run(ObjectArrayDim2.class);
114 run(ObjectArrayDim3.class);
115 run(ObjectArrayDim4.class);
117 // @Stable Object field: dynamic arrays
118 run(ObjectArrayLowerDim0.class);
119 run(ObjectArrayLowerDim1.class);
120 run(ObjectArrayLowerDim2.class);
122 // Nested @Stable fields
123 run(NestedStableField.class);
124 run(NestedStableField1.class);
125 run(NestedStableField2.class);
126 run(NestedStableField3.class);
128 if (failed) {
129 throw new Error("TEST FAILED");
130 }
131 }
133 /* ==================================================== */
135 enum Values {A, B, C, D, E, F}
137 static class DefaultValue {
138 public @Stable Object v;
140 public static final DefaultValue c = new DefaultValue();
141 public static Object get() { return c.v; }
142 public static void test() throws Exception {
143 Object val1 = get();
144 c.v = Values.A; Object val2 = get();
145 assertEquals(val1, null);
146 assertEquals(val2, Values.A);
147 }
148 }
150 /* ==================================================== */
152 static class ObjectStable {
153 public @Stable Values v;
155 public static final ObjectStable c = new ObjectStable ();
156 public static Values get() { return c.v; }
157 public static void test() throws Exception {
158 c.v = Values.A; Values val1 = get();
159 c.v = Values.B; Values val2 = get();
160 assertEquals(val1, Values.A);
161 assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
162 }
163 }
165 /* ==================================================== */
167 static class DefaultStaticValue {
168 public static @Stable Object v;
170 public static final DefaultStaticValue c = new DefaultStaticValue();
171 public static Object get() { return c.v; }
172 public static void test() throws Exception {
173 Object val1 = get();
174 c.v = Values.A; Object val2 = get();
175 assertEquals(val1, null);
176 assertEquals(val2, Values.A);
177 }
178 }
180 /* ==================================================== */
182 static class StaticObjectStable {
183 public static @Stable Values v;
185 public static final ObjectStable c = new ObjectStable ();
186 public static Values get() { return c.v; }
187 public static void test() throws Exception {
188 c.v = Values.A; Values val1 = get();
189 c.v = Values.B; Values val2 = get();
190 assertEquals(val1, Values.A);
191 assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
192 }
193 }
195 /* ==================================================== */
197 static class VolatileObjectStable {
198 public @Stable volatile Values v;
200 public static final VolatileObjectStable c = new VolatileObjectStable ();
201 public static Values get() { return c.v; }
202 public static void test() throws Exception {
203 c.v = Values.A; Values val1 = get();
204 c.v = Values.B; Values val2 = get();
205 assertEquals(val1, Values.A);
206 assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
207 }
208 }
210 /* ==================================================== */
211 // @Stable array == field && all components are stable
213 static class ObjectArrayDim1 {
214 public @Stable Object[] v;
216 public static final ObjectArrayDim1 c = new ObjectArrayDim1();
217 public static Object get() { return c.v[0]; }
218 public static Object get1() { return c.v[10]; }
219 public static Object[] get2() { return c.v; }
220 public static void test() throws Exception {
221 {
222 c.v = new Object[1]; c.v[0] = Values.A; Object val1 = get();
223 c.v[0] = Values.B; Object val2 = get();
224 assertEquals(val1, Values.A);
225 assertEquals(val2, (isServerWithStable ? Values.A : Values.B));
227 c.v = new Object[1]; c.v[0] = Values.C; Object val3 = get();
228 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
229 : Values.C));
230 }
232 {
233 c.v = new Object[20]; c.v[10] = Values.A; Object val1 = get1();
234 c.v[10] = Values.B; Object val2 = get1();
235 assertEquals(val1, Values.A);
236 assertEquals(val2, (isServerWithStable ? Values.A : Values.B));
238 c.v = new Object[20]; c.v[10] = Values.C; Object val3 = get1();
239 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
240 : Values.C));
241 }
243 {
244 c.v = new Object[1]; Object[] val1 = get2();
245 c.v = new Object[1]; Object[] val2 = get2();
246 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
247 }
248 }
249 }
251 /* ==================================================== */
253 static class ObjectArrayDim2 {
254 public @Stable Object[][] v;
256 public static final ObjectArrayDim2 c = new ObjectArrayDim2();
257 public static Object get() { return c.v[0][0]; }
258 public static Object[] get1() { return c.v[0]; }
259 public static Object[][] get2() { return c.v; }
260 public static void test() throws Exception {
261 {
262 c.v = new Object[1][1]; c.v[0][0] = Values.A; Object val1 = get();
263 c.v[0][0] = Values.B; Object val2 = get();
264 assertEquals(val1, Values.A);
265 assertEquals(val2, (isServerWithStable ? Values.A : Values.B));
267 c.v = new Object[1][1]; c.v[0][0] = Values.C; Object val3 = get();
268 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
269 : Values.C));
271 c.v[0] = new Object[1]; c.v[0][0] = Values.D; Object val4 = get();
272 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
273 : Values.D));
274 }
276 {
277 c.v = new Object[1][1]; Object[] val1 = get1();
278 c.v[0] = new Object[1]; Object[] val2 = get1();
279 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
280 }
282 {
283 c.v = new Object[1][1]; Object[][] val1 = get2();
284 c.v = new Object[1][1]; Object[][] val2 = get2();
285 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
286 }
287 }
288 }
290 /* ==================================================== */
292 static class ObjectArrayDim3 {
293 public @Stable Object[][][] v;
295 public static final ObjectArrayDim3 c = new ObjectArrayDim3();
296 public static Object get() { return c.v[0][0][0]; }
297 public static Object[] get1() { return c.v[0][0]; }
298 public static Object[][] get2() { return c.v[0]; }
299 public static Object[][][] get3() { return c.v; }
300 public static void test() throws Exception {
301 {
302 c.v = new Object[1][1][1]; c.v[0][0][0] = Values.A; Object val1 = get();
303 c.v[0][0][0] = Values.B; Object val2 = get();
304 assertEquals(val1, Values.A);
305 assertEquals(val2, (isServerWithStable ? Values.A : Values.B));
307 c.v = new Object[1][1][1]; c.v[0][0][0] = Values.C; Object val3 = get();
308 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
309 : Values.C));
311 c.v[0] = new Object[1][1]; c.v[0][0][0] = Values.D; Object val4 = get();
312 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
313 : Values.D));
315 c.v[0][0] = new Object[1]; c.v[0][0][0] = Values.E; Object val5 = get();
316 assertEquals(val5, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
317 : Values.E));
318 }
320 {
321 c.v = new Object[1][1][1]; Object[] val1 = get1();
322 c.v[0][0] = new Object[1]; Object[] val2 = get1();
323 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
324 }
326 {
327 c.v = new Object[1][1][1]; Object[][] val1 = get2();
328 c.v[0] = new Object[1][1]; Object[][] val2 = get2();
329 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
330 }
332 {
333 c.v = new Object[1][1][1]; Object[][][] val1 = get3();
334 c.v = new Object[1][1][1]; Object[][][] val2 = get3();
335 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
336 }
337 }
338 }
340 /* ==================================================== */
342 static class ObjectArrayDim4 {
343 public @Stable Object[][][][] v;
345 public static final ObjectArrayDim4 c = new ObjectArrayDim4();
346 public static Object get() { return c.v[0][0][0][0]; }
347 public static Object[] get1() { return c.v[0][0][0]; }
348 public static Object[][] get2() { return c.v[0][0]; }
349 public static Object[][][] get3() { return c.v[0]; }
350 public static Object[][][][] get4() { return c.v; }
351 public static void test() throws Exception {
352 {
353 c.v = new Object[1][1][1][1]; c.v[0][0][0][0] = Values.A; Object val1 = get();
354 c.v[0][0][0][0] = Values.B; Object val2 = get();
355 assertEquals(val1, Values.A);
356 assertEquals(val2, (isServerWithStable ? Values.A : Values.B));
358 c.v = new Object[1][1][1][1]; c.v[0][0][0][0] = Values.C; Object val3 = get();
359 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
360 : Values.C));
362 c.v[0] = new Object[1][1][1]; c.v[0][0][0][0] = Values.D; Object val4 = get();
363 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
364 : Values.D));
366 c.v[0][0] = new Object[1][1]; c.v[0][0][0][0] = Values.E; Object val5 = get();
367 assertEquals(val5, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
368 : Values.E));
370 c.v[0][0][0] = new Object[1]; c.v[0][0][0][0] = Values.F; Object val6 = get();
371 assertEquals(val6, (isStableEnabled ? (isServerWithStable ? Values.A : Values.B)
372 : Values.F));
373 }
375 {
376 c.v = new Object[1][1][1][1]; Object[] val1 = get1();
377 c.v[0][0][0] = new Object[1]; Object[] val2 = get1();
378 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
379 }
381 {
382 c.v = new Object[1][1][1][1]; Object[][] val1 = get2();
383 c.v[0][0] = new Object[1][1]; Object[][] val2 = get2();
384 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
385 }
387 {
388 c.v = new Object[1][1][1][1]; Object[][][] val1 = get3();
389 c.v[0] = new Object[1][1][1]; Object[][][] val2 = get3();
390 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
391 }
393 {
394 c.v = new Object[1][1][1][1]; Object[][][][] val1 = get4();
395 c.v = new Object[1][1][1][1]; Object[][][][] val2 = get4();
396 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
397 }
398 }
399 }
401 /* ==================================================== */
402 // Dynamic Dim is higher than static
403 static class ObjectArrayLowerDim0 {
404 public @Stable Object v;
406 public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
407 public static Object get() { return ((Object[])c.v)[0]; }
408 public static Object[] get1() { return (Object[])c.v; }
410 public static void test() throws Exception {
411 {
412 c.v = new Object[1]; ((Object[])c.v)[0] = Values.A; Object val1 = get();
413 ((Object[])c.v)[0] = Values.B; Object val2 = get();
415 assertEquals(val1, Values.A);
416 assertEquals(val2, Values.B);
417 }
419 {
420 c.v = new Object[1]; Object[] val1 = get1();
421 c.v = new Object[1]; Object[] val2 = get1();
422 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
423 }
424 }
425 }
427 /* ==================================================== */
429 static class ObjectArrayLowerDim1 {
430 public @Stable Object[] v;
432 public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
433 public static Object get() { return ((Object[][])c.v)[0][0]; }
434 public static Object[] get1() { return (Object[])(c.v[0]); }
435 public static Object[] get2() { return c.v; }
437 public static void test() throws Exception {
438 {
439 c.v = new Object[1][1]; ((Object[][])c.v)[0][0] = Values.A; Object val1 = get();
440 ((Object[][])c.v)[0][0] = Values.B; Object val2 = get();
442 assertEquals(val1, Values.A);
443 assertEquals(val2, Values.B);
444 }
446 {
447 c.v = new Object[1][1]; c.v[0] = new Object[0]; Object[] val1 = get1();
448 c.v[0] = new Object[0]; Object[] val2 = get1();
450 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
451 }
453 {
454 c.v = new Object[0][0]; Object[] val1 = get2();
455 c.v = new Object[0][0]; Object[] val2 = get2();
457 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
458 }
459 }
460 }
462 /* ==================================================== */
464 static class ObjectArrayLowerDim2 {
465 public @Stable Object[][] v;
467 public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
468 public static Object get() { return ((Object[][][])c.v)[0][0][0]; }
469 public static Object[] get1() { return (Object[])(c.v[0][0]); }
470 public static Object[][] get2() { return (Object[][])(c.v[0]); }
471 public static Object[][] get3() { return c.v; }
473 public static void test() throws Exception {
474 {
475 c.v = new Object[1][1][1]; ((Object[][][])c.v)[0][0][0] = Values.A; Object val1 = get();
476 ((Object[][][])c.v)[0][0][0] = Values.B; Object val2 = get();
478 assertEquals(val1, Values.A);
479 assertEquals(val2, Values.B);
480 }
482 {
483 c.v = new Object[1][1][1]; c.v[0][0] = new Object[0]; Object[] val1 = get1();
484 c.v[0][0] = new Object[0]; Object[] val2 = get1();
486 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
487 }
489 {
490 c.v = new Object[1][1][1]; c.v[0] = new Object[0][0]; Object[][] val1 = get2();
491 c.v[0] = new Object[0][0]; Object[][] val2 = get2();
493 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
494 }
496 {
497 c.v = new Object[0][0][0]; Object[][] val1 = get3();
498 c.v = new Object[0][0][0]; Object[][] val2 = get3();
500 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
501 }
502 }
503 }
505 /* ==================================================== */
507 static class NestedStableField {
508 static class A {
509 public @Stable Object a;
511 }
512 public @Stable A v;
514 public static final NestedStableField c = new NestedStableField();
515 public static A get() { return c.v; }
516 public static Object get1() { return get().a; }
518 public static void test() throws Exception {
519 {
520 c.v = new A(); c.v.a = Values.A; A val1 = get();
521 c.v.a = Values.B; A val2 = get();
523 assertEquals(val1.a, Values.B);
524 assertEquals(val2.a, Values.B);
525 }
527 {
528 c.v = new A(); c.v.a = Values.A; Object val1 = get1();
529 c.v.a = Values.B; Object val2 = get1();
530 c.v = new A(); c.v.a = Values.C; Object val3 = get1();
532 assertEquals(val1, Values.A);
533 assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
534 assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
535 }
536 }
537 }
539 /* ==================================================== */
541 static class NestedStableField1 {
542 static class A {
543 public @Stable Object a;
544 public @Stable A next;
545 }
546 public @Stable A v;
548 public static final NestedStableField1 c = new NestedStableField1();
549 public static A get() { return c.v.next.next.next.next.next.next.next; }
550 public static Object get1() { return get().a; }
552 public static void test() throws Exception {
553 {
554 c.v = new A(); c.v.next = new A(); c.v.next.next = c.v;
555 c.v.a = Values.A; c.v.next.a = Values.A; A val1 = get();
556 c.v.a = Values.B; c.v.next.a = Values.B; A val2 = get();
558 assertEquals(val1.a, Values.B);
559 assertEquals(val2.a, Values.B);
560 }
562 {
563 c.v = new A(); c.v.next = c.v;
564 c.v.a = Values.A; Object val1 = get1();
565 c.v.a = Values.B; Object val2 = get1();
566 c.v = new A(); c.v.next = c.v;
567 c.v.a = Values.C; Object val3 = get1();
569 assertEquals(val1, Values.A);
570 assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
571 assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
572 }
573 }
574 }
575 /* ==================================================== */
577 static class NestedStableField2 {
578 static class A {
579 public @Stable Object a;
580 public @Stable A left;
581 public A right;
582 }
584 public @Stable A v;
586 public static final NestedStableField2 c = new NestedStableField2();
587 public static Object get() { return c.v.left.left.left.a; }
588 public static Object get1() { return c.v.left.left.right.left.a; }
590 public static void test() throws Exception {
591 {
592 c.v = new A(); c.v.left = c.v.right = c.v;
593 c.v.a = Values.A; Object val1 = get(); Object val2 = get1();
594 c.v.a = Values.B; Object val3 = get(); Object val4 = get1();
596 assertEquals(val1, Values.A);
597 assertEquals(val3, (isStableEnabled ? Values.A : Values.B));
599 assertEquals(val2, Values.A);
600 assertEquals(val4, Values.B);
601 }
602 }
603 }
605 /* ==================================================== */
607 static class NestedStableField3 {
608 static class A {
609 public @Stable Object a;
610 public @Stable A[] left;
611 public A[] right;
612 }
614 public @Stable A[] v;
616 public static final NestedStableField3 c = new NestedStableField3();
617 public static Object get() { return c.v[0].left[1].left[0].left[1].a; }
618 public static Object get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
620 public static void test() throws Exception {
621 {
622 A elem = new A();
623 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
624 elem.a = Values.A; Object val1 = get(); Object val2 = get1();
625 elem.a = Values.B; Object val3 = get(); Object val4 = get1();
627 assertEquals(val1, Values.A);
628 assertEquals(val3, (isServerWithStable ? Values.A : Values.B));
630 assertEquals(val2, Values.A);
631 assertEquals(val4, Values.B);
632 }
633 }
634 }
636 /* ==================================================== */
637 // Auxiliary methods
638 static void assertEquals(Object i, Object j) { if (i != j) throw new AssertionError(i + " != " + j); }
639 static void assertTrue(boolean b) { if (!b) throw new AssertionError(); }
641 static boolean failed = false;
643 public static void run(Class<?> test) {
644 Throwable ex = null;
645 System.out.print(test.getName()+": ");
646 try {
647 test.getMethod("test").invoke(null);
648 } catch (InvocationTargetException e) {
649 ex = e.getCause();
650 } catch (Throwable e) {
651 ex = e;
652 } finally {
653 if (ex == null) {
654 System.out.println("PASSED");
655 } else {
656 failed = true;
657 System.out.println("FAILED");
658 ex.printStackTrace(System.out);
659 }
660 }
661 }
662 }