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