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