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