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 TestStableChar 28 * @summary tests on stable fields and arrays 29 * @library /testlibrary /testlibrary/whitebox 30 * @build TestStableChar 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/TestStableChar 35 * java/lang/invoke/TestStableChar$CharStable 36 * java/lang/invoke/TestStableChar$StaticCharStable 37 * java/lang/invoke/TestStableChar$VolatileCharStable 38 * java/lang/invoke/TestStableChar$CharArrayDim1 39 * java/lang/invoke/TestStableChar$CharArrayDim2 40 * java/lang/invoke/TestStableChar$CharArrayDim3 41 * java/lang/invoke/TestStableChar$CharArrayDim4 42 * java/lang/invoke/TestStableChar$ObjectArrayLowerDim0 43 * java/lang/invoke/TestStableChar$ObjectArrayLowerDim1 44 * java/lang/invoke/TestStableChar$NestedStableField 45 * java/lang/invoke/TestStableChar$NestedStableField$A 46 * java/lang/invoke/TestStableChar$NestedStableField1 47 * java/lang/invoke/TestStableChar$NestedStableField1$A 48 * java/lang/invoke/TestStableChar$NestedStableField2 49 * java/lang/invoke/TestStableChar$NestedStableField2$A 50 * java/lang/invoke/TestStableChar$NestedStableField3 51 * java/lang/invoke/TestStableChar$NestedStableField3$A 52 * java/lang/invoke/TestStableChar$DefaultValue 53 * java/lang/invoke/TestStableChar$DefaultStaticValue 54 * java/lang/invoke/TestStableChar$ObjectArrayLowerDim2 55 * 56 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 57 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 58 * -server -XX:-TieredCompilation 59 * -XX:+FoldStableValues 60 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 61 * java.lang.invoke.TestStableChar 62 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 63 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 64 * -server -XX:-TieredCompilation 65 * -XX:-FoldStableValues 66 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 67 * java.lang.invoke.TestStableChar 68 * 69 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 70 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 71 * -server -XX:+TieredCompilation -XX:TieredStopAtLevel=1 72 * -XX:+FoldStableValues 73 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 74 * java.lang.invoke.TestStableChar 75 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 76 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 77 * -server -XX:+TieredCompilation -XX:TieredStopAtLevel=1 78 * -XX:-FoldStableValues 79 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 80 * java.lang.invoke.TestStableChar 81 * 82 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 83 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 84 * -client -XX:-TieredCompilation 85 * -XX:+FoldStableValues 86 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 87 * java.lang.invoke.TestStableChar 88 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions 89 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 90 * -client -XX:-TieredCompilation 91 * -XX:-FoldStableValues 92 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 93 * java.lang.invoke.TestStableChar 94 */ 95 package java.lang.invoke; 96 97 import java.lang.reflect.InvocationTargetException; 98 99 public class TestStableChar { 100 static final boolean isStableEnabled = StableConfiguration.isStableEnabled; 101 static final boolean isServerWithStable = StableConfiguration.isServerWithStable; 102 103 public static void main(String[] args) throws Exception { 104 run(DefaultValue.class); 105 run(CharStable.class); 106 run(DefaultStaticValue.class); 107 run(StaticCharStable.class); 108 run(VolatileCharStable.class); 109 110 // @Stable arrays: Dim 1-4 111 run(CharArrayDim1.class); 112 run(CharArrayDim2.class); 113 run(CharArrayDim3.class); 114 run(CharArrayDim4.class); 115 116 // @Stable Object field: dynamic arrays 117 run(ObjectArrayLowerDim0.class); 118 run(ObjectArrayLowerDim1.class); 119 run(ObjectArrayLowerDim2.class); 120 121 // Nested @Stable fields 122 run(NestedStableField.class); 123 run(NestedStableField1.class); 124 run(NestedStableField2.class); 125 run(NestedStableField3.class); 126 127 if (failed) { 128 throw new Error("TEST FAILED"); 129 } 130 } 131 132 /* ==================================================== */ 133 134 static class DefaultValue { 135 public @Stable char v; 136 137 public static final DefaultValue c = new DefaultValue(); 138 public static char get() { return c.v; } 139 public static void test() throws Exception { 140 char val1 = get(); 141 c.v = 'a'; char val2 = get(); 142 assertEquals(val1, 0); 143 assertEquals(val2, 'a'); 144 } 145 } 146 147 /* ==================================================== */ 148 149 static class CharStable { 150 public @Stable char v; 151 152 public static final CharStable c = new CharStable(); 153 public static char get() { return c.v; } 154 public static void test() throws Exception { 155 c.v = 'a'; char val1 = get(); 156 c.v = 'b'; char val2 = get(); 157 assertEquals(val1, 'a'); 158 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 159 } 160 } 161 162 /* ==================================================== */ 163 164 static class DefaultStaticValue { 165 public static @Stable char v; 166 167 public static final DefaultStaticValue c = new DefaultStaticValue(); 168 public static char get() { return c.v; } 169 public static void test() throws Exception { 170 char val1 = get(); 171 c.v = 'a'; char val2 = get(); 172 assertEquals(val1, 0); 173 assertEquals(val2, 'a'); 174 } 175 } 176 177 /* ==================================================== */ 178 179 static class StaticCharStable { 180 public @Stable char v; 181 182 public static final StaticCharStable c = new StaticCharStable(); 183 public static char get() { return c.v; } 184 public static void test() throws Exception { 185 c.v = 'a'; char val1 = get(); 186 c.v = 'b'; char val2 = get(); 187 assertEquals(val1, 'a'); 188 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 189 } 190 } 191 192 /* ==================================================== */ 193 194 static class VolatileCharStable { 195 public @Stable volatile char v; 196 197 public static final VolatileCharStable c = new VolatileCharStable(); 198 public static char get() { return c.v; } 199 public static void test() throws Exception { 200 c.v = 'a'; char val1 = get(); 201 c.v = 'b'; char val2 = get(); 202 assertEquals(val1, 'a'); 203 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 204 } 205 } 206 207 /* ==================================================== */ 208 // @Stable array == field && all components are stable 209 210 static class CharArrayDim1 { 211 public @Stable char[] v; 212 213 public static final CharArrayDim1 c = new CharArrayDim1(); 214 public static char get() { return c.v[0]; } 215 public static char get1() { return c.v[10]; } 216 public static char[] get2() { return c.v; } 217 public static void test() throws Exception { 218 { 219 c.v = new char[1]; c.v[0] = 'a'; char val1 = get(); 220 c.v[0] = 'b'; char val2 = get(); 221 assertEquals(val1, 'a'); 222 assertEquals(val2, (isServerWithStable ? 'a' : 'b')); 223 224 c.v = new char[1]; c.v[0] = 'c'; char val3 = get(); 225 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 226 : 'c')); 227 } 228 229 { 230 c.v = new char[20]; c.v[10] = 'a'; char val1 = get1(); 231 c.v[10] = 'b'; char val2 = get1(); 232 assertEquals(val1, 'a'); 233 assertEquals(val2, (isServerWithStable ? 'a' : 'b')); 234 235 c.v = new char[20]; c.v[10] = 'c'; char val3 = get1(); 236 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 237 : 'c')); 238 } 239 240 { 241 c.v = new char[1]; char[] val1 = get2(); 242 c.v = new char[1]; char[] val2 = get2(); 243 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 244 } 245 } 246 } 247 248 /* ==================================================== */ 249 250 static class CharArrayDim2 { 251 public @Stable char[][] v; 252 253 public static final CharArrayDim2 c = new CharArrayDim2(); 254 public static char get() { return c.v[0][0]; } 255 public static char[] get1() { return c.v[0]; } 256 public static char[][] get2() { return c.v; } 257 public static void test() throws Exception { 258 { 259 c.v = new char[1][1]; c.v[0][0] = 'a'; char val1 = get(); 260 c.v[0][0] = 'b'; char val2 = get(); 261 assertEquals(val1, 'a'); 262 assertEquals(val2, (isServerWithStable ? 'a' : 'b')); 263 264 c.v = new char[1][1]; c.v[0][0] = 'c'; char val3 = get(); 265 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 266 : 'c')); 267 268 c.v[0] = new char[1]; c.v[0][0] = 'd'; char val4 = get(); 269 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 270 : 'd')); 271 } 272 273 { 274 c.v = new char[1][1]; char[] val1 = get1(); 275 c.v[0] = new char[1]; char[] val2 = get1(); 276 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 277 } 278 279 { 280 c.v = new char[1][1]; char[][] val1 = get2(); 281 c.v = new char[1][1]; char[][] val2 = get2(); 282 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 283 } 284 } 285 } 286 287 /* ==================================================== */ 288 289 static class CharArrayDim3 { 290 public @Stable char[][][] v; 291 292 public static final CharArrayDim3 c = new CharArrayDim3(); 293 public static char get() { return c.v[0][0][0]; } 294 public static char[] get1() { return c.v[0][0]; } 295 public static char[][] get2() { return c.v[0]; } 296 public static char[][][] get3() { return c.v; } 297 public static void test() throws Exception { 298 { 299 c.v = new char[1][1][1]; c.v[0][0][0] = 'a'; char val1 = get(); 300 c.v[0][0][0] = 'b'; char val2 = get(); 301 assertEquals(val1, 'a'); 302 assertEquals(val2, (isServerWithStable ? 'a' : 'b')); 303 304 c.v = new char[1][1][1]; c.v[0][0][0] = 'c'; char val3 = get(); 305 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 306 : 'c')); 307 308 c.v[0] = new char[1][1]; c.v[0][0][0] = 'd'; char val4 = get(); 309 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 310 : 'd')); 311 312 c.v[0][0] = new char[1]; c.v[0][0][0] = 'e'; char val5 = get(); 313 assertEquals(val5, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 314 : 'e')); 315 } 316 317 { 318 c.v = new char[1][1][1]; char[] val1 = get1(); 319 c.v[0][0] = new char[1]; char[] val2 = get1(); 320 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 321 } 322 323 { 324 c.v = new char[1][1][1]; char[][] val1 = get2(); 325 c.v[0] = new char[1][1]; char[][] val2 = get2(); 326 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 327 } 328 329 { 330 c.v = new char[1][1][1]; char[][][] val1 = get3(); 331 c.v = new char[1][1][1]; char[][][] val2 = get3(); 332 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 333 } 334 } 335 } 336 337 /* ==================================================== */ 338 339 static class CharArrayDim4 { 340 public @Stable char[][][][] v; 341 342 public static final CharArrayDim4 c = new CharArrayDim4(); 343 public static char get() { return c.v[0][0][0][0]; } 344 public static char[] get1() { return c.v[0][0][0]; } 345 public static char[][] get2() { return c.v[0][0]; } 346 public static char[][][] get3() { return c.v[0]; } 347 public static char[][][][] get4() { return c.v; } 348 public static void test() throws Exception { 349 { 350 c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'a'; char val1 = get(); 351 c.v[0][0][0][0] = 'b'; char val2 = get(); 352 assertEquals(val1, 'a'); 353 assertEquals(val2, (isServerWithStable ? 'a' : 'b')); 354 355 c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'c'; char val3 = get(); 356 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 357 : 'c')); 358 359 c.v[0] = new char[1][1][1]; c.v[0][0][0][0] = 'd'; char val4 = get(); 360 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 361 : 'd')); 362 363 c.v[0][0] = new char[1][1]; c.v[0][0][0][0] = 'e'; char val5 = get(); 364 assertEquals(val5, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 365 : 'e')); 366 367 c.v[0][0][0] = new char[1]; c.v[0][0][0][0] = 'f'; char val6 = get(); 368 assertEquals(val6, (isStableEnabled ? (isServerWithStable ? 'a' : 'b') 369 : 'f')); 370 } 371 372 { 373 c.v = new char[1][1][1][1]; char[] val1 = get1(); 374 c.v[0][0][0] = new char[1]; char[] val2 = get1(); 375 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 376 } 377 378 { 379 c.v = new char[1][1][1][1]; char[][] val1 = get2(); 380 c.v[0][0] = new char[1][1]; char[][] val2 = get2(); 381 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 382 } 383 384 { 385 c.v = new char[1][1][1][1]; char[][][] val1 = get3(); 386 c.v[0] = new char[1][1][1]; char[][][] val2 = get3(); 387 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 388 } 389 390 { 391 c.v = new char[1][1][1][1]; char[][][][] val1 = get4(); 392 c.v = new char[1][1][1][1]; char[][][][] val2 = get4(); 393 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 394 } 395 } 396 } 397 398 /* ==================================================== */ 399 // Dynamic Dim is higher than static 400 static class ObjectArrayLowerDim0 { 401 public @Stable Object v; 402 403 public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0(); 404 public static char get() { return ((char[])c.v)[0]; } 405 public static char[] get1() { return (char[])c.v; } 406 407 public static void test() throws Exception { 408 { 409 c.v = new char[1]; ((char[])c.v)[0] = 'a'; char val1 = get(); 410 ((char[])c.v)[0] = 'b'; char val2 = get(); 411 412 assertEquals(val1, 'a'); 413 assertEquals(val2, 'b'); 414 } 415 416 { 417 c.v = new char[1]; char[] val1 = get1(); 418 c.v = new char[1]; char[] val2 = get1(); 419 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 420 } 421 } 422 } 423 424 /* ==================================================== */ 425 426 static class ObjectArrayLowerDim1 { 427 public @Stable Object[] v; 428 429 public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1(); 430 public static char get() { return ((char[][])c.v)[0][0]; } 431 public static char[] get1() { return (char[])(c.v[0]); } 432 public static Object[] get2() { return c.v; } 433 434 public static void test() throws Exception { 435 { 436 c.v = new char[1][1]; ((char[][])c.v)[0][0] = 'a'; char val1 = get(); 437 ((char[][])c.v)[0][0] = 'b'; char val2 = get(); 438 439 assertEquals(val1, 'a'); 440 assertEquals(val2, 'b'); 441 } 442 443 { 444 c.v = new char[1][1]; c.v[0] = new char[0]; char[] val1 = get1(); 445 c.v[0] = new char[0]; char[] val2 = get1(); 446 447 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 448 } 449 450 { 451 c.v = new char[0][0]; Object[] val1 = get2(); 452 c.v = new char[0][0]; Object[] val2 = get2(); 453 454 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 455 } 456 } 457 } 458 459 /* ==================================================== */ 460 461 static class ObjectArrayLowerDim2 { 462 public @Stable Object[][] v; 463 464 public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2(); 465 public static char get() { return ((char[][][])c.v)[0][0][0]; } 466 public static char[] get1() { return (char[])(c.v[0][0]); } 467 public static char[][] get2() { return (char[][])(c.v[0]); } 468 public static Object[][] get3() { return c.v; } 469 470 public static void test() throws Exception { 471 { 472 c.v = new char[1][1][1]; ((char[][][])c.v)[0][0][0] = 'a'; char val1 = get(); 473 ((char[][][])c.v)[0][0][0] = 'b'; char val2 = get(); 474 475 assertEquals(val1, 'a'); 476 assertEquals(val2, 'b'); 477 } 478 479 { 480 c.v = new char[1][1][1]; c.v[0][0] = new char[0]; char[] val1 = get1(); 481 c.v[0][0] = new char[0]; char[] val2 = get1(); 482 483 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 484 } 485 486 { 487 c.v = new char[1][1][1]; c.v[0] = new char[0][0]; char[][] val1 = get2(); 488 c.v[0] = new char[0][0]; char[][] val2 = get2(); 489 490 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 491 } 492 493 { 494 c.v = new char[0][0][0]; Object[][] val1 = get3(); 495 c.v = new char[0][0][0]; Object[][] val2 = get3(); 496 497 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 498 } 499 } 500 } 501 502 /* ==================================================== */ 503 504 static class NestedStableField { 505 static class A { 506 public @Stable char a; 507 508 } 509 public @Stable A v; 510 511 public static final NestedStableField c = new NestedStableField(); 512 public static A get() { return c.v; } 513 public static char get1() { return get().a; } 514 515 public static void test() throws Exception { 516 { 517 c.v = new A(); c.v.a = 'a'; A val1 = get(); 518 c.v.a = 'b'; A val2 = get(); 519 520 assertEquals(val1.a, 'b'); 521 assertEquals(val2.a, 'b'); 522 } 523 524 { 525 c.v = new A(); c.v.a = 'a'; char val1 = get1(); 526 c.v.a = 'b'; char val2 = get1(); 527 c.v = new A(); c.v.a = 'c'; char val3 = get1(); 528 529 assertEquals(val1, 'a'); 530 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 531 assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 532 } 533 } 534 } 535 536 /* ==================================================== */ 537 538 static class NestedStableField1 { 539 static class A { 540 public @Stable char a; 541 public @Stable A next; 542 } 543 public @Stable A v; 544 545 public static final NestedStableField1 c = new NestedStableField1(); 546 public static A get() { return c.v.next.next.next.next.next.next.next; } 547 public static char get1() { return get().a; } 548 549 public static void test() throws Exception { 550 { 551 c.v = new A(); c.v.next = new A(); c.v.next.next = c.v; 552 c.v.a = 'a'; c.v.next.a = 'a'; A val1 = get(); 553 c.v.a = 'b'; c.v.next.a = 'b'; A val2 = get(); 554 555 assertEquals(val1.a, 'b'); 556 assertEquals(val2.a, 'b'); 557 } 558 559 { 560 c.v = new A(); c.v.next = c.v; 561 c.v.a = 'a'; char val1 = get1(); 562 c.v.a = 'b'; char val2 = get1(); 563 c.v = new A(); c.v.next = c.v; 564 c.v.a = 'c'; char val3 = get1(); 565 566 assertEquals(val1, 'a'); 567 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 568 assertEquals(val3, (isStableEnabled ? 'a' : 'c')); 569 } 570 } 571 } 572 /* ==================================================== */ 573 574 static class NestedStableField2 { 575 static class A { 576 public @Stable char a; 577 public @Stable A left; 578 public A right; 579 } 580 581 public @Stable A v; 582 583 public static final NestedStableField2 c = new NestedStableField2(); 584 public static char get() { return c.v.left.left.left.a; } 585 public static char get1() { return c.v.left.left.right.left.a; } 586 587 public static void test() throws Exception { 588 { 589 c.v = new A(); c.v.left = c.v.right = c.v; 590 c.v.a = 'a'; char val1 = get(); char val2 = get1(); 591 c.v.a = 'b'; char val3 = get(); char val4 = get1(); 592 593 assertEquals(val1, 'a'); 594 assertEquals(val3, (isStableEnabled ? 'a' : 'b')); 595 596 assertEquals(val2, 'a'); 597 assertEquals(val4, 'b'); 598 } 599 } 600 } 601 602 /* ==================================================== */ 603 604 static class NestedStableField3 { 605 static class A { 606 public @Stable char a; 607 public @Stable A[] left; 608 public A[] right; 609 } 610 611 public @Stable A[] v; 612 613 public static final NestedStableField3 c = new NestedStableField3(); 614 public static char get() { return c.v[0].left[1].left[0].left[1].a; } 615 public static char get1() { return c.v[1].left[0].left[1].right[0].left[1].a; } 616 617 public static void test() throws Exception { 618 { 619 A elem = new A(); 620 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v; 621 elem.a = 'a'; char val1 = get(); char val2 = get1(); 622 elem.a = 'b'; char val3 = get(); char val4 = get1(); 623 624 assertEquals(val1, 'a'); 625 assertEquals(val3, (isServerWithStable ? 'a' : 'b')); 626 627 assertEquals(val2, 'a'); 628 assertEquals(val4, 'b'); 629 } 630 } 631 } 632 633 /* ==================================================== */ 634 // Auxiliary methods 635 static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } 636 static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } 637 638 static boolean failed = false; 639 640 public static void run(Class<?> test) { 641 Throwable ex = null; 642 System.out.print(test.getName()+": "); 643 try { 644 test.getMethod("test").invoke(null); 645 } catch (InvocationTargetException e) { 646 ex = e.getCause(); 647 } catch (Throwable e) { 648 ex = e; 649 } finally { 650 if (ex == null) { 651 System.out.println("PASSED"); 652 } else { 653 failed = true; 654 System.out.println("FAILED"); 655 ex.printStackTrace(System.out); 656 } 657 } 658 } 659 }