1 /*
2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessString
27  */
28 
29 import org.testng.annotations.BeforeClass;
30 import org.testng.annotations.DataProvider;
31 import org.testng.annotations.Test;
32 
33 import java.lang.invoke.MethodHandles;
34 import java.lang.invoke.VarHandle;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.List;
38 
39 import static org.testng.Assert.*;
40 
41 public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest {
42     static final String static_final_v = "foo";
43 
44     static String static_v;
45 
46     final String final_v = "foo";
47 
48     String v;
49 
50     VarHandle vhFinalField;
51 
52     VarHandle vhField;
53 
54     VarHandle vhStaticField;
55 
56     VarHandle vhStaticFinalField;
57 
58     VarHandle vhArray;
59 
60     @BeforeClass
setup()61     public void setup() throws Exception {
62         vhFinalField = MethodHandles.lookup().findVarHandle(
63                 VarHandleTestMethodHandleAccessString.class, "final_v", String.class);
64 
65         vhField = MethodHandles.lookup().findVarHandle(
66                 VarHandleTestMethodHandleAccessString.class, "v", String.class);
67 
68         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
69             VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class);
70 
71         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
72             VarHandleTestMethodHandleAccessString.class, "static_v", String.class);
73 
74         vhArray = MethodHandles.arrayElementVarHandle(String[].class);
75     }
76 
77 
78     @DataProvider
accessTestCaseProvider()79     public Object[][] accessTestCaseProvider() throws Exception {
80         List<AccessTestCase<?>> cases = new ArrayList<>();
81 
82         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
83             cases.add(new MethodHandleAccessTestCase("Instance field",
84                                                      vhField, f, hs -> testInstanceField(this, hs)));
85             cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
86                                                      vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
87                                                      false));
88 
89             cases.add(new MethodHandleAccessTestCase("Static field",
90                                                      vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticField));
91             cases.add(new MethodHandleAccessTestCase("Static field unsupported",
92                                                      vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticFieldUnsupported,
93                                                      false));
94 
95             cases.add(new MethodHandleAccessTestCase("Array",
96                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArray));
97             cases.add(new MethodHandleAccessTestCase("Array unsupported",
98                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArrayUnsupported,
99                                                      false));
100             cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
101                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArrayIndexOutOfBounds,
102                                                      false));
103         }
104 
105         // Work around issue with jtreg summary reporting which truncates
106         // the String result of Object.toString to 30 characters, hence
107         // the first dummy argument
108         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
109     }
110 
111     @Test(dataProvider = "accessTestCaseProvider")
testAccess(String desc, AccessTestCase<T> atc)112     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
113         T t = atc.get();
114         int iters = atc.requiresLoop() ? ITERS : 1;
115         for (int c = 0; c < iters; c++) {
116             atc.testAccess(t);
117         }
118     }
119 
120 
testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs)121     static void testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
122         // Plain
123         {
124             hs.get(TestAccessMode.SET).invokeExact(recv, "foo");
125             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
126             assertEquals(x, "foo", "set String value");
127         }
128 
129 
130         // Volatile
131         {
132             hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, "bar");
133             String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv);
134             assertEquals(x, "bar", "setVolatile String value");
135         }
136 
137         // Lazy
138         {
139             hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, "foo");
140             String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv);
141             assertEquals(x, "foo", "setRelease String value");
142         }
143 
144         // Opaque
145         {
146             hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, "bar");
147             String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv);
148             assertEquals(x, "bar", "setOpaque String value");
149         }
150 
151         hs.get(TestAccessMode.SET).invokeExact(recv, "foo");
152 
153         // Compare
154         {
155             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "bar");
156             assertEquals(r, true, "success compareAndSet String");
157             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
158             assertEquals(x, "bar", "success compareAndSet String value");
159         }
160 
161         {
162             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "baz");
163             assertEquals(r, false, "failing compareAndSet String");
164             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
165             assertEquals(x, "bar", "failing compareAndSet String value");
166         }
167 
168         {
169             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "foo");
170             assertEquals(r, "bar", "success compareAndExchange String");
171             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
172             assertEquals(x, "foo", "success compareAndExchange String value");
173         }
174 
175         {
176             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "baz");
177             assertEquals(r, "foo", "failing compareAndExchange String");
178             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
179             assertEquals(x, "foo", "failing compareAndExchange String value");
180         }
181 
182         {
183             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "bar");
184             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
185             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
186             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
187         }
188 
189         {
190             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "baz");
191             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
192             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
193             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
194         }
195 
196         {
197             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "foo");
198             assertEquals(r, "bar", "success compareAndExchangeRelease String");
199             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
200             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
201         }
202 
203         {
204             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "baz");
205             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
206             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
207             assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
208         }
209 
210         {
211             boolean success = false;
212             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
213                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "bar");
214             }
215             assertEquals(success, true, "weakCompareAndSetPlain String");
216             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
217             assertEquals(x, "bar", "weakCompareAndSetPlain String value");
218         }
219 
220         {
221             boolean success = false;
222             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
223                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "foo");
224             }
225             assertEquals(success, true, "weakCompareAndSetAcquire String");
226             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
227             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
228         }
229 
230         {
231             boolean success = false;
232             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
233                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "bar");
234             }
235             assertEquals(success, true, "weakCompareAndSetRelease String");
236             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
237             assertEquals(x, "bar", "weakCompareAndSetRelease String");
238         }
239 
240         {
241             boolean success = false;
242             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
243                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "foo");
244             }
245             assertEquals(success, true, "weakCompareAndSet String");
246             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
247             assertEquals(x, "foo", "weakCompareAndSet String");
248         }
249 
250         // Compare set and get
251         {
252             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "bar");
253             assertEquals(o, "foo", "getAndSet String");
254             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
255             assertEquals(x, "bar", "getAndSet String value");
256         }
257 
258 
259     }
260 
testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs)261     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
262 
263         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
264             checkUOE(am, () -> {
265                 String r = (String) hs.get(am).invokeExact(recv, "foo");
266             });
267         }
268 
269         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
270             checkUOE(am, () -> {
271                 String r = (String) hs.get(am).invokeExact(recv, "foo");
272             });
273         }
274     }
275 
276 
testStaticField(Handles hs)277     static void testStaticField(Handles hs) throws Throwable {
278         // Plain
279         {
280             hs.get(TestAccessMode.SET).invokeExact("foo");
281             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
282             assertEquals(x, "foo", "set String value");
283         }
284 
285 
286         // Volatile
287         {
288             hs.get(TestAccessMode.SET_VOLATILE).invokeExact("bar");
289             String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact();
290             assertEquals(x, "bar", "setVolatile String value");
291         }
292 
293         // Lazy
294         {
295             hs.get(TestAccessMode.SET_RELEASE).invokeExact("foo");
296             String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact();
297             assertEquals(x, "foo", "setRelease String value");
298         }
299 
300         // Opaque
301         {
302             hs.get(TestAccessMode.SET_OPAQUE).invokeExact("bar");
303             String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact();
304             assertEquals(x, "bar", "setOpaque String value");
305         }
306 
307         hs.get(TestAccessMode.SET).invokeExact("foo");
308 
309         // Compare
310         {
311             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "bar");
312             assertEquals(r, true, "success compareAndSet String");
313             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
314             assertEquals(x, "bar", "success compareAndSet String value");
315         }
316 
317         {
318             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "baz");
319             assertEquals(r, false, "failing compareAndSet String");
320             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
321             assertEquals(x, "bar", "failing compareAndSet String value");
322         }
323 
324         {
325             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "foo");
326             assertEquals(r, "bar", "success compareAndExchange String");
327             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
328             assertEquals(x, "foo", "success compareAndExchange String value");
329         }
330 
331         {
332             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "baz");
333             assertEquals(r, "foo", "failing compareAndExchange String");
334             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
335             assertEquals(x, "foo", "failing compareAndExchange String value");
336         }
337 
338         {
339             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "bar");
340             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
341             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
342             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
343         }
344 
345         {
346             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "baz");
347             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
348             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
349             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
350         }
351 
352         {
353             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "foo");
354             assertEquals(r, "bar", "success compareAndExchangeRelease String");
355             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
356             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
357         }
358 
359         {
360             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "baz");
361             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
362             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
363             assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
364         }
365 
366         {
367             boolean success = false;
368             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
369                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "bar");
370             }
371             assertEquals(success, true, "weakCompareAndSetPlain String");
372             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
373             assertEquals(x, "bar", "weakCompareAndSetPlain String value");
374         }
375 
376         {
377             boolean success = false;
378             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
379                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "foo");
380             }
381             assertEquals(success, true, "weakCompareAndSetAcquire String");
382             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
383             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
384         }
385 
386         {
387             boolean success = false;
388             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
389                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar");
390             }
391             assertEquals(success, true, "weakCompareAndSetRelease String");
392             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
393             assertEquals(x, "bar", "weakCompareAndSetRelease String");
394         }
395 
396         {
397             boolean success = false;
398             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
399                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "foo");
400             }
401             assertEquals(success, true, "weakCompareAndSet String");
402             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
403             assertEquals(x, "foo", "weakCompareAndSet String");
404         }
405 
406         // Compare set and get
407         {
408             hs.get(TestAccessMode.SET).invokeExact("foo");
409 
410             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar");
411             assertEquals(o, "foo", "getAndSet String");
412             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
413             assertEquals(x, "bar", "getAndSet String value");
414         }
415 
416         // Compare set and get
417         {
418             hs.get(TestAccessMode.SET).invokeExact("foo");
419 
420             String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact("bar");
421             assertEquals(o, "foo", "getAndSetAcquire String");
422             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
423             assertEquals(x, "bar", "getAndSetAcquire String value");
424         }
425 
426         // Compare set and get
427         {
428             hs.get(TestAccessMode.SET).invokeExact("foo");
429 
430             String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact("bar");
431             assertEquals(o, "foo", "getAndSetRelease String");
432             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
433             assertEquals(x, "bar", "getAndSetRelease String value");
434         }
435 
436 
437     }
438 
testStaticFieldUnsupported(Handles hs)439     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
440 
441         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
442             checkUOE(am, () -> {
443                 String r = (String) hs.get(am).invokeExact("foo");
444             });
445         }
446 
447         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
448             checkUOE(am, () -> {
449                 String r = (String) hs.get(am).invokeExact("foo");
450             });
451         }
452     }
453 
454 
testArray(Handles hs)455     static void testArray(Handles hs) throws Throwable {
456         String[] array = new String[10];
457 
458         for (int i = 0; i < array.length; i++) {
459             // Plain
460             {
461                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
462                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
463                 assertEquals(x, "foo", "get String value");
464             }
465 
466 
467             // Volatile
468             {
469                 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, "bar");
470                 String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i);
471                 assertEquals(x, "bar", "setVolatile String value");
472             }
473 
474             // Lazy
475             {
476                 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, "foo");
477                 String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i);
478                 assertEquals(x, "foo", "setRelease String value");
479             }
480 
481             // Opaque
482             {
483                 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, "bar");
484                 String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i);
485                 assertEquals(x, "bar", "setOpaque String value");
486             }
487 
488             hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
489 
490             // Compare
491             {
492                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "bar");
493                 assertEquals(r, true, "success compareAndSet String");
494                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
495                 assertEquals(x, "bar", "success compareAndSet String value");
496             }
497 
498             {
499                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "baz");
500                 assertEquals(r, false, "failing compareAndSet String");
501                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
502                 assertEquals(x, "bar", "failing compareAndSet String value");
503             }
504 
505             {
506                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "foo");
507                 assertEquals(r, "bar", "success compareAndExchange String");
508                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
509                 assertEquals(x, "foo", "success compareAndExchange String value");
510             }
511 
512             {
513                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "baz");
514                 assertEquals(r, "foo", "failing compareAndExchange String");
515                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
516                 assertEquals(x, "foo", "failing compareAndExchange String value");
517             }
518 
519             {
520                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "bar");
521                 assertEquals(r, "foo", "success compareAndExchangeAcquire String");
522                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
523                 assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
524             }
525 
526             {
527                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "baz");
528                 assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
529                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
530                 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
531             }
532 
533             {
534                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "foo");
535                 assertEquals(r, "bar", "success compareAndExchangeRelease String");
536                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
537                 assertEquals(x, "foo", "success compareAndExchangeRelease String value");
538             }
539 
540             {
541                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "baz");
542                 assertEquals(r, "foo", "failing compareAndExchangeRelease String");
543                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
544                 assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
545             }
546 
547             {
548                 boolean success = false;
549                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
550                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "bar");
551                 }
552                 assertEquals(success, true, "weakCompareAndSetPlain String");
553                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
554                 assertEquals(x, "bar", "weakCompareAndSetPlain String value");
555             }
556 
557             {
558                 boolean success = false;
559                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
560                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "foo");
561                 }
562                 assertEquals(success, true, "weakCompareAndSetAcquire String");
563                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
564                 assertEquals(x, "foo", "weakCompareAndSetAcquire String");
565             }
566 
567             {
568                 boolean success = false;
569                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
570                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, "foo", "bar");
571                 }
572                 assertEquals(success, true, "weakCompareAndSetRelease String");
573                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
574                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
575             }
576 
577             {
578                 boolean success = false;
579                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
580                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "foo");
581                 }
582                 assertEquals(success, true, "weakCompareAndSet String");
583                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
584                 assertEquals(x, "foo", "weakCompareAndSet String");
585             }
586 
587             // Compare set and get
588             {
589                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
590 
591                 String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "bar");
592                 assertEquals(o, "foo", "getAndSet String");
593                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
594                 assertEquals(x, "bar", "getAndSet String value");
595             }
596 
597             {
598                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
599 
600                 String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, "bar");
601                 assertEquals(o, "foo", "getAndSetAcquire String");
602                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
603                 assertEquals(x, "bar", "getAndSetAcquire String value");
604             }
605 
606             {
607                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
608 
609                 String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, "bar");
610                 assertEquals(o, "foo", "getAndSetRelease String");
611                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
612                 assertEquals(x, "bar", "getAndSetRelease String value");
613             }
614 
615 
616         }
617     }
618 
testArrayUnsupported(Handles hs)619     static void testArrayUnsupported(Handles hs) throws Throwable {
620         String[] array = new String[10];
621 
622         final int i = 0;
623 
624         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
625             checkUOE(am, () -> {
626                 String o = (String) hs.get(am).invokeExact(array, i, "foo");
627             });
628         }
629 
630         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
631             checkUOE(am, () -> {
632                 String o = (String) hs.get(am).invokeExact(array, i, "foo");
633             });
634         }
635     }
636 
testArrayIndexOutOfBounds(Handles hs)637     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
638         String[] array = new String[10];
639 
640         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
641             final int ci = i;
642 
643             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
644                 checkIOOBE(am, () -> {
645                     String x = (String) hs.get(am).invokeExact(array, ci);
646                 });
647             }
648 
649             for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
650                 checkIOOBE(am, () -> {
651                     hs.get(am).invokeExact(array, ci, "foo");
652                 });
653             }
654 
655             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
656                 checkIOOBE(am, () -> {
657                     boolean r = (boolean) hs.get(am).invokeExact(array, ci, "foo", "bar");
658                 });
659             }
660 
661             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
662                 checkIOOBE(am, () -> {
663                     String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo");
664                 });
665             }
666 
667             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
668                 checkIOOBE(am, () -> {
669                     String o = (String) hs.get(am).invokeExact(array, ci, "foo");
670                 });
671             }
672 
673 
674         }
675     }
676 }
677 
678