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  * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations
 29  *          to hit compilation thresholds
 30  * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessString
 31  */
 32 
 33 import org.testng.annotations.BeforeClass;
 34 import org.testng.annotations.DataProvider;
 35 import org.testng.annotations.Test;
 36 
 37 import java.lang.invoke.MethodHandle;
 38 import java.lang.invoke.MethodHandles;
 39 import java.lang.invoke.VarHandle;
 40 import java.util.ArrayList;
 41 import java.util.Arrays;
 42 import java.util.List;
 43 
 44 import static org.testng.Assert.*;
 45 
 46 public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest {
 47     static final String static_final_v = "foo";
 48 
 49     static String static_v;
 50 
 51     final String final_v = "foo";
 52 
 53     String v;
 54 
 55     VarHandle vhFinalField;
 56 
 57     VarHandle vhField;
 58 
 59     VarHandle vhStaticField;
 60 
 61     VarHandle vhStaticFinalField;
 62 
 63     VarHandle vhArray;
 64 
 65     @BeforeClass
 66     public void setup() throws Exception {
 67         vhFinalField = MethodHandles.lookup().findVarHandle(
 68                 VarHandleTestMethodHandleAccessString.class, "final_v", String.class);
 69 
 70         vhField = MethodHandles.lookup().findVarHandle(
 71                 VarHandleTestMethodHandleAccessString.class, "v", String.class);
 72 
 73         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
 74             VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class);
 75 
 76         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
 77             VarHandleTestMethodHandleAccessString.class, "static_v", String.class);
 78 
 79         vhArray = MethodHandles.arrayElementVarHandle(String[].class);
 80     }
 81 
 82 
 83     @DataProvider
 84     public Object[][] accessTestCaseProvider() throws Exception {
 85         List<AccessTestCase<?>> cases = new ArrayList<>();
 86 
 87         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
 88             cases.add(new MethodHandleAccessTestCase("Instance field",
 89                                                      vhField, f, hs -> testInstanceField(this, hs)));
 90             cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
 91                                                      vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
 92                                                      false));
 93 
 94             cases.add(new MethodHandleAccessTestCase("Static field",
 95                                                      vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticField));
 96             cases.add(new MethodHandleAccessTestCase("Static field unsupported",
 97                                                      vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticFieldUnsupported,
 98                                                      false));
 99 
