Path: blob/master/test/hotspot/jtreg/compiler/intrinsics/unsafe/ByteBufferTest.java
41153 views
/*1* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2015, 2016, Red Hat Inc. 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324import jdk.test.lib.Utils;2526import java.nio.Buffer;27import java.nio.BufferOverflowException;28import java.nio.BufferUnderflowException;29import java.nio.ByteBuffer;30import java.nio.ByteOrder;31import java.nio.CharBuffer;32import java.nio.DoubleBuffer;33import java.nio.FloatBuffer;34import java.nio.IntBuffer;35import java.nio.LongBuffer;36import java.nio.ShortBuffer;37import java.util.Arrays;38import java.util.Random;3940import static java.nio.ByteOrder.BIG_ENDIAN;41import static java.nio.ByteOrder.LITTLE_ENDIAN;4243// A wrapper for a ByteBuffer which maintains a backing array and a44// position. Whenever this wrapper is written the backing array and45// the wrapped byte buffer are updated together, and whenever it is46// read we check that the ByteBuffer and the backing array are identical.4748class MyByteBuffer {49final ByteBuffer buf;50final byte[] bytes;51int pos;52ByteOrder byteOrder = BIG_ENDIAN;5354MyByteBuffer(ByteBuffer buf) {55this.buf = buf;56this.bytes = new byte[buf.capacity()];57pos = 0;58}5960public final MyByteBuffer order(ByteOrder bo) {61byteOrder = bo;62buf.order(bo);63return this;64}6566static MyByteBuffer allocate(int capacity) {67return new MyByteBuffer(ByteBuffer.allocate(capacity));68}6970static MyByteBuffer allocateDirect(int capacity) {71return new MyByteBuffer(ByteBuffer.allocateDirect(capacity));72}7374int capacity() { return bytes.length; }75int position() {76if (buf.position() != pos)77throw new RuntimeException();78return buf.position();79}8081byte[] actualArray() {82buf.rewind();83byte[] actual = new byte[bytes.length];84buf.get(actual, 0, actual.length);85buf.rewind();8687return actual;88}89byte[] expectedArray() { return bytes; }9091private static byte long7(long x) { return (byte)(x >> 56); }92private static byte long6(long x) { return (byte)(x >> 48); }93private static byte long5(long x) { return (byte)(x >> 40); }94private static byte long4(long x) { return (byte)(x >> 32); }95private static byte long3(long x) { return (byte)(x >> 24); }96private static byte long2(long x) { return (byte)(x >> 16); }97private static byte long1(long x) { return (byte)(x >> 8); }98private static byte long0(long x) { return (byte)(x ); }99100private static byte int3(int x) { return (byte)(x >> 24); }101private static byte int2(int x) { return (byte)(x >> 16); }102private static byte int1(int x) { return (byte)(x >> 8); }103private static byte int0(int x) { return (byte)(x ); }104105private static byte short1(short x) { return (byte)(x >> 8); }106private static byte short0(short x) { return (byte)(x ); }107108byte _get(long i) { return bytes[(int)i]; }109void _put(long i, byte x) { bytes[(int)i] = x; }110111private void putLongX(long a, long x) {112if (byteOrder == BIG_ENDIAN) {113x = Long.reverseBytes(x);114}115_put(a + 7, long7(x));116_put(a + 6, long6(x));117_put(a + 5, long5(x));118_put(a + 4, long4(x));119_put(a + 3, long3(x));120_put(a + 2, long2(x));121_put(a + 1, long1(x));122_put(a , long0(x));123}124125private void putIntX(long a, int x) {126if (byteOrder == BIG_ENDIAN) {127x = Integer.reverseBytes(x);128}129_put(a + 3, int3(x));130_put(a + 2, int2(x));131_put(a + 1, int1(x));132_put(a , int0(x));133}134135private void putShortX(int bi, short x) {136if (byteOrder == BIG_ENDIAN) {137x = Short.reverseBytes(x);138}139_put(bi , short0(x));140_put(bi + 1, short1(x));141}142143static private int makeInt(byte b3, byte b2, byte b1, byte b0) {144return (((b3 ) << 24) |145((b2 & 0xff) << 16) |146((b1 & 0xff) << 8) |147((b0 & 0xff) ));148}149int getIntX(long a) {150int x = makeInt(_get(a + 3),151_get(a + 2),152_get(a + 1),153_get(a));154if (byteOrder == BIG_ENDIAN) {155x = Integer.reverseBytes(x);156}157return x;158}159160static private long makeLong(byte b7, byte b6, byte b5, byte b4,161byte b3, byte b2, byte b1, byte b0)162{163return ((((long)b7 ) << 56) |164(((long)b6 & 0xff) << 48) |165(((long)b5 & 0xff) << 40) |166(((long)b4 & 0xff) << 32) |167(((long)b3 & 0xff) << 24) |168(((long)b2 & 0xff) << 16) |169(((long)b1 & 0xff) << 8) |170(((long)b0 & 0xff) ));171}172173long getLongX(long a) {174long x = makeLong(_get(a + 7),175_get(a + 6),176_get(a + 5),177_get(a + 4),178_get(a + 3),179_get(a + 2),180_get(a + 1),181_get(a));182if (byteOrder == BIG_ENDIAN) {183x = Long.reverseBytes(x);184}185return x;186}187188static private short makeShort(byte b1, byte b0) {189return (short)((b1 << 8) | (b0 & 0xff));190}191192short getShortX(long a) {193short x = makeShort(_get(a + 1),194_get(a ));195if (byteOrder == BIG_ENDIAN) {196x = Short.reverseBytes(x);197}198return x;199}200201double getDoubleX(long a) {202long x = getLongX(a);203return Double.longBitsToDouble(x);204}205206double getFloatX(long a) {207int x = getIntX(a);208return Float.intBitsToFloat(x);209}210211void ck(long x, long y) {212if (x != y) {213throw new RuntimeException(" x = " + Long.toHexString(x) + ", y = " + Long.toHexString(y));214}215}216217void ck(double x, double y) {218if (x == x && y == y && x != y) {219ck(x, y);220}221}222223// Method accessors224225long getLong(int i) { ck(buf.getLong(i), getLongX(i)); return buf.getLong(i); }226int getInt(int i) { ck(buf.getInt(i), getIntX(i)); return buf.getInt(i); }227short getShort(int i) { ck(buf.getShort(i), getShortX(i)); return buf.getShort(i); }228char getChar(int i) { ck(buf.getChar(i), (char)getShortX(i)); return buf.getChar(i); }229double getDouble(int i) { ck(buf.getDouble(i), getDoubleX(i)); return buf.getDouble(i); }230float getFloat(int i) { ck(buf.getFloat(i), getFloatX(i)); return buf.getFloat(i); }231232void putLong(int i, long x) { buf.putLong(i, x); putLongX(i, x); }233void putInt(int i, int x) { buf.putInt(i, x); putIntX(i, x); }234void putShort(int i, short x) { buf.putShort(i, x); putShortX(i, x); }235void putChar(int i, char x) { buf.putChar(i, x); putShortX(i, (short)x); }236void putDouble(int i, double x) { buf.putDouble(i, x); putLongX(i, Double.doubleToRawLongBits(x)); }237void putFloat(int i, float x) { buf.putFloat(i, x); putIntX(i, Float.floatToRawIntBits(x)); }238239long getLong() { ck(buf.getLong(buf.position()), getLongX(pos)); long x = buf.getLong(); pos += 8; return x; }240int getInt() { ck(buf.getInt(buf.position()), getIntX(pos)); int x = buf.getInt(); pos += 4; return x; }241short getShort() { ck(buf.getShort(buf.position()), getShortX(pos)); short x = buf.getShort(); pos += 2; return x; }242char getChar() { ck(buf.getChar(buf.position()), (char)getShortX(pos)); char x = buf.getChar(); pos += 2; return x; }243double getDouble() { ck(buf.getDouble(buf.position()), getDoubleX(pos)); double x = buf.getDouble(); pos += 8; return x; }244float getFloat() { ck(buf.getFloat(buf.position()), getFloatX(pos)); float x = buf.getFloat(); pos += 4; return x; }245246void putLong(long x) { putLongX(pos, x); pos += 8; buf.putLong(x); }247void putInt(int x) { putIntX(pos, x); pos += 4; buf.putInt(x); }248void putShort(short x) { putShortX(pos, x); pos += 2; buf.putShort(x); }249void putChar(char x) { putShortX(pos, (short)x); pos += 2; buf.putChar(x); }250void putDouble(double x) { putLongX(pos, Double.doubleToRawLongBits(x)); pos += 8; buf.putDouble(x); }251void putFloat(float x) { putIntX(pos, Float.floatToRawIntBits(x)); pos += 4; buf.putFloat(x); }252253// View accessors254255long getLong(LongBuffer vb, int i) { ck(vb.get(i / 8), getLongX(i)); return vb.get(i / 8); }256int getInt(IntBuffer vb, int i) { ck(vb.get(i / 4), getIntX(i)); return vb.get(i / 4); }257short getShort(ShortBuffer vb, int i) { ck(vb.get(i / 2), getShortX(i)); return vb.get(i / 2); }258char getChar(CharBuffer vb, int i) { ck(vb.get(i / 2), (char)getShortX(i)); return vb.get(i / 2); }259double getDouble(DoubleBuffer vb, int i) { ck(vb.get(i / 8), getDoubleX(i)); return vb.get(i / 8); }260float getFloat(FloatBuffer vb, int i) { ck(vb.get(i / 4), getFloatX(i)); return vb.get(i / 4); }261262void putLong(LongBuffer vb, int i, long x) { vb.put(i / 8, x); putLongX(i, x); }263void putInt(IntBuffer vb, int i, int x) { vb.put(i / 4, x); putIntX(i, x); }264void putShort(ShortBuffer vb, int i, short x) { vb.put(i / 2, x); putShortX(i, x); }265void putChar(CharBuffer vb, int i, char x) { vb.put(i / 2, x); putShortX(i, (short)x); }266void putDouble(DoubleBuffer vb, int i, double x) { vb.put(i / 8, x); putLongX(i, Double.doubleToRawLongBits(x)); }267void putFloat(FloatBuffer vb, int i, float x) { vb.put(i / 4, x); putIntX(i, Float.floatToRawIntBits(x)); }268269long getLong(LongBuffer v) { ck(v.get(v.position()), getLongX(pos)); long x = v.get(); pos += 8; return x; }270int getInt(IntBuffer v) { ck(v.get(v.position()), getIntX(pos)); int x = v.get(); pos += 4; return x; }271short getShort(ShortBuffer v) { ck(v.get(v.position()), getShortX(pos)); short x = v.get(); pos += 2; return x; }272char getChar(CharBuffer v) { ck(v.get(v.position()), (char)getShortX(pos)); char x = v.get(); pos += 2; return x; }273double getDouble(DoubleBuffer v) { ck(v.get(v.position()), getDoubleX(pos)); double x = v.get(); pos += 8; return x; }274float getFloat(FloatBuffer v) { ck(v.get(v.position()), getFloatX(pos)); float x = v.get(); pos += 4; return x; }275276void putLong(LongBuffer v, long x) { putLongX(pos, x); pos += 8; v.put(x); }277void putInt(IntBuffer v, int x) { putIntX(pos, x); pos += 4; v.put(x); }278void putShort(ShortBuffer v, short x) { putShortX(pos, x); pos += 2; v.put(x); }279void putChar(CharBuffer v, char x) { putShortX(pos, (short)x); pos += 2; v.put(x); }280void putDouble(DoubleBuffer v, double x) { putLongX(pos, Double.doubleToRawLongBits(x)); pos += 8; v.put(x); }281void putFloat(FloatBuffer v, float x) { putIntX(pos, Float.floatToRawIntBits(x)); pos += 4; v.put(x); }282283void rewind() { pos = 0; buf.rewind(); }284}285286public abstract class ByteBufferTest implements Runnable {287288Random random = Utils.getRandomInstance();289MyByteBuffer data;290291static int randomOffset(Random r, MyByteBuffer buf, int size) {292return r.nextInt(buf.capacity() - size);293}294295static int randomAlignedOffset(Random r, MyByteBuffer buf, int unitSize) {296return r.nextInt(buf.capacity() / unitSize) * unitSize;297}298299long iterations;300301ByteBufferTest(long iterations, boolean direct) {302this.iterations = iterations;303data = direct304? MyByteBuffer.allocateDirect(1024)305: MyByteBuffer.allocate(1024);306}307308// The core of the test. Walk over the buffer reading and writing309// random data, XORing it as we go. We can detect writes in the310// wrong place, writes which are too long or too short, and reads311// or writes of the wrong data,312void step(Random r) {313stepUsingAccessors(r);314stepUsingViews(r);315}316317void stepUsingAccessors(Random r) {318data.order((r.nextInt() & 1) != 0 ? BIG_ENDIAN : LITTLE_ENDIAN);319320data.rewind();321while (data.position() < data.capacity())322data.putLong(data.getLong() ^ random.nextLong());323324data.rewind();325while (data.position() < data.capacity())326data.putInt(data.getInt() ^ random.nextInt());327328data.rewind();329while (data.position() < data.capacity())330data.putShort((short)(data.getShort() ^ random.nextInt()));331332data.rewind();333while (data.position() < data.capacity())334data.putChar((char)(data.getChar() ^ random.nextInt()));335336data.rewind();337while (data.position() < data.capacity())338data.putDouble(combine(data.getDouble(), random.nextLong()));339340data.rewind();341while (data.position() < data.capacity())342data.putFloat(combine(data.getFloat(), random.nextInt()));343344for (int i = 0; i < 100; i++) {345int offset = randomOffset(r, data, Long.BYTES);346data.putLong(offset, data.getLong(offset) ^ random.nextLong());347}348for (int i = 0; i < 100; i++) {349int offset = randomOffset(r, data, Integer.BYTES);350data.putInt(offset, data.getInt(offset) ^ random.nextInt());351}352for (int i = 0; i < 100; i++) {353int offset = randomOffset(r, data, Short.BYTES);354data.putShort(offset, (short)(data.getShort(offset) ^ random.nextInt()));355}356for (int i = 0; i < 100; i++) {357int offset = randomOffset(r, data, Character.BYTES);358data.putChar(offset, (char)(data.getChar(offset) ^ random.nextInt()));359}360for (int i = 0; i < 100; i++) {361int offset = randomOffset(r, data, Double.BYTES);362data.putDouble(offset, combine(data.getDouble(offset), random.nextLong()));363}364for (int i = 0; i < 100; i++) {365int offset = randomOffset(r, data, Float.BYTES);366data.putFloat(offset, combine(data.getFloat(offset), random.nextInt()));367}368}369370void stepUsingViews(Random r) {371data.order((r.nextInt() & 1) != 0 ? BIG_ENDIAN : LITTLE_ENDIAN);372373data.rewind();374LongBuffer lbuf = data.buf.asLongBuffer();375while (lbuf.position() < data.capacity() / Long.BYTES)376data.putLong(lbuf, data.getLong(lbuf) ^ random.nextLong());377378data.rewind();379IntBuffer ibuf = data.buf.asIntBuffer();380while (ibuf.position() < data.capacity() / Integer.BYTES)381data.putInt(ibuf, data.getInt(ibuf) ^ random.nextInt());382383data.rewind();384ShortBuffer sbuf = data.buf.asShortBuffer();385while (sbuf.position() < data.capacity() / Short.BYTES)386data.putShort(sbuf, (short)(data.getShort(sbuf) ^ random.nextInt()));387388data.rewind();389CharBuffer cbuf = data.buf.asCharBuffer();390while (cbuf.position() < data.capacity() / Character.BYTES)391data.putChar(cbuf, (char)(data.getChar(cbuf) ^ random.nextInt()));392393data.rewind();394DoubleBuffer dbuf = data.buf.asDoubleBuffer();395while (dbuf.position() < data.capacity() / Double.BYTES)396data.putDouble(dbuf, combine(data.getDouble(dbuf), random.nextLong()));397398data.rewind();399FloatBuffer fbuf = data.buf.asFloatBuffer();400while (fbuf.position() < data.capacity() / Float.BYTES)401data.putFloat(fbuf, combine(data.getFloat(fbuf), random.nextInt()));402403for (int i = 0; i < 100; i++) {404int offset = randomAlignedOffset(r, data, Long.BYTES);405data.putLong(lbuf, offset, data.getLong(lbuf, offset) ^ random.nextLong());406}407for (int i = 0; i < 100; i++) {408int offset = randomAlignedOffset(r, data, Integer.BYTES);409data.putInt(ibuf, offset, data.getInt(ibuf, offset) ^ random.nextInt());410}411for (int i = 0; i < 100; i++) {412int offset = randomAlignedOffset(r, data, Short.BYTES);413data.putShort(sbuf, offset, (short)(data.getShort(sbuf, offset) ^ random.nextInt()));414}415for (int i = 0; i < 100; i++) {416int offset = randomAlignedOffset(r, data, Character.BYTES);417data.putChar(cbuf, offset, (char)(data.getChar(cbuf, offset) ^ random.nextInt()));418}419for (int i = 0; i < 100; i++) {420int offset = randomAlignedOffset(r, data, Double.BYTES);421data.putDouble(dbuf, offset, combine(data.getDouble(dbuf, offset), random.nextLong()));422}423for (int i = 0; i < 100; i++) {424int offset = randomAlignedOffset(r, data, Float.BYTES);425data.putFloat(fbuf, offset, combine(data.getFloat(fbuf, offset), random.nextInt()));426}427}428429// XOR the bit pattern of a double and a long, returning the430// result as a double.431//432// We convert signalling NaNs to quiet NaNs. We need to do this433// because some platforms (in particular legacy 80x87) do not434// provide transparent conversions between integer and435// floating-point types even when using raw conversions but436// quietly convert sNaN to qNaN. This causes spurious test437// failures when the template interpreter uses 80x87 and the JITs438// use XMM registers.439//440public double combine(double prev, long bits) {441bits ^= Double.doubleToRawLongBits(prev);442double result = Double.longBitsToDouble(bits);443if (Double.isNaN(result)) {444result = Double.longBitsToDouble(bits | 0x8000000000000l);445}446return result;447}448449// XOR the bit pattern of a float and an int, returning the result450// as a float. Convert sNaNs to qNaNs.451public Float combine(float prev, int bits) {452bits ^= Float.floatToRawIntBits(prev);453Float result = Float.intBitsToFloat(bits);454if (Float.isNaN(result)) {455result = Float.intBitsToFloat(bits | 0x400000);456}457return result;458}459460enum PrimitiveType {461BYTE(1), CHAR(2), SHORT(2), INT(4), LONG(8), FLOAT(4), DOUBLE(8);462463public final int size;464PrimitiveType(int size) {465this.size = size;466}467}468469Buffer asView(ByteBuffer b, PrimitiveType t) {470switch (t) {471case BYTE: return b;472case CHAR: return b.asCharBuffer();473case SHORT: return b.asShortBuffer();474case INT: return b.asIntBuffer();475case LONG: return b.asLongBuffer();476case FLOAT: return b.asFloatBuffer();477case DOUBLE: return b.asDoubleBuffer();478}479throw new InternalError("Should not reach here");480}481482void getOne(ByteBuffer b, PrimitiveType t) {483switch (t) {484case BYTE: b.get(); break;485case CHAR: b.getChar(); break;486case SHORT: b.getShort(); break;487case INT: b.getInt(); break;488case LONG: b.getLong(); break;489case FLOAT: b.getFloat(); break;490case DOUBLE: b.getDouble(); break;491}492}493494void putOne(ByteBuffer b, PrimitiveType t) {495switch (t) {496case BYTE: b.put((byte)0); break;497case CHAR: b.putChar('0'); break;498case SHORT: b.putShort((short)0); break;499case INT: b.putInt(0); break;500case LONG: b.putLong(0); break;501case FLOAT: b.putFloat(0); break;502case DOUBLE: b.putDouble(0); break;503}504}505506void asViewGetOne(ByteBuffer b, PrimitiveType t) {507switch (t) {508case BYTE: b.get(); break;509case CHAR: b.asCharBuffer().get(); break;510case SHORT: b.asShortBuffer().get(); break;511case INT: b.asIntBuffer().get(); break;512case LONG: b.asLongBuffer().get(); break;513case FLOAT: b.asFloatBuffer().get(); break;514case DOUBLE: b.asDoubleBuffer().get(); break;515}516}517518void asViewPutOne(ByteBuffer b, PrimitiveType t) {519switch (t) {520case BYTE: b.put((byte)0); break;521case CHAR: b.asCharBuffer().put('0'); break;522case SHORT: b.asShortBuffer().put((short)0); break;523case INT: b.asIntBuffer().put(0); break;524case LONG: b.asLongBuffer().put(0); break;525case FLOAT: b.asFloatBuffer().put(0); break;526case DOUBLE: b.asDoubleBuffer().put(0); break;527}528}529530void getOne(ByteBuffer b, PrimitiveType t, int index) {531switch (t) {532case BYTE: b.get(index); break;533case CHAR: b.getChar(index); break;534case SHORT: b.getShort(index); break;535case INT: b.getInt(index); break;536case LONG: b.getLong(index); break;537case FLOAT: b.getFloat(index); break;538case DOUBLE: b.getDouble(index); break;539}540}541542void putOne(ByteBuffer b, PrimitiveType t, int index) {543switch (t) {544case BYTE: b.put(index, (byte)0); break;545case CHAR: b.putChar(index, '0'); break;546case SHORT: b.putShort(index, (short)0); break;547case INT: b.putInt(index, 0); break;548case LONG: b.putLong(index, 0); break;549case FLOAT: b.putFloat(index, 0); break;550case DOUBLE: b.putDouble(index, 0); break;551}552}553554void asViewGetOne(Buffer v, PrimitiveType t, int index) {555switch (t) {556case BYTE: ((ByteBuffer) v).get(index); break;557case CHAR: ((CharBuffer) v).get(index); break;558case SHORT: ((ShortBuffer) v).get(index); break;559case INT: ((IntBuffer) v).get(index); break;560case LONG: ((LongBuffer) v).get(index); break;561case FLOAT: ((FloatBuffer) v).get(index); break;562case DOUBLE: ((DoubleBuffer) v).get(index); break;563}564}565566void asViewPutOne(Buffer v, PrimitiveType t, int index) {567switch (t) {568case BYTE: ((ByteBuffer) v).put(index, (byte)0); break;569case CHAR: ((CharBuffer) v).put(index, '0'); break;570case SHORT: ((ShortBuffer) v).put(index, (short)0); break;571case INT: ((IntBuffer) v).put(index, 0); break;572case LONG: ((LongBuffer) v).put(index, 0); break;573case FLOAT: ((FloatBuffer) v).put(index, 0); break;574case DOUBLE: ((DoubleBuffer) v).put(index, 0); break;575}576}577578void checkBoundaryConditions() {579for (int i = 0; i < 100; i++) {580int bufSize = random.nextInt(16);581ByteBuffer buf = data.buf.isDirect()582? ByteBuffer.allocateDirect(bufSize)583: ByteBuffer.allocate(bufSize);584for (PrimitiveType t : PrimitiveType.values()) {585buf.rewind();586Buffer viewBuf = asView(buf, t);587for (int j = 0; j < 100; j++) {588int offset = random.nextInt(32) - 8;589int threw = 0;590int checks = 6;591try {592try {593buf.position(offset);594getOne(buf, t);595}596catch (BufferUnderflowException e) {597if (offset + t.size < bufSize)598throw new RuntimeException599("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);600threw++;601}602catch (IllegalArgumentException e) {603if (offset >= 0 && offset + t.size < bufSize)604throw new RuntimeException605("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);606threw++;607}608609try {610buf.position(offset);611asViewGetOne(buf, t);612}613catch (BufferUnderflowException e) {614if (offset + t.size < bufSize)615throw new RuntimeException616("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);617threw++;618}619catch (IllegalArgumentException e) {620if (offset >= 0 && offset + t.size < bufSize)621throw new RuntimeException622("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);623threw++;624}625626try {627buf.position(offset);628putOne(buf, t);629}630catch (BufferOverflowException e) {631if (offset + t.size < bufSize)632throw new RuntimeException633("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);634threw++;635}636catch (IllegalArgumentException e) {637if (offset >= 0 && offset + t.size < bufSize)638throw new RuntimeException639("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);640threw++;641}642643try {644buf.position(offset);645asViewPutOne(buf, t);646}647catch (BufferOverflowException e) {648if (offset + t.size < bufSize)649throw new RuntimeException650("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);651threw++;652}653catch (IllegalArgumentException e) {654if (offset >= 0 && offset + t.size < bufSize)655throw new RuntimeException656("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);657threw++;658}659660try {661putOne(buf, t, offset);662}663catch (IndexOutOfBoundsException e) {664if (offset >= 0 && offset + t.size < bufSize)665throw new RuntimeException666("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);667threw++;668}669670try {671getOne(buf, t, offset);672}673catch (IndexOutOfBoundsException e) {674if (offset >= 0 && offset + t.size < bufSize)675throw new RuntimeException676("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);677threw++;678}679680// If offset is aligned access using the view681if (offset % t.size == 0) {682checks = 8;683int viewOffset = offset / t.size;684685686try {687asViewPutOne(viewBuf, t, viewOffset);688}689catch (IndexOutOfBoundsException e) {690if (offset >= 0 && offset + t.size < bufSize)691throw new RuntimeException692("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);693threw++;694}695696try {697asViewGetOne(viewBuf, t, viewOffset);698}699catch (IndexOutOfBoundsException e) {700if (offset >= 0 && offset + t.size < bufSize)701throw new RuntimeException702("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);703threw++;704}705}706707if (threw == 0) {708// Make sure that we should not have thrown.709if (offset < 0 || offset + t.size > bufSize) {710throw new RuntimeException711("should have thrown but did not, type = " + t712+ ", offset = " + offset + ", bufSize = " + bufSize);713}714}715else if (threw != checks) {716// If one of the {get,put} operations threw717// due to an invalid offset then all four of718// them should have thrown.719throw new RuntimeException720("should have thrown but at least one did not, type = " + t721+ ", offset = " + offset + ", bufSize = " + bufSize);722}723}724catch (Throwable th) {725throw new RuntimeException726("unexpected throw: type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, th);727728}729}730}731}732}733734public void run() {735checkBoundaryConditions();736737for (int i = 0; i < data.capacity(); i += 8) {738data.putLong(i, random.nextLong());739}740741for (int i = 0; i < iterations; i++) {742step(random);743}744745if (!Arrays.equals(data.actualArray(), data.expectedArray())) {746throw new RuntimeException();747}748}749}750751752