1/*
2 * Copyright (c) 2015, 2018, 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// Android-added: package for test.
25package test.java.lang.invoke.VarHandles;
26
27/*
28 * @test
29 * @bug 8154556
30 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
31 * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAs$Type$
32 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAs$Type$
33 */
34
35import org.testng.annotations.DataProvider;
36import org.testng.annotations.Test;
37
38import java.lang.invoke.MethodHandles;
39import java.lang.invoke.VarHandle;
40import java.nio.ByteBuffer;
41import java.nio.ByteOrder;
42import java.util.ArrayList;
43import java.util.Arrays;
44import java.util.EnumSet;
45import java.util.List;
46
47import static org.testng.Assert.*;
48
49public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest {
50    static final int SIZE = $BoxType$.BYTES;
51
52    static final $type$ VALUE_1 = $value1$;
53
54    static final $type$ VALUE_2 = $value2$;
55
56    static final $type$ VALUE_3 = $value3$;
57
58
59    @Override
60    public void setupVarHandleSources() {
61        // Combinations of VarHandle byte[] or ByteBuffer
62        vhss = new ArrayList<>();
63        for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
64
65            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
66                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
67            VarHandleSource aeh = new VarHandleSource(
68                    MethodHandles.byteArrayViewVarHandle($type$[].class, bo),
69                    endianess, MemoryMode.READ_WRITE);
70            vhss.add(aeh);
71
72            VarHandleSource bbh = new VarHandleSource(
73                    MethodHandles.byteBufferViewVarHandle($type$[].class, bo),
74                    endianess, MemoryMode.READ_WRITE);
75            vhss.add(bbh);
76        }
77    }
78
79
80    @Test(dataProvider = "varHandlesProvider")
81    public void testIsAccessModeSupported(VarHandleSource vhs) {
82        VarHandle vh = vhs.s;
83
84        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
85        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
86
87        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
88        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
89        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
90        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
91        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
92        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
93
94#if[CAS]
95        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
96        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
97        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
98        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
99        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
100        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
101        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
102        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
103        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
104        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
105        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
106#else[CAS]
107        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
108        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
109        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
110        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
111        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
112        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
113        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
114        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
115        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
116        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
117        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
118#end[CAS]
119
120#if[AtomicAdd]
121        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
122        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
123        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
124#else[AtomicAdd]
125        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
126        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
127        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
128#end[AtomicAdd]
129
130#if[Bitwise]
131        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
132        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
133        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
134        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
135        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
136        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
137        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
138        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
139        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
140#else[Bitwise]
141        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
142        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
143        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
144        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
145        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
146        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
147        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
148        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
149        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
150#end[Bitwise]
151    }
152
153    @Test(dataProvider = "typesProvider")
154    public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
155        assertEquals(vh.varType(), $type$.class);
156
157        assertEquals(vh.coordinateTypes(), pts);
158
159        testTypes(vh);
160    }
161
162
163    @DataProvider
164    public Object[][] accessTestCaseProvider() throws Exception {
165        List<AccessTestCase<?>> cases = new ArrayList<>();
166
167        for (ByteArrayViewSource<?> bav : bavss) {
168            for (VarHandleSource vh : vhss) {
169                if (vh.matches(bav)) {
170                    if (bav instanceof ByteArraySource) {
171                        ByteArraySource bas = (ByteArraySource) bav;
172
173                        cases.add(new VarHandleSourceAccessTestCase(
174                                "read write", bav, vh, h -> testArrayReadWrite(bas, h),
175                                true));
176                        cases.add(new VarHandleSourceAccessTestCase(
177                                "null array", bav, vh, h -> testArrayNPE(bas, h),
178                                false));
179                        cases.add(new VarHandleSourceAccessTestCase(
180                                "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
181                                false));
182                        cases.add(new VarHandleSourceAccessTestCase(
183                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
184                                false));
185                        cases.add(new VarHandleSourceAccessTestCase(
186                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
187                                false));
188                    }
189                    else {
190                        ByteBufferSource bbs = (ByteBufferSource) bav;
191
192                        if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
193                            cases.add(new VarHandleSourceAccessTestCase(
194                                    "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
195                                    true));
196                        }
197                        else {
198                            cases.add(new VarHandleSourceAccessTestCase(
199                                    "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
200                                    true));
201                        }
202
203                        cases.add(new VarHandleSourceAccessTestCase(
204                                "null buffer", bav, vh, h -> testArrayNPE(bbs, h),
205                                false));
206                        cases.add(new VarHandleSourceAccessTestCase(
207                                "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
208                                false));
209                        cases.add(new VarHandleSourceAccessTestCase(
210                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
211                                false));
212                        cases.add(new VarHandleSourceAccessTestCase(
213                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
214                                false));
215                    }
216                }
217            }
218        }
219
220        // Work around issue with jtreg summary reporting which truncates
221        // the String result of Object.toString to 30 characters, hence
222        // the first dummy argument
223        return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
224    }
225
226    @Test(dataProvider = "accessTestCaseProvider")
227    public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
228        T t = atc.get();
229        int iters = atc.requiresLoop() ? ITERS : 1;
230        for (int c = 0; c < iters; c++) {
231            atc.testAccess(t);
232        }
233    }
234
235
236    static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) {
237        VarHandle vh = vhs.s;
238        byte[] array = null;
239        int ci = 1;
240
241        checkNPE(() -> {
242            $type$ x = ($type$) vh.get(array, ci);
243        });
244
245        checkNPE(() -> {
246            vh.set(array, ci, VALUE_1);
247        });
248
249        checkNPE(() -> {
250            $type$ x = ($type$) vh.getVolatile(array, ci);
251        });
252
253        checkNPE(() -> {
254            $type$ x = ($type$) vh.getAcquire(array, ci);
255        });
256
257        checkNPE(() -> {
258            $type$ x = ($type$) vh.getOpaque(array, ci);
259        });
260
261        checkNPE(() -> {
262            vh.setVolatile(array, ci, VALUE_1);
263        });
264
265        checkNPE(() -> {
266            vh.setRelease(array, ci, VALUE_1);
267        });
268
269        checkNPE(() -> {
270            vh.setOpaque(array, ci, VALUE_1);
271        });
272
273#if[CAS]
274        checkNPE(() -> {
275            boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
276        });
277
278        checkNPE(() -> {
279            $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
280        });
281
282        checkNPE(() -> {
283            $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
284        });
285
286        checkNPE(() -> {
287            $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
288        });
289
290        checkNPE(() -> {
291            boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
292        });
293
294        checkNPE(() -> {
295            boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
296        });
297
298        checkNPE(() -> {
299            boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
300        });
301
302        checkNPE(() -> {
303            boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
304        });
305
306        checkNPE(() -> {
307            $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
308        });
309
310        checkNPE(() -> {
311            $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
312        });
313
314        checkNPE(() -> {
315            $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
316        });
317#end[CAS]
318
319#if[AtomicAdd]
320        checkNPE(() -> {
321            $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
322        });
323
324        checkNPE(() -> {
325            $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
326        });
327
328        checkNPE(() -> {
329            $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
330        });
331#end[AtomicAdd]
332
333#if[Bitwise]
334        checkNPE(() -> {
335            $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
336        });
337
338        checkNPE(() -> {
339            $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
340        });
341
342        checkNPE(() -> {
343            $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
344        });
345
346        checkNPE(() -> {
347            $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
348        });
349
350        checkNPE(() -> {
351            $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
352        });
353
354        checkNPE(() -> {
355            $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
356        });
357
358        checkNPE(() -> {
359            $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
360        });
361
362        checkNPE(() -> {
363            $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
364        });
365
366        checkNPE(() -> {
367            $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
368        });
369#end[Bitwise]
370    }
371
372    static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
373        VarHandle vh = vhs.s;
374        ByteBuffer array = null;
375        int ci = 1;
376
377        checkNPE(() -> {
378            $type$ x = ($type$) vh.get(array, ci);
379        });
380
381        checkNPE(() -> {
382            vh.set(array, ci, VALUE_1);
383        });
384
385        checkNPE(() -> {
386            $type$ x = ($type$) vh.getVolatile(array, ci);
387        });
388
389        checkNPE(() -> {
390            $type$ x = ($type$) vh.getAcquire(array, ci);
391        });
392
393        checkNPE(() -> {
394            $type$ x = ($type$) vh.getOpaque(array, ci);
395        });
396
397        checkNPE(() -> {
398            vh.setVolatile(array, ci, VALUE_1);
399        });
400
401        checkNPE(() -> {
402            vh.setRelease(array, ci, VALUE_1);
403        });
404
405        checkNPE(() -> {
406            vh.setOpaque(array, ci, VALUE_1);
407        });
408
409#if[CAS]
410        checkNPE(() -> {
411            boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
412        });
413
414        checkNPE(() -> {
415            $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
416        });
417
418        checkNPE(() -> {
419            $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
420        });
421
422        checkNPE(() -> {
423            $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
424        });
425
426        checkNPE(() -> {
427            boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
428        });
429
430        checkNPE(() -> {
431            boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
432        });
433
434        checkNPE(() -> {
435            boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
436        });
437
438        checkNPE(() -> {
439            boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
440        });
441
442        checkNPE(() -> {
443            $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
444        });
445
446        checkNPE(() -> {
447            $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
448        });
449
450        checkNPE(() -> {
451            $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
452        });
453#end[CAS]
454
455#if[AtomicAdd]
456        checkNPE(() -> {
457            $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
458        });
459
460        checkNPE(() -> {
461            $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
462        });
463
464        checkNPE(() -> {
465            $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
466        });
467#end[AtomicAdd]
468
469#if[Bitwise]
470        checkNPE(() -> {
471            $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
472        });
473
474        checkNPE(() -> {
475            $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
476        });
477
478        checkNPE(() -> {
479            $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
480        });
481
482        checkNPE(() -> {
483            $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
484        });
485
486        checkNPE(() -> {
487            $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
488        });
489
490        checkNPE(() -> {
491            $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
492        });
493
494        checkNPE(() -> {
495            $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
496        });
497
498        checkNPE(() -> {
499            $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
500        });
501
502        checkNPE(() -> {
503            $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
504        });
505#end[Bitwise]
506    }
507
508    static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
509        VarHandle vh = vhs.s;
510        byte[] array = bs.s;
511        int ci = 1;
512
513#if[!CAS]
514        checkUOE(() -> {
515            boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
516        });
517
518        checkUOE(() -> {
519            $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
520        });
521
522        checkUOE(() -> {
523            $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
524        });
525
526        checkUOE(() -> {
527            $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
528        });
529
530        checkUOE(() -> {
531            boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
532        });
533
534        checkUOE(() -> {
535            boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
536        });
537
538        checkUOE(() -> {
539            boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
540        });
541
542        checkUOE(() -> {
543            boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
544        });
545
546        checkUOE(() -> {
547            $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
548        });
549
550        checkUOE(() -> {
551            $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
552        });
553
554        checkUOE(() -> {
555            $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
556        });
557#end[CAS]
558
559#if[!AtomicAdd]
560        checkUOE(() -> {
561            $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
562        });
563
564        checkUOE(() -> {
565            $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
566        });
567
568        checkUOE(() -> {
569            $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
570        });
571#end[AtomicAdd]
572
573#if[!Bitwise]
574        checkUOE(() -> {
575            $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
576        });
577
578        checkUOE(() -> {
579            $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
580        });
581
582        checkUOE(() -> {
583            $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
584        });
585
586        checkUOE(() -> {
587            $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
588        });
589
590        checkUOE(() -> {
591            $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
592        });
593
594        checkUOE(() -> {
595            $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
596        });
597
598        checkUOE(() -> {
599            $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
600        });
601
602        checkUOE(() -> {
603            $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
604        });
605
606        checkUOE(() -> {
607            $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
608        });
609#end[Bitwise]
610    }
611
612    static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
613        VarHandle vh = vhs.s;
614        ByteBuffer array = bs.s;
615        int ci = 0;
616        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
617
618        if (readOnly) {
619            checkROBE(() -> {
620                vh.set(array, ci, VALUE_1);
621            });
622        }
623
624        if (readOnly) {
625            checkROBE(() -> {
626                vh.setVolatile(array, ci, VALUE_1);
627            });
628
629            checkROBE(() -> {
630                vh.setRelease(array, ci, VALUE_1);
631            });
632
633            checkROBE(() -> {
634                vh.setOpaque(array, ci, VALUE_1);
635            });
636#if[CAS]
637
638            checkROBE(() -> {
639                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
640            });
641
642            checkROBE(() -> {
643                $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
644            });
645
646            checkROBE(() -> {
647                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
648            });
649
650            checkROBE(() -> {
651                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
652            });
653
654            checkROBE(() -> {
655                boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
656            });
657
658            checkROBE(() -> {
659                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
660            });
661
662            checkROBE(() -> {
663                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
664            });
665
666            checkROBE(() -> {
667                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
668            });
669
670            checkROBE(() -> {
671                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
672            });
673
674            checkROBE(() -> {
675                $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
676            });
677
678            checkROBE(() -> {
679                $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
680            });
681
682#else[CAS]
683            checkUOE(() -> {
684                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
685            });
686
687            checkUOE(() -> {
688                $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
689            });
690
691            checkUOE(() -> {
692                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
693            });
694
695            checkUOE(() -> {
696                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
697            });
698
699            checkUOE(() -> {
700                boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
701            });
702
703            checkUOE(() -> {
704                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
705            });
706
707            checkUOE(() -> {
708                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
709            });
710
711            checkUOE(() -> {
712                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
713            });
714
715            checkUOE(() -> {
716                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
717            });
718
719            checkUOE(() -> {
720                $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
721            });
722
723            checkUOE(() -> {
724                $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
725            });
726#end[CAS]
727
728#if[AtomicAdd]
729            checkROBE(() -> {
730                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
731            });
732
733            checkROBE(() -> {
734                $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
735            });
736
737            checkROBE(() -> {
738                $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
739            });
740#else[AtomicAdd]
741            checkUOE(() -> {
742                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
743            });
744
745            checkUOE(() -> {
746                $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
747            });
748
749            checkUOE(() -> {
750                $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
751            });
752#end[AtomicAdd]
753
754#if[Bitwise]
755            checkROBE(() -> {
756                $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
757            });
758
759            checkROBE(() -> {
760                $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
761            });
762
763            checkROBE(() -> {
764                $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
765            });
766
767            checkROBE(() -> {
768                $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
769            });
770
771            checkROBE(() -> {
772                $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
773            });
774
775            checkROBE(() -> {
776                $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
777            });
778
779            checkROBE(() -> {
780                $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
781            });
782
783            checkROBE(() -> {
784                $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
785            });
786
787            checkROBE(() -> {
788                $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
789            });
790#else[Bitwise]
791            checkUOE(() -> {
792                $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
793            });
794
795            checkUOE(() -> {
796                $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
797            });
798
799            checkUOE(() -> {
800                $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
801            });
802
803            checkUOE(() -> {
804                $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
805            });
806
807            checkUOE(() -> {
808                $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
809            });
810
811            checkUOE(() -> {
812                $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
813            });
814
815            checkUOE(() -> {
816                $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
817            });
818
819            checkUOE(() -> {
820                $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
821            });
822
823            checkUOE(() -> {
824                $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
825            });
826#end[Bitwise]
827        }
828        else {
829#if[!CAS]
830            checkUOE(() -> {
831                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
832            });
833
834            checkUOE(() -> {
835                $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
836            });
837
838            checkUOE(() -> {
839                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
840            });
841
842            checkUOE(() -> {
843                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
844            });
845
846            checkUOE(() -> {
847                boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
848            });
849
850            checkUOE(() -> {
851                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
852            });
853
854            checkUOE(() -> {
855                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
856            });
857
858            checkUOE(() -> {
859                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
860            });
861
862            checkUOE(() -> {
863                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
864            });
865
866            checkUOE(() -> {
867                $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
868            });
869
870            checkUOE(() -> {
871                $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
872            });
873#end[CAS]
874#if[!AtomicAdd]
875            checkUOE(() -> {
876                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
877            });
878
879            checkUOE(() -> {
880                $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
881            });
882
883            checkUOE(() -> {
884                $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
885            });
886#end[AtomicAdd]
887#if[!Bitwise]
888            checkUOE(() -> {
889                $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
890            });
891
892            checkUOE(() -> {
893                $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
894            });
895
896            checkUOE(() -> {
897                $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
898            });
899
900            checkUOE(() -> {
901                $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
902            });
903
904            checkUOE(() -> {
905                $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
906            });
907
908            checkUOE(() -> {
909                $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
910            });
911
912            checkUOE(() -> {
913                $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
914            });
915
916            checkUOE(() -> {
917                $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
918            });
919
920            checkUOE(() -> {
921                $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
922            });
923#end[Bitwise]
924        }
925    }
926
927
928    static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
929        VarHandle vh = vhs.s;
930        byte[] array = bs.s;
931
932        int length = array.length - SIZE + 1;
933        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
934            final int ci = i;
935
936            checkIOOBE(() -> {
937                $type$ x = ($type$) vh.get(array, ci);
938            });
939
940            checkIOOBE(() -> {
941                vh.set(array, ci, VALUE_1);
942            });
943
944            checkIOOBE(() -> {
945                $type$ x = ($type$) vh.getVolatile(array, ci);
946            });
947
948            checkIOOBE(() -> {
949                $type$ x = ($type$) vh.getAcquire(array, ci);
950            });
951
952            checkIOOBE(() -> {
953                $type$ x = ($type$) vh.getOpaque(array, ci);
954            });
955
956            checkIOOBE(() -> {
957                vh.setVolatile(array, ci, VALUE_1);
958            });
959
960            checkIOOBE(() -> {
961                vh.setRelease(array, ci, VALUE_1);
962            });
963
964            checkIOOBE(() -> {
965                vh.setOpaque(array, ci, VALUE_1);
966            });
967#if[CAS]
968
969            checkIOOBE(() -> {
970                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
971            });
972
973            checkIOOBE(() -> {
974                $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
975            });
976
977            checkIOOBE(() -> {
978                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
979            });
980
981            checkIOOBE(() -> {
982                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
983            });
984
985            checkIOOBE(() -> {
986                boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
987            });
988
989            checkIOOBE(() -> {
990                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
991            });
992
993            checkIOOBE(() -> {
994                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
995            });
996
997            checkIOOBE(() -> {
998                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
999            });
1000
1001            checkIOOBE(() -> {
1002                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1003            });
1004
1005            checkIOOBE(() -> {
1006                $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1007            });
1008
1009            checkIOOBE(() -> {
1010                $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1011            });
1012#end[CAS]
1013
1014#if[AtomicAdd]
1015            checkIOOBE(() -> {
1016                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1017            });
1018
1019            checkIOOBE(() -> {
1020                $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1021            });
1022
1023            checkIOOBE(() -> {
1024                $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1025            });
1026#end[AtomicAdd]
1027
1028#if[Bitwise]
1029            checkIOOBE(() -> {
1030                $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1031            });
1032
1033            checkIOOBE(() -> {
1034                $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1035            });
1036
1037            checkIOOBE(() -> {
1038                $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1039            });
1040
1041            checkIOOBE(() -> {
1042                $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1043            });
1044
1045            checkIOOBE(() -> {
1046                $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1047            });
1048
1049            checkIOOBE(() -> {
1050                $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1051            });
1052
1053            checkIOOBE(() -> {
1054                $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1055            });
1056
1057            checkIOOBE(() -> {
1058                $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1059            });
1060
1061            checkIOOBE(() -> {
1062                $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1063            });
1064#end[Bitwise]
1065
1066        }
1067    }
1068
1069    static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
1070        VarHandle vh = vhs.s;
1071        ByteBuffer array = bs.s;
1072
1073        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
1074
1075        int length = array.limit() - SIZE + 1;
1076        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
1077            final int ci = i;
1078
1079            checkIOOBE(() -> {
1080                $type$ x = ($type$) vh.get(array, ci);
1081            });
1082
1083            if (!readOnly) {
1084                checkIOOBE(() -> {
1085                    vh.set(array, ci, VALUE_1);
1086                });
1087            }
1088
1089            checkIOOBE(() -> {
1090                $type$ x = ($type$) vh.getVolatile(array, ci);
1091            });
1092
1093            checkIOOBE(() -> {
1094                $type$ x = ($type$) vh.getAcquire(array, ci);
1095            });
1096
1097            checkIOOBE(() -> {
1098                $type$ x = ($type$) vh.getOpaque(array, ci);
1099            });
1100
1101            if (!readOnly) {
1102                checkIOOBE(() -> {
1103                    vh.setVolatile(array, ci, VALUE_1);
1104                });
1105
1106                checkIOOBE(() -> {
1107                    vh.setRelease(array, ci, VALUE_1);
1108                });
1109
1110                checkIOOBE(() -> {
1111                    vh.setOpaque(array, ci, VALUE_1);
1112                });
1113
1114#if[CAS]
1115                checkIOOBE(() -> {
1116                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
1117                });
1118
1119                checkIOOBE(() -> {
1120                    $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
1121                });
1122
1123                checkIOOBE(() -> {
1124                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
1125                });
1126
1127                checkIOOBE(() -> {
1128                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
1129                });
1130
1131                checkIOOBE(() -> {
1132                    boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
1133                });
1134
1135                checkIOOBE(() -> {
1136                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
1137                });
1138
1139                checkIOOBE(() -> {
1140                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
1141                });
1142
1143                checkIOOBE(() -> {
1144                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
1145                });
1146
1147                checkIOOBE(() -> {
1148                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1149                });
1150
1151                checkIOOBE(() -> {
1152                    $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1153                });
1154
1155                checkIOOBE(() -> {
1156                    $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1157                });
1158#end[CAS]
1159
1160#if[AtomicAdd]
1161                checkIOOBE(() -> {
1162                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1163                });
1164
1165                checkIOOBE(() -> {
1166                    $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1167                });
1168
1169                checkIOOBE(() -> {
1170                    $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1171                });
1172#end[AtomicAdd]
1173
1174#if[Bitwise]
1175                checkIOOBE(() -> {
1176                    $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1177                });
1178
1179                checkIOOBE(() -> {
1180                    $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1181                });
1182
1183                checkIOOBE(() -> {
1184                    $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1185                });
1186
1187                checkIOOBE(() -> {
1188                    $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1189                });
1190
1191                checkIOOBE(() -> {
1192                    $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1193                });
1194
1195                checkIOOBE(() -> {
1196                    $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1197                });
1198
1199                checkIOOBE(() -> {
1200                    $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1201                });
1202
1203                checkIOOBE(() -> {
1204                    $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1205                });
1206
1207                checkIOOBE(() -> {
1208                    $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1209                });
1210#end[Bitwise]
1211            }
1212        }
1213    }
1214
1215    static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
1216        VarHandle vh = vhs.s;
1217        byte[] array = bs.s;
1218
1219        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
1220
1221        int length = array.length - SIZE + 1;
1222        for (int i = 0; i < length; i++) {
1223            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1224            final int ci = i;
1225
1226            if (!iAligned) {
1227                checkISE(() -> {
1228                    $type$ x = ($type$) vh.getVolatile(array, ci);
1229                });
1230
1231                checkISE(() -> {
1232                    $type$ x = ($type$) vh.getAcquire(array, ci);
1233                });
1234
1235                checkISE(() -> {
1236                    $type$ x = ($type$) vh.getOpaque(array, ci);
1237                });
1238
1239                checkISE(() -> {
1240                    vh.setVolatile(array, ci, VALUE_1);
1241                });
1242
1243                checkISE(() -> {
1244                    vh.setRelease(array, ci, VALUE_1);
1245                });
1246
1247                checkISE(() -> {
1248                    vh.setOpaque(array, ci, VALUE_1);
1249                });
1250#if[CAS]
1251
1252                checkISE(() -> {
1253                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
1254                });
1255
1256                checkISE(() -> {
1257                    $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
1258                });
1259
1260                checkISE(() -> {
1261                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
1262                });
1263
1264                checkISE(() -> {
1265                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
1266                });
1267
1268                checkISE(() -> {
1269                    boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
1270                });
1271
1272                checkISE(() -> {
1273                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
1274                });
1275
1276                checkISE(() -> {
1277                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
1278                });
1279
1280                checkISE(() -> {
1281                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
1282                });
1283
1284                checkISE(() -> {
1285                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1286                });
1287
1288                checkISE(() -> {
1289                    $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1290                });
1291
1292                checkISE(() -> {
1293                    $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1294                });
1295#end[CAS]
1296
1297#if[AtomicAdd]
1298                checkISE(() -> {
1299                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1300                });
1301
1302                checkISE(() -> {
1303                    $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1304                });
1305
1306                checkISE(() -> {
1307                    $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1308                });
1309#end[AtomicAdd]
1310
1311#if[Bitwise]
1312                checkISE(() -> {
1313                    $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1314                });
1315
1316                checkISE(() -> {
1317                    $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1318                });
1319
1320                checkISE(() -> {
1321                    $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1322                });
1323
1324                checkISE(() -> {
1325                    $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1326                });
1327
1328                checkISE(() -> {
1329                    $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1330                });
1331
1332                checkISE(() -> {
1333                    $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1334                });
1335
1336                checkISE(() -> {
1337                    $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1338                });
1339
1340                checkISE(() -> {
1341                    $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1342                });
1343
1344                checkISE(() -> {
1345                    $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1346                });
1347#end[Bitwise]
1348            }
1349        }
1350    }
1351
1352    static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
1353        VarHandle vh = vhs.s;
1354        ByteBuffer array = bs.s;
1355
1356        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
1357        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1358
1359        int length = array.limit() - SIZE + 1;
1360        for (int i = 0; i < length; i++) {
1361            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1362            final int ci = i;
1363
1364            if (!iAligned) {
1365                checkISE(() -> {
1366                    $type$ x = ($type$) vh.getVolatile(array, ci);
1367                });
1368
1369                checkISE(() -> {
1370                    $type$ x = ($type$) vh.getAcquire(array, ci);
1371                });
1372
1373                checkISE(() -> {
1374                    $type$ x = ($type$) vh.getOpaque(array, ci);
1375                });
1376
1377                if (!readOnly) {
1378                    checkISE(() -> {
1379                        vh.setVolatile(array, ci, VALUE_1);
1380                    });
1381
1382                    checkISE(() -> {
1383                        vh.setRelease(array, ci, VALUE_1);
1384                    });
1385
1386                    checkISE(() -> {
1387                        vh.setOpaque(array, ci, VALUE_1);
1388                    });
1389
1390#if[CAS]
1391                    checkISE(() -> {
1392                        boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
1393                    });
1394
1395                    checkISE(() -> {
1396                        $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
1397                    });
1398
1399                    checkISE(() -> {
1400                        $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
1401                    });
1402
1403                    checkISE(() -> {
1404                        $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
1405                    });
1406
1407                    checkISE(() -> {
1408                        boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
1409                    });
1410
1411                    checkISE(() -> {
1412                        boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
1413                    });
1414
1415                    checkISE(() -> {
1416                        boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
1417                    });
1418
1419                    checkISE(() -> {
1420                        boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
1421                    });
1422
1423                    checkISE(() -> {
1424                        $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1425                    });
1426
1427                    checkISE(() -> {
1428                        $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1429                    });
1430
1431                    checkISE(() -> {
1432                        $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1433                    });
1434#end[CAS]
1435
1436#if[AtomicAdd]
1437                    checkISE(() -> {
1438                        $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1439                    });
1440
1441                    checkISE(() -> {
1442                        $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1443                    });
1444
1445                    checkISE(() -> {
1446                        $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1447                    });
1448#end[AtomicAdd]
1449
1450#if[Bitwise]
1451                    checkISE(() -> {
1452                        $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1453                    });
1454
1455                    checkISE(() -> {
1456                        $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1457                    });
1458
1459                    checkISE(() -> {
1460                        $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1461                    });
1462
1463                    checkISE(() -> {
1464                        $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1465                    });
1466
1467                    checkISE(() -> {
1468                        $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1469                    });
1470
1471                    checkISE(() -> {
1472                        $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1473                    });
1474
1475                    checkISE(() -> {
1476                        $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1477                    });
1478
1479                    checkISE(() -> {
1480                        $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1481                    });
1482
1483                    checkISE(() -> {
1484                        $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1485                    });
1486#end[Bitwise]
1487                }
1488            }
1489        }
1490    }
1491
1492    static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
1493        VarHandle vh = vhs.s;
1494        byte[] array = bs.s;
1495
1496        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
1497
1498        bs.fill((byte) 0xff);
1499        int length = array.length - SIZE + 1;
1500        for (int i = 0; i < length; i++) {
1501            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1502
1503            // Plain
1504            {
1505                vh.set(array, i, VALUE_1);
1506                $type$ x = ($type$) vh.get(array, i);
1507                assertEquals(x, VALUE_1, "get $type$ value");
1508            }
1509
1510
1511            if (iAligned) {
1512                // Volatile
1513                {
1514                    vh.setVolatile(array, i, VALUE_2);
1515                    $type$ x = ($type$) vh.getVolatile(array, i);
1516                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
1517                }
1518
1519                // Lazy
1520                {
1521                    vh.setRelease(array, i, VALUE_1);
1522                    $type$ x = ($type$) vh.getAcquire(array, i);
1523                    assertEquals(x, VALUE_1, "setRelease $type$ value");
1524                }
1525
1526                // Opaque
1527                {
1528                    vh.setOpaque(array, i, VALUE_2);
1529                    $type$ x = ($type$) vh.getOpaque(array, i);
1530                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
1531                }
1532#if[CAS]
1533
1534                vh.set(array, i, VALUE_1);
1535
1536                // Compare
1537                {
1538                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
1539                    assertEquals(r, true, "success compareAndSet $type$");
1540                    $type$ x = ($type$) vh.get(array, i);
1541                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
1542                }
1543
1544                {
1545                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1546                    assertEquals(r, false, "failing compareAndSet $type$");
1547                    $type$ x = ($type$) vh.get(array, i);
1548                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
1549                }
1550
1551                {
1552                    $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1553                    assertEquals(r, VALUE_2, "success compareAndExchange $type$");
1554                    $type$ x = ($type$) vh.get(array, i);
1555                    assertEquals(x, VALUE_1, "success compareAndExchange $type$ value");
1556                }
1557
1558                {
1559                    $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1560                    assertEquals(r, VALUE_1, "failing compareAndExchange $type$");
1561                    $type$ x = ($type$) vh.get(array, i);
1562                    assertEquals(x, VALUE_1, "failing compareAndExchange $type$ value");
1563                }
1564
1565                {
1566                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1567                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
1568                    $type$ x = ($type$) vh.get(array, i);
1569                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
1570                }
1571
1572                {
1573                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1574                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
1575                    $type$ x = ($type$) vh.get(array, i);
1576                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
1577                }
1578
1579                {
1580                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1581                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
1582                    $type$ x = ($type$) vh.get(array, i);
1583                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
1584                }
1585
1586                {
1587                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1588                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
1589                    $type$ x = ($type$) vh.get(array, i);
1590                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
1591                }
1592
1593                {
1594                    boolean success = false;
1595                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1596                        success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1597                    }
1598                    assertEquals(success, true, "weakCompareAndSetPlain $type$");
1599                    $type$ x = ($type$) vh.get(array, i);
1600                    assertEquals(x, VALUE_2, "weakCompareAndSetPlain $type$ value");
1601                }
1602
1603                {
1604                    boolean success = false;
1605                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1606                        success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1607                    }
1608                    assertEquals(success, true, "weakCompareAndSetAcquire $type$");
1609                    $type$ x = ($type$) vh.get(array, i);
1610                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
1611                }
1612
1613                {
1614                    boolean success = false;
1615                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1616                        success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1617                    }
1618                    assertEquals(success, true, "weakCompareAndSetRelease $type$");
1619                    $type$ x = ($type$) vh.get(array, i);
1620                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
1621                }
1622
1623                {
1624                    boolean success = false;
1625                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1626                        success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1627                    }
1628                    assertEquals(success, true, "weakCompareAndSet $type$");
1629                    $type$ x = ($type$) vh.get(array, i);
1630                    assertEquals(x, VALUE_1, "weakCompareAndSet $type$");
1631                }
1632
1633                // Compare set and get
1634                {
1635                    vh.set(array, i, VALUE_1);
1636
1637                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
1638                    assertEquals(o, VALUE_1, "getAndSet $type$");
1639                    $type$ x = ($type$) vh.get(array, i);
1640                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
1641                }
1642
1643                {
1644                    vh.set(array, i, VALUE_1);
1645
1646                    $type$ o = ($type$) vh.getAndSetAcquire(array, i, VALUE_2);
1647                    assertEquals(o, VALUE_1, "getAndSetAcquire $type$");
1648                    $type$ x = ($type$) vh.get(array, i);
1649                    assertEquals(x, VALUE_2, "getAndSetAcquire $type$ value");
1650                }
1651
1652                {
1653                    vh.set(array, i, VALUE_1);
1654
1655                    $type$ o = ($type$) vh.getAndSetRelease(array, i, VALUE_2);
1656                    assertEquals(o, VALUE_1, "getAndSetRelease $type$");
1657                    $type$ x = ($type$) vh.get(array, i);
1658                    assertEquals(x, VALUE_2, "getAndSetRelease $type$ value");
1659                }
1660#end[CAS]
1661
1662#if[AtomicAdd]
1663                // get and add, add and get
1664                {
1665                    vh.set(array, i, VALUE_1);
1666
1667                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_2);
1668                    assertEquals(o, VALUE_1, "getAndAdd $type$");
1669                    $type$ x = ($type$) vh.get(array, i);
1670                    assertEquals(x, VALUE_1 + VALUE_2, "getAndAdd $type$ value");
1671                }
1672
1673                {
1674                    vh.set(array, i, VALUE_1);
1675
1676                    $type$ o = ($type$) vh.getAndAddAcquire(array, i, VALUE_2);
1677                    assertEquals(o, VALUE_1, "getAndAddAcquire $type$");
1678                    $type$ x = ($type$) vh.get(array, i);
1679                    assertEquals(x, VALUE_1 + VALUE_2, "getAndAddAcquire $type$ value");
1680                }
1681
1682                {
1683                    vh.set(array, i, VALUE_1);
1684
1685                    $type$ o = ($type$) vh.getAndAddRelease(array, i, VALUE_2);
1686                    assertEquals(o, VALUE_1, "getAndAddRelease $type$");
1687                    $type$ x = ($type$) vh.get(array, i);
1688                    assertEquals(x, VALUE_1 + VALUE_2, "getAndAddRelease $type$ value");
1689                }
1690#end[AtomicAdd]
1691
1692#if[Bitwise]
1693                // get and bitwise or
1694                {
1695                    vh.set(array, i, VALUE_1);
1696
1697                    $type$ o = ($type$) vh.getAndBitwiseOr(array, i, VALUE_2);
1698                    assertEquals(o, VALUE_1, "getAndBitwiseOr $type$");
1699                    $type$ x = ($type$) vh.get(array, i);
1700                    assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOr $type$ value");
1701                }
1702
1703                {
1704                    vh.set(array, i, VALUE_1);
1705
1706                    $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, VALUE_2);
1707                    assertEquals(o, VALUE_1, "getAndBitwiseOrAcquire $type$");
1708                    $type$ x = ($type$) vh.get(array, i);
1709                    assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrAcquire $type$ value");
1710                }
1711
1712                {
1713                    vh.set(array, i, VALUE_1);
1714
1715                    $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, VALUE_2);
1716                    assertEquals(o, VALUE_1, "getAndBitwiseOrRelease $type$");
1717                    $type$ x = ($type$) vh.get(array, i);
1718                    assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrRelease $type$ value");
1719                }
1720
1721                // get and bitwise and
1722                {
1723                    vh.set(array, i, VALUE_1);
1724
1725                    $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, VALUE_2);
1726                    assertEquals(o, VALUE_1, "getAndBitwiseAnd $type$");
1727                    $type$ x = ($type$) vh.get(array, i);
1728                    assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAnd $type$ value");
1729                }
1730
1731                {
1732                    vh.set(array, i, VALUE_1);
1733
1734                    $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, VALUE_2);
1735                    assertEquals(o, VALUE_1, "getAndBitwiseAndAcquire $type$");
1736                    $type$ x = ($type$) vh.get(array, i);
1737                    assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndAcquire $type$ value");
1738                }
1739
1740                {
1741                    vh.set(array, i, VALUE_1);
1742
1743                    $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, VALUE_2);
1744                    assertEquals(o, VALUE_1, "getAndBitwiseAndRelease $type$");
1745                    $type$ x = ($type$) vh.get(array, i);
1746                    assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndRelease $type$ value");
1747                }
1748
1749                // get and bitwise xor
1750                {
1751                    vh.set(array, i, VALUE_1);
1752
1753                    $type$ o = ($type$) vh.getAndBitwiseXor(array, i, VALUE_2);
1754                    assertEquals(o, VALUE_1, "getAndBitwiseXor $type$");
1755                    $type$ x = ($type$) vh.get(array, i);
1756                    assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXor $type$ value");
1757                }
1758
1759                {
1760                    vh.set(array, i, VALUE_1);
1761
1762                    $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, VALUE_2);
1763                    assertEquals(o, VALUE_1, "getAndBitwiseXorAcquire $type$");
1764                    $type$ x = ($type$) vh.get(array, i);
1765                    assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorAcquire $type$ value");
1766                }
1767
1768                {
1769                    vh.set(array, i, VALUE_1);
1770
1771                    $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, VALUE_2);
1772                    assertEquals(o, VALUE_1, "getAndBitwiseXorRelease $type$");
1773                    $type$ x = ($type$) vh.get(array, i);
1774                    assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorRelease $type$ value");
1775                }
1776#end[Bitwise]
1777            }
1778        }
1779    }
1780
1781
1782    static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
1783        VarHandle vh = vhs.s;
1784        ByteBuffer array = bs.s;
1785
1786        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1787
1788        bs.fill((byte) 0xff);
1789        int length = array.limit() - SIZE + 1;
1790        for (int i = 0; i < length; i++) {
1791            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1792
1793            // Plain
1794            {
1795                vh.set(array, i, VALUE_1);
1796                $type$ x = ($type$) vh.get(array, i);
1797                assertEquals(x, VALUE_1, "get $type$ value");
1798            }
1799
1800            if (iAligned) {
1801                // Volatile
1802                {
1803                    vh.setVolatile(array, i, VALUE_2);
1804                    $type$ x = ($type$) vh.getVolatile(array, i);
1805                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
1806                }
1807
1808                // Lazy
1809                {
1810                    vh.setRelease(array, i, VALUE_1);
1811                    $type$ x = ($type$) vh.getAcquire(array, i);
1812                    assertEquals(x, VALUE_1, "setRelease $type$ value");
1813                }
1814
1815                // Opaque
1816                {
1817                    vh.setOpaque(array, i, VALUE_2);
1818                    $type$ x = ($type$) vh.getOpaque(array, i);
1819                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
1820                }
1821#if[CAS]
1822
1823                vh.set(array, i, VALUE_1);
1824
1825                // Compare
1826                {
1827                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
1828                    assertEquals(r, true, "success compareAndSet $type$");
1829                    $type$ x = ($type$) vh.get(array, i);
1830                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
1831                }
1832
1833                {
1834                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1835                    assertEquals(r, false, "failing compareAndSet $type$");
1836                    $type$ x = ($type$) vh.get(array, i);
1837                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
1838                }
1839
1840                {
1841                    $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1842                    assertEquals(r, VALUE_2, "success compareAndExchange $type$");
1843                    $type$ x = ($type$) vh.get(array, i);
1844                    assertEquals(x, VALUE_1, "success compareAndExchange $type$ value");
1845                }
1846
1847                {
1848                    $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1849                    assertEquals(r, VALUE_1, "failing compareAndExchange $type$");
1850                    $type$ x = ($type$) vh.get(array, i);
1851                    assertEquals(x, VALUE_1, "failing compareAndExchange $type$ value");
1852                }
1853
1854                {
1855                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1856                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
1857                    $type$ x = ($type$) vh.get(array, i);
1858                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
1859                }
1860
1861                {
1862                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1863                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
1864                    $type$ x = ($type$) vh.get(array, i);
1865                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
1866                }
1867
1868                {
1869                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1870                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
1871                    $type$ x = ($type$) vh.get(array, i);
1872                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
1873                }
1874
1875                {
1876                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1877                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
1878                    $type$ x = ($type$) vh.get(array, i);
1879                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
1880                }
1881
1882                {
1883                    boolean success = false;
1884                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1885                        success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1886                    }
1887                    assertEquals(success, true, "weakCompareAndSetPlain $type$");
1888                    $type$ x = ($type$) vh.get(array, i);
1889                    assertEquals(x, VALUE_2, "weakCompareAndSetPlain $type$ value");
1890                }
1891
1892                {
1893                    boolean success = false;
1894                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1895                        success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1896                    }
1897                    assertEquals(success, true, "weakCompareAndSetAcquire $type$");
1898                    $type$ x = ($type$) vh.get(array, i);
1899                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
1900                }
1901
1902                {
1903                    boolean success = false;
1904                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1905                        success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1906                    }
1907                    assertEquals(success, true, "weakCompareAndSetRelease $type$");
1908                    $type$ x = ($type$) vh.get(array, i);
1909                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
1910                }
1911
1912                {
1913                    boolean success = false;
1914                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1915                        success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1916                    }
1917                    assertEquals(success, true, "weakCompareAndSet $type$");
1918                    $type$ x = ($type$) vh.get(array, i);
1919                    assertEquals(x, VALUE_1, "weakCompareAndSet $type$");
1920                }
1921
1922                // Compare set and get
1923                {
1924                    vh.set(array, i, VALUE_1);
1925
1926                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
1927                    assertEquals(o, VALUE_1, "getAndSet $type$");
1928                    $type$ x = ($type$) vh.get(array, i);
1929                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
1930                }
1931
1932                {
1933                    vh.set(array, i, VALUE_1);
1934
1935                    $type$ o = ($type$) vh.getAndSetAcquire(array, i, VALUE_2);
1936                    assertEquals(o, VALUE_1, "getAndSetAcquire $type$");
1937                    $type$ x = ($type$) vh.get(array, i);
1938                    assertEquals(x, VALUE_2, "getAndSetAcquire $type$ value");
1939                }
1940
1941                {
1942                    vh.set(array, i, VALUE_1);
1943
1944                    $type$ o = ($type$) vh.getAndSetRelease(array, i, VALUE_2);
1945                    assertEquals(o, VALUE_1, "getAndSetRelease $type$");
1946                    $type$ x = ($type$) vh.get(array, i);
1947                    assertEquals(x, VALUE_2, "getAndSetRelease $type$ value");
1948                }
1949#end[CAS]
1950
1951#if[AtomicAdd]
1952                // get and add, add and get
1953                {
1954                    vh.set(array, i, VALUE_1);
1955
1956                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_2);
1957                    assertEquals(o, VALUE_1, "getAndAdd $type$");
1958                    $type$ x = ($type$) vh.get(array, i);
1959                    assertEquals(x, VALUE_1 + VALUE_2, "getAndAdd $type$ value");
1960                }
1961
1962                {
1963                    vh.set(array, i, VALUE_1);
1964
1965                    $type$ o = ($type$) vh.getAndAddAcquire(array, i, VALUE_2);
1966                    assertEquals(o, VALUE_1, "getAndAddAcquire $type$");
1967                    $type$ x = ($type$) vh.get(array, i);
1968                    assertEquals(x, VALUE_1 + VALUE_2, "getAndAddAcquire $type$ value");
1969                }
1970
1971                {
1972                    vh.set(array, i, VALUE_1);
1973
1974                    $type$ o = ($type$) vh.getAndAddRelease(array, i, VALUE_2);
1975                    assertEquals(o, VALUE_1, "getAndAddRelease $type$");
1976                    $type$ x = ($type$) vh.get(array, i);
1977                    assertEquals(x, VALUE_1 + VALUE_2, "getAndAddRelease $type$ value");
1978                }
1979#end[AtomicAdd]
1980
1981#if[Bitwise]
1982                // get and bitwise or
1983                {
1984                    vh.set(array, i, VALUE_1);
1985
1986                    $type$ o = ($type$) vh.getAndBitwiseOr(array, i, VALUE_2);
1987                    assertEquals(o, VALUE_1, "getAndBitwiseOr $type$");
1988                    $type$ x = ($type$) vh.get(array, i);
1989                    assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOr $type$ value");
1990                }
1991
1992                {
1993                    vh.set(array, i, VALUE_1);
1994
1995                    $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, VALUE_2);
1996                    assertEquals(o, VALUE_1, "getAndBitwiseOrAcquire $type$");
1997                    $type$ x = ($type$) vh.get(array, i);
1998                    assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrAcquire $type$ value");
1999                }
2000
2001                {
2002                    vh.set(array, i, VALUE_1);
2003
2004                    $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, VALUE_2);
2005                    assertEquals(o, VALUE_1, "getAndBitwiseOrRelease $type$");
2006                    $type$ x = ($type$) vh.get(array, i);
2007                    assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrRelease $type$ value");
2008                }
2009
2010                // get and bitwise and
2011                {
2012                    vh.set(array, i, VALUE_1);
2013
2014                    $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, VALUE_2);
2015                    assertEquals(o, VALUE_1, "getAndBitwiseAnd $type$");
2016                    $type$ x = ($type$) vh.get(array, i);
2017                    assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAnd $type$ value");
2018                }
2019
2020                {
2021                    vh.set(array, i, VALUE_1);
2022
2023                    $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, VALUE_2);
2024                    assertEquals(o, VALUE_1, "getAndBitwiseAndAcquire $type$");
2025                    $type$ x = ($type$) vh.get(array, i);
2026                    assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndAcquire $type$ value");
2027                }
2028
2029                {
2030                    vh.set(array, i, VALUE_1);
2031
2032                    $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, VALUE_2);
2033                    assertEquals(o, VALUE_1, "getAndBitwiseAndRelease $type$");
2034                    $type$ x = ($type$) vh.get(array, i);
2035                    assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndRelease $type$ value");
2036                }
2037
2038                // get and bitwise xor
2039                {
2040                    vh.set(array, i, VALUE_1);
2041
2042                    $type$ o = ($type$) vh.getAndBitwiseXor(array, i, VALUE_2);
2043                    assertEquals(o, VALUE_1, "getAndBitwiseXor $type$");
2044                    $type$ x = ($type$) vh.get(array, i);
2045                    assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXor $type$ value");
2046                }
2047
2048                {
2049                    vh.set(array, i, VALUE_1);
2050
2051                    $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, VALUE_2);
2052                    assertEquals(o, VALUE_1, "getAndBitwiseXorAcquire $type$");
2053                    $type$ x = ($type$) vh.get(array, i);
2054                    assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorAcquire $type$ value");
2055                }
2056
2057                {
2058                    vh.set(array, i, VALUE_1);
2059
2060                    $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, VALUE_2);
2061                    assertEquals(o, VALUE_1, "getAndBitwiseXorRelease $type$");
2062                    $type$ x = ($type$) vh.get(array, i);
2063                    assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorRelease $type$ value");
2064                }
2065#end[Bitwise]
2066            }
2067        }
2068    }
2069
2070    static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
2071        VarHandle vh = vhs.s;
2072        ByteBuffer array = bs.s;
2073
2074        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
2075
2076        ByteBuffer bb = ByteBuffer.allocate(SIZE);
2077        bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
2078        bs.fill(bb.put$Type$(0, VALUE_2).array());
2079
2080        int length = array.limit() - SIZE + 1;
2081        for (int i = 0; i < length; i++) {
2082            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
2083
2084            $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
2085                    ? rotateLeft(VALUE_2, (i % SIZE) << 3)
2086                    : rotateRight(VALUE_2, (i % SIZE) << 3);
2087            // Plain
2088            {
2089                $type$ x = ($type$) vh.get(array, i);
2090                assertEquals(x, v, "get $type$ value");
2091            }
2092
2093            if (iAligned) {
2094                // Volatile
2095                {
2096                    $type$ x = ($type$) vh.getVolatile(array, i);
2097                    assertEquals(x, v, "getVolatile $type$ value");
2098                }
2099
2100                // Lazy
2101                {
2102                    $type$ x = ($type$) vh.getAcquire(array, i);
2103                    assertEquals(x, v, "getRelease $type$ value");
2104                }
2105
2106                // Opaque
2107                {
2108                    $type$ x = ($type$) vh.getOpaque(array, i);
2109                    assertEquals(x, v, "getOpaque $type$ value");
2110                }
2111            }
2112        }
2113    }
2114
2115}
2116
2117