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