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