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