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