1 /* 2 * Copyright (c) 2015, 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 26 * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessByte 27 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte 28 * @run testng/othervm -Diters=20000 VarHandleTestAccessByte 29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessByte 30 */ 31 32 import org.testng.annotations.BeforeClass; 33 import org.testng.annotations.DataProvider; 34 import org.testng.annotations.Test; 35 36 import java.lang.invoke.MethodHandles; 37 import java.lang.invoke.VarHandle; 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.List; 41 42 import static org.testng.Assert.*; 43 44 public class VarHandleTestAccessByte extends VarHandleBaseTest { 45 static final byte static_final_v = (byte)1; 46 47 static byte static_v; 48 49 final byte final_v = (byte)1; 50 51 byte v; 52 53 VarHandle vhFinalField; 54 55 VarHandle vhField; 56 57 VarHandle vhStaticField; 58 59 VarHandle vhStaticFinalField; 60 61 VarHandle vhArray; 62 63 @BeforeClass 64 public void setup() throws Exception { 65 vhFinalField = MethodHandles.lookup().findVarHandle( 66 VarHandleTestAccessByte.class, "final_v", byte.class); 67 68 vhField = MethodHandles.lookup().findVarHandle( 69 VarHandleTestAccessByte.class, "v", byte.class); 70 71 vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( 72 VarHandleTestAccessByte.class, "static_final_v", byte.class); 73 74 vhStaticField = MethodHandles.lookup().findStaticVarHandle( 75 VarHandleTestAccessByte.class, "static_v", byte.class); 76 77 vhArray = MethodHandles.arrayElementVarHandle(byte[].class); 78 } 79 80 81 @DataProvider 82 public Object[][] varHandlesProvider() throws Exception { 83 List<VarHandle> vhs = new ArrayList<>(); 84 vhs.add(vhField); 85 vhs.add(vhStaticField); 86 vhs.add(vhArray); 87 88 return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); 89 } 90 91 @Test(dataProvider = "varHandlesProvider") 92 public void testIsAccessModeSupported(VarHandle vh) { 93 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); 94 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); 95 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); 96 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); 97 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); 98 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); 99 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); 100 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); 101 102 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 103 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 104 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 105 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 106 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 107 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE)); 108 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 109 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 110 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 111 112 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 113 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 114 } 115 116 117 @DataProvider 118 public Object[][] typesProvider() throws Exception { 119 List<Object[]> types = new ArrayList<>(); 120 types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessByte.class)}); 121 types.add(new Object[] {vhStaticField, Arrays.asList()}); 122 types.add(new Object[] {vhArray, Arrays.asList(byte[].class, int.class)}); 123 124 return types.stream().toArray(Object[][]::new); 125 } 126 127 @Test(dataProvider = "typesProvider") 128 public void testTypes(VarHandle vh, List<Class<?>> pts) { 129 assertEquals(vh.varType(), byte.class); 130 131 assertEquals(vh.coordinateTypes(), pts); 132 133 testTypes(vh); 134 } 135 136 137 @Test 138 public void testLookupInstanceToStatic() { 139 checkIAE("Lookup of static final field to instance final field", () -> { 140 MethodHandles.lookup().findStaticVarHandle( 141 VarHandleTestAccessByte.class, "final_v", byte.class); 142 }); 143 144 checkIAE("Lookup of static field to instance field", () -> { 145 MethodHandles.lookup().findStaticVarHandle( 146 VarHandleTestAccessByte.class, "v", byte.class); 147 }); 148 } 149 150 @Test 151 public void testLookupStaticToInstance() { 152 checkIAE("Lookup of instance final field to static final field", () -> { 153 MethodHandles.lookup().findVarHandle( 154 VarHandleTestAccessByte.class, "static_final_v", byte.class); 155 }); 156 157 checkIAE("Lookup of instance field to static field", () -> { 158 vhStaticField = MethodHandles.lookup().findVarHandle( 159 VarHandleTestAccessByte.class, "static_v", byte.class); 160 }); 161 } 162 163 164 @DataProvider 165 public Object[][] accessTestCaseProvider() throws Exception { 166 List<AccessTestCase<?>> cases = new ArrayList<>(); 167 168 cases.add(new VarHandleAccessTestCase("Instance final field", 169 vhFinalField, vh -> testInstanceFinalField(this, vh))); 170 cases.add(new VarHandleAccessTestCase("Instance final field unsupported", 171 vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), 172 false)); 173 174 cases.add(new VarHandleAccessTestCase("Static final field", 175 vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalField)); 176 cases.add(new VarHandleAccessTestCase("Static final field unsupported", 177 vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalFieldUnsupported, 178 false)); 179 180 cases.add(new VarHandleAccessTestCase("Instance field", 181 vhField, vh -> testInstanceField(this, vh))); 182 cases.add(new VarHandleAccessTestCase("Instance field unsupported", 183 vhField, vh -> testInstanceFieldUnsupported(this, vh), 184 false)); 185 186 cases.add(new VarHandleAccessTestCase("Static field", 187 vhStaticField, VarHandleTestAccessByte::testStaticField)); 188 cases.add(new VarHandleAccessTestCase("Static field unsupported", 189 vhStaticField, VarHandleTestAccessByte::testStaticFieldUnsupported, 190 false)); 191 192 cases.add(new VarHandleAccessTestCase("Array", 193 vhArray, VarHandleTestAccessByte::testArray)); 194 cases.add(new VarHandleAccessTestCase("Array unsupported", 195 vhArray, VarHandleTestAccessByte::testArrayUnsupported, 196 false)); 197 cases.add(new VarHandleAccessTestCase("Array index out of bounds", 198 vhArray, VarHandleTestAccessByte::testArrayIndexOutOfBounds, 199 false)); 200 201 // Work around issue with jtreg summary reporting which truncates 202 // the String result of Object.toString to 30 characters, hence 203 // the first dummy argument 204 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); 205 } 206 207 @Test(dataProvider = "accessTestCaseProvider") 208 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable { 209 T t = atc.get(); 210 int iters = atc.requiresLoop() ? ITERS : 1; 211 for (int c = 0; c < iters; c++) { 212 atc.testAccess(t); 213 } 214 } 215 216 217 218 219 static void testInstanceFinalField(VarHandleTestAccessByte recv, VarHandle vh) { 220 // Plain 221 { 222 byte x = (byte) vh.get(recv); 223 assertEquals(x, (byte)1, "get byte value"); 224 } 225 226 227 // Volatile 228 { 229 byte x = (byte) vh.getVolatile(recv); 230 assertEquals(x, (byte)1, "getVolatile byte value"); 231 } 232 233 // Lazy 234 { 235 byte x = (byte) vh.getAcquire(recv); 236 assertEquals(x, (byte)1, "getRelease byte value"); 237 } 238 239 // Opaque 240 { 241 byte x = (byte) vh.getOpaque(recv); 242 assertEquals(x, (byte)1, "getOpaque byte value"); 243 } 244 } 245 246 static void testInstanceFinalFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) { 247 checkUOE(() -> { 248 vh.set(recv, (byte)2); 249 }); 250 251 checkUOE(() -> { 252 vh.setVolatile(recv, (byte)2); 253 }); 254 255 checkUOE(() -> { 256 vh.setRelease(recv, (byte)2); 257 }); 258 259 checkUOE(() -> { 260 vh.setOpaque(recv, (byte)2); 261 }); 262 263 checkUOE(() -> { 264 boolean r = vh.compareAndSet(recv, (byte)1, (byte)2); 265 }); 266 267 checkUOE(() -> { 268 byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2); 269 }); 270 271 checkUOE(() -> { 272 byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2); 273 }); 274 275 checkUOE(() -> { 276 byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2); 277 }); 278 279 checkUOE(() -> { 280 boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2); 281 }); 282 283 checkUOE(() -> { 284 boolean r = vh.weakCompareAndSetVolatile(recv, (byte)1, (byte)2); 285 }); 286 287 checkUOE(() -> { 288 boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2); 289 }); 290 291 checkUOE(() -> { 292 boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2); 293 }); 294 295 checkUOE(() -> { 296 byte o = (byte) vh.getAndAdd(recv, (byte)1); 297 }); 298 299 checkUOE(() -> { 300 byte o = (byte) vh.addAndGet(recv, (byte)1); 301 }); 302 } 303 304 305 static void testStaticFinalField(VarHandle vh) { 306 // Plain 307 { 308 byte x = (byte) vh.get(); 309 assertEquals(x, (byte)1, "get byte value"); 310 } 311 312 313 // Volatile 314 { 315 byte x = (byte) vh.getVolatile(); 316 assertEquals(x, (byte)1, "getVolatile byte value"); 317 } 318 319 // Lazy 320 { 321 byte x = (byte) vh.getAcquire(); 322 assertEquals(x, (byte)1, "getRelease byte value"); 323 } 324 325 // Opaque 326 { 327 byte x = (byte) vh.getOpaque(); 328 assertEquals(x, (byte)1, "getOpaque byte value"); 329 } 330 } 331 332 static void testStaticFinalFieldUnsupported(VarHandle vh) { 333 checkUOE(() -> { 334 vh.set((byte)2); 335 }); 336 337 checkUOE(() -> { 338 vh.setVolatile((byte)2); 339 }); 340 341 checkUOE(() -> { 342 vh.setRelease((byte)2); 343 }); 344 345 checkUOE(() -> { 346 vh.setOpaque((byte)2); 347 }); 348 349 checkUOE(() -> { 350 boolean r = vh.compareAndSet((byte)1, (byte)2); 351 }); 352 353 checkUOE(() -> { 354 byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2); 355 }); 356 357 checkUOE(() -> { 358 byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2); 359 }); 360 361 checkUOE(() -> { 362 byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2); 363 }); 364 365 checkUOE(() -> { 366 boolean r = vh.weakCompareAndSet((byte)1, (byte)2); 367 }); 368 369 checkUOE(() -> { 370 boolean r = vh.weakCompareAndSetVolatile((byte)1, (byte)2); 371 }); 372 373 checkUOE(() -> { 374 boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2); 375 }); 376 377 checkUOE(() -> { 378 boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2); 379 }); 380 381 checkUOE(() -> { 382 byte o = (byte) vh.getAndAdd((byte)1); 383 }); 384 385 checkUOE(() -> { 386 byte o = (byte) vh.addAndGet((byte)1); 387 }); 388 } 389 390 391 static void testInstanceField(VarHandleTestAccessByte recv, VarHandle vh) { 392 // Plain 393 { 394 vh.set(recv, (byte)1); 395 byte x = (byte) vh.get(recv); 396 assertEquals(x, (byte)1, "set byte value"); 397 } 398 399 400 // Volatile 401 { 402 vh.setVolatile(recv, (byte)2); 403 byte x = (byte) vh.getVolatile(recv); 404 assertEquals(x, (byte)2, "setVolatile byte value"); 405 } 406 407 // Lazy 408 { 409 vh.setRelease(recv, (byte)1); 410 byte x = (byte) vh.getAcquire(recv); 411 assertEquals(x, (byte)1, "setRelease byte value"); 412 } 413 414 // Opaque 415 { 416 vh.setOpaque(recv, (byte)2); 417 byte x = (byte) vh.getOpaque(recv); 418 assertEquals(x, (byte)2, "setOpaque byte value"); 419 } 420 421 422 } 423 424 static void testInstanceFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) { 425 checkUOE(() -> { 426 boolean r = vh.compareAndSet(recv, (byte)1, (byte)2); 427 }); 428 429 checkUOE(() -> { 430 byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2); 431 }); 432 433 checkUOE(() -> { 434 byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2); 435 }); 436 437 checkUOE(() -> { 438 byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2); 439 }); 440 441 checkUOE(() -> { 442 boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2); 443 }); 444 445 checkUOE(() -> { 446 boolean r = vh.weakCompareAndSetVolatile(recv, (byte)1, (byte)2); 447 }); 448 449 checkUOE(() -> { 450 boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2); 451 }); 452 453 checkUOE(() -> { 454 boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2); 455 }); 456 457 checkUOE(() -> { 458 byte o = (byte) vh.getAndAdd(recv, (byte)1); 459 }); 460 461 checkUOE(() -> { 462 byte o = (byte) vh.addAndGet(recv, (byte)1); 463 }); 464 } 465 466 467 static void testStaticField(VarHandle vh) { 468 // Plain 469 { 470 vh.set((byte)1); 471 byte x = (byte) vh.get(); 472 assertEquals(x, (byte)1, "set byte value"); 473 } 474 475 476 // Volatile 477 { 478 vh.setVolatile((byte)2); 479 byte x = (byte) vh.getVolatile(); 480 assertEquals(x, (byte)2, "setVolatile byte value"); 481 } 482 483 // Lazy 484 { 485 vh.setRelease((byte)1); 486 byte x = (byte) vh.getAcquire(); 487 assertEquals(x, (byte)1, "setRelease byte value"); 488 } 489 490 // Opaque 491 { 492 vh.setOpaque((byte)2); 493 byte x = (byte) vh.getOpaque(); 494 assertEquals(x, (byte)2, "setOpaque byte value"); 495 } 496 497 498 } 499 500 static void testStaticFieldUnsupported(VarHandle vh) { 501 checkUOE(() -> { 502 boolean r = vh.compareAndSet((byte)1, (byte)2); 503 }); 504 505 checkUOE(() -> { 506 byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2); 507 }); 508 509 checkUOE(() -> { 510 byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2); 511 }); 512 513 checkUOE(() -> { 514 byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2); 515 }); 516 517 checkUOE(() -> { 518 boolean r = vh.weakCompareAndSet((byte)1, (byte)2); 519 }); 520 521 checkUOE(() -> { 522 boolean r = vh.weakCompareAndSetVolatile((byte)1, (byte)2); 523 }); 524 525 checkUOE(() -> { 526 boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2); 527 }); 528 529 checkUOE(() -> { 530 boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2); 531 }); 532 533 checkUOE(() -> { 534 byte o = (byte) vh.getAndAdd((byte)1); 535 }); 536 537 checkUOE(() -> { 538 byte o = (byte) vh.addAndGet((byte)1); 539 }); 540 } 541 542 543 static void testArray(VarHandle vh) { 544 byte[] array = new byte[10]; 545 546 for (int i = 0; i < array.length; i++) { 547 // Plain 548 { 549 vh.set(array, i, (byte)1); 550 byte x = (byte) vh.get(array, i); 551 assertEquals(x, (byte)1, "get byte value"); 552 } 553 554 555 // Volatile 556 { 557 vh.setVolatile(array, i, (byte)2); 558 byte x = (byte) vh.getVolatile(array, i); 559 assertEquals(x, (byte)2, "setVolatile byte value"); 560 } 561 562 // Lazy 563 { 564 vh.setRelease(array, i, (byte)1); 565 byte x = (byte) vh.getAcquire(array, i); 566 assertEquals(x, (byte)1, "setRelease byte value"); 567 } 568 569 // Opaque 570 { 571 vh.setOpaque(array, i, (byte)2); 572 byte x = (byte) vh.getOpaque(array, i); 573 assertEquals(x, (byte)2, "setOpaque byte value"); 574 } 575 576 577 } 578 } 579 580 static void testArrayUnsupported(VarHandle vh) { 581 byte[] array = new byte[10]; 582 583 int i = 0; 584 checkUOE(() -> { 585 boolean r = vh.compareAndSet(array, i, (byte)1, (byte)2); 586 }); 587 588 checkUOE(() -> { 589 byte r = (byte) vh.compareAndExchangeVolatile(array, i, (byte)1, (byte)2); 590 }); 591 592 checkUOE(() -> { 593 byte r = (byte) vh.compareAndExchangeAcquire(array, i, (byte)1, (byte)2); 594 }); 595 596 checkUOE(() -> { 597 byte r = (byte) vh.compareAndExchangeRelease(array, i, (byte)1, (byte)2); 598 }); 599 600 checkUOE(() -> { 601 boolean r = vh.weakCompareAndSet(array, i, (byte)1, (byte)2); 602 }); 603 604 checkUOE(() -> { 605 boolean r = vh.weakCompareAndSetVolatile(array, i, (byte)1, (byte)2); 606 }); 607 608 checkUOE(() -> { 609 boolean r = vh.weakCompareAndSetAcquire(array, i, (byte)1, (byte)2); 610 }); 611 612 checkUOE(() -> { 613 boolean r = vh.weakCompareAndSetRelease(array, i, (byte)1, (byte)2); 614 }); 615 616 checkUOE(() -> { 617 byte o = (byte) vh.getAndAdd(array, i, (byte)1); 618 }); 619 620 checkUOE(() -> { 621 byte o = (byte) vh.addAndGet(array, i, (byte)1); 622 }); 623 } 624 625 static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { 626 byte[] array = new byte[10]; 627 628 for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { 629 final int ci = i; 630 631 checkIOOBE(() -> { 632 byte x = (byte) vh.get(array, ci); 633 }); 634 635 checkIOOBE(() -> { 636 vh.set(array, ci, (byte)1); 637 }); 638 639 checkIOOBE(() -> { 640 byte x = (byte) vh.getVolatile(array, ci); 641 }); 642 643 checkIOOBE(() -> { 644 vh.setVolatile(array, ci, (byte)1); 645 }); 646 647 checkIOOBE(() -> { 648 byte x = (byte) vh.getAcquire(array, ci); 649 }); 650 651 checkIOOBE(() -> { 652 vh.setRelease(array, ci, (byte)1); 653 }); 654 655 checkIOOBE(() -> { 656 byte x = (byte) vh.getOpaque(array, ci); 657 }); 658 659 checkIOOBE(() -> { 660 vh.setOpaque(array, ci, (byte)1); 661 }); 662 663 664 } 665 } 666 } 667