X-VarHandleTestByteArrayView.java.template revision 14549:099857ef9d0c
1/* 2 * Copyright (c) 2015, 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. 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 * @bug 8154556 27 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$ 28 * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$ 29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$ 30 */ 31 32import org.testng.annotations.DataProvider; 33import org.testng.annotations.Test; 34 35import java.lang.invoke.MethodHandles; 36import java.lang.invoke.VarHandle; 37import java.nio.ByteBuffer; 38import java.nio.ByteOrder; 39import java.util.ArrayList; 40import java.util.Arrays; 41import java.util.EnumSet; 42import java.util.List; 43 44import static org.testng.Assert.*; 45 46public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { 47 static final int SIZE = $BoxType$.BYTES; 48 49 static final $type$ VALUE_1 = $value1$; 50 51 static final $type$ VALUE_2 = $value2$; 52 53 static final $type$ VALUE_3 = $value3$; 54 55 56 @Override 57 public void setupVarHandleSources() { 58 // Combinations of VarHandle byte[] or ByteBuffer 59 vhss = new ArrayList<>(); 60 for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { 61 62 ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN 63 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; 64 VarHandleSource aeh = new VarHandleSource( 65 MethodHandles.byteArrayViewVarHandle($type$[].class, bo), 66 endianess, MemoryMode.READ_WRITE); 67 vhss.add(aeh); 68 69 VarHandleSource bbh = new VarHandleSource( 70 MethodHandles.byteBufferViewVarHandle($type$[].class, bo), 71 endianess, MemoryMode.READ_WRITE); 72 vhss.add(bbh); 73 } 74 } 75 76 77 @Test(dataProvider = "varHandlesProvider") 78 public void testIsAccessModeSupported(VarHandleSource vhs) { 79 VarHandle vh = vhs.s; 80 81 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); 82 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); 83 84 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); 85 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); 86 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); 87 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); 88 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); 89 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); 90 91#if[CAS] 92 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 93 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 94 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 95 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 96 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 97 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE)); 98 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 99 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 100 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 101#else[CAS] 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#end[CAS] 112 113#if[AtomicAdd] 114 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 115 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 116#else[AtomicAdd] 117 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 118 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 119#end[AtomicAdd] 120 } 121 122 @Test(dataProvider = "typesProvider") 123 public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) { 124 assertEquals(vh.varType(), $type$.class); 125 126 assertEquals(vh.coordinateTypes(), pts); 127 128 testTypes(vh); 129 } 130 131 132 @DataProvider 133 public Object[][] accessTestCaseProvider() throws Exception { 134 List<AccessTestCase<?>> cases = new ArrayList<>(); 135 136 for (ByteArrayViewSource<?> bav : bavss) { 137 for (VarHandleSource vh : vhss) { 138 if (vh.matches(bav)) { 139 if (bav instanceof ByteArraySource) { 140 ByteArraySource bas = (ByteArraySource) bav; 141 142 cases.add(new VarHandleSourceAccessTestCase( 143 "read write", bav, vh, h -> testArrayReadWrite(bas, h), 144 true)); 145 cases.add(new VarHandleSourceAccessTestCase( 146 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), 147 false)); 148 cases.add(new VarHandleSourceAccessTestCase( 149 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), 150 false)); 151 cases.add(new VarHandleSourceAccessTestCase( 152 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), 153 false)); 154 } 155 else { 156 ByteBufferSource bbs = (ByteBufferSource) bav; 157 158 if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { 159 cases.add(new VarHandleSourceAccessTestCase( 160 "read write", bav, vh, h -> testArrayReadWrite(bbs, h), 161 true)); 162 } 163 else { 164 cases.add(new VarHandleSourceAccessTestCase( 165 "read only", bav, vh, h -> testArrayReadOnly(bbs, h), 166 true)); 167 } 168 169 cases.add(new VarHandleSourceAccessTestCase( 170 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), 171 false)); 172 cases.add(new VarHandleSourceAccessTestCase( 173 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), 174 false)); 175 cases.add(new VarHandleSourceAccessTestCase( 176 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), 177 false)); 178 } 179 } 180 } 181 } 182 183 // Work around issue with jtreg summary reporting which truncates 184 // the String result of Object.toString to 30 characters, hence 185 // the first dummy argument 186 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); 187 } 188 189 @Test(dataProvider = "accessTestCaseProvider") 190 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable { 191 T t = atc.get(); 192 int iters = atc.requiresLoop() ? ITERS : 1; 193 for (int c = 0; c < iters; c++) { 194 atc.testAccess(t); 195 } 196 } 197 198 199 static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { 200 VarHandle vh = vhs.s; 201 byte[] array = bs.s; 202 int ci = 1; 203 204#if[!CAS] 205 checkUOE(() -> { 206 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 207 }); 208 209 checkUOE(() -> { 210 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 211 }); 212 213 checkUOE(() -> { 214 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 215 }); 216 217 checkUOE(() -> { 218 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 219 }); 220 221 checkUOE(() -> { 222 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 223 }); 224 225 checkUOE(() -> { 226 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 227 }); 228 229 checkUOE(() -> { 230 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 231 }); 232 233 checkUOE(() -> { 234 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 235 }); 236 237 checkUOE(() -> { 238 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 239 }); 240#end[CAS] 241 242#if[!AtomicAdd] 243 checkUOE(() -> { 244 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 245 }); 246 247 checkUOE(() -> { 248 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 249 }); 250#end[AtomicAdd] 251 } 252 253 static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { 254 VarHandle vh = vhs.s; 255 ByteBuffer array = bs.s; 256 int ci = 0; 257 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 258 259 if (readOnly) { 260 checkROBE(() -> { 261 vh.set(array, ci, VALUE_1); 262 }); 263 } 264 265 if (readOnly) { 266 checkROBE(() -> { 267 vh.setVolatile(array, ci, VALUE_1); 268 }); 269 270 checkROBE(() -> { 271 vh.setRelease(array, ci, VALUE_1); 272 }); 273 274 checkROBE(() -> { 275 vh.setOpaque(array, ci, VALUE_1); 276 }); 277#if[CAS] 278 279 checkROBE(() -> { 280 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 281 }); 282 283 checkROBE(() -> { 284 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 285 }); 286 287 checkROBE(() -> { 288 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 289 }); 290 291 checkROBE(() -> { 292 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 293 }); 294 295 checkROBE(() -> { 296 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 297 }); 298 299 checkROBE(() -> { 300 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 301 }); 302 303 checkROBE(() -> { 304 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 305 }); 306 307 checkROBE(() -> { 308 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 309 }); 310 311 checkROBE(() -> { 312 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 313 }); 314 315#else[CAS] 316 checkUOE(() -> { 317 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 318 }); 319 320 checkUOE(() -> { 321 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 322 }); 323 324 checkUOE(() -> { 325 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 326 }); 327 328 checkUOE(() -> { 329 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 330 }); 331 332 checkUOE(() -> { 333 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 334 }); 335 336 checkUOE(() -> { 337 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 338 }); 339 340 checkUOE(() -> { 341 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 342 }); 343 344 checkUOE(() -> { 345 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 346 }); 347 348 checkUOE(() -> { 349 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 350 }); 351#end[CAS] 352 353#if[AtomicAdd] 354 checkROBE(() -> { 355 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 356 }); 357 358 checkROBE(() -> { 359 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 360 }); 361#else[AtomicAdd] 362 checkUOE(() -> { 363 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 364 }); 365 366 checkUOE(() -> { 367 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 368 }); 369#end[AtomicAdd] 370 } 371 else { 372#if[!CAS] 373 checkUOE(() -> { 374 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 375 }); 376 377 checkUOE(() -> { 378 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 379 }); 380 381 checkUOE(() -> { 382 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 383 }); 384 385 checkUOE(() -> { 386 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 387 }); 388 389 checkUOE(() -> { 390 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 391 }); 392 393 checkUOE(() -> { 394 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 395 }); 396 397 checkUOE(() -> { 398 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 399 }); 400 401 checkUOE(() -> { 402 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 403 }); 404 405 checkUOE(() -> { 406 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 407 }); 408#end[CAS] 409#if[!AtomicAdd] 410 checkUOE(() -> { 411 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 412 }); 413 414 checkUOE(() -> { 415 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 416 }); 417#end[AtomicAdd] 418 } 419 } 420 421 422 static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { 423 VarHandle vh = vhs.s; 424 byte[] array = bs.s; 425 426 int length = array.length - SIZE + 1; 427 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { 428 final int ci = i; 429 430 checkIOOBE(() -> { 431 $type$ x = ($type$) vh.get(array, ci); 432 }); 433 434 checkIOOBE(() -> { 435 vh.set(array, ci, VALUE_1); 436 }); 437 438 checkIOOBE(() -> { 439 $type$ x = ($type$) vh.getVolatile(array, ci); 440 }); 441 442 checkIOOBE(() -> { 443 $type$ x = ($type$) vh.getAcquire(array, ci); 444 }); 445 446 checkIOOBE(() -> { 447 $type$ x = ($type$) vh.getOpaque(array, ci); 448 }); 449 450 checkIOOBE(() -> { 451 vh.setVolatile(array, ci, VALUE_1); 452 }); 453 454 checkIOOBE(() -> { 455 vh.setRelease(array, ci, VALUE_1); 456 }); 457 458 checkIOOBE(() -> { 459 vh.setOpaque(array, ci, VALUE_1); 460 }); 461#if[CAS] 462 463 checkIOOBE(() -> { 464 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 465 }); 466 467 checkIOOBE(() -> { 468 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 469 }); 470 471 checkIOOBE(() -> { 472 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 473 }); 474 475 checkIOOBE(() -> { 476 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 477 }); 478 479 checkIOOBE(() -> { 480 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 481 }); 482 483 checkIOOBE(() -> { 484 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 485 }); 486 487 checkIOOBE(() -> { 488 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 489 }); 490 491 checkIOOBE(() -> { 492 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 493 }); 494 495 checkIOOBE(() -> { 496 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 497 }); 498#end[CAS] 499 500#if[AtomicAdd] 501 checkIOOBE(() -> { 502 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 503 }); 504 505 checkIOOBE(() -> { 506 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 507 }); 508#end[AtomicAdd] 509 510 } 511 } 512 513 static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { 514 VarHandle vh = vhs.s; 515 ByteBuffer array = bs.s; 516 517 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 518 519 int length = array.limit() - SIZE + 1; 520 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { 521 final int ci = i; 522 523 checkIOOBE(() -> { 524 $type$ x = ($type$) vh.get(array, ci); 525 }); 526 527 if (!readOnly) { 528 checkIOOBE(() -> { 529 vh.set(array, ci, VALUE_1); 530 }); 531 } 532 533 checkIOOBE(() -> { 534 $type$ x = ($type$) vh.getVolatile(array, ci); 535 }); 536 537 checkIOOBE(() -> { 538 $type$ x = ($type$) vh.getAcquire(array, ci); 539 }); 540 541 checkIOOBE(() -> { 542 $type$ x = ($type$) vh.getOpaque(array, ci); 543 }); 544 545 if (!readOnly) { 546 checkIOOBE(() -> { 547 vh.setVolatile(array, ci, VALUE_1); 548 }); 549 550 checkIOOBE(() -> { 551 vh.setRelease(array, ci, VALUE_1); 552 }); 553 554 checkIOOBE(() -> { 555 vh.setOpaque(array, ci, VALUE_1); 556 }); 557 558#if[CAS] 559 checkIOOBE(() -> { 560 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 561 }); 562 563 checkIOOBE(() -> { 564 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 565 }); 566 567 checkIOOBE(() -> { 568 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 569 }); 570 571 checkIOOBE(() -> { 572 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 573 }); 574 575 checkIOOBE(() -> { 576 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 577 }); 578 579 checkIOOBE(() -> { 580 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 581 }); 582 583 checkIOOBE(() -> { 584 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 585 }); 586 587 checkIOOBE(() -> { 588 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 589 }); 590 591 checkIOOBE(() -> { 592 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 593 }); 594#end[CAS] 595 596#if[AtomicAdd] 597 checkIOOBE(() -> { 598 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 599 }); 600 601 checkIOOBE(() -> { 602 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 603 }); 604#end[AtomicAdd] 605 } 606 } 607 } 608 609 static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { 610 VarHandle vh = vhs.s; 611 byte[] array = bs.s; 612 613 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); 614 615 int length = array.length - SIZE + 1; 616 for (int i = 0; i < length; i++) { 617 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 618 final int ci = i; 619 620 if (!iAligned) { 621 checkISE(() -> { 622 $type$ x = ($type$) vh.getVolatile(array, ci); 623 }); 624 625 checkISE(() -> { 626 $type$ x = ($type$) vh.getAcquire(array, ci); 627 }); 628 629 checkISE(() -> { 630 $type$ x = ($type$) vh.getOpaque(array, ci); 631 }); 632 633 checkISE(() -> { 634 vh.setVolatile(array, ci, VALUE_1); 635 }); 636 637 checkISE(() -> { 638 vh.setRelease(array, ci, VALUE_1); 639 }); 640 641 checkISE(() -> { 642 vh.setOpaque(array, ci, VALUE_1); 643 }); 644#if[CAS] 645 646 checkISE(() -> { 647 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 648 }); 649 650 checkISE(() -> { 651 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 652 }); 653 654 checkISE(() -> { 655 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 656 }); 657 658 checkISE(() -> { 659 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 660 }); 661 662 checkISE(() -> { 663 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 664 }); 665 666 checkISE(() -> { 667 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 668 }); 669 670 checkISE(() -> { 671 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 672 }); 673 674 checkISE(() -> { 675 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 676 }); 677 678 checkISE(() -> { 679 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 680 }); 681#end[CAS] 682 683#if[AtomicAdd] 684 checkISE(() -> { 685 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 686 }); 687 688 checkISE(() -> { 689 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 690 }); 691#end[AtomicAdd] 692 693 } 694 } 695 } 696 697 static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { 698 VarHandle vh = vhs.s; 699 ByteBuffer array = bs.s; 700 701 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 702 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 703 704 int length = array.limit() - SIZE + 1; 705 for (int i = 0; i < length; i++) { 706 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 707 final int ci = i; 708 709 if (!iAligned) { 710 checkISE(() -> { 711 $type$ x = ($type$) vh.getVolatile(array, ci); 712 }); 713 714 checkISE(() -> { 715 $type$ x = ($type$) vh.getAcquire(array, ci); 716 }); 717 718 checkISE(() -> { 719 $type$ x = ($type$) vh.getOpaque(array, ci); 720 }); 721 722 if (!readOnly) { 723 checkISE(() -> { 724 vh.setVolatile(array, ci, VALUE_1); 725 }); 726 727 checkISE(() -> { 728 vh.setRelease(array, ci, VALUE_1); 729 }); 730 731 checkISE(() -> { 732 vh.setOpaque(array, ci, VALUE_1); 733 }); 734 735#if[CAS] 736 checkISE(() -> { 737 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 738 }); 739 740 checkISE(() -> { 741 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 742 }); 743 744 checkISE(() -> { 745 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 746 }); 747 748 checkISE(() -> { 749 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 750 }); 751 752 checkISE(() -> { 753 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 754 }); 755 756 checkISE(() -> { 757 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2); 758 }); 759 760 checkISE(() -> { 761 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 762 }); 763 764 checkISE(() -> { 765 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 766 }); 767 768 checkISE(() -> { 769 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 770 }); 771#end[CAS] 772 773#if[AtomicAdd] 774 checkISE(() -> { 775 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 776 }); 777 778 checkISE(() -> { 779 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 780 }); 781#end[AtomicAdd] 782 } 783 } 784 } 785 } 786 787 static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { 788 VarHandle vh = vhs.s; 789 byte[] array = bs.s; 790 791 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); 792 793 bs.fill((byte) 0xff); 794 int length = array.length - SIZE + 1; 795 for (int i = 0; i < length; i++) { 796 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 797 798 // Plain 799 { 800 vh.set(array, i, VALUE_1); 801 $type$ x = ($type$) vh.get(array, i); 802 assertEquals(x, VALUE_1, "get $type$ value"); 803 } 804 805 806 if (iAligned) { 807 // Volatile 808 { 809 vh.setVolatile(array, i, VALUE_2); 810 $type$ x = ($type$) vh.getVolatile(array, i); 811 assertEquals(x, VALUE_2, "setVolatile $type$ value"); 812 } 813 814 // Lazy 815 { 816 vh.setRelease(array, i, VALUE_1); 817 $type$ x = ($type$) vh.getAcquire(array, i); 818 assertEquals(x, VALUE_1, "setRelease $type$ value"); 819 } 820 821 // Opaque 822 { 823 vh.setOpaque(array, i, VALUE_2); 824 $type$ x = ($type$) vh.getOpaque(array, i); 825 assertEquals(x, VALUE_2, "setOpaque $type$ value"); 826 } 827#if[CAS] 828 829 vh.set(array, i, VALUE_1); 830 831 // Compare 832 { 833 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 834 assertEquals(r, true, "success compareAndSet $type$"); 835 $type$ x = ($type$) vh.get(array, i); 836 assertEquals(x, VALUE_2, "success compareAndSet $type$ value"); 837 } 838 839 { 840 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 841 assertEquals(r, false, "failing compareAndSet $type$"); 842 $type$ x = ($type$) vh.get(array, i); 843 assertEquals(x, VALUE_2, "failing compareAndSet $type$ value"); 844 } 845 846 { 847 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 848 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); 849 $type$ x = ($type$) vh.get(array, i); 850 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); 851 } 852 853 { 854 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 855 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); 856 $type$ x = ($type$) vh.get(array, i); 857 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value"); 858 } 859 860 { 861 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 862 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$"); 863 $type$ x = ($type$) vh.get(array, i); 864 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value"); 865 } 866 867 { 868 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 869 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$"); 870 $type$ x = ($type$) vh.get(array, i); 871 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value"); 872 } 873 874 { 875 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 876 assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$"); 877 $type$ x = ($type$) vh.get(array, i); 878 assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value"); 879 } 880 881 { 882 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 883 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$"); 884 $type$ x = ($type$) vh.get(array, i); 885 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value"); 886 } 887 888 { 889 boolean success = false; 890 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 891 success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 892 } 893 assertEquals(success, true, "weakCompareAndSet $type$"); 894 $type$ x = ($type$) vh.get(array, i); 895 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 896 } 897 898 { 899 boolean success = false; 900 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 901 success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 902 } 903 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 904 $type$ x = ($type$) vh.get(array, i); 905 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 906 } 907 908 { 909 boolean success = false; 910 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 911 success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 912 } 913 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 914 $type$ x = ($type$) vh.get(array, i); 915 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 916 } 917 918 { 919 boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1); 920 assertEquals(r, true, "weakCompareAndSetVolatile $type$"); 921 $type$ x = ($type$) vh.get(array, i); 922 assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value"); 923 } 924 925 // Compare set and get 926 { 927 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2); 928 assertEquals(o, VALUE_1, "getAndSet $type$"); 929 $type$ x = ($type$) vh.get(array, i); 930 assertEquals(x, VALUE_2, "getAndSet $type$ value"); 931 } 932#end[CAS] 933 934#if[AtomicAdd] 935 vh.set(array, i, VALUE_1); 936 937 // get and add, add and get 938 { 939 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 940 assertEquals(o, VALUE_1, "getAndAdd $type$"); 941 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 942 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 943 } 944#end[AtomicAdd] 945 } 946 } 947 } 948 949 950 static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { 951 VarHandle vh = vhs.s; 952 ByteBuffer array = bs.s; 953 954 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 955 956 bs.fill((byte) 0xff); 957 int length = array.limit() - SIZE + 1; 958 for (int i = 0; i < length; i++) { 959 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 960 961 // Plain 962 { 963 vh.set(array, i, VALUE_1); 964 $type$ x = ($type$) vh.get(array, i); 965 assertEquals(x, VALUE_1, "get $type$ value"); 966 } 967 968 if (iAligned) { 969 // Volatile 970 { 971 vh.setVolatile(array, i, VALUE_2); 972 $type$ x = ($type$) vh.getVolatile(array, i); 973 assertEquals(x, VALUE_2, "setVolatile $type$ value"); 974 } 975 976 // Lazy 977 { 978 vh.setRelease(array, i, VALUE_1); 979 $type$ x = ($type$) vh.getAcquire(array, i); 980 assertEquals(x, VALUE_1, "setRelease $type$ value"); 981 } 982 983 // Opaque 984 { 985 vh.setOpaque(array, i, VALUE_2); 986 $type$ x = ($type$) vh.getOpaque(array, i); 987 assertEquals(x, VALUE_2, "setOpaque $type$ value"); 988 } 989#if[CAS] 990 991 vh.set(array, i, VALUE_1); 992 993 // Compare 994 { 995 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 996 assertEquals(r, true, "success compareAndSet $type$"); 997 $type$ x = ($type$) vh.get(array, i); 998 assertEquals(x, VALUE_2, "success compareAndSet $type$ value"); 999 } 1000 1001 { 1002 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 1003 assertEquals(r, false, "failing compareAndSet $type$"); 1004 $type$ x = ($type$) vh.get(array, i); 1005 assertEquals(x, VALUE_2, "failing compareAndSet $type$ value"); 1006 } 1007 1008 { 1009 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 1010 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); 1011 $type$ x = ($type$) vh.get(array, i); 1012 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); 1013 } 1014 1015 { 1016 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 1017 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); 1018 $type$ x = ($type$) vh.get(array, i); 1019 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value"); 1020 } 1021 1022 { 1023 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 1024 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$"); 1025 $type$ x = ($type$) vh.get(array, i); 1026 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value"); 1027 } 1028 1029 { 1030 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 1031 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$"); 1032 $type$ x = ($type$) vh.get(array, i); 1033 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value"); 1034 } 1035 1036 { 1037 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 1038 assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$"); 1039 $type$ x = ($type$) vh.get(array, i); 1040 assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value"); 1041 } 1042 1043 { 1044 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 1045 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$"); 1046 $type$ x = ($type$) vh.get(array, i); 1047 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value"); 1048 } 1049 1050 { 1051 boolean success = false; 1052 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1053 success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 1054 } 1055 assertEquals(success, true, "weakCompareAndSet $type$"); 1056 $type$ x = ($type$) vh.get(array, i); 1057 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 1058 } 1059 1060 { 1061 boolean success = false; 1062 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1063 success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 1064 } 1065 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 1066 $type$ x = ($type$) vh.get(array, i); 1067 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 1068 } 1069 1070 { 1071 boolean success = false; 1072 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1073 success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 1074 } 1075 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 1076 $type$ x = ($type$) vh.get(array, i); 1077 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 1078 } 1079 1080 { 1081 boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1); 1082 assertEquals(r, true, "weakCompareAndSetVolatile $type$"); 1083 $type$ x = ($type$) vh.get(array, i); 1084 assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value"); 1085 } 1086 1087 // Compare set and get 1088 { 1089 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2); 1090 assertEquals(o, VALUE_1, "getAndSet $type$"); 1091 $type$ x = ($type$) vh.get(array, i); 1092 assertEquals(x, VALUE_2, "getAndSet $type$ value"); 1093 } 1094#end[CAS] 1095 1096#if[AtomicAdd] 1097 vh.set(array, i, VALUE_1); 1098 1099 // get and add, add and get 1100 { 1101 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 1102 assertEquals(o, VALUE_1, "getAndAdd $type$"); 1103 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 1104 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 1105 } 1106#end[AtomicAdd] 1107 } 1108 } 1109 } 1110 1111 static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { 1112 VarHandle vh = vhs.s; 1113 ByteBuffer array = bs.s; 1114 1115 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 1116 1117 ByteBuffer bb = ByteBuffer.allocate(SIZE); 1118 bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); 1119 bs.fill(bb.put$Type$(0, VALUE_2).array()); 1120 1121 int length = array.limit() - SIZE + 1; 1122 for (int i = 0; i < length; i++) { 1123 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 1124 1125 $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) 1126 ? rotateLeft(VALUE_2, (i % SIZE) << 3) 1127 : rotateRight(VALUE_2, (i % SIZE) << 3); 1128 // Plain 1129 { 1130 $type$ x = ($type$) vh.get(array, i); 1131 assertEquals(x, v, "get $type$ value"); 1132 } 1133 1134 if (iAligned) { 1135 // Volatile 1136 { 1137 $type$ x = ($type$) vh.getVolatile(array, i); 1138 assertEquals(x, v, "getVolatile $type$ value"); 1139 } 1140 1141 // Lazy 1142 { 1143 $type$ x = ($type$) vh.getAcquire(array, i); 1144 assertEquals(x, v, "getRelease $type$ value"); 1145 } 1146 1147 // Opaque 1148 { 1149 $type$ x = ($type$) vh.getOpaque(array, i); 1150 assertEquals(x, v, "getOpaque $type$ value"); 1151 } 1152 } 1153 } 1154 } 1155 1156} 1157 1158