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