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