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 62 import java.lang.reflect.InvocationTargetException; 63 64 public class TestStableByte { 65 static final boolean isStableEnabled = StableConfiguration.isStableEnabled; 66 67 public static void main(String[] args) throws Exception { 68 run(DefaultValue.class); 69 run(ByteStable.class); 70 run(DefaultStaticValue.class); 71 run(StaticByteStable.class); 72 run(VolatileByteStable.class); 73 74 // @Stable arrays: Dim 1-4 75 run(ByteArrayDim1.class); 76 run(ByteArrayDim2.class); 77 run(ByteArrayDim3.class); 78 run(ByteArrayDim4.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 static class DefaultValue { 99 public @Stable byte v; 100 101 public static final DefaultValue c = new DefaultValue(); 102 public static byte get() { return c.v; } 103 public static void test() throws Exception { 104 byte val1 = get(); 105 c.v = 1; byte val2 = get(); 106 assertEquals(val1, 0); 107 assertEquals(val2, 1); 108 } 109 } 110 111 /* ==================================================== */ 112 113 static class ByteStable { 114 public @Stable byte v; 115 116 public static final ByteStable c = new ByteStable(); 117 public static byte get() { return c.v; } 118 public static void test() throws Exception { 119 c.v = 5; byte val1 = get(); 120 c.v = 127; byte val2 = get(); 121 assertEquals(val1, 5); 122 assertEquals(val2, (isStableEnabled ? 5 : 127)); 123 } 124 } 125 126 /* ==================================================== */ 127 128 static class DefaultStaticValue { 129 public static @Stable byte v; 130 131 public static final DefaultStaticValue c = new DefaultStaticValue(); 132 public static byte get() { return c.v; } 133 public static void test() throws Exception { 134 byte val1 = get(); 135 c.v = 1; byte val2 = get(); 136 assertEquals(val1, 0); 137 assertEquals(val2, 1); 138 } 139 } 140 141 /* ==================================================== */ 142 143 static class StaticByteStable { 144 public static @Stable byte v; 145 146 public static final StaticByteStable c = new StaticByteStable(); 147 public static byte get() { return c.v; } 148 public static void test() throws Exception { 149 c.v = 5; byte val1 = get(); 150 c.v = 127; byte val2 = get(); 151 assertEquals(val1, 5); 152 assertEquals(val2, (isStableEnabled ? 5 : 127)); 153 } 154 } 155 156 /* ==================================================== */ 157 158 static class VolatileByteStable { 159 public @Stable volatile byte v; 160 161 public static final VolatileByteStable c = new VolatileByteStable(); 162 public static byte get() { return c.v; } 163 public static void test() throws Exception { 164 c.v = 5; byte val1 = get(); 165 c.v = 127; byte val2 = get(); 166 assertEquals(val1, 5); 167 assertEquals(val2, (isStableEnabled ? 5 : 127)); 168 } 169 } 170 171 /* ==================================================== */ 172 // @Stable array == field && all components are stable 173 174 static class ByteArrayDim1 { 175 public @Stable byte[] v; 176 177 public static final ByteArrayDim1 c = new ByteArrayDim1(); 178 public static byte get() { return c.v[0]; } 179 public static byte get1() { return c.v[10]; } 180 public static byte[] get2() { return c.v; } 181 public static void test() throws Exception { 182 { 183 c.v = new byte[1]; c.v[0] = 1; byte val1 = get(); 184 c.v[0] = 2; byte val2 = get(); 185 assertEquals(val1, 1); 186 assertEquals(val2, (isStableEnabled ? 1 : 2)); 187 188 c.v = new byte[1]; c.v[0] = 3; byte val3 = get(); 189 assertEquals(val3, (isStableEnabled ? (isStableEnabled ? 1 : 2) 190 : 3)); 191 } 192 193 { 194 c.v = new byte[20]; c.v[10] = 1; byte val1 = get1(); 195 c.v[10] = 2; byte val2 = get1(); 196 assertEquals(val1, 1); 197 assertEquals(val2, (isStableEnabled ? 1 : 2)); 198 199 c.v = new byte[20]; c.v[10] = 3; byte val3 = get1(); 200 assertEquals(val3, (isStableEnabled ? (isStableEnabled ? 1 : 2) 201 : 3)); 202 } 203 204 { 205 c.v = new byte[1]; byte[] val1 = get2(); 206 c.v = new byte[1]; byte[] val2 = get2(); 207 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 208 } 209 } 210 } 211 212 /* ==================================================== */ 213 214 static class ByteArrayDim2 { 215 public @Stable byte[][] v; 216 217 public static final ByteArrayDim2 c = new ByteArrayDim2(); 218 public static byte get() { return c.v[0][0]; } 219 public static byte[] get1() { return c.v[0]; } 220 public static byte[][] get2() { return c.v; } 221 public static void test() throws Exception { 222 { 223 c.v = new byte[1][1]; c.v[0][0] = 1; byte val1 = get(); 224 c.v[0][0] = 2; byte val2 = get(); 225 assertEquals(val1, 1); 226 assertEquals(val2, (isStableEnabled ? 1 : 2)); 227 228 c.v = new byte[1][1]; c.v[0][0] = 3; byte val3 = get(); 229 assertEquals(val3, (isStableEnabled ? (isStableEnabled ? 1 : 2) 230 : 3)); 231 232 c.v[0] = new byte[1]; c.v[0][0] = 4; byte val4 = get(); 233 assertEquals(val4, (isStableEnabled ? (isStableEnabled ? 1 : 2) 234 : 4)); 235 } 236 237 { 238 c.v = new byte[1][1]; byte[] val1 = get1(); 239 c.v[0] = new byte[1]; byte[] val2 = get1(); 240 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 241 } 242 243 { 244 c.v = new byte[1][1]; byte[][] val1 = get2(); 245 c.v = new byte[1][1]; byte[][] val2 = get2(); 246 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 247 } 248 } 249 } 250 251 /* ==================================================== */ 252 253 static class ByteArrayDim3 { 254 public @Stable byte[][][] v; 255 256 public static final ByteArrayDim3 c = new ByteArrayDim3(); 257 public static byte get() { return c.v[0][0][0]; } 258 public static byte[] get1() { return c.v[0][0]; } 259 public static byte[][] get2() { return c.v[0]; } 260 public static byte[][][] get3() { return c.v; } 261 public static void test() throws Exception { 262 { 263 c.v = new byte[1][1][1]; c.v[0][0][0] = 1; byte val1 = get(); 264 c.v[0][0][0] = 2; byte val2 = get(); 265 assertEquals(val1, 1); 266 assertEquals(val2, (isStableEnabled ? 1 : 2)); 267 268 c.v = new byte[1][1][1]; c.v[0][0][0] = 3; byte val3 = get(); 269 assertEquals(val3, (isStableEnabled ? (isStableEnabled ? 1 : 2) 270 : 3)); 271 272 c.v[0] = new byte[1][1]; c.v[0][0][0] = 4; byte val4 = get(); 273 assertEquals(val4, (isStableEnabled ? (isStableEnabled ? 1 : 2) 274 : 4)); 275 276 c.v[0][0] = new byte[1]; c.v[0][0][0] = 5; byte val5 = get(); 277 assertEquals(val5, (isStableEnabled ? (isStableEnabled ? 1 : 2) 278 : 5)); 279 } 280 281 { 282 c.v = new byte[1][1][1]; byte[] val1 = get1(); 283 c.v[0][0] = new byte[1]; byte[] val2 = get1(); 284 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 285 } 286 287 { 288 c.v = new byte[1][1][1]; byte[][] val1 = get2(); 289 c.v[0] = new byte[1][1]; byte[][] val2 = get2(); 290 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 291 } 292 293 { 294 c.v = new byte[1][1][1]; byte[][][] val1 = get3(); 295 c.v = new byte[1][1][1]; byte[][][] val2 = get3(); 296 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 297 } 298 } 299 } 300 301 /* ==================================================== */ 302 303 static class ByteArrayDim4 { 304 public @Stable byte[][][][] v; 305 306 public static final ByteArrayDim4 c = new ByteArrayDim4(); 307 public static byte get() { return c.v[0][0][0][0]; } 308 public static byte[] get1() { return c.v[0][0][0]; } 309 public static byte[][] get2() { return c.v[0][0]; } 310 public static byte[][][] get3() { return c.v[0]; } 311 public static byte[][][][] get4() { return c.v; } 312 public static void test() throws Exception { 313 { 314 c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 1; byte val1 = get(); 315 c.v[0][0][0][0] = 2; byte val2 = get(); 316 assertEquals(val1, 1); 317 assertEquals(val2, (isStableEnabled ? 1 : 2)); 318 319 c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 3; byte val3 = get(); 320 assertEquals(val3, (isStableEnabled ? (isStableEnabled ? 1 : 2) 321 : 3)); 322 323 c.v[0] = new byte[1][1][1]; c.v[0][0][0][0] = 4; byte val4 = get(); 324 assertEquals(val4, (isStableEnabled ? (isStableEnabled ? 1 : 2) 325 : 4)); 326 327 c.v[0][0] = new byte[1][1]; c.v[0][0][0][0] = 5; byte val5 = get(); 328 assertEquals(val5, (isStableEnabled ? (isStableEnabled ? 1 : 2) 329 : 5)); 330 331 c.v[0][0][0] = new byte[1]; c.v[0][0][0][0] = 6; byte val6 = get(); 332 assertEquals(val6, (isStableEnabled ? (isStableEnabled ? 1 : 2) 333 : 6)); 334 } 335 336 { 337 c.v = new byte[1][1][1][1]; byte[] val1 = get1(); 338 c.v[0][0][0] = new byte[1]; byte[] val2 = get1(); 339 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 340 } 341 342 { 343 c.v = new byte[1][1][1][1]; byte[][] val1 = get2(); 344 c.v[0][0] = new byte[1][1]; byte[][] val2 = get2(); 345 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 346 } 347 348 { 349 c.v = new byte[1][1][1][1]; byte[][][] val1 = get3(); 350 c.v[0] = new byte[1][1][1]; byte[][][] val2 = get3(); 351 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 352 } 353 354 { 355 c.v = new byte[1][1][1][1]; byte[][][][] val1 = get4(); 356 c.v = new byte[1][1][1][1]; byte[][][][] val2 = get4(); 357 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 358 } 359 360 } 361 } 362 363 /* ==================================================== */ 364 // Dynamic Dim is higher than static 365 366 static class ObjectArrayLowerDim0 { 367 public @Stable Object v; 368 369 public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0(); 370 public static byte get() { return ((byte[])c.v)[0]; } 371 public static byte[] get1() { return (byte[])c.v; } 372 373 public static void test() throws Exception { 374 { 375 c.v = new byte[1]; ((byte[])c.v)[0] = 1; byte val1 = get(); 376 ((byte[])c.v)[0] = 2; byte val2 = get(); 377 378 assertEquals(val1, 1); 379 assertEquals(val2, 2); 380 } 381 382 { 383 c.v = new byte[1]; byte[] val1 = get1(); 384 c.v = new byte[1]; byte[] 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 byte get() { return ((byte[][])c.v)[0][0]; } 397 public static byte[] get1() { return (byte[])(c.v[0]); } 398 public static Object[] get2() { return c.v; } 399 400 public static void test() throws Exception { 401 { 402 c.v = new byte[1][1]; ((byte[][])c.v)[0][0] = 1; byte val1 = get(); 403 ((byte[][])c.v)[0][0] = 2; byte val2 = get(); 404 405 assertEquals(val1, 1); 406 assertEquals(val2, 2); 407 } 408 409 { 410 c.v = new byte[1][1]; c.v[0] = new byte[0]; byte[] val1 = get1(); 411 c.v[0] = new byte[0]; byte[] val2 = get1(); 412 413 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 414 } 415 416 { 417 c.v = new byte[0][0]; Object[] val1 = get2(); 418 c.v = new byte[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 byte get() { return ((byte[][][])c.v)[0][0][0]; } 432 public static byte[] get1() { return (byte[])(c.v[0][0]); } 433 public static byte[][] get2() { return (byte[][])(c.v[0]); } 434 public static Object[][] get3() { return c.v; } 435 436 public static void test() throws Exception { 437 { 438 c.v = new byte[1][1][1]; ((byte[][][])c.v)[0][0][0] = 1; byte val1 = get(); 439 ((byte[][][])c.v)[0][0][0] = 2; byte val2 = get(); 440 441 assertEquals(val1, 1); 442 assertEquals(val2, 2); 443 } 444 445 { 446 c.v = new byte[1][1][1]; c.v[0][0] = new byte[0]; byte[] val1 = get1(); 447 c.v[0][0] = new byte[0]; byte[] val2 = get1(); 448 449 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 450 } 451 452 { 453 c.v = new byte[1][1][1]; c.v[0] = new byte[0][0]; byte[][] val1 = get2(); 454 c.v[0] = new byte[0][0]; byte[][] val2 = get2(); 455 456 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 457 } 458 459 { 460 c.v = new byte[0][0][0]; Object[][] val1 = get3(); 461 c.v = new byte[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 byte 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 byte get1() { return get().a; } 480 481 public static void test() throws Exception { 482 { 483 c.v = new A(); c.v.a = 1; A val1 = get(); 484 c.v.a = 2; A val2 = get(); 485 486 assertEquals(val1.a, 2); 487 assertEquals(val2.a, 2); 488 } 489 490 { 491 c.v = new A(); c.v.a = 1; byte val1 = get1(); 492 c.v.a = 2; byte val2 = get1(); 493 c.v = new A(); c.v.a = 3; byte val3 = get1(); 494 495 assertEquals(val1, 1); 496 assertEquals(val2, (isStableEnabled ? 1 : 2)); 497 assertEquals(val3, (isStableEnabled ? 1 : 3)); 498 } 499 } 500 } 501 502 /* ==================================================== */ 503 504 static class NestedStableField1 { 505 static class A { 506 public @Stable byte 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 byte 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 = 1; c.v.next.a = 1; A val1 = get(); 519 c.v.a = 2; c.v.next.a = 2; A val2 = get(); 520 521 assertEquals(val1.a, 2); 522 assertEquals(val2.a, 2); 523 } 524 525 { 526 c.v = new A(); c.v.next = c.v; 527 c.v.a = 1; byte val1 = get1(); 528 c.v.a = 2; byte val2 = get1(); 529 c.v = new A(); c.v.next = c.v; 530 c.v.a = 3; byte val3 = get1(); 531 532 assertEquals(val1, 1); 533 assertEquals(val2, (isStableEnabled ? 1 : 2)); 534 assertEquals(val3, (isStableEnabled ? 1 : 3)); 535 } 536 } 537 } 538 /* ==================================================== */ 539 540 static class NestedStableField2 { 541 static class A { 542 public @Stable byte 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 byte get() { return c.v.left.left.left.a; } 551 public static byte 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 = 1; byte val1 = get(); byte val2 = get1(); 557 c.v.a = 2; byte val3 = get(); byte val4 = get1(); 558 559 assertEquals(val1, 1); 560 assertEquals(val3, (isStableEnabled ? 1 : 2)); 561 562 assertEquals(val2, 1); 563 assertEquals(val4, 2); 564 } 565 } 566 } 567 568 /* ==================================================== */ 569 570 static class NestedStableField3 { 571 static class A { 572 public @Stable byte 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 byte get() { return c.v[0].left[1].left[0].left[1].a; } 581 public static byte 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 = 1; byte val1 = get(); byte val2 = get1(); 588 elem.a = 2; byte val3 = get(); byte val4 = get1(); 589 590 assertEquals(val1, 1); 591 assertEquals(val3, (isStableEnabled ? 1 : 2)); 592 593 assertEquals(val2, 1); 594 assertEquals(val4, 2); 595 } 596 } 597 } 598 599 /* ==================================================== */ 600 // Auxiliary methods 601 static void assertEquals(int i, int 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 }