1 /* 2 * Copyright (c) 2013, 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 StableValueTest 28 * @summary tests on stable fields and arrays 29 * @library /testlibrary 30 * @compile -XDignore.symbol.file StableValueTest.java 31 * @run main ClassFileInstaller StableValueTest StableValueTest$BoolStable StableValueTest$ByteStable StableValueTest$CharStable 32 * StableValueTest$DoubleStable StableValueTest$FloatStable StableValueTest$IntArrayArity1 33 * StableValueTest$IntArrayArity2 StableValueTest$IntArrayArity3 StableValueTest$IntArrayArity4 34 * StableValueTest$IntStable StableValueTest$LongStable StableValueTest$ObjectArrayArity0 35 * StableValueTest$ObjectArrayArity1 StableValueTest$ObjectStable$Values StableValueTest$ObjectStable 36 * StableValueTest$ShortStable StableValueTest$StaticBoolStable StableValueTest$StaticByteStable 37 * StableValueTest$StaticCharStable StableValueTest$StaticDoubleStable StableValueTest$StaticFloatStable 38 * StableValueTest$StaticIntStable StableValueTest$StaticLongStable StableValueTest$StaticShortStable 39 * StableValueTest$VolatileBoolStable StableValueTest$VolatileByteStable StableValueTest$VolatileCharStable 40 * StableValueTest$VolatileDoubleStable StableValueTest$VolatileFloatStable StableValueTest$VolatileIntStable 41 * StableValueTest$VolatileLongStable StableValueTest$VolatileObjectStable$Values 42 * StableValueTest$VolatileObjectStable StableValueTest$VolatileShortStable 43 * StableValueTest$NestedStableField StableValueTest$NestedStableField$A 44 * StableValueTest$NestedStableField1 StableValueTest$NestedStableField1$A 45 * StableValueTest$NestedStableField2 StableValueTest$NestedStableField2$A 46 * StableValueTest$NestedStableField3 StableValueTest$NestedStableField3$A 47 * 48 * @run main/othervm -Xbootclasspath/a:. -server -XX:-TieredCompilation -Xcomp -XX:+UnlockExperimentalVMOptions 49 * -XX:+FoldStableValues -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 StableValueTest 50 * @run main/othervm -Xbootclasspath/a:. -server -XX:-TieredCompilation -Xcomp -XX:+UnlockExperimentalVMOptions 51 * -XX:-FoldStableValues -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 StableValueTest 52 */ 53 import com.sun.management.HotSpotDiagnosticMXBean; 54 import com.sun.management.VMOption; 55 import sun.invoke.Stable; 56 import sun.management.ManagementFactoryHelper; 57 58 import java.lang.reflect.InvocationTargetException; 59 60 public class StableValueTest { 61 public static void main(String[] args) throws Exception { 62 System.out.println("@Stable enabled: "+isStableEnabled); 63 System.out.println(); 64 65 // @Stable primitive & raw Object fields 66 run(ObjectStable.class); 67 run(BoolStable.class); 68 run(ByteStable.class); 69 run(ShortStable.class); 70 run(CharStable.class); 71 run(IntStable.class); 72 run(LongStable.class); 73 run(FloatStable.class); 74 run(DoubleStable.class); 75 76 // @Stable primitive & raw Object static fields 77 run(StaticBoolStable.class); 78 run(StaticByteStable.class); 79 run(StaticShortStable.class); 80 run(StaticCharStable.class); 81 run(StaticIntStable.class); 82 run(StaticLongStable.class); 83 run(StaticFloatStable.class); 84 run(StaticDoubleStable.class); 85 86 // @Stable primitive & raw Object volatile instance fields 87 run(VolatileObjectStable.class); 88 run(VolatileBoolStable.class); 89 run(VolatileByteStable.class); 90 run(VolatileShortStable.class); 91 run(VolatileCharStable.class); 92 run(VolatileIntStable.class); 93 run(VolatileLongStable.class); 94 run(VolatileFloatStable.class); 95 run(VolatileDoubleStable.class); 96 97 // @Stable arrays: arity 1-4 98 run(IntArrayArity1.class); 99 run(IntArrayArity2.class); 100 run(IntArrayArity3.class); 101 run(IntArrayArity4.class); 102 103 // @Stable Object field: dynamic arrays 104 run(ObjectArrayArity0.class); 105 run(ObjectArrayArity1.class); 106 107 // Nested @Stable fields 108 run(NestedStableField.class); 109 run(NestedStableField1.class); 110 run(NestedStableField2.class); 111 run(NestedStableField3.class); 112 113 if (failed) { 114 throw new Error("TEST FAILED"); 115 } 116 } 117 118 /* ==================================================== */ 119 120 static class ObjectStable { 121 enum Values { A, B} 122 public @Stable Values v; 123 124 public static final ObjectStable c = new ObjectStable (); 125 public static Values get() { return c.v; } 126 public static void test() throws Exception { 127 c.v = Values.A; Values val1 = get(); 128 c.v = Values.B; Values val2 = get(); 129 assertEquals(val1, Values.A); 130 assertEquals(val2, (isStableEnabled ? Values.A : Values.B)); 131 } 132 } 133 134 /* ==================================================== */ 135 136 static class BoolStable { 137 public @Stable boolean v; 138 139 public static final BoolStable c = new BoolStable(); 140 public static boolean get() { return c.v; } 141 public static void test() throws Exception { 142 c.v = true; boolean val1 = get(); 143 c.v = false; boolean val2 = get(); 144 assertEquals(val1, true); 145 assertEquals(val2, (isStableEnabled ? true : false)); 146 } 147 } 148 149 /* ==================================================== */ 150 151 static class ByteStable { 152 public @Stable byte v; 153 154 public static final ByteStable c = new ByteStable(); 155 public static byte get() { return c.v; } 156 public static void test() throws Exception { 157 c.v = 5; byte val1 = get(); 158 c.v = 127; byte val2 = get(); 159 assertEquals(val1, 5); 160 assertEquals(val2, (isStableEnabled ? 5 : 127)); 161 } 162 } 163 164 /* ==================================================== */ 165 166 static class ShortStable { 167 public @Stable short v; 168 169 public static final ShortStable c = new ShortStable(); 170 public static short get() { return c.v; } 171 public static void test() throws Exception { 172 c.v = 1; short val1 = get(); 173 c.v = 32767; short val2 = get(); 174 assertEquals(val1, 1); 175 assertEquals(val2, (isStableEnabled ? 1 : 32767)); 176 } 177 } 178 179 /* ==================================================== */ 180 181 static class CharStable { 182 public @Stable char v; 183 184 public static final CharStable c = new CharStable(); 185 public static char get() { return c.v; } 186 public static void test() throws Exception { 187 c.v = 'a'; char val1 = get(); 188 c.v = 'b'; char val2 = get(); 189 assertEquals(val1, 'a'); 190 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 191 } 192 } 193 194 /* ==================================================== */ 195 196 static class IntStable { 197 public @Stable int v; 198 199 public static final IntStable c = new IntStable(); 200 public static int get() { return c.v; } 201 public static void test() throws Exception { 202 c.v = 1; int val1 = get(); 203 c.v = 2; int val2 = get(); 204 assertEquals(val1, 1); 205 assertEquals(val2, (isStableEnabled ? 1 : 2)); 206 } 207 } 208 209 /* ==================================================== */ 210 211 static class FloatStable { 212 public @Stable float v; 213 214 public static final FloatStable c = new FloatStable(); 215 public static float get() { return c.v; } 216 public static void test() throws Exception { 217 c.v = 1.0F; float val1 = get(); 218 c.v = 2.0F; float val2 = get(); 219 assertEquals(val1, 1.0F); 220 assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F)); 221 } 222 } 223 224 /* ==================================================== */ 225 226 static class LongStable { 227 public @Stable long v; 228 229 public static final LongStable c = new LongStable(); 230 public static long get() { return c.v; } 231 public static void test() throws Exception { 232 c.v = 5; long val1 = get(); 233 c.v = Long.MAX_VALUE; long val2 = get(); 234 assertEquals(val1, 5); 235 assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE)); 236 } 237 } 238 239 /* ==================================================== */ 240 241 static class DoubleStable { 242 public @Stable double v; 243 244 public static final DoubleStable c = new DoubleStable(); 245 public static double get() { return c.v; } 246 public static void test() throws Exception { 247 c.v = 1.0; double val1 = get(); 248 c.v = Double.MAX_VALUE; double val2 = get(); 249 assertEquals(val1, 1.0); 250 assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE)); 251 } 252 } 253 254 /* ==================================================== */ 255 256 static class StaticBoolStable { 257 public static @Stable boolean v; 258 259 public static final StaticBoolStable c = new StaticBoolStable(); 260 public static boolean get() { return c.v; } 261 public static void test() throws Exception { 262 c.v = true; boolean val1 = get(); 263 c.v = false; boolean val2 = get(); 264 assertEquals(val1, true); 265 assertEquals(val2, (isStableEnabled ? true : false)); 266 } 267 } 268 269 /* ==================================================== */ 270 271 static class StaticByteStable { 272 public static @Stable byte v; 273 274 public static final StaticByteStable c = new StaticByteStable(); 275 public static byte get() { return c.v; } 276 public static void test() throws Exception { 277 c.v = 5; byte val1 = get(); 278 c.v = 127; byte val2 = get(); 279 assertEquals(val1, 5); 280 assertEquals(val2, (isStableEnabled ? 5 : 127)); 281 } 282 } 283 284 /* ==================================================== */ 285 286 static class StaticShortStable { 287 public static @Stable short v; 288 289 public static final StaticShortStable c = new StaticShortStable(); 290 public static short get() { return c.v; } 291 public static void test() throws Exception { 292 c.v = 1; short val1 = get(); 293 c.v = 32767; short val2 = get(); 294 assertEquals(val1, 1); 295 assertEquals(val2, (isStableEnabled ? 1 : 32767)); 296 } 297 } 298 299 /* ==================================================== */ 300 301 static class StaticCharStable { 302 public static @Stable char v; 303 304 public static final StaticCharStable c = new StaticCharStable(); 305 public static char get() { return c.v; } 306 public static void test() throws Exception { 307 c.v = 'a'; char val1 = get(); 308 c.v = 'b'; char val2 = get(); 309 assertEquals(val1, 'a'); 310 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 311 } 312 } 313 314 /* ==================================================== */ 315 316 static class StaticIntStable { 317 public static @Stable int v; 318 319 public static final StaticIntStable c = new StaticIntStable(); 320 public static int get() { return c.v; } 321 public static void test() throws Exception { 322 c.v = 1; int val1 = get(); 323 c.v = 2; int val2 = get(); 324 assertEquals(val1, 1); 325 assertEquals(val2, (isStableEnabled ? 1 : 2)); 326 } 327 } 328 329 /* ==================================================== */ 330 331 static class StaticFloatStable { 332 public static @Stable float v; 333 334 public static final StaticFloatStable c = new StaticFloatStable(); 335 public static float get() { return c.v; } 336 public static void test() throws Exception { 337 c.v = 1.0F; float val1 = get(); 338 c.v = 2.0F; float val2 = get(); 339 assertEquals(val1, 1.0F); 340 assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F)); 341 } 342 } 343 344 /* ==================================================== */ 345 346 static class StaticLongStable { 347 public static @Stable long v; 348 349 public static final StaticLongStable c = new StaticLongStable(); 350 public static long get() { return c.v; } 351 public static void test() throws Exception { 352 c.v = 5; long val1 = get(); 353 c.v = Long.MAX_VALUE; long val2 = get(); 354 assertEquals(val1, 5); 355 assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE)); 356 } 357 } 358 359 /* ==================================================== */ 360 361 static class StaticDoubleStable { 362 public static @Stable double v; 363 364 public static final StaticDoubleStable c = new StaticDoubleStable(); 365 public static double get() { return c.v; } 366 public static void test() throws Exception { 367 c.v = 1.0; double val1 = get(); 368 c.v = Double.MAX_VALUE; double val2 = get(); 369 assertEquals(val1, 1.0); 370 assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE)); 371 } 372 } 373 374 /* ==================================================== */ 375 376 static class VolatileObjectStable { 377 enum Values { A, B} 378 public @Stable volatile Values v; 379 380 public static final VolatileObjectStable c = new VolatileObjectStable (); 381 public static Values get() { return c.v; } 382 public static void test() throws Exception { 383 c.v = Values.A; Values val1 = get(); 384 c.v = Values.B; Values val2 = get(); 385 assertEquals(val1, Values.A); 386 assertEquals(val2, (isStableEnabled ? Values.A : Values.B)); 387 } 388 } 389 390 /* ==================================================== */ 391 392 static class VolatileBoolStable { 393 public @Stable volatile boolean v; 394 395 public static final VolatileBoolStable c = new VolatileBoolStable(); 396 public static boolean get() { return c.v; } 397 public static void test() throws Exception { 398 c.v = true; boolean val1 = get(); 399 c.v = false; boolean val2 = get(); 400 assertEquals(val1, true); 401 assertEquals(val2, (isStableEnabled ? true : false)); 402 } 403 } 404 405 /* ==================================================== */ 406 407 static class VolatileByteStable { 408 public @Stable volatile byte v; 409 410 public static final VolatileByteStable c = new VolatileByteStable(); 411 public static byte get() { return c.v; } 412 public static void test() throws Exception { 413 c.v = 5; byte val1 = get(); 414 c.v = 127; byte val2 = get(); 415 assertEquals(val1, 5); 416 assertEquals(val2, (isStableEnabled ? 5 : 127)); 417 } 418 } 419 420 /* ==================================================== */ 421 422 static class VolatileShortStable { 423 public @Stable volatile short v; 424 425 public static final VolatileShortStable c = new VolatileShortStable(); 426 public static short get() { return c.v; } 427 public static void test() throws Exception { 428 c.v = 1; short val1 = get(); 429 c.v = 32767; short val2 = get(); 430 assertEquals(val1, 1); 431 assertEquals(val2, (isStableEnabled ? 1 : 32767)); 432 } 433 } 434 435 /* ==================================================== */ 436 437 static class VolatileCharStable { 438 public @Stable volatile char v; 439 440 public static final VolatileCharStable c = new VolatileCharStable(); 441 public static char get() { return c.v; } 442 public static void test() throws Exception { 443 c.v = 'a'; char val1 = get(); 444 c.v = 'b'; char val2 = get(); 445 assertEquals(val1, 'a'); 446 assertEquals(val2, (isStableEnabled ? 'a' : 'b')); 447 } 448 } 449 450 /* ==================================================== */ 451 452 static class VolatileIntStable { 453 public @Stable volatile int v; 454 455 public static final VolatileIntStable c = new VolatileIntStable(); 456 public static int get() { return c.v; } 457 public static void test() throws Exception { 458 c.v = 1; int val1 = get(); 459 c.v = 2; int val2 = get(); 460 assertEquals(val1, 1); 461 assertEquals(val2, (isStableEnabled ? 1 : 2)); 462 } 463 } 464 465 /* ==================================================== */ 466 467 static class VolatileFloatStable { 468 public @Stable volatile float v; 469 470 public static final VolatileFloatStable c = new VolatileFloatStable(); 471 public static float get() { return c.v; } 472 public static void test() throws Exception { 473 c.v = 1.0F; float val1 = get(); 474 c.v = 2.0F; float val2 = get(); 475 assertEquals(val1, 1.0F); 476 assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F)); 477 } 478 } 479 480 /* ==================================================== */ 481 482 static class VolatileLongStable { 483 public @Stable volatile long v; 484 485 public static final VolatileLongStable c = new VolatileLongStable(); 486 public static long get() { return c.v; } 487 public static void test() throws Exception { 488 c.v = 5; long val1 = get(); 489 c.v = Long.MAX_VALUE; long val2 = get(); 490 assertEquals(val1, 5); 491 assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE)); 492 } 493 } 494 495 /* ==================================================== */ 496 497 static class VolatileDoubleStable { 498 public @Stable double v; 499 500 public static final VolatileDoubleStable c = new VolatileDoubleStable(); 501 public static double get() { return c.v; } 502 public static void test() throws Exception { 503 c.v = 1.0; double val1 = get(); 504 c.v = Double.MAX_VALUE; double val2 = get(); 505 assertEquals(val1, 1.0); 506 assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE)); 507 } 508 } 509 510 /* ==================================================== */ 511 // @Stable array == field && all components are stable 512 513 static class IntArrayArity1 { 514 public static @Stable int[] v; 515 516 public static final IntArrayArity1 c = new IntArrayArity1(); 517 public static int get() { return c.v[0]; } 518 public static int[] get1() { return c.v; } 519 public static void test() throws Exception { 520 { 521 c.v = new int[1]; c.v[0] = 1; int val1 = get(); 522 c.v[0] = 2; int val2 = get(); 523 assertEquals(val1, 1); 524 assertEquals(val2, (isStableEnabled ? 1 : 2)); 525 526 c.v = new int[1]; c.v[0] = 3; int val3 = get(); 527 assertEquals(val3, (isStableEnabled ? 1 : 3)); 528 } 529 530 { 531 c.v = new int[1]; int[] val1 = get1(); 532 c.v = new int[1]; int[] val2 = get1(); 533 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 534 } 535 } 536 } 537 538 /* ==================================================== */ 539 540 static class IntArrayArity2 { 541 public static @Stable int[][] v; 542 543 public static final IntArrayArity2 c = new IntArrayArity2(); 544 public static int get() { return c.v[0][0]; } 545 public static int[] get1() { return c.v[0]; } 546 public static int[][] get2() { return c.v; } 547 public static void test() throws Exception { 548 { 549 c.v = new int[1][1]; c.v[0][0] = 1; int val1 = get(); 550 c.v[0][0] = 2; int val2 = get(); 551 assertEquals(val1, 1); 552 assertEquals(val2, (isStableEnabled ? 1 : 2)); 553 554 c.v = new int[1][1]; c.v[0][0] = 3; int val3 = get(); 555 assertEquals(val3, (isStableEnabled ? 1 : 3)); 556 557 c.v[0] = new int[1]; c.v[0][0] = 4; int val4 = get(); 558 assertEquals(val4, (isStableEnabled ? 1 : 4)); 559 } 560 561 { 562 c.v = new int[1][1]; int[] val1 = get1(); 563 c.v[0] = new int[1]; int[] val2 = get1(); 564 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 565 } 566 567 { 568 c.v = new int[1][1]; int[][] val1 = get2(); 569 c.v = new int[1][1]; int[][] val2 = get2(); 570 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 571 } 572 } 573 } 574 575 /* ==================================================== */ 576 577 static class IntArrayArity3 { 578 public static @Stable int[][][] v; 579 580 public static final IntArrayArity3 c = new IntArrayArity3(); 581 public static int get() { return c.v[0][0][0]; } 582 public static int[] get1() { return c.v[0][0]; } 583 public static int[][] get2() { return c.v[0]; } 584 public static int[][][] get3() { return c.v; } 585 public static void test() throws Exception { 586 { 587 c.v = new int[1][1][1]; c.v[0][0][0] = 1; int val1 = get(); 588 c.v[0][0][0] = 2; int val2 = get(); 589 assertEquals(val1, 1); 590 assertEquals(val2, (isStableEnabled ? 1 : 2)); 591 592 c.v = new int[1][1][1]; c.v[0][0][0] = 3; int val3 = get(); 593 assertEquals(val3, (isStableEnabled ? 1 : 3)); 594 595 c.v[0] = new int[1][1]; c.v[0][0][0] = 4; int val4 = get(); 596 assertEquals(val4, (isStableEnabled ? 1 : 4)); 597 598 c.v[0][0] = new int[1]; c.v[0][0][0] = 5; int val5 = get(); 599 assertEquals(val5, (isStableEnabled ? 1 : 5)); 600 } 601 602 { 603 c.v = new int[1][1][1]; int[] val1 = get1(); 604 c.v[0][0] = new int[1]; int[] val2 = get1(); 605 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 606 } 607 608 { 609 c.v = new int[1][1][1]; int[][] val1 = get2(); 610 c.v[0] = new int[1][1]; int[][] val2 = get2(); 611 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 612 } 613 614 { 615 c.v = new int[1][1][1]; int[][][] val1 = get3(); 616 c.v = new int[1][1][1]; int[][][] val2 = get3(); 617 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 618 } 619 } 620 } 621 622 /* ==================================================== */ 623 624 static class IntArrayArity4 { 625 public static @Stable int[][][][] v; 626 627 public static final IntArrayArity4 c = new IntArrayArity4(); 628 public static int get() { return c.v[0][0][0][0]; } 629 public static int[] get1() { return c.v[0][0][0]; } 630 public static int[][] get2() { return c.v[0][0]; } 631 public static int[][][] get3() { return c.v[0]; } 632 public static int[][][][] get4() { return c.v; } 633 public static void test() throws Exception { 634 { 635 c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 1; int val1 = get(); 636 c.v[0][0][0][0] = 2; int val2 = get(); 637 assertEquals(val1, 1); 638 assertEquals(val2, (isStableEnabled ? 1 : 2)); 639 640 c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 3; int val3 = get(); 641 assertEquals(val3, (isStableEnabled ? 1 : 3)); 642 643 c.v[0] = new int[1][1][1]; c.v[0][0][0][0] = 4; int val4 = get(); 644 assertEquals(val4, (isStableEnabled ? 1 : 4)); 645 646 c.v[0][0] = new int[1][1]; c.v[0][0][0][0] = 5; int val5 = get(); 647 assertEquals(val5, (isStableEnabled ? 1 : 5)); 648 649 c.v[0][0][0] = new int[1]; c.v[0][0][0][0] = 6; int val6 = get(); 650 assertEquals(val6, (isStableEnabled ? 1 : 6)); 651 } 652 653 { 654 c.v = new int[1][1][1][1]; int[] val1 = get1(); 655 c.v[0][0][0] = new int[1]; int[] val2 = get1(); 656 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 657 } 658 659 { 660 c.v = new int[1][1][1][1]; int[][] val1 = get2(); 661 c.v[0][0] = new int[1][1]; int[][] val2 = get2(); 662 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 663 } 664 665 { 666 c.v = new int[1][1][1][1]; int[][][] val1 = get3(); 667 c.v[0] = new int[1][1][1]; int[][][] val2 = get3(); 668 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 669 } 670 671 { 672 c.v = new int[1][1][1][1]; int[][][][] val1 = get4(); 673 c.v = new int[1][1][1][1]; int[][][][] val2 = get4(); 674 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 675 } 676 677 } 678 } 679 680 /* ==================================================== */ 681 // Dynamic arity is higher than static 682 683 static class ObjectArrayArity0 { 684 public static @Stable Object v; 685 686 public static final ObjectArrayArity0 c = new ObjectArrayArity0(); 687 public static int get() { return ((int[])c.v)[0]; } 688 public static int[] get1() { return (int[])c.v; } 689 690 public static void test() throws Exception { 691 { 692 c.v = new int[1]; ((int[])c.v)[0] = 1; int val1 = get(); 693 ((int[])c.v)[0] = 2; int val2 = get(); 694 695 assertEquals(val1, 1); 696 assertEquals(val2, 2); 697 } 698 699 { 700 c.v = new int[1]; int[] val1 = get1(); 701 c.v = new int[1]; int[] val2 = get1(); 702 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 703 } 704 } 705 } 706 707 /* ==================================================== */ 708 709 static class ObjectArrayArity1 { 710 public static @Stable Object[] v; 711 712 public static final ObjectArrayArity1 c = new ObjectArrayArity1(); 713 public static int get() { return ((int[][])c.v)[0][0]; } 714 public static int[] get1() { return (int[])(c.v[0]); } 715 public static Object[] get2() { return c.v; } 716 717 public static void test() throws Exception { 718 { 719 c.v = new int[1][1]; ((int[][])c.v)[0][0] = 1; int val1 = get(); 720 ((int[][])c.v)[0][0] = 2; int val2 = get(); 721 722 assertEquals(val1, 1); 723 assertEquals(val2, 2); 724 } 725 726 { 727 c.v = new int[1][1]; c.v[0] = new int[0]; int[] val1 = get1(); 728 c.v[0] = new int[0]; int[] val2 = get1(); 729 730 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 731 } 732 733 { 734 c.v = new int[0][0]; Object[] val1 = get2(); 735 c.v = new int[0][0]; Object[] val2 = get2(); 736 737 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 738 } 739 } 740 } 741 742 /* ==================================================== */ 743 744 static class NestedStableField { 745 static class A { 746 public @Stable int a; 747 748 } 749 public static @Stable A v; 750 751 public static final NestedStableField c = new NestedStableField(); 752 public static A get() { return c.v; } 753 public static int get1() { return get().a; } 754 755 public static void test() throws Exception { 756 { 757 c.v = new A(); c.v.a = 1; A val1 = get(); 758 c.v.a = 2; A val2 = get(); 759 760 assertEquals(val1.a, 2); 761 assertEquals(val2.a, 2); 762 } 763 764 { 765 c.v = new A(); c.v.a = 1; int val1 = get1(); 766 c.v.a = 2; int val2 = get1(); 767 c.v = new A(); c.v.a = 3; int val3 = get1(); 768 769 assertEquals(val1, 1); 770 assertEquals(val2, (isStableEnabled ? 1 : 2)); 771 assertEquals(val3, (isStableEnabled ? 1 : 3)); 772 } 773 } 774 } 775 776 /* ==================================================== */ 777 778 static class NestedStableField1 { 779 static class A { 780 public @Stable int a; 781 public @Stable A next; 782 } 783 public static @Stable A v; 784 785 public static final NestedStableField1 c = new NestedStableField1(); 786 public static A get() { return c.v.next.next.next.next.next.next.next; } 787 public static int get1() { return get().a; } 788 789 public static void test() throws Exception { 790 { 791 c.v = new A(); c.v.next = new A(); c.v.next.next = c.v; 792 c.v.a = 1; c.v.next.a = 1; A val1 = get(); 793 c.v.a = 2; c.v.next.a = 2; A val2 = get(); 794 795 assertEquals(val1.a, 2); 796 assertEquals(val2.a, 2); 797 } 798 799 { 800 c.v = new A(); c.v.next = c.v; 801 c.v.a = 1; int val1 = get1(); 802 c.v.a = 2; int val2 = get1(); 803 c.v = new A(); c.v.next = c.v; 804 c.v.a = 3; int val3 = get1(); 805 806 assertEquals(val1, 1); 807 assertEquals(val2, (isStableEnabled ? 1 : 2)); 808 assertEquals(val3, (isStableEnabled ? 1 : 3)); 809 } 810 } 811 } 812 /* ==================================================== */ 813 814 static class NestedStableField2 { 815 static class A { 816 public @Stable int a; 817 public @Stable A left; 818 public A right; 819 } 820 821 public static @Stable A v; 822 823 public static final NestedStableField2 c = new NestedStableField2(); 824 public static int get() { return c.v.left.left.left.a; } 825 public static int get1() { return c.v.left.left.right.left.a; } 826 827 public static void test() throws Exception { 828 { 829 c.v = new A(); c.v.left = c.v.right = c.v; 830 c.v.a = 1; int val1 = get(); int val2 = get1(); 831 c.v.a = 2; int val3 = get(); int val4 = get1(); 832 833 assertEquals(val1, 1); 834 assertEquals(val3, (isStableEnabled ? 1 : 2)); 835 836 assertEquals(val2, 1); 837 assertEquals(val4, 2); 838 } 839 } 840 } 841 842 /* ==================================================== */ 843 844 static class NestedStableField3 { 845 static class A { 846 public @Stable int a; 847 public @Stable A[] left; 848 public A[] right; 849 } 850 851 public static @Stable A[] v; 852 853 public static final NestedStableField3 c = new NestedStableField3(); 854 public static int get() { return c.v[0].left[1].left[0].left[1].a; } 855 public static int get1() { return c.v[1].left[0].left[1].right[0].left[1].a; } 856 857 public static void test() throws Exception { 858 { 859 A elem = new A(); 860 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v; 861 elem.a = 1; int val1 = get(); int val2 = get1(); 862 elem.a = 2; int val3 = get(); int val4 = get1(); 863 864 assertEquals(val1, 1); 865 assertEquals(val3, (isStableEnabled ? 1 : 2)); 866 867 assertEquals(val2, 1); 868 assertEquals(val4, 2); 869 } 870 } 871 } 872 873 /* ==================================================== */ 874 // Auxiliary methods 875 static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } 876 static void assertEquals(long i, long j) { if (i != j) throw new AssertionError(i + " != " + j); } 877 static void assertEquals(boolean i, boolean j) { if (i != j) throw new AssertionError(i + " != " + j); } 878 static void assertEquals(float i, float j) { if (i != j) throw new AssertionError(i + " != " + j); } 879 static void assertEquals(double i, double j) { if (i != j) throw new AssertionError(i + " != " + j); } 880 static void assertEquals(Object i, Object j) { if (!i.equals(j)) throw new AssertionError(i + " != " + j); } 881 static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } 882 883 static boolean failed = false; 884 885 public static void run(Class<?> test) { 886 Throwable ex = null; 887 System.out.print(test.getName()+": "); 888 try { 889 test.getMethod("test").invoke(null); 890 } catch (InvocationTargetException e) { 891 ex = e.getCause(); 892 } catch (Throwable e) { 893 ex = e; 894 } finally { 895 if (ex == null) { 896 System.out.println("PASSED"); 897 } else { 898 failed = true; 899 System.out.println("FAILED"); 900 ex.printStackTrace(System.out); 901 } 902 } 903 } 904 905 static final boolean isStableEnabled; 906 static { 907 HotSpotDiagnosticMXBean diagnostic 908 = ManagementFactoryHelper.getDiagnosticMXBean(); 909 VMOption tmp; 910 try { 911 tmp = diagnostic.getVMOption("FoldStableValues"); 912 } catch (IllegalArgumentException e) { 913 tmp = null; 914 } 915 isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue())); 916 } 917 }