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