TestStableLong.java revision 9765:d469127da7b0
1238106Sdes/*
2238106Sdes * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3238106Sdes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4238106Sdes *
5238106Sdes * This code is free software; you can redistribute it and/or modify it
6238106Sdes * under the terms of the GNU General Public License version 2 only, as
7238106Sdes * published by the Free Software Foundation.  Oracle designates this
8238106Sdes * particular file as subject to the "Classpath" exception as provided
9238106Sdes * by Oracle in the LICENSE file that accompanied this code.
10238106Sdes *
11238106Sdes * This code is distributed in the hope that it will be useful, but WITHOUT
12238106Sdes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13238106Sdes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14238106Sdes * version 2 for more details (a copy is included in the LICENSE file that
15238106Sdes * accompanied this code).
16238106Sdes *
17238106Sdes * You should have received a copy of the GNU General Public License version
18238106Sdes * 2 along with this work; if not, write to the Free Software Foundation,
19238106Sdes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20238106Sdes *
21238106Sdes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22238106Sdes * or visit www.oracle.com if you need additional information or have any
23238106Sdes * questions.
24269257Sdes */
25269257Sdes
26269257Sdes/*
27269257Sdes * @test TestStableLong
28269257Sdes * @summary tests on stable fields and arrays
29269257Sdes * @library /testlibrary /test/lib
30269257Sdes * @build TestStableLong StableConfiguration sun.hotspot.WhiteBox
31269257Sdes * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
32269257Sdes * @run main ClassFileInstaller
33269257Sdes *           java/lang/invoke/StableConfiguration
34238106Sdes *           java/lang/invoke/TestStableLong
35238106Sdes *           java/lang/invoke/TestStableLong$LongStable
36238106Sdes *           java/lang/invoke/TestStableLong$StaticLongStable
37238106Sdes *           java/lang/invoke/TestStableLong$VolatileLongStable
38238106Sdes *           java/lang/invoke/TestStableLong$LongArrayDim1
39238106Sdes *           java/lang/invoke/TestStableLong$LongArrayDim2
40238106Sdes *           java/lang/invoke/TestStableLong$LongArrayDim3
41238106Sdes *           java/lang/invoke/TestStableLong$LongArrayDim4
42238106Sdes *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim0
43238106Sdes *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim1
44238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField
45238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField$A
46238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField1
47238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField1$A
48238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField2
49238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField2$A
50238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField3
51238106Sdes *           java/lang/invoke/TestStableLong$NestedStableField3$A
52238106Sdes *           java/lang/invoke/TestStableLong$DefaultValue
53238106Sdes *           java/lang/invoke/TestStableLong$DefaultStaticValue
54285206Sdes *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim2
55238106Sdes *
56238106Sdes * @run main/othervm -Xbootclasspath/a:.
57238106Sdes *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
58238106Sdes *                   -XX:-TieredCompilation
59238106Sdes *                   -XX:+FoldStableValues
60238106Sdes *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
61238106Sdes *                   java.lang.invoke.TestStableLong
62238106Sdes * @run main/othervm -Xbootclasspath/a:.
63238106Sdes *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
64238106Sdes *                   -XX:-TieredCompilation
65238106Sdes *                   -XX:-FoldStableValues
66238106Sdes *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
67238106Sdes *                   java.lang.invoke.TestStableLong
68238106Sdes *
69238106Sdes * @run main/othervm -Xbootclasspath/a:.
70238106Sdes *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
71255580Sdes *                   -XX:+TieredCompilation -XX:TieredStopAtLevel=1
72238106Sdes *                   -XX:+FoldStableValues
73238106Sdes *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
74238106Sdes *                   java.lang.invoke.TestStableLong
75238106Sdes * @run main/othervm -Xbootclasspath/a:.
76238106Sdes *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
77238106Sdes *                   -XX:+TieredCompilation -XX:TieredStopAtLevel=1
78238106Sdes *                   -XX:-FoldStableValues
79238106Sdes *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
80238106Sdes *                   java.lang.invoke.TestStableLong
81238106Sdes *
82238106Sdes */
83238106Sdespackage java.lang.invoke;
84238106Sdes
85238106Sdesimport jdk.internal.vm.annotation.Stable;
86238106Sdes
87238106Sdesimport java.lang.reflect.InvocationTargetException;
88238106Sdes
89238106Sdespublic class TestStableLong {
90238106Sdes    static final boolean isStableEnabled    = StableConfiguration.isStableEnabled;
91238106Sdes    static final boolean isServerWithStable = StableConfiguration.isServerWithStable;
92238106Sdes
93238106Sdes    public static void main(String[] args) throws Exception {
94238106Sdes        run(DefaultValue.class);
95238106Sdes        run(LongStable.class);
96238106Sdes        run(DefaultStaticValue.class);
97238106Sdes        run(StaticLongStable.class);
98238106Sdes        run(VolatileLongStable.class);
99238106Sdes
100238106Sdes        // @Stable arrays: Dim 1-4
101238106Sdes        run(LongArrayDim1.class);
102238106Sdes        run(LongArrayDim2.class);
103238106Sdes        run(LongArrayDim3.class);
104238106Sdes        run(LongArrayDim4.class);
105238106Sdes
106238106Sdes        // @Stable Object field: dynamic arrays
107269257Sdes        run(ObjectArrayLowerDim0.class);
108238106Sdes        run(ObjectArrayLowerDim1.class);
109238106Sdes        run(ObjectArrayLowerDim2.class);
110238106Sdes
111238106Sdes        // Nested @Stable fields
112238106Sdes        run(NestedStableField.class);
113238106Sdes        run(NestedStableField1.class);
114238106Sdes        run(NestedStableField2.class);
115238106Sdes        run(NestedStableField3.class);
116238106Sdes
117238106Sdes        if (failed) {
118238106Sdes            throw new Error("TEST FAILED");
119238106Sdes        }
120238106Sdes    }
121238106Sdes
122238106Sdes    /* ==================================================== */
123238106Sdes
124238106Sdes    static class DefaultValue {
125238106Sdes        public @Stable long v;
126238106Sdes
127238106Sdes        public static final DefaultValue c = new DefaultValue();
128238106Sdes        public static long get() { return c.v; }
129238106Sdes        public static void test() throws Exception {
130238106Sdes                      long val1 = get();
131238106Sdes            c.v = 1L; long val2 = get();
132238106Sdes            assertEquals(val1, 0);
133238106Sdes            assertEquals(val2, 1L);
134238106Sdes        }
135238106Sdes    }
136238106Sdes
137238106Sdes    /* ==================================================== */
138238106Sdes
139238106Sdes    static class LongStable {
140238106Sdes        public @Stable long v;
141238106Sdes
142238106Sdes        public static final LongStable c = new LongStable();
143238106Sdes        public static long get() { return c.v; }
144238106Sdes        public static void test() throws Exception {
145238106Sdes            c.v = 5;              long val1 = get();
146238106Sdes            c.v = Long.MAX_VALUE; long val2 = get();
147238106Sdes            assertEquals(val1, 5);
148238106Sdes            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
149238106Sdes        }
150238106Sdes    }
151238106Sdes
152238106Sdes    /* ==================================================== */
153238106Sdes
154238106Sdes    static class DefaultStaticValue {
155238106Sdes        public static @Stable long v;
156238106Sdes
157238106Sdes        public static final DefaultStaticValue c = new DefaultStaticValue();
158238106Sdes        public static long get() { return c.v; }
159238106Sdes        public static void test() throws Exception {
160238106Sdes                      long val1 = get();
161238106Sdes            c.v = 1L; long val2 = get();
162238106Sdes            assertEquals(val1, 0);
163238106Sdes            assertEquals(val2, 1L);
164238106Sdes        }
165238106Sdes    }
166238106Sdes
167238106Sdes    /* ==================================================== */
168238106Sdes
169238106Sdes    static class StaticLongStable {
170238106Sdes        public static @Stable long v;
171238106Sdes
172238106Sdes        public static final StaticLongStable c = new StaticLongStable();
173238106Sdes        public static long get() { return c.v; }
174238106Sdes        public static void test() throws Exception {
175238106Sdes            c.v = 5;              long val1 = get();
176238106Sdes            c.v = Long.MAX_VALUE; long val2 = get();
177238106Sdes            assertEquals(val1, 5);
178238106Sdes            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
179238106Sdes        }
180238106Sdes    }
181238106Sdes
182238106Sdes    /* ==================================================== */
183238106Sdes
184238106Sdes    static class VolatileLongStable {
185238106Sdes        public @Stable volatile long v;
186238106Sdes
187238106Sdes        public static final VolatileLongStable c = new VolatileLongStable();
188238106Sdes        public static long get() { return c.v; }
189238106Sdes        public static void test() throws Exception {
190238106Sdes            c.v = 5;              long val1 = get();
191238106Sdes            c.v = Long.MAX_VALUE; long val2 = get();
192238106Sdes            assertEquals(val1, 5);
193238106Sdes            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
194238106Sdes        }
195238106Sdes    }
196238106Sdes
197238106Sdes    /* ==================================================== */
198238106Sdes    // @Stable array == field && all components are stable
199238106Sdes
200238106Sdes    static class LongArrayDim1 {
201238106Sdes        public @Stable long[] v;
202238106Sdes
203238106Sdes        public static final LongArrayDim1 c = new LongArrayDim1();
204238106Sdes        public static long get() { return c.v[0]; }
205238106Sdes        public static long get1() { return c.v[10]; }
206238106Sdes        public static long[] get2() { return c.v; }
207238106Sdes        public static void test() throws Exception {
208238106Sdes            {
209238106Sdes                c.v = new long[1]; c.v[0] = 1; long val1 = get();
210238106Sdes                                   c.v[0] = 2; long val2 = get();
211238106Sdes                assertEquals(val1, 1);
212238106Sdes                assertEquals(val2, (isServerWithStable ? 1 : 2));
213291767Sdes
214238106Sdes                c.v = new long[1]; c.v[0] = 3; long val3 = get();
215238106Sdes                assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2)
216238106Sdes                                                    : 3));
217238106Sdes            }
218238106Sdes
219238106Sdes            {
220238106Sdes                c.v = new long[20]; c.v[10] = 1; long val1 = get1();
221238106Sdes                                    c.v[10] = 2; long val2 = get1();
222238106Sdes                assertEquals(val1, 1);
223238106Sdes                assertEquals(val2, (isServerWithStable ? 1 : 2));
224238106Sdes
225291767Sdes                c.v = new long[20]; c.v[10] = 3; long val3 = get1();
226238106Sdes                assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2)
227238106Sdes                                                    : 3));
228238106Sdes            }
229238106Sdes
230238106Sdes            {
231238106Sdes                c.v = new long[1]; long[] val1 = get2();
232238106Sdes                c.v = new long[1]; long[] val2 = get2();
233238106Sdes                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
234238106Sdes            }
235238106Sdes        }
236238106Sdes    }
237291767Sdes
238238106Sdes    /* ==================================================== */
239238106Sdes
240238106Sdes    static class LongArrayDim2 {
241238106Sdes        public @Stable long[][] v;
242238106Sdes
243238106Sdes        public static final LongArrayDim2 c = new LongArrayDim2();
244238106Sdes        public static long get() { return c.v[0][0]; }
245238106Sdes        public static long[] get1() { return c.v[0]; }
246238106Sdes        public static long[][] get2() { return c.v; }
247238106Sdes        public static void test() throws Exception {
248238106Sdes            {
249291767Sdes                c.v = new long[1][1]; c.v[0][0] = 1; long val1 = get();
250238106Sdes                                      c.v[0][0] = 2; long val2 = get();
251238106Sdes                assertEquals(val1, 1);
252238106Sdes                assertEquals(val2, (isServerWithStable ? 1 : 2));
253238106Sdes
254238106Sdes                c.v = new long[1][1]; c.v[0][0] = 3; long val3 = get();
255238106Sdes                assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2)
256238106Sdes                                                    : 3));
257238106Sdes
258238106Sdes                c.v[0] = new long[1]; c.v[0][0] = 4; long val4 = get();
259238106Sdes                assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 1 : 2)
260238106Sdes                                                    : 4));
261238106Sdes            }
262238106Sdes
263238106Sdes            {
264238106Sdes                c.v = new long[1][1]; long[] val1 = get1();
265238106Sdes                c.v[0] = new long[1]; long[] val2 = get1();
266285206Sdes                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
267238106Sdes            }
268238106Sdes
269238106Sdes            {
270238106Sdes                c.v = new long[1][1]; long[][] val1 = get2();
271238106Sdes                c.v = new long[1][1]; long[][] val2 = get2();
272238106Sdes                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
273238106Sdes            }
274238106Sdes        }
275238106Sdes    }
276238106Sdes
277238106Sdes    /* ==================================================== */
278238106Sdes
279238106Sdes    static class LongArrayDim3 {
280238106Sdes        public @Stable long[][][] v;
281238106Sdes
282238106Sdes        public static final LongArrayDim3 c = new LongArrayDim3();
283238106Sdes        public static long get() { return c.v[0][0][0]; }
284238106Sdes        public static long[] get1() { return c.v[0][0]; }
285238106Sdes        public static long[][] get2() { return c.v[0]; }
286238106Sdes        public static long[][][] get3() { return c.v; }
287285206Sdes        public static void test() throws Exception {
288238106Sdes            {
289238106Sdes                c.v = new long[1][1][1]; c.v[0][0][0] = 1; long val1 = get();
290238106Sdes                                         c.v[0][0][0] = 2; long val2 = get();
291238106Sdes                assertEquals(val1, 1);
292238106Sdes                assertEquals(val2, (isServerWithStable ? 1 : 2));
293238106Sdes
294238106Sdes                c.v = new long[1][1][1]; c.v[0][0][0] = 3; long val3 = get();
295238106Sdes                assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2)
296238106Sdes                                                    : 3));
297238106Sdes
298238106Sdes                c.v[0] = new long[1][1]; c.v[0][0][0] = 4; long val4 = get();
299238106Sdes                assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 1 : 2)
300238106Sdes                                                    : 4));
301238106Sdes
302238106Sdes                c.v[0][0] = new long[1]; c.v[0][0][0] = 5; long val5 = get();
303285206Sdes                assertEquals(val5, (isStableEnabled ? (isServerWithStable ? 1 : 2)
304238106Sdes                                                    : 5));
305238106Sdes            }
306238106Sdes
307238106Sdes            {
308238106Sdes                c.v = new long[1][1][1]; long[] val1 = get1();
309238106Sdes                c.v[0][0] = new long[1]; long[] val2 = get1();
310238106Sdes                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
311238106Sdes            }
312238106Sdes
313238106Sdes            {
314285206Sdes                c.v = new long[1][1][1]; long[][] val1 = get2();
315238106Sdes                c.v[0] = new long[1][1]; long[][] val2 = get2();
316238106Sdes                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
317238106Sdes            }
318238106Sdes
319238106Sdes            {
320238106Sdes                c.v = new long[1][1][1]; long[][][] val1 = get3();
321238106Sdes                c.v = new long[1][1][1]; long[][][] val2 = get3();
322238106Sdes                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
323238106Sdes            }
324238106Sdes        }
325238106Sdes    }
326285206Sdes
327238106Sdes    /* ==================================================== */
328238106Sdes
329238106Sdes    static class LongArrayDim4 {
330238106Sdes        public @Stable long[][][][] v;
331238106Sdes
332238106Sdes        public static final LongArrayDim4 c = new LongArrayDim4();
333238106Sdes        public static long get() { return c.v[0][0][0][0]; }
334238106Sdes        public static long[] get1() { return c.v[0][0][0]; }
335238106Sdes        public static long[][] get2() { return c.v[0][0]; }
336238106Sdes        public static long[][][] get3() { return c.v[0]; }
337238106Sdes        public static long[][][][] get4() { return c.v; }
338238106Sdes        public static void test() throws Exception {
339285206Sdes            {
340238106Sdes                c.v = new long[1][1][1][1]; c.v[0][0][0][0] = 1; long val1 = get();
341238106Sdes                                            c.v[0][0][0][0] = 2; long val2 = get();
342238106Sdes                assertEquals(val1, 1);
343238106Sdes                assertEquals(val2, (isServerWithStable ? 1 : 2));
344238106Sdes
345238106Sdes                c.v = new long[1][1][1][1]; c.v[0][0][0][0] = 3; long val3 = get();
346238106Sdes                assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2)
347238106Sdes                                                    : 3));
348238106Sdes
349238106Sdes                c.v[0] = new long[1][1][1]; c.v[0][0][0][0] = 4; long val4 = get();
350238106Sdes                assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 1 : 2)
351238106Sdes                                                    : 4));
352285206Sdes
353238106Sdes                c.v[0][0] = new long[1][1]; c.v[0][0][0][0] = 5; long val5 = get();
354238106Sdes                assertEquals(val5, (isStableEnabled ? (isServerWithStable ? 1 : 2)
355238106Sdes                                                    : 5));
356238106Sdes
357238106Sdes                c.v[0][0][0] = new long[1]; c.v[0][0][0][0] = 6; long val6 = get();
358238106Sdes                assertEquals(val6, (isStableEnabled ? (isServerWithStable ? 1 : 2)
359238106Sdes                                                    : 6));
360238106Sdes            }
361238106Sdes
362238106Sdes            {
363238106Sdes                c.v = new long[1][1][1][1]; long[] val1 = get1();
364238106Sdes                c.v[0][0][0] = new long[1]; long[] val2 = get1();
365285206Sdes                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
366238106Sdes            }
367238106Sdes
368238106Sdes            {
369238106Sdes                c.v = new long[1][1][1][1]; long[][] val1 = get2();
370238106Sdes                c.v[0][0] = new long[1][1]; long[][] val2 = get2();
371238106Sdes                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
372238106Sdes            }
373238106Sdes
374238106Sdes            {
375238106Sdes                c.v = new long[1][1][1][1]; long[][][] val1 = get3();
376238106Sdes                c.v[0] = new long[1][1][1]; long[][][] val2 = get3();
377285206Sdes                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
378238106Sdes            }
379238106Sdes
380238106Sdes            {
381238106Sdes                c.v = new long[1][1][1][1]; long[][][][] val1 = get4();
382238106Sdes                c.v = new long[1][1][1][1]; long[][][][] val2 = get4();
383238106Sdes                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
384238106Sdes            }
385238106Sdes        }
386238106Sdes    }
387238106Sdes
388238106Sdes    /* ==================================================== */
389238106Sdes    // Dynamic Dim is higher than static
390238106Sdes    static class ObjectArrayLowerDim0 {
391238106Sdes        public @Stable Object v;
392238106Sdes
393238106Sdes        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
394238106Sdes        public static long get() { return ((long[])c.v)[0]; }
395238106Sdes        public static long[] get1() { return (long[])c.v; }
396238106Sdes
397238106Sdes        public static void test() throws Exception {
398238106Sdes            {
399238106Sdes                c.v = new long[1]; ((long[])c.v)[0] = 1; long val1 = get();
400238106Sdes                                   ((long[])c.v)[0] = 2; long val2 = get();
401238106Sdes
402269257Sdes                assertEquals(val1, 1);
403238106Sdes                assertEquals(val2, 2);
404238106Sdes            }
405238106Sdes
406238106Sdes            {
407238106Sdes                c.v = new long[1]; long[] val1 = get1();
408238106Sdes                c.v = new long[1]; long[] val2 = get1();
409238106Sdes                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
410238106Sdes            }
411238106Sdes        }
412238106Sdes    }
413238106Sdes
414    /* ==================================================== */
415
416    static class ObjectArrayLowerDim1 {
417        public @Stable Object[] v;
418
419        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
420        public static long get() { return ((long[][])c.v)[0][0]; }
421        public static long[] get1() { return (long[])(c.v[0]); }
422        public static Object[] get2() { return c.v; }
423
424        public static void test() throws Exception {
425            {
426                c.v = new long[1][1]; ((long[][])c.v)[0][0] = 1; long val1 = get();
427                                      ((long[][])c.v)[0][0] = 2; long val2 = get();
428
429                assertEquals(val1, 1);
430                assertEquals(val2, 2);
431            }
432
433            {
434                c.v = new long[1][1]; c.v[0] = new long[0]; long[] val1 = get1();
435                                     c.v[0] = new long[0]; long[] val2 = get1();
436
437                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
438            }
439
440            {
441                c.v = new long[0][0]; Object[] val1 = get2();
442                c.v = new long[0][0]; Object[] val2 = get2();
443
444                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
445            }
446        }
447    }
448
449    /* ==================================================== */
450
451    static class ObjectArrayLowerDim2 {
452        public @Stable Object[][] v;
453
454        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
455        public static long get() { return ((long[][][])c.v)[0][0][0]; }
456        public static long[] get1() { return (long[])(c.v[0][0]); }
457        public static long[][] get2() { return (long[][])(c.v[0]); }
458        public static Object[][] get3() { return c.v; }
459
460        public static void test() throws Exception {
461            {
462                c.v = new long[1][1][1]; ((long[][][])c.v)[0][0][0] = 1L; long val1 = get();
463                                         ((long[][][])c.v)[0][0][0] = 2L; long val2 = get();
464
465                assertEquals(val1, 1L);
466                assertEquals(val2, 2L);
467            }
468
469            {
470                c.v = new long[1][1][1]; c.v[0][0] = new long[0]; long[] val1 = get1();
471                                         c.v[0][0] = new long[0]; long[] val2 = get1();
472
473                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
474            }
475
476            {
477                c.v = new long[1][1][1]; c.v[0] = new long[0][0]; long[][] val1 = get2();
478                                         c.v[0] = new long[0][0]; long[][] val2 = get2();
479
480                assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
481            }
482
483            {
484                c.v = new long[0][0][0]; Object[][] val1 = get3();
485                c.v = new long[0][0][0]; Object[][] val2 = get3();
486
487                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
488            }
489        }
490    }
491
492    /* ==================================================== */
493
494    static class NestedStableField {
495        static class A {
496            public @Stable long a;
497
498        }
499        public @Stable A v;
500
501        public static final NestedStableField c = new NestedStableField();
502        public static A get() { return c.v; }
503        public static long get1() { return get().a; }
504
505        public static void test() throws Exception {
506            {
507                c.v = new A(); c.v.a = 1; A val1 = get();
508                               c.v.a = 2; A val2 = get();
509
510                assertEquals(val1.a, 2);
511                assertEquals(val2.a, 2);
512            }
513
514            {
515                c.v = new A(); c.v.a = 1; long val1 = get1();
516                               c.v.a = 2; long val2 = get1();
517                c.v = new A(); c.v.a = 3; long val3 = get1();
518
519                assertEquals(val1, 1);
520                assertEquals(val2, (isStableEnabled ? 1 : 2));
521                assertEquals(val3, (isStableEnabled ? 1 : 3));
522            }
523        }
524    }
525
526    /* ==================================================== */
527
528    static class NestedStableField1 {
529        static class A {
530            public @Stable long a;
531            public @Stable A next;
532        }
533        public @Stable A v;
534
535        public static final NestedStableField1 c = new NestedStableField1();
536        public static A get() { return c.v.next.next.next.next.next.next.next; }
537        public static long get1() { return get().a; }
538
539        public static void test() throws Exception {
540            {
541                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
542                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
543                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
544
545                assertEquals(val1.a, 2);
546                assertEquals(val2.a, 2);
547            }
548
549            {
550                c.v = new A(); c.v.next = c.v;
551                               c.v.a = 1; long val1 = get1();
552                               c.v.a = 2; long val2 = get1();
553                c.v = new A(); c.v.next = c.v;
554                               c.v.a = 3; long val3 = get1();
555
556                assertEquals(val1, 1);
557                assertEquals(val2, (isStableEnabled ? 1 : 2));
558                assertEquals(val3, (isStableEnabled ? 1 : 3));
559            }
560        }
561    }
562   /* ==================================================== */
563
564    static class NestedStableField2 {
565        static class A {
566            public @Stable long a;
567            public @Stable A left;
568            public         A right;
569        }
570
571        public @Stable A v;
572
573        public static final NestedStableField2 c = new NestedStableField2();
574        public static long get() { return c.v.left.left.left.a; }
575        public static long get1() { return c.v.left.left.right.left.a; }
576
577        public static void test() throws Exception {
578            {
579                c.v = new A(); c.v.left = c.v.right = c.v;
580                               c.v.a = 1; long val1 = get(); long val2 = get1();
581                               c.v.a = 2; long val3 = get(); long val4 = get1();
582
583                assertEquals(val1, 1);
584                assertEquals(val3, (isStableEnabled ? 1 : 2));
585
586                assertEquals(val2, 1);
587                assertEquals(val4, 2);
588            }
589        }
590    }
591
592    /* ==================================================== */
593
594    static class NestedStableField3 {
595        static class A {
596            public @Stable long a;
597            public @Stable A[] left;
598            public         A[] right;
599        }
600
601        public @Stable A[] v;
602
603        public static final NestedStableField3 c = new NestedStableField3();
604        public static long get() { return c.v[0].left[1].left[0].left[1].a; }
605        public static long get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
606
607        public static void test() throws Exception {
608            {
609                A elem = new A();
610                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
611                               elem.a = 1; long val1 = get(); long val2 = get1();
612                               elem.a = 2; long val3 = get(); long val4 = get1();
613
614                assertEquals(val1, 1);
615                assertEquals(val3, (isServerWithStable ? 1 : 2));
616
617                assertEquals(val2, 1);
618                assertEquals(val4, 2);
619            }
620        }
621    }
622
623    /* ==================================================== */
624    // Auxiliary methods
625    static void assertEquals(long i, long j) { if (i != j)  throw new AssertionError(i + " != " + j); }
626    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
627
628    static boolean failed = false;
629
630    public static void run(Class<?> test) {
631        Throwable ex = null;
632        System.out.print(test.getName()+": ");
633        try {
634            test.getMethod("test").invoke(null);
635        } catch (InvocationTargetException e) {
636            ex = e.getCause();
637        } catch (Throwable e) {
638            ex = e;
639        } finally {
640            if (ex == null) {
641                System.out.println("PASSED");
642            } else {
643                failed = true;
644                System.out.println("FAILED");
645                ex.printStackTrace(System.out);
646            }
647        }
648    }
649}
650