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