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