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