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