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