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 VarHandleTestMethodHandleAccessDouble
  27  */
  28 
  29 import org.testng.annotations.BeforeClass;
  30 import org.testng.annotations.DataProvider;
  31 import org.testng.annotations.Test;
  32 
  33 import java.lang.invoke.MethodHandles;
  34 import java.lang.invoke.VarHandle;
  35 import java.util.ArrayList;
  36 import java.util.Arrays;
  37 import java.util.List;
  38 
  39 import static org.testng.Assert.*;
  40 
  41 public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest {
  42     static final double static_final_v = 1.0d;
  43 
  44     static double static_v;
  45 
  46     final double final_v = 1.0d;
  47 
  48     double v;
  49 
  50     VarHandle vhFinalField;
  51 
  52     VarHandle vhField;
  53 
  54     VarHandle vhStaticField;
  55 
  56     VarHandle vhStaticFinalField;
  57 
  58     VarHandle vhArray;
  59 
  60     @BeforeClass
  61     public void setup() throws Exception {
  62         vhFinalField = MethodHandles.lookup().findVarHandle(
  63                 VarHandleTestMethodHandleAccessDouble.class, "final_v", double.class);
  64 
  65         vhField = MethodHandles.lookup().findVarHandle(
  66                 VarHandleTestMethodHandleAccessDouble.class, "v", double.class);
  67 
  68         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
  69             VarHandleTestMethodHandleAccessDouble.class, "static_final_v", double.class);
  70 
  71         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
  72             VarHandleTestMethodHandleAccessDouble.class, "static_v", double.class);
  73 
  74         vhArray = MethodHandles.arrayElementVarHandle(double[].class);
  75     }
  76 
  77 
  78     @DataProvider
  79     public Object[][] accessTestCaseProvider() throws Exception {
  80         List<AccessTestCase<?>> cases = new ArrayList<>();
  81 
  82         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
  83             cases.add(new MethodHandleAccessTestCase("Instance field",
  84                                                      vhField, f, hs -> testInstanceField(this, hs)));
  85             cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
  86                                                      vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
  87                                                      false));
  88 
  89             cases.add(new MethodHandleAccessTestCase("Static field",
  90                                                      vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticField));
  91             cases.add(new MethodHandleAccessTestCase("Static field unsupported",
  92                                                      vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticFieldUnsupported,
  93                                                      false));
  94 
  95             cases.add(new MethodHandleAccessTestCase("Array",
  96                                                      vhArray, f, VarHandleTestMethodHandleAccessDouble::testArray));
  97             cases.add(new MethodHandleAccessTestCase("Array unsupported",
  98                                                      vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayUnsupported,
  99                                                      false));
 100             cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
 101                                                      vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayIndexOutOfBounds,
 102                                                      false));
 103         }
 104 
 105         // Work around issue with jtreg summary reporting which truncates
 106         // the String result of Object.toString to 30 characters, hence
 107         // the first dummy argument
 108         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 109     }
 110 
 111     @Test(dataProvider = "accessTestCaseProvider")
 112     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 113         T t = atc.get();
 114         int iters = atc.requiresLoop() ? ITERS : 1;
 115         for (int c = 0; c < iters; c++) {
 116             atc.testAccess(t);
 117         }
 118     }
 119 
 120 
 121     static void testInstanceField(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable {
 122         // Plain
 123         {
 124             hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d);
 125             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 126             assertEquals(x, 1.0d, "set double value");
 127         }
 128 
 129 
 130         // Volatile
 131         {
 132             hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, 2.0d);
 133             double x = (double) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv);
 134             assertEquals(x, 2.0d, "setVolatile double value");
 135         }
 136 
 137         // Lazy
 138         {
 139             hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, 1.0d);
 140             double x = (double) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv);
 141             assertEquals(x, 1.0d, "setRelease double value");
 142         }
 143 
 144         // Opaque
 145         {
 146             hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, 2.0d);
 147             double x = (double) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv);
 148             assertEquals(x, 2.0d, "setOpaque double value");
 149         }
 150 
 151         hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d);
 152 
 153         // Compare
 154         {
 155             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0d, 2.0d);
 156             assertEquals(r, true, "success compareAndSet double");
 157             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 158             assertEquals(x, 2.0d, "success compareAndSet double value");
 159         }
 160 
 161         {
 162             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, 1.0d, 3.0d);
 163             assertEquals(r, false, "failing compareAndSet double");
 164             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 165             assertEquals(x, 2.0d, "failing compareAndSet double value");
 166         }
 167 
 168         {
 169             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 2.0d, 1.0d);
 170             assertEquals(r, 2.0d, "success compareAndExchange double");
 171             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 172             assertEquals(x, 1.0d, "success compareAndExchange double value");
 173         }
 174 
 175         {
 176             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, 2.0d, 3.0d);
 177             assertEquals(r, 1.0d, "failing compareAndExchange double");
 178             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 179             assertEquals(x, 1.0d, "failing compareAndExchange double value");
 180         }
 181 
 182         {
 183             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0d, 2.0d);
 184             assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
 185             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 186             assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
 187         }
 188 
 189         {
 190             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, 1.0d, 3.0d);
 191             assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
 192             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 193             assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
 194         }
 195 
 196         {
 197             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0d, 1.0d);
 198             assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
 199             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 200             assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
 201         }
 202 
 203         {
 204             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, 2.0d, 3.0d);
 205             assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
 206             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 207             assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
 208         }
 209 
 210         {
 211             boolean success = false;
 212             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 213                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0d, 2.0d);
 214             }
 215             assertEquals(success, true, "weakCompareAndSetPlain double");
 216             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 217             assertEquals(x, 2.0d, "weakCompareAndSetPlain double value");
 218         }
 219 
 220         {
 221             boolean success = false;
 222             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 223                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0d, 1.0d);
 224             }
 225             assertEquals(success, true, "weakCompareAndSetAcquire double");
 226             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 227             assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
 228         }
 229 
 230         {
 231             boolean success = false;
 232             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 233                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0d, 2.0d);
 234             }
 235             assertEquals(success, true, "weakCompareAndSetRelease double");
 236             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 237             assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
 238         }
 239 
 240         {
 241             boolean success = false;
 242             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 243                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0d, 1.0d);
 244             }
 245             assertEquals(success, true, "weakCompareAndSet double");
 246             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 247             assertEquals(x, 1.0d, "weakCompareAndSet double");
 248         }
 249 
 250         // Compare set and get
 251         {
 252             double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2.0d);
 253             assertEquals(o, 1.0d, "getAndSet double");
 254             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 255             assertEquals(x, 2.0d, "getAndSet double value");
 256         }
 257 
 258         // get and add, add and get
 259         {
 260             hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d);
 261 
 262             double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, 2.0d);
 263             assertEquals(o, 1.0d, "getAndAdd double");
 264             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 265             assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value");
 266         }
 267 
 268         {
 269             hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d);
 270 
 271             double o = (double) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, 2.0d);
 272             assertEquals(o, 1.0d, "getAndAddAcquire double");
 273             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 274             assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value");
 275         }
 276 
 277         {
 278             hs.get(TestAccessMode.SET).invokeExact(recv, 1.0d);
 279 
 280             double o = (double) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, 2.0d);
 281             assertEquals(o, 1.0d, "getAndAddRelease double");
 282             double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv);
 283             assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value");
 284         }
 285 
 286     }
 287 
 288     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable {
 289 
 290 
 291         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 292             checkUOE(am, () -> {
 293                 double r = (double) hs.get(am).invokeExact(recv, 1.0d);
 294             });
 295         }
 296     }
 297 
 298 
 299     static void testStaticField(Handles hs) throws Throwable {
 300         // Plain
 301         {
 302             hs.get(TestAccessMode.SET).invokeExact(1.0d);
 303             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 304             assertEquals(x, 1.0d, "set double value");
 305         }
 306 
 307 
 308         // Volatile
 309         {
 310             hs.get(TestAccessMode.SET_VOLATILE).invokeExact(2.0d);
 311             double x = (double) hs.get(TestAccessMode.GET_VOLATILE).invokeExact();
 312             assertEquals(x, 2.0d, "setVolatile double value");
 313         }
 314 
 315         // Lazy
 316         {
 317             hs.get(TestAccessMode.SET_RELEASE).invokeExact(1.0d);
 318             double x = (double) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact();
 319             assertEquals(x, 1.0d, "setRelease double value");
 320         }
 321 
 322         // Opaque
 323         {
 324             hs.get(TestAccessMode.SET_OPAQUE).invokeExact(2.0d);
 325             double x = (double) hs.get(TestAccessMode.GET_OPAQUE).invokeExact();
 326             assertEquals(x, 2.0d, "setOpaque double value");
 327         }
 328 
 329         hs.get(TestAccessMode.SET).invokeExact(1.0d);
 330 
 331         // Compare
 332         {
 333             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0d, 2.0d);
 334             assertEquals(r, true, "success compareAndSet double");
 335             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 336             assertEquals(x, 2.0d, "success compareAndSet double value");
 337         }
 338 
 339         {
 340             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(1.0d, 3.0d);
 341             assertEquals(r, false, "failing compareAndSet double");
 342             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 343             assertEquals(x, 2.0d, "failing compareAndSet double value");
 344         }
 345 
 346         {
 347             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(2.0d, 1.0d);
 348             assertEquals(r, 2.0d, "success compareAndExchange double");
 349             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 350             assertEquals(x, 1.0d, "success compareAndExchange double value");
 351         }
 352 
 353         {
 354             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(2.0d, 3.0d);
 355             assertEquals(r, 1.0d, "failing compareAndExchange double");
 356             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 357             assertEquals(x, 1.0d, "failing compareAndExchange double value");
 358         }
 359 
 360         {
 361             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0d, 2.0d);
 362             assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
 363             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 364             assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
 365         }
 366 
 367         {
 368             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(1.0d, 3.0d);
 369             assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
 370             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 371             assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
 372         }
 373 
 374         {
 375             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0d, 1.0d);
 376             assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
 377             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 378             assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
 379         }
 380 
 381         {
 382             double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(2.0d, 3.0d);
 383             assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
 384             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 385             assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
 386         }
 387 
 388         {
 389             boolean success = false;
 390             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 391                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0d, 2.0d);
 392             }
 393             assertEquals(success, true, "weakCompareAndSetPlain double");
 394             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 395             assertEquals(x, 2.0d, "weakCompareAndSetPlain double value");
 396         }
 397 
 398         {
 399             boolean success = false;
 400             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 401                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0d, 1.0d);
 402             }
 403             assertEquals(success, true, "weakCompareAndSetAcquire double");
 404             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 405             assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
 406         }
 407 
 408         {
 409             boolean success = false;
 410             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 411                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0d, 2.0d);
 412             }
 413             assertEquals(success, true, "weakCompareAndSetRelease double");
 414             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 415             assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
 416         }
 417 
 418         {
 419             boolean success = false;
 420             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 421                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0d, 1.0d);
 422             }
 423             assertEquals(success, true, "weakCompareAndSet double");
 424             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 425             assertEquals(x, 1.0d, "weakCompareAndSet double");
 426         }
 427 
 428         // Compare set and get
 429         {
 430             hs.get(TestAccessMode.SET).invokeExact(1.0d);
 431 
 432             double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2.0d);
 433             assertEquals(o, 1.0d, "getAndSet double");
 434             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 435             assertEquals(x, 2.0d, "getAndSet double value");
 436         }
 437 
 438         // Compare set and get
 439         {
 440             hs.get(TestAccessMode.SET).invokeExact(1.0d);
 441 
 442             double o = (double) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(2.0d);
 443             assertEquals(o, 1.0d, "getAndSetAcquire double");
 444             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 445             assertEquals(x, 2.0d, "getAndSetAcquire double value");
 446         }
 447 
 448         // Compare set and get
 449         {
 450             hs.get(TestAccessMode.SET).invokeExact(1.0d);
 451 
 452             double o = (double) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(2.0d);
 453             assertEquals(o, 1.0d, "getAndSetRelease double");
 454             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 455             assertEquals(x, 2.0d, "getAndSetRelease double value");
 456         }
 457 
 458         // get and add, add and get
 459         {
 460             hs.get(TestAccessMode.SET).invokeExact(1.0d);
 461 
 462             double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(2.0d);
 463             assertEquals(o, 1.0d, "getAndAdd double");
 464             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 465             assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value");
 466         }
 467 
 468         {
 469             hs.get(TestAccessMode.SET).invokeExact(1.0d);
 470 
 471             double o = (double) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(2.0d);
 472             assertEquals(o, 1.0d, "getAndAddAcquire double");
 473             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 474             assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value");
 475         }
 476 
 477         {
 478             hs.get(TestAccessMode.SET).invokeExact(1.0d);
 479 
 480             double o = (double) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(2.0d);
 481             assertEquals(o, 1.0d, "getAndAddRelease double");
 482             double x = (double) hs.get(TestAccessMode.GET).invokeExact();
 483             assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value");
 484         }
 485 
 486     }
 487 
 488     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
 489 
 490 
 491         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 492             checkUOE(am, () -> {
 493                 double r = (double) hs.get(am).invokeExact(1.0d);
 494             });
 495         }
 496     }
 497 
 498 
 499     static void testArray(Handles hs) throws Throwable {
 500         double[] array = new double[10];
 501 
 502         for (int i = 0; i < array.length; i++) {
 503             // Plain
 504             {
 505                 hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 506                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 507                 assertEquals(x, 1.0d, "get double value");
 508             }
 509 
 510 
 511             // Volatile
 512             {
 513                 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, 2.0d);
 514                 double x = (double) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i);
 515                 assertEquals(x, 2.0d, "setVolatile double value");
 516             }
 517 
 518             // Lazy
 519             {
 520                 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, 1.0d);
 521                 double x = (double) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i);
 522                 assertEquals(x, 1.0d, "setRelease double value");
 523             }
 524 
 525             // Opaque
 526             {
 527                 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, 2.0d);
 528                 double x = (double) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i);
 529                 assertEquals(x, 2.0d, "setOpaque double value");
 530             }
 531 
 532             hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 533 
 534             // Compare
 535             {
 536                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0d, 2.0d);
 537                 assertEquals(r, true, "success compareAndSet double");
 538                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 539                 assertEquals(x, 2.0d, "success compareAndSet double value");
 540             }
 541 
 542             {
 543                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, 1.0d, 3.0d);
 544                 assertEquals(r, false, "failing compareAndSet double");
 545                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 546                 assertEquals(x, 2.0d, "failing compareAndSet double value");
 547             }
 548 
 549             {
 550                 double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 2.0d, 1.0d);
 551                 assertEquals(r, 2.0d, "success compareAndExchange double");
 552                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 553                 assertEquals(x, 1.0d, "success compareAndExchange double value");
 554             }
 555 
 556             {
 557                 double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, 2.0d, 3.0d);
 558                 assertEquals(r, 1.0d, "failing compareAndExchange double");
 559                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 560                 assertEquals(x, 1.0d, "failing compareAndExchange double value");
 561             }
 562 
 563             {
 564                 double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0d, 2.0d);
 565                 assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
 566                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 567                 assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
 568             }
 569 
 570             {
 571                 double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, 1.0d, 3.0d);
 572                 assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
 573                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 574                 assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
 575             }
 576 
 577             {
 578                 double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0d, 1.0d);
 579                 assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
 580                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 581                 assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
 582             }
 583 
 584             {
 585                 double r = (double) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, 2.0d, 3.0d);
 586                 assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
 587                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 588                 assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
 589             }
 590 
 591             {
 592                 boolean success = false;
 593                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 594                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0d, 2.0d);
 595                 }
 596                 assertEquals(success, true, "weakCompareAndSetPlain double");
 597                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 598                 assertEquals(x, 2.0d, "weakCompareAndSetPlain double value");
 599             }
 600 
 601             {
 602                 boolean success = false;
 603                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 604                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d, 1.0d);
 605                 }
 606                 assertEquals(success, true, "weakCompareAndSetAcquire double");
 607                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 608                 assertEquals(x, 1.0d, "weakCompareAndSetAcquire double");
 609             }
 610 
 611             {
 612                 boolean success = false;
 613                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 614                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1.0d, 2.0d);
 615                 }
 616                 assertEquals(success, true, "weakCompareAndSetRelease double");
 617                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 618                 assertEquals(x, 2.0d, "weakCompareAndSetRelease double");
 619             }
 620 
 621             {
 622                 boolean success = false;
 623                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 624                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0d, 1.0d);
 625                 }
 626                 assertEquals(success, true, "weakCompareAndSet double");
 627                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 628                 assertEquals(x, 1.0d, "weakCompareAndSet double");
 629             }
 630 
 631             // Compare set and get
 632             {
 633                 hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 634 
 635                 double o = (double) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2.0d);
 636                 assertEquals(o, 1.0d, "getAndSet double");
 637                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 638                 assertEquals(x, 2.0d, "getAndSet double value");
 639             }
 640 
 641             {
 642                 hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 643 
 644                 double o = (double) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d);
 645                 assertEquals(o, 1.0d, "getAndSetAcquire double");
 646                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 647                 assertEquals(x, 2.0d, "getAndSetAcquire double value");
 648             }
 649 
 650             {
 651                 hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 652 
 653                 double o = (double) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, 2.0d);
 654                 assertEquals(o, 1.0d, "getAndSetRelease double");
 655                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 656                 assertEquals(x, 2.0d, "getAndSetRelease double value");
 657             }
 658 
 659             // get and add, add and get
 660             {
 661                 hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 662 
 663                 double o = (double) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, 2.0d);
 664                 assertEquals(o, 1.0d, "getAndAdd double");
 665                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 666                 assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double value");
 667             }
 668 
 669             {
 670                 hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 671 
 672                 double o = (double) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, 2.0d);
 673                 assertEquals(o, 1.0d, "getAndAddAcquire double");
 674                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 675                 assertEquals(x, (double)(1.0d + 2.0d), "getAndAddAcquire double value");
 676             }
 677 
 678             {
 679                 hs.get(TestAccessMode.SET).invokeExact(array, i, 1.0d);
 680 
 681                 double o = (double) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, 2.0d);
 682                 assertEquals(o, 1.0d, "getAndAddRelease double");
 683                 double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i);
 684                 assertEquals(x, (double)(1.0d + 2.0d), "getAndAddRelease double value");
 685             }
 686 
 687         }
 688     }
 689 
 690     static void testArrayUnsupported(Handles hs) throws Throwable {
 691         double[] array = new double[10];
 692 
 693         final int i = 0;
 694 
 695 
 696         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 697             checkUOE(am, () -> {
 698                 double o = (double) hs.get(am).invokeExact(array, i, 1.0d);
 699             });
 700         }
 701     }
 702 
 703     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
 704         double[] array = new double[10];
 705 
 706         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
 707             final int ci = i;
 708 
 709             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
 710                 checkIOOBE(am, () -> {
 711                     double x = (double) hs.get(am).invokeExact(array, ci);
 712                 });
 713             }
 714 
 715             for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
 716                 checkIOOBE(am, () -> {
 717                     hs.get(am).invokeExact(array, ci, 1.0d);
 718                 });
 719             }
 720 
 721             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 722                 checkIOOBE(am, () -> {
 723                     boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1.0d, 2.0d);
 724                 });
 725             }
 726 
 727             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 728                 checkIOOBE(am, () -> {
 729                     double r = (double) hs.get(am).invokeExact(array, ci, 2.0d, 1.0d);
 730                 });
 731             }
 732 
 733             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 734                 checkIOOBE(am, () -> {
 735                     double o = (double) hs.get(am).invokeExact(array, ci, 1.0d);
 736                 });
 737             }
 738 
 739             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 740                 checkIOOBE(am, () -> {
 741                     double o = (double) hs.get(am).invokeExact(array, ci, 3.0d);
 742                 });
 743             }
 744 
 745         }
 746     }
 747 }
 748