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