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