100             cases.add(new MethodHandleAccessTestCase("Array",
101                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArray));
102             cases.add(new MethodHandleAccessTestCase("Array unsupported",
103                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArrayUnsupported,
104                                                      false));
105             cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
106                                                      vhArray, f, VarHandleTestMethodHandleAccessString::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     @Test(dataProvider = "accessTestCaseProvider")
117     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
118         T t = atc.get();
119         int iters = atc.requiresLoop() ? ITERS : 1;
120         for (int c = 0; c < iters; c++) {
121             atc.testAccess(t);
122         }
123     }
124 
125 
126     static void testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
127         // Plain
128         {
129             hs.get(TestAccessMode.SET).invokeExact(recv, "foo");
130             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
131             assertEquals(x, "foo", "set String value");
132         }
133 
134 
135         // Volatile
136         {
137             hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, "bar");
138             String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv);
139             assertEquals(x, "bar", "setVolatile String value");
140         }
141 
142         // Lazy
143         {
144             hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, "foo");
145             String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv);
146             assertEquals(x, "foo", "setRelease String value");
147         }
148 
149         // Opaque
150         {
151             hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, "bar");
152             String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv);
153             assertEquals(x, "bar", "setOpaque String value");
154         }
155 
156         hs.get(TestAccessMode.SET).invokeExact(recv, "foo");
157 
158         // Compare
159         {
160             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "bar");
161             assertEquals(r, true, "success compareAndSet String");
162             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
163             assertEquals(x, "bar", "success compareAndSet String value");
164         }
165 
166         {
167             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "baz");
168             assertEquals(r, false, "failing compareAndSet String");
169             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
170             assertEquals(x, "bar", "failing compareAndSet String value");
171         }
172 
173         {
174             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "foo");
175             assertEquals(r, "bar", "success compareAndExchange String");
176             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
177             assertEquals(x, "foo", "success compareAndExchange String value");
178         }
179 
180         {
181             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "baz");
182             assertEquals(r, "foo", "failing compareAndExchange String");
183             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
184             assertEquals(x, "foo", "failing compareAndExchange String value");
185         }
186 
187         {
188             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "bar");
189             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
190             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
191             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
192         }
193 
194         {
195             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "baz");
196             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
197             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
198             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
199         }
200 
201         {
202             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "foo");
203             assertEquals(r, "bar", "success compareAndExchangeRelease String");
204             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
205             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
206         }
207 
208         {
209             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "baz");
210             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
211             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
212             assertEquals(x, "foo", "failing compareAndExchangeRelease String 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, "foo", "bar");
220                 if (!success) weakDelay();
221             }
222             assertEquals(success, true, "success weakCompareAndSetPlain String");
223             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
224             assertEquals(x, "bar", "success weakCompareAndSetPlain String value");
225         }
226 
227         {
228             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "baz");
229             assertEquals(success, false, "failing weakCompareAndSetPlain String");
230             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
231             assertEquals(x, "bar", "failing weakCompareAndSetPlain String 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, "bar", "foo");
239                 if (!success) weakDelay();
240             }
241             assertEquals(success, true, "success weakCompareAndSetAcquire String");
242             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
243             assertEquals(x, "foo", "success weakCompareAndSetAcquire String");
244         }
245 
246         {
247             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "baz");
248             assertEquals(success, false, "failing weakCompareAndSetAcquire String");
249             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
250             assertEquals(x, "foo", "failing weakCompareAndSetAcquire String 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, "foo", "bar");
258                 if (!success) weakDelay();
259             }
260             assertEquals(success, true, "success weakCompareAndSetRelease String");
261             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
262             assertEquals(x, "bar", "success weakCompareAndSetRelease String");
263         }
264 
265         {
266             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "baz");
267             assertEquals(success, false, "failing weakCompareAndSetRelease String");
268             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
269             assertEquals(x, "bar", "failing weakCompareAndSetRelease String 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, "bar", "foo");
277                 if (!success) weakDelay();
278             }
279             assertEquals(success, true, "success weakCompareAndSet String");
280             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
281             assertEquals(x, "foo", "success weakCompareAndSet String");
282         }
283 
284         {
285             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "baz");
286             assertEquals(success, false, "failing weakCompareAndSet String");
287             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
288             assertEquals(x, "foo", "failing weakCompareAndSet String value");
289         }
290 
291         // Compare set and get
292         {
293             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "bar");
294             assertEquals(o, "foo", "getAndSet String");
295             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
296             assertEquals(x, "bar", "getAndSet String value");
297         }
298 
299 
300     }
301 
302     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
303 
304         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
305             checkUOE(am, () -> {
306                 String r = (String) hs.get(am).invokeExact(recv, "foo");
307             });
308         }
309 
310         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
311             checkUOE(am, () -> {
312                 String r = (String) hs.get(am).invokeExact(recv, "foo");
313             });
314         }
315     }
316 
317 
318     static void testStaticField(Handles hs) throws Throwable {
319         // Plain
320         {
321             hs.get(TestAccessMode.SET).invokeExact("foo");
322             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
323             assertEquals(x, "foo", "set String value");
324         }
325 
326 
327         // Volatile
328         {
329             hs.get(TestAccessMode.SET_VOLATILE).invokeExact("bar");
330             String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact();
331             assertEquals(x, "bar", "setVolatile String value");
332         }
333 
334         // Lazy
335         {
336             hs.get(TestAccessMode.SET_RELEASE).invokeExact("foo");
337             String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact();
338             assertEquals(x, "foo", "setRelease String value");
339         }
340 
341         // Opaque
342         {
343             hs.get(TestAccessMode.SET_OPAQUE).invokeExact("bar");
344             String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact();
345             assertEquals(x, "bar", "setOpaque String value");
346         }
347 
348         hs.get(TestAccessMode.SET).invokeExact("foo");
349 
350         // Compare
351         {
352             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "bar");
353             assertEquals(r, true, "success compareAndSet String");
354             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
355             assertEquals(x, "bar", "success compareAndSet String value");
356         }
357 
358         {
359             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "baz");
360             assertEquals(r, false, "failing compareAndSet String");
361             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
362             assertEquals(x, "bar", "failing compareAndSet String value");
363         }
364 
365         {
366             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "foo");
367             assertEquals(r, "bar", "success compareAndExchange String");
368             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
369             assertEquals(x, "foo", "success compareAndExchange String value");
370         }
371 
372         {
373             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "baz");
374             assertEquals(r, "foo", "failing compareAndExchange String");
375             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
376             assertEquals(x, "foo", "failing compareAndExchange String value");
377         }
378 
379         {
380             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "bar");
381             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
382             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
383             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
384         }
385 
386         {
387             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "baz");
388             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
389             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
390             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
391         }
392 
393         {
394             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "foo");
395             assertEquals(r, "bar", "success compareAndExchangeRelease String");
396             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
397             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
398         }
399 
400         {
401             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "baz");
402             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
403             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
404             assertEquals(x, "foo", "failing compareAndExchangeRelease String 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("foo", "bar");
412                 if (!success) weakDelay();
413             }
414             assertEquals(success, true, "success weakCompareAndSetPlain String");
415             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
416             assertEquals(x, "bar", "success weakCompareAndSetPlain String value");
417         }
418 
419         {
420             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "baz");
421             assertEquals(success, false, "failing weakCompareAndSetPlain String");
422             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
423             assertEquals(x, "bar", "failing weakCompareAndSetPlain String 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("bar", "foo");
431                 if (!success) weakDelay();
432             }
433             assertEquals(success, true, "success weakCompareAndSetAcquire String");
434             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
435             assertEquals(x, "foo", "success weakCompareAndSetAcquire String");
436         }
437 
438         {
439             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE);
440             boolean success = (boolean) mh.invokeExact("bar", "baz");
441             assertEquals(success, false, "failing weakCompareAndSetAcquire String");
442             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
443             assertEquals(x, "foo", "failing weakCompareAndSetAcquire String 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("foo", "bar");
451                 if (!success) weakDelay();
452             }
453             assertEquals(success, true, "success weakCompareAndSetRelease String");
454             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
455             assertEquals(x, "bar", "success weakCompareAndSetRelease String");
456         }
457 
458         {
459             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "baz");
460             assertEquals(success, false, "failing weakCompareAndSetRelease String");
461             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
462             assertEquals(x, "bar", "failing weakCompareAndSetRelease String 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("bar", "foo");
470                 if (!success) weakDelay();
471             }
472             assertEquals(success, true, "success weakCompareAndSet String");
473             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
474             assertEquals(x, "foo", "success weakCompareAndSet String");
475         }
476 
477         {
478             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "baz");
479             assertEquals(success, false, "failing weakCompareAndSet String");
480             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
481             assertEquals(x, "foo", "failing weakCompareAndSetRe String value");
482         }
483 
484         // Compare set and get
485         {
486             hs.get(TestAccessMode.SET).invokeExact("foo");
487 
488             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar");
489             assertEquals(o, "foo", "getAndSet String");
490             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
491             assertEquals(x, "bar", "getAndSet String value");
492         }
493 
494         // Compare set and get
495         {
496             hs.get(TestAccessMode.SET).invokeExact("foo");
497 
498             String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact("bar");
499             assertEquals(o, "foo", "getAndSetAcquire String");
500             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
501             assertEquals(x, "bar", "getAndSetAcquire String value");
502         }
503 
504         // Compare set and get
505         {
506             hs.get(TestAccessMode.SET).invokeExact("foo");
507 
508             String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact("bar");
509             assertEquals(o, "foo", "getAndSetRelease String");
510             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
511             assertEquals(x, "bar", "getAndSetRelease String 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                 String r = (String) hs.get(am).invokeExact("foo");
522             });
523         }
524 
525         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
526             checkUOE(am, () -> {
527                 String r = (String) hs.get(am).invokeExact("foo");
528             });
529         }
530     }
531 
532 
533     static void testArray(Handles hs) throws Throwable {
534         String[] array = new String[10];
535 
536         for (int i = 0; i < array.length; i++) {
537             // Plain
538             {
539                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
540                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
541                 assertEquals(x, "foo", "get String value");
542             }
543 
544 
545             // Volatile
546             {
547                 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, "bar");
548                 String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i);
549                 assertEquals(x, "bar", "setVolatile String value");
550             }
551 
552             // Lazy
553             {
554                 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, "foo");
555                 String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i);
556                 assertEquals(x, "foo", "setRelease String value");
557             }
558 
559             // Opaque
560             {
561                 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, "bar");
562                 String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i);
563                 assertEquals(x, "bar", "setOpaque String value");
564             }
565 
566             hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
567 
568             // Compare
569             {
570                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "bar");
571                 assertEquals(r, true, "success compareAndSet String");
572                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
573                 assertEquals(x, "bar", "success compareAndSet String value");
574             }
575 
576             {
577                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "baz");
578                 assertEquals(r, false, "failing compareAndSet String");
579                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
580                 assertEquals(x, "bar", "failing compareAndSet String value");
581             }
582 
583             {
584                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "foo");
585                 assertEquals(r, "bar", "success compareAndExchange String");
586                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
587                 assertEquals(x, "foo", "success compareAndExchange String value");
588             }
589 
590             {
591                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "baz");
592                 assertEquals(r, "foo", "failing compareAndExchange String");
593                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
594                 assertEquals(x, "foo", "failing compareAndExchange String value");
595             }
596 
597             {
598                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "bar");
599                 assertEquals(r, "foo", "success compareAndExchangeAcquire String");
600                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
601                 assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
602             }
603 
604             {
605                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "baz");
606                 assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
607                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
608                 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
609             }
610 
611             {
612                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "foo");
613                 assertEquals(r, "bar", "success compareAndExchangeRelease String");
614                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
615                 assertEquals(x, "foo", "success compareAndExchangeRelease String value");
616             }
617 
618             {
619                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "baz");
620                 assertEquals(r, "foo", "failing compareAndExchangeRelease String");
621                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
622                 assertEquals(x, "foo", "failing compareAndExchangeRelease String 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, "foo", "bar");
630                     if (!success) weakDelay();
631                 }
632                 assertEquals(success, true, "success weakCompareAndSetPlain String");
633                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
634                 assertEquals(x, "bar", "success weakCompareAndSetPlain String value");
635             }
636 
637             {
638                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "baz");
639                 assertEquals(success, false, "failing weakCompareAndSetPlain String");
640                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
641                 assertEquals(x, "bar", "failing weakCompareAndSetPlain String 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, "bar", "foo");
649                     if (!success) weakDelay();
650                 }
651                 assertEquals(success, true, "success weakCompareAndSetAcquire String");
652                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
653                 assertEquals(x, "foo", "success weakCompareAndSetAcquire String");
654             }
655 
656             {
657                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "baz");
658                 assertEquals(success, false, "failing weakCompareAndSetAcquire String");
659                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
660                 assertEquals(x, "foo", "failing weakCompareAndSetAcquire String 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, "foo", "bar");
668                     if (!success) weakDelay();
669                 }
670                 assertEquals(success, true, "success weakCompareAndSetRelease String");
671                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
672                 assertEquals(x, "bar", "success weakCompareAndSetRelease String");
673             }
674 
675             {
676                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "foo", "baz");
677                 assertEquals(success, false, "failing weakCompareAndSetAcquire String");
678                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
679                 assertEquals(x, "bar", "failing weakCompareAndSetAcquire String 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, "bar", "foo");
687                     if (!success) weakDelay();
688                 }
689                 assertEquals(success, true, "success weakCompareAndSet String");
690                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
691                 assertEquals(x, "foo", "success weakCompareAndSet String");
692             }
693 
694             {
695                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "baz");
696                 assertEquals(success, false, "failing weakCompareAndSet String");
697                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
698                 assertEquals(x, "foo", "failing weakCompareAndSet String value");
699             }
700 
701             // Compare set and get
702             {
703                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
704 
705                 String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "bar");
706                 assertEquals(o, "foo", "getAndSet String");
707                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
708                 assertEquals(x, "bar", "getAndSet String value");
709             }
710 
711             {
712                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
713 
714                 String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, "bar");
715                 assertEquals(o, "foo", "getAndSetAcquire String");
716                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
717                 assertEquals(x, "bar", "getAndSetAcquire String value");
718             }
719 
720             {
721                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
722 
723                 String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, "bar");
724                 assertEquals(o, "foo", "getAndSetRelease String");
725                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
726                 assertEquals(x, "bar", "getAndSetRelease String value");
727             }
728 
729 
730         }
731     }
732 
733     static void testArrayUnsupported(Handles hs) throws Throwable {
734         String[] array = new String[10];
735 
736         final int i = 0;
737 
738         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
739             checkUOE(am, () -> {
740                 String o = (String) hs.get(am).invokeExact(array, i, "foo");
741             });
742         }
743 
744         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
745             checkUOE(am, () -> {
746                 String o = (String) hs.get(am).invokeExact(array, i, "foo");
747             });
748         }
749     }
750 
751     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
752         String[] array = new String[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                     String x = (String) 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, "foo");
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, "foo", "bar");
772                 });
773             }
774 
775             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
776                 checkAIOOBE(am, () -> {
777                     String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo");
778                 });
779             }
780 
781             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
782                 checkAIOOBE(am, () -> {
783                     String o = (String) hs.get(am).invokeExact(array, ci, "foo");
784                 });
785             }
786 
787 
788         }
789     }
790 }
791