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 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat 27 * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsFloat 28 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat 29 */ 30 31 import org.testng.annotations.DataProvider; 32 import org.testng.annotations.Test; 33 34 import java.lang.invoke.MethodHandles; 35 import java.lang.invoke.VarHandle; 36 import java.nio.ByteBuffer; 37 import java.nio.ByteOrder; 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.EnumSet; 41 import java.util.List; 42 43 import static org.testng.Assert.*; 44 45 public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { 46 static final int SIZE = Float.BYTES; 47 48 static final float VALUE_1 = 0x01020304; 49 50 static final float VALUE_2 = 0x11121314; 51 52 static final float VALUE_3 = 0x21222324; 53 54 55 @Override 56 public void setupVarHandleSources() { 57 // Combinations of VarHandle byte[] or ByteBuffer 58 vhss = new ArrayList<>(); 59 for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { 60 VarHandleSource aeh = new VarHandleSource( 61 MethodHandles.byteArrayViewVarHandle(float[].class, 62 endianess == MemoryMode.BIG_ENDIAN), 63 endianess, MemoryMode.READ_WRITE); 64 vhss.add(aeh); 65 66 VarHandleSource bbh = new VarHandleSource( 67 MethodHandles.byteBufferViewVarHandle(float[].class, 68 endianess == MemoryMode.BIG_ENDIAN), 69 endianess, MemoryMode.READ_WRITE); 70 vhss.add(bbh); 71 } 72 } 73 74 75 @Test(dataProvider = "varHandlesProvider") 76 public void testIsAccessModeSupported(VarHandleSource vhs) { 77 VarHandle vh = vhs.s; 78 79 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); 80 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); 81 82 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); 83 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); 84 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); 85 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); 86 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); 87 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); 88 89 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 90 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 91 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 92 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 93 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 94 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 95 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 96 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 97 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 98 99 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 100 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 101 } 102 103 @Test(dataProvider = "typesProvider") 104 public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) { 105 assertEquals(vh.varType(), float.class); 106 107 assertEquals(vh.coordinateTypes(), pts); 108 109 testTypes(vh); 110 } 111 112 113 @DataProvider 114 public Object[][] accessTestCaseProvider() throws Exception { 115 List<AccessTestCase<?>> cases = new ArrayList<>(); 116 117 for (ByteArrayViewSource<?> bav : bavss) { 118 for (VarHandleSource vh : vhss) { 119 if (vh.matches(bav)) { 120 if (bav instanceof ByteArraySource) { 121 ByteArraySource bas = (ByteArraySource) bav; 122 123 cases.add(new VarHandleSourceAccessTestCase( 124 "read write", bav, vh, h -> testArrayReadWrite(bas, h), 125 true)); 126 cases.add(new VarHandleSourceAccessTestCase( 127 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), 128 false)); 129 cases.add(new VarHandleSourceAccessTestCase( 130 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), 131 false)); 132 cases.add(new VarHandleSourceAccessTestCase( 133 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), 134 false)); 135 } 136 else { 137 ByteBufferSource bbs = (ByteBufferSource) bav; 138 139 if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { 140 cases.add(new VarHandleSourceAccessTestCase( 141 "read write", bav, vh, h -> testArrayReadWrite(bbs, h), 142 true)); 143 } 144 else { 145 cases.add(new VarHandleSourceAccessTestCase( 146 "read only", bav, vh, h -> testArrayReadOnly(bbs, h), 147 true)); 148 } 149 150 cases.add(new VarHandleSourceAccessTestCase( 151 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), 152 false)); 153 cases.add(new VarHandleSourceAccessTestCase( 154 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), 155 false)); 156 cases.add(new VarHandleSourceAccessTestCase( 157 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), 158 false)); 159 } 160 } 161 } 162 } 163 164 // Work around issue with jtreg summary reporting which truncates 165 // the String result of Object.toString to 30 characters, hence 166 // the first dummy argument 167 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); 168 } 169 170 @Test(dataProvider = "accessTestCaseProvider") 171 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable { 172 T t = atc.get(); 173 int iters = atc.requiresLoop() ? ITERS : 1; 174 for (int c = 0; c < iters; c++) { 175 atc.testAccess(t); 176 } 177 } 178 179 180 static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { 181 VarHandle vh = vhs.s; 182 byte[] array = bs.s; 183 int ci = 1; 184 185 186 checkUOE(() -> { 187 float o = (float) vh.getAndAdd(array, ci, VALUE_1); 188 }); 189 190 checkUOE(() -> { 191 float o = (float) vh.addAndGet(array, ci, VALUE_1); 192 }); 193 } 194 195 static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { 196 VarHandle vh = vhs.s; 197 ByteBuffer array = bs.s; 198 int ci = 0; 199 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 200 201 if (readOnly) { 202 checkROBE(() -> { 203 vh.set(array, ci, VALUE_1); 204 }); 205 } 206 207 if (readOnly) { 208 checkROBE(() -> { 209 vh.setVolatile(array, ci, VALUE_1); 210 }); 211 212 checkROBE(() -> { 213 vh.setRelease(array, ci, VALUE_1); 214 }); 215 216 checkROBE(() -> { 217 vh.setOpaque(array, ci, VALUE_1); 218 }); 219 220 checkROBE(() -> { 221 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 222 }); 223 224 checkROBE(() -> { 225 float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 226 }); 227 228 checkROBE(() -> { 229 float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 230 }); 231 232 checkROBE(() -> { 233 float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 234 }); 235 236 checkROBE(() -> { 237 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 238 }); 239 240 checkROBE(() -> { 241 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 242 }); 243 244 checkROBE(() -> { 245 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 246 }); 247 248 checkROBE(() -> { 249 float o = (float) vh.getAndSet(array, ci, VALUE_1); 250 }); 251 checkUOE(() -> { 252 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 253 }); 254 255 checkUOE(() -> { 256 float o = (float) vh.getAndAdd(array, ci, VALUE_1); 257 }); 258 259 checkUOE(() -> { 260 float o = (float) vh.addAndGet(array, ci, VALUE_1); 261 }); 262 } 263 else { 264 checkUOE(() -> { 265 float o = (float) vh.getAndAdd(array, ci, VALUE_1); 266 }); 267 268 checkUOE(() -> { 269 float o = (float) vh.addAndGet(array, ci, VALUE_1); 270 }); 271 } 272 } 273 274 275 static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { 276 VarHandle vh = vhs.s; 277 byte[] array = bs.s; 278 279 int length = array.length - SIZE + 1; 280 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { 281 final int ci = i; 282 283 checkIOOBE(() -> { 284 float x = (float) vh.get(array, ci); 285 }); 286 287 checkIOOBE(() -> { 288 vh.set(array, ci, VALUE_1); 289 }); 290 291 checkIOOBE(() -> { 292 float x = (float) vh.getVolatile(array, ci); 293 }); 294 295 checkIOOBE(() -> { 296 float x = (float) vh.getAcquire(array, ci); 297 }); 298 299 checkIOOBE(() -> { 300 float x = (float) vh.getOpaque(array, ci); 301 }); 302 303 checkIOOBE(() -> { 304 vh.setVolatile(array, ci, VALUE_1); 305 }); 306 307 checkIOOBE(() -> { 308 vh.setRelease(array, ci, VALUE_1); 309 }); 310 311 checkIOOBE(() -> { 312 vh.setOpaque(array, ci, VALUE_1); 313 }); 314 315 checkIOOBE(() -> { 316 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 317 }); 318 319 checkIOOBE(() -> { 320 float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 321 }); 322 323 checkIOOBE(() -> { 324 float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 325 }); 326 327 checkIOOBE(() -> { 328 float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 329 }); 330 331 checkIOOBE(() -> { 332 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 333 }); 334 335 checkIOOBE(() -> { 336 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 337 }); 338 339 checkIOOBE(() -> { 340 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 341 }); 342 343 checkIOOBE(() -> { 344 float o = (float) vh.getAndSet(array, ci, VALUE_1); 345 }); 346 347 348 } 349 } 350 351 static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { 352 VarHandle vh = vhs.s; 353 ByteBuffer array = bs.s; 354 355 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 356 357 int length = array.limit() - SIZE + 1; 358 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { 359 final int ci = i; 360 361 checkIOOBE(() -> { 362 float x = (float) vh.get(array, ci); 363 }); 364 365 if (!readOnly) { 366 checkIOOBE(() -> { 367 vh.set(array, ci, VALUE_1); 368 }); 369 } 370 371 checkIOOBE(() -> { 372 float x = (float) vh.getVolatile(array, ci); 373 }); 374 375 checkIOOBE(() -> { 376 float x = (float) vh.getAcquire(array, ci); 377 }); 378 379 checkIOOBE(() -> { 380 float x = (float) vh.getOpaque(array, ci); 381 }); 382 383 if (!readOnly) { 384 checkIOOBE(() -> { 385 vh.setVolatile(array, ci, VALUE_1); 386 }); 387 388 checkIOOBE(() -> { 389 vh.setRelease(array, ci, VALUE_1); 390 }); 391 392 checkIOOBE(() -> { 393 vh.setOpaque(array, ci, VALUE_1); 394 }); 395 396 checkIOOBE(() -> { 397 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 398 }); 399 400 checkIOOBE(() -> { 401 float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 402 }); 403 404 checkIOOBE(() -> { 405 float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 406 }); 407 408 checkIOOBE(() -> { 409 float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 410 }); 411 412 checkIOOBE(() -> { 413 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 414 }); 415 416 checkIOOBE(() -> { 417 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 418 }); 419 420 checkIOOBE(() -> { 421 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 422 }); 423 424 checkIOOBE(() -> { 425 float o = (float) vh.getAndSet(array, ci, VALUE_1); 426 }); 427 428 } 429 } 430 } 431 432 static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { 433 VarHandle vh = vhs.s; 434 byte[] array = bs.s; 435 436 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); 437 438 int length = array.length - SIZE + 1; 439 for (int i = 0; i < length; i++) { 440 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 441 final int ci = i; 442 443 if (!iAligned) { 444 checkISE(() -> { 445 float x = (float) vh.getVolatile(array, ci); 446 }); 447 448 checkISE(() -> { 449 float x = (float) vh.getAcquire(array, ci); 450 }); 451 452 checkISE(() -> { 453 float x = (float) vh.getOpaque(array, ci); 454 }); 455 456 checkISE(() -> { 457 vh.setVolatile(array, ci, VALUE_1); 458 }); 459 460 checkISE(() -> { 461 vh.setRelease(array, ci, VALUE_1); 462 }); 463 464 checkISE(() -> { 465 vh.setOpaque(array, ci, VALUE_1); 466 }); 467 468 checkISE(() -> { 469 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 470 }); 471 472 checkISE(() -> { 473 float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 474 }); 475 476 checkISE(() -> { 477 float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 478 }); 479 480 checkISE(() -> { 481 float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 482 }); 483 484 checkISE(() -> { 485 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 486 }); 487 488 checkISE(() -> { 489 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 490 }); 491 492 checkISE(() -> { 493 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 494 }); 495 496 checkISE(() -> { 497 float o = (float) vh.getAndSet(array, ci, VALUE_1); 498 }); 499 500 501 } 502 } 503 } 504 505 static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { 506 VarHandle vh = vhs.s; 507 ByteBuffer array = bs.s; 508 509 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 510 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 511 512 int length = array.limit() - SIZE + 1; 513 for (int i = 0; i < length; i++) { 514 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 515 final int ci = i; 516 517 if (!iAligned) { 518 checkISE(() -> { 519 float x = (float) vh.getVolatile(array, ci); 520 }); 521 522 checkISE(() -> { 523 float x = (float) vh.getAcquire(array, ci); 524 }); 525 526 checkISE(() -> { 527 float x = (float) vh.getOpaque(array, ci); 528 }); 529 530 if (!readOnly) { 531 checkISE(() -> { 532 vh.setVolatile(array, ci, VALUE_1); 533 }); 534 535 checkISE(() -> { 536 vh.setRelease(array, ci, VALUE_1); 537 }); 538 539 checkISE(() -> { 540 vh.setOpaque(array, ci, VALUE_1); 541 }); 542 543 checkISE(() -> { 544 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 545 }); 546 547 checkISE(() -> { 548 float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 549 }); 550 551 checkISE(() -> { 552 float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 553 }); 554 555 checkISE(() -> { 556 float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 557 }); 558 559 checkISE(() -> { 560 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 561 }); 562 563 checkISE(() -> { 564 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 565 }); 566 567 checkISE(() -> { 568 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 569 }); 570 571 checkISE(() -> { 572 float o = (float) vh.getAndSet(array, ci, VALUE_1); 573 }); 574 575 } 576 } 577 } 578 } 579 580 static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { 581 VarHandle vh = vhs.s; 582 byte[] array = bs.s; 583 584 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); 585 586 bs.fill((byte) 0xff); 587 int length = array.length - SIZE + 1; 588 for (int i = 0; i < length; i++) { 589 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 590 591 // Plain 592 { 593 vh.set(array, i, VALUE_1); 594 float x = (float) vh.get(array, i); 595 assertEquals(x, VALUE_1, "get float value"); 596 } 597 598 599 if (iAligned) { 600 // Volatile 601 { 602 vh.setVolatile(array, i, VALUE_2); 603 float x = (float) vh.getVolatile(array, i); 604 assertEquals(x, VALUE_2, "setVolatile float value"); 605 } 606 607 // Lazy 608 { 609 vh.setRelease(array, i, VALUE_1); 610 float x = (float) vh.getAcquire(array, i); 611 assertEquals(x, VALUE_1, "setRelease float value"); 612 } 613 614 // Opaque 615 { 616 vh.setOpaque(array, i, VALUE_2); 617 float x = (float) vh.getOpaque(array, i); 618 assertEquals(x, VALUE_2, "setOpaque float value"); 619 } 620 621 vh.set(array, i, VALUE_1); 622 623 // Compare 624 { 625 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 626 assertEquals(r, true, "success compareAndSet float"); 627 float x = (float) vh.get(array, i); 628 assertEquals(x, VALUE_2, "success compareAndSet float value"); 629 } 630 631 { 632 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 633 assertEquals(r, false, "failing compareAndSet float"); 634 float x = (float) vh.get(array, i); 635 assertEquals(x, VALUE_2, "failing compareAndSet float value"); 636 } 637 638 { 639 float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 640 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float"); 641 float x = (float) vh.get(array, i); 642 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value"); 643 } 644 645 { 646 float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 647 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float"); 648 float x = (float) vh.get(array, i); 649 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile float value"); 650 } 651 652 { 653 float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 654 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float"); 655 float x = (float) vh.get(array, i); 656 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value"); 657 } 658 659 { 660 float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 661 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float"); 662 float x = (float) vh.get(array, i); 663 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value"); 664 } 665 666 { 667 float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 668 assertEquals(r, VALUE_2, "success compareAndExchangeRelease float"); 669 float x = (float) vh.get(array, i); 670 assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value"); 671 } 672 673 { 674 float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 675 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float"); 676 float x = (float) vh.get(array, i); 677 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value"); 678 } 679 680 { 681 boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 682 assertEquals(r, true, "weakCompareAndSet float"); 683 float x = (float) vh.get(array, i); 684 assertEquals(x, VALUE_2, "weakCompareAndSet float value"); 685 } 686 687 { 688 boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 689 assertEquals(r, true, "weakCompareAndSetAcquire float"); 690 float x = (float) vh.get(array, i); 691 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); 692 } 693 694 { 695 boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 696 assertEquals(r, true, "weakCompareAndSetRelease float"); 697 float x = (float) vh.get(array, i); 698 assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); 699 } 700 701 // Compare set and get 702 { 703 float o = (float) vh.getAndSet(array, i, VALUE_1); 704 assertEquals(o, VALUE_2, "getAndSet float"); 705 float x = (float) vh.get(array, i); 706 assertEquals(x, VALUE_1, "getAndSet float value"); 707 } 708 709 } 710 } 711 } 712 713 714 static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { 715 VarHandle vh = vhs.s; 716 ByteBuffer array = bs.s; 717 718 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 719 720 bs.fill((byte) 0xff); 721 int length = array.limit() - SIZE + 1; 722 for (int i = 0; i < length; i++) { 723 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 724 725 // Plain 726 { 727 vh.set(array, i, VALUE_1); 728 float x = (float) vh.get(array, i); 729 assertEquals(x, VALUE_1, "get float value"); 730 } 731 732 if (iAligned) { 733 // Volatile 734 { 735 vh.setVolatile(array, i, VALUE_2); 736 float x = (float) vh.getVolatile(array, i); 737 assertEquals(x, VALUE_2, "setVolatile float value"); 738 } 739 740 // Lazy 741 { 742 vh.setRelease(array, i, VALUE_1); 743 float x = (float) vh.getAcquire(array, i); 744 assertEquals(x, VALUE_1, "setRelease float value"); 745 } 746 747 // Opaque 748 { 749 vh.setOpaque(array, i, VALUE_2); 750 float x = (float) vh.getOpaque(array, i); 751 assertEquals(x, VALUE_2, "setOpaque float value"); 752 } 753 754 vh.set(array, i, VALUE_1); 755 756 // Compare 757 { 758 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 759 assertEquals(r, true, "success compareAndSet float"); 760 float x = (float) vh.get(array, i); 761 assertEquals(x, VALUE_2, "success compareAndSet float value"); 762 } 763 764 { 765 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 766 assertEquals(r, false, "failing compareAndSet float"); 767 float x = (float) vh.get(array, i); 768 assertEquals(x, VALUE_2, "failing compareAndSet float value"); 769 } 770 771 { 772 float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 773 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float"); 774 float x = (float) vh.get(array, i); 775 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value"); 776 } 777 778 { 779 float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 780 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float"); 781 float x = (float) vh.get(array, i); 782 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile float value"); 783 } 784 785 { 786 float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 787 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float"); 788 float x = (float) vh.get(array, i); 789 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value"); 790 } 791 792 { 793 float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 794 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float"); 795 float x = (float) vh.get(array, i); 796 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value"); 797 } 798 799 { 800 float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 801 assertEquals(r, VALUE_2, "success compareAndExchangeRelease float"); 802 float x = (float) vh.get(array, i); 803 assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value"); 804 } 805 806 { 807 float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 808 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float"); 809 float x = (float) vh.get(array, i); 810 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value"); 811 } 812 813 { 814 boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 815 assertEquals(r, true, "weakCompareAndSet float"); 816 float x = (float) vh.get(array, i); 817 assertEquals(x, VALUE_2, "weakCompareAndSet float value"); 818 } 819 820 { 821 boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 822 assertEquals(r, true, "weakCompareAndSetAcquire float"); 823 float x = (float) vh.get(array, i); 824 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); 825 } 826 827 { 828 boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 829 assertEquals(r, true, "weakCompareAndSetRelease float"); 830 float x = (float) vh.get(array, i); 831 assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); 832 } 833 834 // Compare set and get 835 { 836 float o = (float) vh.getAndSet(array, i, VALUE_1); 837 assertEquals(o, VALUE_2, "getAndSet float"); 838 float x = (float) vh.get(array, i); 839 assertEquals(x, VALUE_1, "getAndSet float value"); 840 } 841 842 } 843 } 844 } 845 846 static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { 847 VarHandle vh = vhs.s; 848 ByteBuffer array = bs.s; 849 850 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 851 852 ByteBuffer bb = ByteBuffer.allocate(SIZE); 853 bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); 854 bs.fill(bb.putFloat(0, VALUE_2).array()); 855 856 int length = array.limit() - SIZE + 1; 857 for (int i = 0; i < length; i++) { 858 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 859 860 float v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) 861 ? rotateLeft(VALUE_2, (i % SIZE) << 3) 862 : rotateRight(VALUE_2, (i % SIZE) << 3); 863 // Plain 864 { 865 float x = (float) vh.get(array, i); 866 assertEquals(x, v, "get float value"); 867 } 868 869 if (iAligned) { 870 // Volatile 871 { 872 float x = (float) vh.getVolatile(array, i); 873 assertEquals(x, v, "getVolatile float value"); 874 } 875 876 // Lazy 877 { 878 float x = (float) vh.getAcquire(array, i); 879 assertEquals(x, v, "getRelease float value"); 880 } 881 882 // Opaque 883 { 884 float x = (float) vh.getOpaque(array, i); 885 assertEquals(x, v, "getOpaque float value"); 886 } 887 } 888 } 889 } 890 891 } 892