xref: /aosp_15_r20/art/test/712-varhandle-invocations/src/VarHandleArrayTests.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandles;
18*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.VarHandle;
19*795d594fSAndroid Build Coastguard Worker import java.nio.ByteBuffer;
20*795d594fSAndroid Build Coastguard Worker import java.nio.ByteOrder;
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker // These tests cover DoVarHandleInvokeCommon in interpreter_common.cc.
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker public class VarHandleArrayTests {
25*795d594fSAndroid Build Coastguard Worker     public static class ArrayStoreTest extends VarHandleUnitTest {
26*795d594fSAndroid Build Coastguard Worker         private static final Integer ZERO = Integer.valueOf(0);
27*795d594fSAndroid Build Coastguard Worker         private static final Integer ONE = Integer.valueOf(1);
28*795d594fSAndroid Build Coastguard Worker         private static final Integer TWO = Integer.valueOf(2);
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker         private final Integer[] values = new Integer[10];
31*795d594fSAndroid Build Coastguard Worker 
testIntegerArrayVarHandle()32*795d594fSAndroid Build Coastguard Worker         private void testIntegerArrayVarHandle() {
33*795d594fSAndroid Build Coastguard Worker             final VarHandle vh = MethodHandles.arrayElementVarHandle(Integer[].class);
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kSet
36*795d594fSAndroid Build Coastguard Worker             vh.set(values, 0, ZERO);
37*795d594fSAndroid Build Coastguard Worker             assertEquals(0, values[0].intValue());
38*795d594fSAndroid Build Coastguard Worker             vh.set((Object[]) values, 1, ONE);
39*795d594fSAndroid Build Coastguard Worker             assertEquals(ONE, values[1]);
40*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vh.set(values, values.length, null));
41*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.set(values, 6, new Object()));
42*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.set((Object[]) values, 6, new Object()));
43*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vh.set((Integer[]) null, 6, ONE));
44*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.set(values, 'c'));
45*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.set((Object[]) values, 5, 'c'));
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kGetAndUpdate
48*795d594fSAndroid Build Coastguard Worker             assertEquals(ZERO, (Integer) vh.getAndSet(values, 0, ONE));
49*795d594fSAndroid Build Coastguard Worker             assertEquals(ONE, values[0]);
50*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vh.getAndSet(values, values.length, null));
51*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.getAndSet(values, 6, new Object()));
52*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.getAndSet((Object[]) values, 6, new Object()));
53*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vh.getAndSet((Integer[]) null, 6, ONE));
54*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.getAndSet(values, 'c'));
55*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.getAndSet((Object[]) values, 5, 'c'));
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kCompareAndExchange
58*795d594fSAndroid Build Coastguard Worker             assertEquals(ONE, (Integer) vh.compareAndExchange(values, 0, ONE, TWO));
59*795d594fSAndroid Build Coastguard Worker             assertEquals(TWO, values[0]);
60*795d594fSAndroid Build Coastguard Worker             assertEquals(TWO, (Integer) vh.compareAndExchange(values, 0, ONE, ZERO));
61*795d594fSAndroid Build Coastguard Worker             assertEquals(TWO, values[0]);
62*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vh.compareAndExchange(values, values.length, null, null));
63*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.compareAndExchange(values, 6, 6, new Object()));
64*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.compareAndExchange((Object[]) values, 6, 6, new Object()));
65*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vh.compareAndExchange((Integer[]) null, 6, ONE, ONE));
66*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.compareAndExchange(values, null, 'c'));
67*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.compareAndExchange((Object[]) values, 5, null, 'c'));
68*795d594fSAndroid Build Coastguard Worker 
69*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kCompareAndSet
70*795d594fSAndroid Build Coastguard Worker             assertEquals(true, (boolean) vh.compareAndSet(values, 0, TWO, ONE));
71*795d594fSAndroid Build Coastguard Worker             assertEquals(ONE, values[0]);
72*795d594fSAndroid Build Coastguard Worker             assertEquals(false, (boolean) vh.compareAndSet(values, 0, ZERO, TWO));
73*795d594fSAndroid Build Coastguard Worker             assertEquals(ONE, values[0]);
74*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vh.compareAndSet(values, values.length, null, null));
75*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.compareAndSet(values, 6, 6, new Object()));
76*795d594fSAndroid Build Coastguard Worker             assertThrowsCCE(() -> vh.compareAndSet((Object[]) values, 6, 6, new Object()));
77*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vh.compareAndSet((Integer[]) null, 6, ONE, ONE));
78*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.compareAndSet(values, null, 'c'));
79*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vh.compareAndSet((Object[]) values, 5, null, 'c'));
80*795d594fSAndroid Build Coastguard Worker         }
81*795d594fSAndroid Build Coastguard Worker 
testObjectArrayVarHandle()82*795d594fSAndroid Build Coastguard Worker         private void testObjectArrayVarHandle() {
83*795d594fSAndroid Build Coastguard Worker             final VarHandle vho = MethodHandles.arrayElementVarHandle(Object[].class);
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kSet
86*795d594fSAndroid Build Coastguard Worker             vho.set(values, 0, ONE);
87*795d594fSAndroid Build Coastguard Worker             assertEquals(ONE, values[0]);
88*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vho.set(values, values.length, null));
89*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.set(values, 0, new Object()));
90*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.set(values, 0, "hello"));
91*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vho.set(null, 0, ZERO));
92*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.set(0, ZERO));
93*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.set(values, ZERO));
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kGetAndUpdate
96*795d594fSAndroid Build Coastguard Worker             assertEquals(ONE, vho.getAndSetAcquire(values, 0, TWO));
97*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vho.getAndSetRelease(values, values.length, null));
98*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.getAndSet(values, 0, new Object()));
99*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.getAndSet(values, 0, "hello"));
100*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vho.getAndSet(null, 0, ZERO));
101*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.getAndSet(0, ZERO));
102*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.getAndSet(values, ZERO));
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kCompareAndExchange
105*795d594fSAndroid Build Coastguard Worker             assertEquals(TWO, vho.compareAndExchange(values, 0, TWO, ZERO));
106*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vho.compareAndExchange(values, values.length, ONE, TWO));
107*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.compareAndExchange(values, 0, ONE, new Object()));
108*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.compareAndExchange(values, 0, ONE, "hello"));
109*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vho.compareAndExchange(null, 0, ONE, ZERO));
110*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.compareAndExchange(0, ZERO, ONE));
111*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.compareAndExchange(values, ONE, ZERO));
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker             // AccessModeTemplate::kCompareAndSet
114*795d594fSAndroid Build Coastguard Worker             assertEquals(true, (boolean) vho.compareAndSet(values, 0, ZERO, ONE));
115*795d594fSAndroid Build Coastguard Worker             assertThrowsAIOBE(() -> vho.compareAndSet(values, values.length, ONE, TWO));
116*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.compareAndSet(values, 0, ONE, new Object()));
117*795d594fSAndroid Build Coastguard Worker             assertThrowsASE(() -> vho.compareAndSet(values, 0, ONE, "hello"));
118*795d594fSAndroid Build Coastguard Worker             assertThrowsNPE(() -> vho.compareAndSet(null, 0, ONE, ZERO));
119*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.compareAndSet(0, ZERO, ONE));
120*795d594fSAndroid Build Coastguard Worker             assertThrowsWMTE(() -> vho.compareAndSet(values, ONE, ZERO));
121*795d594fSAndroid Build Coastguard Worker         }
122*795d594fSAndroid Build Coastguard Worker 
toHost(ByteOrder order, byte b0, byte b1)123*795d594fSAndroid Build Coastguard Worker         private short toHost(ByteOrder order, byte b0, byte b1) {
124*795d594fSAndroid Build Coastguard Worker             final int u0 = Byte.toUnsignedInt(b0);
125*795d594fSAndroid Build Coastguard Worker             final int u1 = Byte.toUnsignedInt(b1);
126*795d594fSAndroid Build Coastguard Worker             if (order == ByteOrder.LITTLE_ENDIAN) {
127*795d594fSAndroid Build Coastguard Worker                 return (short) (u0 + (u1 << 8));
128*795d594fSAndroid Build Coastguard Worker             } else {
129*795d594fSAndroid Build Coastguard Worker                 return (short) (u1 + (u0 << 8));
130*795d594fSAndroid Build Coastguard Worker             }
131*795d594fSAndroid Build Coastguard Worker         }
132*795d594fSAndroid Build Coastguard Worker 
toHost(ByteOrder order, byte b0, byte b1, byte b2, byte b3)133*795d594fSAndroid Build Coastguard Worker         private int toHost(ByteOrder order, byte b0, byte b1, byte b2, byte b3) {
134*795d594fSAndroid Build Coastguard Worker             final int u0 = Byte.toUnsignedInt(b0);
135*795d594fSAndroid Build Coastguard Worker             final int u1 = Byte.toUnsignedInt(b1);
136*795d594fSAndroid Build Coastguard Worker             final int u2 = Byte.toUnsignedInt(b2);
137*795d594fSAndroid Build Coastguard Worker             final int u3 = Byte.toUnsignedInt(b3);
138*795d594fSAndroid Build Coastguard Worker             if (order == ByteOrder.LITTLE_ENDIAN) {
139*795d594fSAndroid Build Coastguard Worker                 return u0 + (u1 << 8) + (u2 << 16) + (u3 << 24);
140*795d594fSAndroid Build Coastguard Worker             } else {
141*795d594fSAndroid Build Coastguard Worker                 return u3 + (u2 << 8) + (u1 << 16) + (u0 << 24);
142*795d594fSAndroid Build Coastguard Worker             }
143*795d594fSAndroid Build Coastguard Worker         }
144*795d594fSAndroid Build Coastguard Worker 
testByteArrayViewVarHandle()145*795d594fSAndroid Build Coastguard Worker         private void testByteArrayViewVarHandle() {
146*795d594fSAndroid Build Coastguard Worker             final int BITS_PER_BYTE = 8;
147*795d594fSAndroid Build Coastguard Worker             byte[] array = new byte[32];
148*795d594fSAndroid Build Coastguard Worker 
149*795d594fSAndroid Build Coastguard Worker             final ByteOrder[] byteOrders =
150*795d594fSAndroid Build Coastguard Worker                     new ByteOrder[] {ByteOrder.LITTLE_ENDIAN, ByteOrder.BIG_ENDIAN};
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker             for (ByteOrder order : byteOrders) {
153*795d594fSAndroid Build Coastguard Worker                 {
154*795d594fSAndroid Build Coastguard Worker                     final VarHandle vhShort =
155*795d594fSAndroid Build Coastguard Worker                             MethodHandles.byteArrayViewVarHandle(short[].class, order);
156*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhShort.get(array, -1));
157*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhShort.get(array, Integer.MIN_VALUE));
158*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhShort.get(array, array.length));
159*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhShort.get(array, array.length - 1));
160*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhShort.get(array, Integer.MAX_VALUE));
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker                     for (int i = 0; i < array.length - 1; ++i) {
163*795d594fSAndroid Build Coastguard Worker                         final boolean isAligned = (i % 2) == 0;
164*795d594fSAndroid Build Coastguard Worker                         final short value = (short) ((i + 1) * 0xff);
165*795d594fSAndroid Build Coastguard Worker                         vhShort.set(array, i, value);
166*795d594fSAndroid Build Coastguard Worker                         assertEquals(value, (short) vhShort.get(array, i));
167*795d594fSAndroid Build Coastguard Worker                         assertEquals(value, toHost(order, array[i], array[i + 1]));
168*795d594fSAndroid Build Coastguard Worker                         for (int j = 0; j < array.length; ++j) {
169*795d594fSAndroid Build Coastguard Worker                             if (j < i || j > i + 1) {
170*795d594fSAndroid Build Coastguard Worker                                 assertEquals((byte) 0, array[j]);
171*795d594fSAndroid Build Coastguard Worker                             }
172*795d594fSAndroid Build Coastguard Worker                         }
173*795d594fSAndroid Build Coastguard Worker                         if (isAligned) {
174*795d594fSAndroid Build Coastguard Worker                             vhShort.getAcquire(array, i);
175*795d594fSAndroid Build Coastguard Worker                             vhShort.setRelease(array, i, (short) 0);
176*795d594fSAndroid Build Coastguard Worker                         } else {
177*795d594fSAndroid Build Coastguard Worker                             final int fi = i;
178*795d594fSAndroid Build Coastguard Worker                             assertThrowsISE(() -> vhShort.getAcquire(array, fi));
179*795d594fSAndroid Build Coastguard Worker                             assertThrowsISE(() -> vhShort.setRelease(array, fi, (short) 0));
180*795d594fSAndroid Build Coastguard Worker                         }
181*795d594fSAndroid Build Coastguard Worker                         vhShort.set(array, i, (short) 0);
182*795d594fSAndroid Build Coastguard Worker                     }
183*795d594fSAndroid Build Coastguard Worker                 }
184*795d594fSAndroid Build Coastguard Worker                 {
185*795d594fSAndroid Build Coastguard Worker                     final VarHandle vhInt =
186*795d594fSAndroid Build Coastguard Worker                             MethodHandles.byteArrayViewVarHandle(int[].class, order);
187*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhInt.get(array, -1));
188*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhInt.get(array, Integer.MIN_VALUE));
189*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhInt.get(array, array.length));
190*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhInt.get(array, array.length - 1));
191*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhInt.get(array, array.length - 2));
192*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhInt.get(array, array.length - 3));
193*795d594fSAndroid Build Coastguard Worker                     assertThrowsIOOBE(() -> vhInt.get(array, Integer.MAX_VALUE));
194*795d594fSAndroid Build Coastguard Worker                     for (int i = 0; i < array.length - 3; ++i) {
195*795d594fSAndroid Build Coastguard Worker                         final boolean isAligned = (i % 4) == 0;
196*795d594fSAndroid Build Coastguard Worker                         final int value = (i + 1) * 0x11223344;
197*795d594fSAndroid Build Coastguard Worker                         vhInt.set(array, i, value);
198*795d594fSAndroid Build Coastguard Worker                         assertEquals(value, vhInt.get(array, i));
199*795d594fSAndroid Build Coastguard Worker                         assertEquals(
200*795d594fSAndroid Build Coastguard Worker                                 value,
201*795d594fSAndroid Build Coastguard Worker                                 toHost(order, array[i], array[i + 1], array[i + 2], array[i + 3]));
202*795d594fSAndroid Build Coastguard Worker                         for (int j = 0; j < array.length; ++j) {
203*795d594fSAndroid Build Coastguard Worker                             if (j < i || j > i + 3) {
204*795d594fSAndroid Build Coastguard Worker                                 assertEquals((byte) 0, array[j]);
205*795d594fSAndroid Build Coastguard Worker                             }
206*795d594fSAndroid Build Coastguard Worker                         }
207*795d594fSAndroid Build Coastguard Worker                         if (isAligned) {
208*795d594fSAndroid Build Coastguard Worker                             vhInt.getAcquire(array, i);
209*795d594fSAndroid Build Coastguard Worker                             vhInt.setRelease(array, i, (int) 0);
210*795d594fSAndroid Build Coastguard Worker                         } else {
211*795d594fSAndroid Build Coastguard Worker                             final int fi = i;
212*795d594fSAndroid Build Coastguard Worker                             assertThrowsISE(() -> vhInt.getAcquire(array, fi));
213*795d594fSAndroid Build Coastguard Worker                             assertThrowsISE(() -> vhInt.setRelease(array, fi, (int) 0));
214*795d594fSAndroid Build Coastguard Worker                         }
215*795d594fSAndroid Build Coastguard Worker                         vhInt.set(array, i, 0);
216*795d594fSAndroid Build Coastguard Worker                     }
217*795d594fSAndroid Build Coastguard Worker                 }
218*795d594fSAndroid Build Coastguard Worker             }
219*795d594fSAndroid Build Coastguard Worker         }
220*795d594fSAndroid Build Coastguard Worker 
testByteBufferVarHandle()221*795d594fSAndroid Build Coastguard Worker         private void testByteBufferVarHandle() {
222*795d594fSAndroid Build Coastguard Worker             final ByteOrder[] byteOrders =
223*795d594fSAndroid Build Coastguard Worker                     new ByteOrder[] {ByteOrder.LITTLE_ENDIAN, ByteOrder.BIG_ENDIAN};
224*795d594fSAndroid Build Coastguard Worker 
225*795d594fSAndroid Build Coastguard Worker             for (final ByteOrder byteOrder : byteOrders) {
226*795d594fSAndroid Build Coastguard Worker                 final ByteBuffer heapBuffer = ByteBuffer.allocate(32);
227*795d594fSAndroid Build Coastguard Worker                 final ByteBuffer directBuffer = ByteBuffer.allocateDirect(32);
228*795d594fSAndroid Build Coastguard Worker                 final ByteBuffer arrayBuffer = ByteBuffer.wrap(new byte[32]);
229*795d594fSAndroid Build Coastguard Worker                 final ByteBuffer anotherArrayBuffer = ByteBuffer.wrap(new byte[32], 3, 23);
230*795d594fSAndroid Build Coastguard Worker                 final ByteBuffer[] buffers = {
231*795d594fSAndroid Build Coastguard Worker                     heapBuffer,
232*795d594fSAndroid Build Coastguard Worker                     ((ByteBuffer) heapBuffer.duplicate().position(1)).slice(),
233*795d594fSAndroid Build Coastguard Worker                     directBuffer,
234*795d594fSAndroid Build Coastguard Worker                     ((ByteBuffer) directBuffer.duplicate().position(1)).slice(),
235*795d594fSAndroid Build Coastguard Worker                     arrayBuffer,
236*795d594fSAndroid Build Coastguard Worker                     ((ByteBuffer) arrayBuffer.duplicate().position(1)).slice(),
237*795d594fSAndroid Build Coastguard Worker                     anotherArrayBuffer,
238*795d594fSAndroid Build Coastguard Worker                     ((ByteBuffer) anotherArrayBuffer.duplicate().position(1)).slice()
239*795d594fSAndroid Build Coastguard Worker                 };
240*795d594fSAndroid Build Coastguard Worker                 for (final ByteBuffer buffer : buffers) {
241*795d594fSAndroid Build Coastguard Worker                     {
242*795d594fSAndroid Build Coastguard Worker                         final VarHandle vhShort =
243*795d594fSAndroid Build Coastguard Worker                                 MethodHandles.byteBufferViewVarHandle(short[].class, byteOrder);
244*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhShort.get(buffer, -1));
245*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhShort.get(buffer, Integer.MIN_VALUE));
246*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhShort.get(buffer, Integer.MAX_VALUE));
247*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhShort.get(buffer, buffer.limit()));
248*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhShort.get(buffer, buffer.limit() - 1));
249*795d594fSAndroid Build Coastguard Worker                         final int zeroAlignment = buffer.alignmentOffset(0, Short.BYTES);
250*795d594fSAndroid Build Coastguard Worker                         for (int i = 0; i < buffer.limit() - 1; ++i) {
251*795d594fSAndroid Build Coastguard Worker                             boolean isAligned = (zeroAlignment + i) % Short.BYTES == 0;
252*795d594fSAndroid Build Coastguard Worker                             final short value = (short) ((i + 1) * 0xff);
253*795d594fSAndroid Build Coastguard Worker                             vhShort.set(buffer, i, value);
254*795d594fSAndroid Build Coastguard Worker                             assertEquals(value, (short) vhShort.get(buffer, i));
255*795d594fSAndroid Build Coastguard Worker                             assertEquals(
256*795d594fSAndroid Build Coastguard Worker                                     value, toHost(byteOrder, buffer.get(i), buffer.get(i + 1)));
257*795d594fSAndroid Build Coastguard Worker                             for (int j = 0; j < buffer.limit(); ++j) {
258*795d594fSAndroid Build Coastguard Worker                                 if (j < i || j > i + 1) {
259*795d594fSAndroid Build Coastguard Worker                                     assertEquals((byte) 0, buffer.get(j));
260*795d594fSAndroid Build Coastguard Worker                                 }
261*795d594fSAndroid Build Coastguard Worker                             }
262*795d594fSAndroid Build Coastguard Worker                             if (isAligned) {
263*795d594fSAndroid Build Coastguard Worker                                 vhShort.getAcquire(buffer, i);
264*795d594fSAndroid Build Coastguard Worker                                 vhShort.setRelease(buffer, i, (short) 0);
265*795d594fSAndroid Build Coastguard Worker                             } else {
266*795d594fSAndroid Build Coastguard Worker                                 final int fi = i;
267*795d594fSAndroid Build Coastguard Worker                                 assertThrowsISE(() -> vhShort.getAcquire(buffer, fi));
268*795d594fSAndroid Build Coastguard Worker                                 assertThrowsISE(() -> vhShort.setRelease(buffer, fi, (short) 0));
269*795d594fSAndroid Build Coastguard Worker                             }
270*795d594fSAndroid Build Coastguard Worker                             vhShort.set(buffer, i, (short) 0);
271*795d594fSAndroid Build Coastguard Worker                         }
272*795d594fSAndroid Build Coastguard Worker                     }
273*795d594fSAndroid Build Coastguard Worker                     {
274*795d594fSAndroid Build Coastguard Worker                         final VarHandle vhInt =
275*795d594fSAndroid Build Coastguard Worker                                 MethodHandles.byteBufferViewVarHandle(int[].class, byteOrder);
276*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhInt.get(buffer, -1));
277*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhInt.get(buffer, Integer.MIN_VALUE));
278*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhInt.get(buffer, Integer.MAX_VALUE));
279*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhInt.get(buffer, buffer.limit()));
280*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhInt.get(buffer, buffer.limit() - 1));
281*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhInt.get(buffer, buffer.limit() - 2));
282*795d594fSAndroid Build Coastguard Worker                         assertThrowsIOOBE(() -> vhInt.get(buffer, buffer.limit() - 3));
283*795d594fSAndroid Build Coastguard Worker                         final int zeroAlignment = buffer.alignmentOffset(0, Integer.BYTES);
284*795d594fSAndroid Build Coastguard Worker                         for (int i = 0; i < buffer.limit() - 3; ++i) {
285*795d594fSAndroid Build Coastguard Worker                             boolean isAligned = (zeroAlignment + i) % Integer.BYTES == 0;
286*795d594fSAndroid Build Coastguard Worker                             final int value = (i + 1) * 0x11223344;
287*795d594fSAndroid Build Coastguard Worker                             vhInt.set(buffer, i, value);
288*795d594fSAndroid Build Coastguard Worker                             assertEquals(value, vhInt.get(buffer, i));
289*795d594fSAndroid Build Coastguard Worker                             assertEquals(
290*795d594fSAndroid Build Coastguard Worker                                     value,
291*795d594fSAndroid Build Coastguard Worker                                     toHost(
292*795d594fSAndroid Build Coastguard Worker                                             byteOrder,
293*795d594fSAndroid Build Coastguard Worker                                             buffer.get(i),
294*795d594fSAndroid Build Coastguard Worker                                             buffer.get(i + 1),
295*795d594fSAndroid Build Coastguard Worker                                             buffer.get(i + 2),
296*795d594fSAndroid Build Coastguard Worker                                             buffer.get(i + 3)));
297*795d594fSAndroid Build Coastguard Worker                             for (int j = 0; j < buffer.limit(); ++j) {
298*795d594fSAndroid Build Coastguard Worker                                 if (j < i || j > i + 3) {
299*795d594fSAndroid Build Coastguard Worker                                     assertEquals((byte) 0, buffer.get(j));
300*795d594fSAndroid Build Coastguard Worker                                 }
301*795d594fSAndroid Build Coastguard Worker                             }
302*795d594fSAndroid Build Coastguard Worker                             if (isAligned) {
303*795d594fSAndroid Build Coastguard Worker                                 vhInt.getAcquire(buffer, i);
304*795d594fSAndroid Build Coastguard Worker                                 vhInt.setRelease(buffer, i, (int) 0);
305*795d594fSAndroid Build Coastguard Worker                             } else {
306*795d594fSAndroid Build Coastguard Worker                                 final int fi = i;
307*795d594fSAndroid Build Coastguard Worker                                 assertThrowsISE(() -> vhInt.getAcquire(buffer, fi));
308*795d594fSAndroid Build Coastguard Worker                                 assertThrowsISE(() -> vhInt.setRelease(buffer, fi, (int) 0));
309*795d594fSAndroid Build Coastguard Worker                             }
310*795d594fSAndroid Build Coastguard Worker                             vhInt.set(buffer, i, 0);
311*795d594fSAndroid Build Coastguard Worker                         }
312*795d594fSAndroid Build Coastguard Worker                     }
313*795d594fSAndroid Build Coastguard Worker                 }
314*795d594fSAndroid Build Coastguard Worker             }
315*795d594fSAndroid Build Coastguard Worker         }
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker         @Override
doTest()318*795d594fSAndroid Build Coastguard Worker         protected void doTest() throws Exception {
319*795d594fSAndroid Build Coastguard Worker             testIntegerArrayVarHandle();
320*795d594fSAndroid Build Coastguard Worker             testObjectArrayVarHandle();
321*795d594fSAndroid Build Coastguard Worker             testByteArrayViewVarHandle();
322*795d594fSAndroid Build Coastguard Worker             testByteBufferVarHandle();
323*795d594fSAndroid Build Coastguard Worker         }
324*795d594fSAndroid Build Coastguard Worker 
main(String[] args)325*795d594fSAndroid Build Coastguard Worker         public static void main(String[] args) {
326*795d594fSAndroid Build Coastguard Worker             new ArrayStoreTest().run();
327*795d594fSAndroid Build Coastguard Worker         }
328*795d594fSAndroid Build Coastguard Worker     }
329*795d594fSAndroid Build Coastguard Worker 
main(String[] args)330*795d594fSAndroid Build Coastguard Worker     public static void main(String[] args) {
331*795d594fSAndroid Build Coastguard Worker         ArrayStoreTest.main(args);
332*795d594fSAndroid Build Coastguard Worker     }
333*795d594fSAndroid Build Coastguard Worker }
334