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