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