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