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