X-VarHandleTestByteArrayView.java.template revision 14156:9c64b9eeb312
1/*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
27 * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAs$Type$
28 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAs$Type$
29 */
30
31import org.testng.annotations.DataProvider;
32import org.testng.annotations.Test;
33
34import java.lang.invoke.MethodHandles;
35import java.lang.invoke.VarHandle;
36import java.nio.ByteBuffer;
37import java.nio.ByteOrder;
38import java.util.ArrayList;
39import java.util.Arrays;
40import java.util.EnumSet;
41import java.util.List;
42
43import static org.testng.Assert.*;
44
45public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest {
46    static final int SIZE = $BoxType$.BYTES;
47
48    static final $type$ VALUE_1 = $value1$;
49
50    static final $type$ VALUE_2 = $value2$;
51
52    static final $type$ VALUE_3 = $value3$;
53
54
55    @Override
56    public void setupVarHandleSources() {
57        // Combinations of VarHandle byte[] or ByteBuffer
58        vhss = new ArrayList<>();
59        for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
60            VarHandleSource aeh = new VarHandleSource(
61                    MethodHandles.byteArrayViewVarHandle($type$[].class,
62                                                         endianess == MemoryMode.BIG_ENDIAN),
63                    endianess, MemoryMode.READ_WRITE);
64            vhss.add(aeh);
65
66            VarHandleSource bbh = new VarHandleSource(
67                    MethodHandles.byteBufferViewVarHandle($type$[].class,
68                                                          endianess == MemoryMode.BIG_ENDIAN),
69                    endianess, MemoryMode.READ_WRITE);
70            vhss.add(bbh);
71        }
72    }
73
74
75    @Test(dataProvider = "varHandlesProvider")
76    public void testIsAccessModeSupported(VarHandleSource vhs) {
77        VarHandle vh = vhs.s;
78
79        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
80        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
81
82        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
83        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
84        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
85        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
86        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
87        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
88
89#if[CAS]
90        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
91        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
92        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
93        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
94        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
95        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
96        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
97        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
98#else[CAS]
99        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
100        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
101        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
102        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
103        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
104        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
105        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
106        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
107#end[CAS]
108
109#if[AtomicAdd]
110        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
111        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
112#else[AtomicAdd]
113        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
114        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
115#end[AtomicAdd]
116    }
117
118    @Test(dataProvider = "typesProvider")
119    public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
120        assertEquals(vh.varType(), $type$.class);
121
122        assertEquals(vh.coordinateTypes(), pts);
123
124        testTypes(vh);
125    }
126
127
128    @DataProvider
129    public Object[][] accessTestCaseProvider() throws Exception {
130        List<AccessTestCase<?>> cases = new ArrayList<>();
131
132        for (ByteArrayViewSource<?> bav : bavss) {
133            for (VarHandleSource vh : vhss) {
134                if (vh.matches(bav)) {
135                    if (bav instanceof ByteArraySource) {
136                        ByteArraySource bas = (ByteArraySource) bav;
137
138                        cases.add(new VarHandleSourceAccessTestCase(
139                                "read write", bav, vh, h -> testArrayReadWrite(bas, h),
140                                true));
141                        cases.add(new VarHandleSourceAccessTestCase(
142                                "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
143                                false));
144                        cases.add(new VarHandleSourceAccessTestCase(
145                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
146                                false));
147                        cases.add(new VarHandleSourceAccessTestCase(
148                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
149                                false));
150                    }
151                    else {
152                        ByteBufferSource bbs = (ByteBufferSource) bav;
153
154                        if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
155                            cases.add(new VarHandleSourceAccessTestCase(
156                                    "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
157                                    true));
158                        }
159                        else {
160                            cases.add(new VarHandleSourceAccessTestCase(
161                                    "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
162                                    true));
163                        }
164
165                        cases.add(new VarHandleSourceAccessTestCase(
166                                "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
167                                false));
168                        cases.add(new VarHandleSourceAccessTestCase(
169                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
170                                false));
171                        cases.add(new VarHandleSourceAccessTestCase(
172                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
173                                false));
174                    }
175                }
176            }
177        }
178
179        // Work around issue with jtreg summary reporting which truncates
180        // the String result of Object.toString to 30 characters, hence
181        // the first dummy argument
182        return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
183    }
184
185    @Test(dataProvider = "accessTestCaseProvider")
186    public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
187        T t = atc.get();
188        int iters = atc.requiresLoop() ? ITERS : 1;
189        for (int c = 0; c < iters; c++) {
190            atc.testAccess(t);
191        }
192    }
193
194
195    static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
196        VarHandle vh = vhs.s;
197        byte[] array = bs.s;
198        int ci = 1;
199
200#if[!CAS]
201        checkUOE(() -> {
202            boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
203        });
204
205        checkUOE(() -> {
206            $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
207        });
208
209        checkUOE(() -> {
210            $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
211        });
212
213        checkUOE(() -> {
214            $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
215        });
216
217        checkUOE(() -> {
218            boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
219        });
220
221        checkUOE(() -> {
222            boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
223        });
224
225        checkUOE(() -> {
226            boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
227        });
228
229        checkUOE(() -> {
230            $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
231        });
232#end[CAS]
233
234#if[!AtomicAdd]
235        checkUOE(() -> {
236            $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
237        });
238
239        checkUOE(() -> {
240            $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
241        });
242#end[AtomicAdd]
243    }
244
245    static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
246        VarHandle vh = vhs.s;
247        ByteBuffer array = bs.s;
248        int ci = 0;
249        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
250
251        if (readOnly) {
252            checkROBE(() -> {
253                vh.set(array, ci, VALUE_1);
254            });
255        }
256
257        if (readOnly) {
258            checkROBE(() -> {
259                vh.setVolatile(array, ci, VALUE_1);
260            });
261
262            checkROBE(() -> {
263                vh.setRelease(array, ci, VALUE_1);
264            });
265
266            checkROBE(() -> {
267                vh.setOpaque(array, ci, VALUE_1);
268            });
269#if[CAS]
270
271            checkROBE(() -> {
272                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
273            });
274
275            checkROBE(() -> {
276                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
277            });
278
279            checkROBE(() -> {
280                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
281            });
282
283            checkROBE(() -> {
284                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
285            });
286
287            checkROBE(() -> {
288                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
289            });
290
291            checkROBE(() -> {
292                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
293            });
294
295            checkROBE(() -> {
296                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
297            });
298
299            checkROBE(() -> {
300                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
301            });
302            checkUOE(() -> {
303                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
304            });
305#else[CAS]
306            checkUOE(() -> {
307                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
308            });
309
310            checkUOE(() -> {
311                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
312            });
313
314            checkUOE(() -> {
315                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
316            });
317
318            checkUOE(() -> {
319                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
320            });
321
322            checkUOE(() -> {
323                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
324            });
325
326            checkUOE(() -> {
327                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
328            });
329
330            checkUOE(() -> {
331                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
332            });
333#end[CAS]
334
335#if[AtomicAdd]
336            checkROBE(() -> {
337                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
338            });
339
340            checkROBE(() -> {
341                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
342            });
343#else[AtomicAdd]
344            checkUOE(() -> {
345                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
346            });
347
348            checkUOE(() -> {
349                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
350            });
351#end[AtomicAdd]
352        }
353        else {
354#if[!CAS]
355            checkUOE(() -> {
356                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
357            });
358
359            checkUOE(() -> {
360                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
361            });
362
363            checkUOE(() -> {
364                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
365            });
366
367            checkUOE(() -> {
368                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
369            });
370
371            checkUOE(() -> {
372                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
373            });
374
375            checkUOE(() -> {
376                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
377            });
378
379            checkUOE(() -> {
380                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
381            });
382
383            checkUOE(() -> {
384                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
385            });
386#end[CAS]
387#if[!AtomicAdd]
388            checkUOE(() -> {
389                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
390            });
391
392            checkUOE(() -> {
393                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
394            });
395#end[AtomicAdd]
396        }
397    }
398
399
400    static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
401        VarHandle vh = vhs.s;
402        byte[] array = bs.s;
403
404        int length = array.length - SIZE + 1;
405        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
406            final int ci = i;
407
408            checkIOOBE(() -> {
409                $type$ x = ($type$) vh.get(array, ci);
410            });
411
412            checkIOOBE(() -> {
413                vh.set(array, ci, VALUE_1);
414            });
415
416            checkIOOBE(() -> {
417                $type$ x = ($type$) vh.getVolatile(array, ci);
418            });
419
420            checkIOOBE(() -> {
421                $type$ x = ($type$) vh.getAcquire(array, ci);
422            });
423
424            checkIOOBE(() -> {
425                $type$ x = ($type$) vh.getOpaque(array, ci);
426            });
427
428            checkIOOBE(() -> {
429                vh.setVolatile(array, ci, VALUE_1);
430            });
431
432            checkIOOBE(() -> {
433                vh.setRelease(array, ci, VALUE_1);
434            });
435
436            checkIOOBE(() -> {
437                vh.setOpaque(array, ci, VALUE_1);
438            });
439#if[CAS]
440
441            checkIOOBE(() -> {
442                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
443            });
444
445            checkIOOBE(() -> {
446                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
447            });
448
449            checkIOOBE(() -> {
450                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
451            });
452
453            checkIOOBE(() -> {
454                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
455            });
456
457            checkIOOBE(() -> {
458                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
459            });
460
461            checkIOOBE(() -> {
462                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
463            });
464
465            checkIOOBE(() -> {
466                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
467            });
468
469            checkIOOBE(() -> {
470                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
471            });
472#end[CAS]
473
474#if[AtomicAdd]
475            checkIOOBE(() -> {
476                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
477            });
478
479            checkIOOBE(() -> {
480                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
481            });
482#end[AtomicAdd]
483
484        }
485    }
486
487    static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
488        VarHandle vh = vhs.s;
489        ByteBuffer array = bs.s;
490
491        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
492
493        int length = array.limit() - SIZE + 1;
494        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
495            final int ci = i;
496
497            checkIOOBE(() -> {
498                $type$ x = ($type$) vh.get(array, ci);
499            });
500
501            if (!readOnly) {
502                checkIOOBE(() -> {
503                    vh.set(array, ci, VALUE_1);
504                });
505            }
506
507            checkIOOBE(() -> {
508                $type$ x = ($type$) vh.getVolatile(array, ci);
509            });
510
511            checkIOOBE(() -> {
512                $type$ x = ($type$) vh.getAcquire(array, ci);
513            });
514
515            checkIOOBE(() -> {
516                $type$ x = ($type$) vh.getOpaque(array, ci);
517            });
518
519            if (!readOnly) {
520                checkIOOBE(() -> {
521                    vh.setVolatile(array, ci, VALUE_1);
522                });
523
524                checkIOOBE(() -> {
525                    vh.setRelease(array, ci, VALUE_1);
526                });
527
528                checkIOOBE(() -> {
529                    vh.setOpaque(array, ci, VALUE_1);
530                });
531
532#if[CAS]
533                checkIOOBE(() -> {
534                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
535                });
536
537                checkIOOBE(() -> {
538                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
539                });
540
541                checkIOOBE(() -> {
542                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
543                });
544
545                checkIOOBE(() -> {
546                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
547                });
548
549                checkIOOBE(() -> {
550                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
551                });
552
553                checkIOOBE(() -> {
554                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
555                });
556
557                checkIOOBE(() -> {
558                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
559                });
560
561                checkIOOBE(() -> {
562                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
563                });
564#end[CAS]
565
566#if[AtomicAdd]
567                checkIOOBE(() -> {
568                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
569                });
570
571                checkIOOBE(() -> {
572                    $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
573                });
574#end[AtomicAdd]
575            }
576        }
577    }
578
579    static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
580        VarHandle vh = vhs.s;
581        byte[] array = bs.s;
582
583        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
584
585        int length = array.length - SIZE + 1;
586        for (int i = 0; i < length; i++) {
587            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
588            final int ci = i;
589
590            if (!iAligned) {
591                checkISE(() -> {
592                    $type$ x = ($type$) vh.getVolatile(array, ci);
593                });
594
595                checkISE(() -> {
596                    $type$ x = ($type$) vh.getAcquire(array, ci);
597                });
598
599                checkISE(() -> {
600                    $type$ x = ($type$) vh.getOpaque(array, ci);
601                });
602
603                checkISE(() -> {
604                    vh.setVolatile(array, ci, VALUE_1);
605                });
606
607                checkISE(() -> {
608                    vh.setRelease(array, ci, VALUE_1);
609                });
610
611                checkISE(() -> {
612                    vh.setOpaque(array, ci, VALUE_1);
613                });
614#if[CAS]
615
616                checkISE(() -> {
617                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
618                });
619
620                checkISE(() -> {
621                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
622                });
623
624                checkISE(() -> {
625                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
626                });
627
628                checkISE(() -> {
629                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
630                });
631
632                checkISE(() -> {
633                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
634                });
635
636                checkISE(() -> {
637                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
638                });
639
640                checkISE(() -> {
641                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
642                });
643
644                checkISE(() -> {
645                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
646                });
647#end[CAS]
648
649#if[AtomicAdd]
650                checkISE(() -> {
651                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
652                });
653
654                checkISE(() -> {
655                    $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
656                });
657#end[AtomicAdd]
658
659            }
660        }
661    }
662
663    static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
664        VarHandle vh = vhs.s;
665        ByteBuffer array = bs.s;
666
667        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
668        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
669
670        int length = array.limit() - SIZE + 1;
671        for (int i = 0; i < length; i++) {
672            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
673            final int ci = i;
674
675            if (!iAligned) {
676                checkISE(() -> {
677                    $type$ x = ($type$) vh.getVolatile(array, ci);
678                });
679
680                checkISE(() -> {
681                    $type$ x = ($type$) vh.getAcquire(array, ci);
682                });
683
684                checkISE(() -> {
685                    $type$ x = ($type$) vh.getOpaque(array, ci);
686                });
687
688                if (!readOnly) {
689                    checkISE(() -> {
690                        vh.setVolatile(array, ci, VALUE_1);
691                    });
692
693                    checkISE(() -> {
694                        vh.setRelease(array, ci, VALUE_1);
695                    });
696
697                    checkISE(() -> {
698                        vh.setOpaque(array, ci, VALUE_1);
699                    });
700
701#if[CAS]
702                    checkISE(() -> {
703                        boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
704                    });
705
706                    checkISE(() -> {
707                        $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
708                    });
709
710                    checkISE(() -> {
711                        $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
712                    });
713
714                    checkISE(() -> {
715                        $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
716                    });
717
718                    checkISE(() -> {
719                        boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
720                    });
721
722                    checkISE(() -> {
723                        boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
724                    });
725
726                    checkISE(() -> {
727                        boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
728                    });
729
730                    checkISE(() -> {
731                        $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
732                    });
733#end[CAS]
734
735#if[AtomicAdd]
736                    checkISE(() -> {
737                        $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
738                    });
739
740                    checkISE(() -> {
741                        $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
742                    });
743#end[AtomicAdd]
744                }
745            }
746        }
747    }
748
749    static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
750        VarHandle vh = vhs.s;
751        byte[] array = bs.s;
752
753        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
754
755        bs.fill((byte) 0xff);
756        int length = array.length - SIZE + 1;
757        for (int i = 0; i < length; i++) {
758            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
759
760            // Plain
761            {
762                vh.set(array, i, VALUE_1);
763                $type$ x = ($type$) vh.get(array, i);
764                assertEquals(x, VALUE_1, "get $type$ value");
765            }
766
767
768            if (iAligned) {
769                // Volatile
770                {
771                    vh.setVolatile(array, i, VALUE_2);
772                    $type$ x = ($type$) vh.getVolatile(array, i);
773                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
774                }
775
776                // Lazy
777                {
778                    vh.setRelease(array, i, VALUE_1);
779                    $type$ x = ($type$) vh.getAcquire(array, i);
780                    assertEquals(x, VALUE_1, "setRelease $type$ value");
781                }
782
783                // Opaque
784                {
785                    vh.setOpaque(array, i, VALUE_2);
786                    $type$ x = ($type$) vh.getOpaque(array, i);
787                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
788                }
789#if[CAS]
790
791                vh.set(array, i, VALUE_1);
792
793                // Compare
794                {
795                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
796                    assertEquals(r, true, "success compareAndSet $type$");
797                    $type$ x = ($type$) vh.get(array, i);
798                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
799                }
800
801                {
802                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
803                    assertEquals(r, false, "failing compareAndSet $type$");
804                    $type$ x = ($type$) vh.get(array, i);
805                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
806                }
807
808                {
809                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
810                    assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
811                    $type$ x = ($type$) vh.get(array, i);
812                    assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
813                }
814
815                {
816                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
817                    assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
818                    $type$ x = ($type$) vh.get(array, i);
819                    assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
820                }
821
822                {
823                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
824                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
825                    $type$ x = ($type$) vh.get(array, i);
826                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
827                }
828
829                {
830                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
831                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
832                    $type$ x = ($type$) vh.get(array, i);
833                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
834                }
835
836                {
837                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
838                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
839                    $type$ x = ($type$) vh.get(array, i);
840                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
841                }
842
843                {
844                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
845                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
846                    $type$ x = ($type$) vh.get(array, i);
847                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
848                }
849
850                {
851                    boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
852                    assertEquals(r, true, "weakCompareAndSet $type$");
853                    $type$ x = ($type$) vh.get(array, i);
854                    assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
855                }
856
857                {
858                    boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
859                    assertEquals(r, true, "weakCompareAndSetAcquire $type$");
860                    $type$ x = ($type$) vh.get(array, i);
861                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
862                }
863
864                {
865                    boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
866                    assertEquals(r, true, "weakCompareAndSetRelease $type$");
867                    $type$ x = ($type$) vh.get(array, i);
868                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
869                }
870
871                // Compare set and get
872                {
873                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
874                    assertEquals(o, VALUE_2, "getAndSet $type$");
875                    $type$ x = ($type$) vh.get(array, i);
876                    assertEquals(x, VALUE_1, "getAndSet $type$ value");
877                }
878#end[CAS]
879
880#if[AtomicAdd]
881                vh.set(array, i, VALUE_1);
882
883                // get and add, add and get
884                {
885                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
886                    assertEquals(o, VALUE_1, "getAndAdd $type$");
887                    $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
888                    assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
889                }
890#end[AtomicAdd]
891            }
892        }
893    }
894
895
896    static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
897        VarHandle vh = vhs.s;
898        ByteBuffer array = bs.s;
899
900        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
901
902        bs.fill((byte) 0xff);
903        int length = array.limit() - SIZE + 1;
904        for (int i = 0; i < length; i++) {
905            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
906
907            // Plain
908            {
909                vh.set(array, i, VALUE_1);
910                $type$ x = ($type$) vh.get(array, i);
911                assertEquals(x, VALUE_1, "get $type$ value");
912            }
913
914            if (iAligned) {
915                // Volatile
916                {
917                    vh.setVolatile(array, i, VALUE_2);
918                    $type$ x = ($type$) vh.getVolatile(array, i);
919                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
920                }
921
922                // Lazy
923                {
924                    vh.setRelease(array, i, VALUE_1);
925                    $type$ x = ($type$) vh.getAcquire(array, i);
926                    assertEquals(x, VALUE_1, "setRelease $type$ value");
927                }
928
929                // Opaque
930                {
931                    vh.setOpaque(array, i, VALUE_2);
932                    $type$ x = ($type$) vh.getOpaque(array, i);
933                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
934                }
935#if[CAS]
936
937                vh.set(array, i, VALUE_1);
938
939                // Compare
940                {
941                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
942                    assertEquals(r, true, "success compareAndSet $type$");
943                    $type$ x = ($type$) vh.get(array, i);
944                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
945                }
946
947                {
948                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
949                    assertEquals(r, false, "failing compareAndSet $type$");
950                    $type$ x = ($type$) vh.get(array, i);
951                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
952                }
953
954                {
955                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
956                    assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
957                    $type$ x = ($type$) vh.get(array, i);
958                    assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
959                }
960
961                {
962                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
963                    assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
964                    $type$ x = ($type$) vh.get(array, i);
965                    assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
966                }
967
968                {
969                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
970                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
971                    $type$ x = ($type$) vh.get(array, i);
972                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
973                }
974
975                {
976                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
977                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
978                    $type$ x = ($type$) vh.get(array, i);
979                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
980                }
981
982                {
983                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
984                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
985                    $type$ x = ($type$) vh.get(array, i);
986                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
987                }
988
989                {
990                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
991                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
992                    $type$ x = ($type$) vh.get(array, i);
993                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
994                }
995
996                {
997                    boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
998                    assertEquals(r, true, "weakCompareAndSet $type$");
999                    $type$ x = ($type$) vh.get(array, i);
1000                    assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
1001                }
1002
1003                {
1004                    boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1005                    assertEquals(r, true, "weakCompareAndSetAcquire $type$");
1006                    $type$ x = ($type$) vh.get(array, i);
1007                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
1008                }
1009
1010                {
1011                    boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1012                    assertEquals(r, true, "weakCompareAndSetRelease $type$");
1013                    $type$ x = ($type$) vh.get(array, i);
1014                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
1015                }
1016
1017                // Compare set and get
1018                {
1019                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
1020                    assertEquals(o, VALUE_2, "getAndSet $type$");
1021                    $type$ x = ($type$) vh.get(array, i);
1022                    assertEquals(x, VALUE_1, "getAndSet $type$ value");
1023                }
1024#end[CAS]
1025
1026#if[AtomicAdd]
1027                vh.set(array, i, VALUE_1);
1028
1029                // get and add, add and get
1030                {
1031                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
1032                    assertEquals(o, VALUE_1, "getAndAdd $type$");
1033                    $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
1034                    assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
1035                }
1036#end[AtomicAdd]
1037            }
1038        }
1039    }
1040
1041    static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
1042        VarHandle vh = vhs.s;
1043        ByteBuffer array = bs.s;
1044
1045        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1046
1047        ByteBuffer bb = ByteBuffer.allocate(SIZE);
1048        bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
1049        bs.fill(bb.put$Type$(0, VALUE_2).array());
1050
1051        int length = array.limit() - SIZE + 1;
1052        for (int i = 0; i < length; i++) {
1053            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1054
1055            $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
1056                    ? rotateLeft(VALUE_2, (i % SIZE) << 3)
1057                    : rotateRight(VALUE_2, (i % SIZE) << 3);
1058            // Plain
1059            {
1060                $type$ x = ($type$) vh.get(array, i);
1061                assertEquals(x, v, "get $type$ value");
1062            }
1063
1064            if (iAligned) {
1065                // Volatile
1066                {
1067                    $type$ x = ($type$) vh.getVolatile(array, i);
1068                    assertEquals(x, v, "getVolatile $type$ value");
1069                }
1070
1071                // Lazy
1072                {
1073                    $type$ x = ($type$) vh.getAcquire(array, i);
1074                    assertEquals(x, v, "getRelease $type$ value");
1075                }
1076
1077                // Opaque
1078                {
1079                    $type$ x = ($type$) vh.getOpaque(array, i);
1080                    assertEquals(x, v, "getOpaque $type$ value");
1081                }
1082            }
1083        }
1084    }
1085
1086}
1087
1088