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