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