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