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