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