Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/compiler/intrinsics/unsafe/ByteBufferTest.java
41153 views
1
/*
2
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2015, 2016, Red Hat Inc. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
import jdk.test.lib.Utils;
26
27
import java.nio.Buffer;
28
import java.nio.BufferOverflowException;
29
import java.nio.BufferUnderflowException;
30
import java.nio.ByteBuffer;
31
import java.nio.ByteOrder;
32
import java.nio.CharBuffer;
33
import java.nio.DoubleBuffer;
34
import java.nio.FloatBuffer;
35
import java.nio.IntBuffer;
36
import java.nio.LongBuffer;
37
import java.nio.ShortBuffer;
38
import java.util.Arrays;
39
import java.util.Random;
40
41
import static java.nio.ByteOrder.BIG_ENDIAN;
42
import static java.nio.ByteOrder.LITTLE_ENDIAN;
43
44
// A wrapper for a ByteBuffer which maintains a backing array and a
45
// position. Whenever this wrapper is written the backing array and
46
// the wrapped byte buffer are updated together, and whenever it is
47
// read we check that the ByteBuffer and the backing array are identical.
48
49
class MyByteBuffer {
50
final ByteBuffer buf;
51
final byte[] bytes;
52
int pos;
53
ByteOrder byteOrder = BIG_ENDIAN;
54
55
MyByteBuffer(ByteBuffer buf) {
56
this.buf = buf;
57
this.bytes = new byte[buf.capacity()];
58
pos = 0;
59
}
60
61
public final MyByteBuffer order(ByteOrder bo) {
62
byteOrder = bo;
63
buf.order(bo);
64
return this;
65
}
66
67
static MyByteBuffer allocate(int capacity) {
68
return new MyByteBuffer(ByteBuffer.allocate(capacity));
69
}
70
71
static MyByteBuffer allocateDirect(int capacity) {
72
return new MyByteBuffer(ByteBuffer.allocateDirect(capacity));
73
}
74
75
int capacity() { return bytes.length; }
76
int position() {
77
if (buf.position() != pos)
78
throw new RuntimeException();
79
return buf.position();
80
}
81
82
byte[] actualArray() {
83
buf.rewind();
84
byte[] actual = new byte[bytes.length];
85
buf.get(actual, 0, actual.length);
86
buf.rewind();
87
88
return actual;
89
}
90
byte[] expectedArray() { return bytes; }
91
92
private static byte long7(long x) { return (byte)(x >> 56); }
93
private static byte long6(long x) { return (byte)(x >> 48); }
94
private static byte long5(long x) { return (byte)(x >> 40); }
95
private static byte long4(long x) { return (byte)(x >> 32); }
96
private static byte long3(long x) { return (byte)(x >> 24); }
97
private static byte long2(long x) { return (byte)(x >> 16); }
98
private static byte long1(long x) { return (byte)(x >> 8); }
99
private static byte long0(long x) { return (byte)(x ); }
100
101
private static byte int3(int x) { return (byte)(x >> 24); }
102
private static byte int2(int x) { return (byte)(x >> 16); }
103
private static byte int1(int x) { return (byte)(x >> 8); }
104
private static byte int0(int x) { return (byte)(x ); }
105
106
private static byte short1(short x) { return (byte)(x >> 8); }
107
private static byte short0(short x) { return (byte)(x ); }
108
109
byte _get(long i) { return bytes[(int)i]; }
110
void _put(long i, byte x) { bytes[(int)i] = x; }
111
112
private void putLongX(long a, long x) {
113
if (byteOrder == BIG_ENDIAN) {
114
x = Long.reverseBytes(x);
115
}
116
_put(a + 7, long7(x));
117
_put(a + 6, long6(x));
118
_put(a + 5, long5(x));
119
_put(a + 4, long4(x));
120
_put(a + 3, long3(x));
121
_put(a + 2, long2(x));
122
_put(a + 1, long1(x));
123
_put(a , long0(x));
124
}
125
126
private void putIntX(long a, int x) {
127
if (byteOrder == BIG_ENDIAN) {
128
x = Integer.reverseBytes(x);
129
}
130
_put(a + 3, int3(x));
131
_put(a + 2, int2(x));
132
_put(a + 1, int1(x));
133
_put(a , int0(x));
134
}
135
136
private void putShortX(int bi, short x) {
137
if (byteOrder == BIG_ENDIAN) {
138
x = Short.reverseBytes(x);
139
}
140
_put(bi , short0(x));
141
_put(bi + 1, short1(x));
142
}
143
144
static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
145
return (((b3 ) << 24) |
146
((b2 & 0xff) << 16) |
147
((b1 & 0xff) << 8) |
148
((b0 & 0xff) ));
149
}
150
int getIntX(long a) {
151
int x = makeInt(_get(a + 3),
152
_get(a + 2),
153
_get(a + 1),
154
_get(a));
155
if (byteOrder == BIG_ENDIAN) {
156
x = Integer.reverseBytes(x);
157
}
158
return x;
159
}
160
161
static private long makeLong(byte b7, byte b6, byte b5, byte b4,
162
byte b3, byte b2, byte b1, byte b0)
163
{
164
return ((((long)b7 ) << 56) |
165
(((long)b6 & 0xff) << 48) |
166
(((long)b5 & 0xff) << 40) |
167
(((long)b4 & 0xff) << 32) |
168
(((long)b3 & 0xff) << 24) |
169
(((long)b2 & 0xff) << 16) |
170
(((long)b1 & 0xff) << 8) |
171
(((long)b0 & 0xff) ));
172
}
173
174
long getLongX(long a) {
175
long x = makeLong(_get(a + 7),
176
_get(a + 6),
177
_get(a + 5),
178
_get(a + 4),
179
_get(a + 3),
180
_get(a + 2),
181
_get(a + 1),
182
_get(a));
183
if (byteOrder == BIG_ENDIAN) {
184
x = Long.reverseBytes(x);
185
}
186
return x;
187
}
188
189
static private short makeShort(byte b1, byte b0) {
190
return (short)((b1 << 8) | (b0 & 0xff));
191
}
192
193
short getShortX(long a) {
194
short x = makeShort(_get(a + 1),
195
_get(a ));
196
if (byteOrder == BIG_ENDIAN) {
197
x = Short.reverseBytes(x);
198
}
199
return x;
200
}
201
202
double getDoubleX(long a) {
203
long x = getLongX(a);
204
return Double.longBitsToDouble(x);
205
}
206
207
double getFloatX(long a) {
208
int x = getIntX(a);
209
return Float.intBitsToFloat(x);
210
}
211
212
void ck(long x, long y) {
213
if (x != y) {
214
throw new RuntimeException(" x = " + Long.toHexString(x) + ", y = " + Long.toHexString(y));
215
}
216
}
217
218
void ck(double x, double y) {
219
if (x == x && y == y && x != y) {
220
ck(x, y);
221
}
222
}
223
224
// Method accessors
225
226
long getLong(int i) { ck(buf.getLong(i), getLongX(i)); return buf.getLong(i); }
227
int getInt(int i) { ck(buf.getInt(i), getIntX(i)); return buf.getInt(i); }
228
short getShort(int i) { ck(buf.getShort(i), getShortX(i)); return buf.getShort(i); }
229
char getChar(int i) { ck(buf.getChar(i), (char)getShortX(i)); return buf.getChar(i); }
230
double getDouble(int i) { ck(buf.getDouble(i), getDoubleX(i)); return buf.getDouble(i); }
231
float getFloat(int i) { ck(buf.getFloat(i), getFloatX(i)); return buf.getFloat(i); }
232
233
void putLong(int i, long x) { buf.putLong(i, x); putLongX(i, x); }
234
void putInt(int i, int x) { buf.putInt(i, x); putIntX(i, x); }
235
void putShort(int i, short x) { buf.putShort(i, x); putShortX(i, x); }
236
void putChar(int i, char x) { buf.putChar(i, x); putShortX(i, (short)x); }
237
void putDouble(int i, double x) { buf.putDouble(i, x); putLongX(i, Double.doubleToRawLongBits(x)); }
238
void putFloat(int i, float x) { buf.putFloat(i, x); putIntX(i, Float.floatToRawIntBits(x)); }
239
240
long getLong() { ck(buf.getLong(buf.position()), getLongX(pos)); long x = buf.getLong(); pos += 8; return x; }
241
int getInt() { ck(buf.getInt(buf.position()), getIntX(pos)); int x = buf.getInt(); pos += 4; return x; }
242
short getShort() { ck(buf.getShort(buf.position()), getShortX(pos)); short x = buf.getShort(); pos += 2; return x; }
243
char getChar() { ck(buf.getChar(buf.position()), (char)getShortX(pos)); char x = buf.getChar(); pos += 2; return x; }
244
double getDouble() { ck(buf.getDouble(buf.position()), getDoubleX(pos)); double x = buf.getDouble(); pos += 8; return x; }
245
float getFloat() { ck(buf.getFloat(buf.position()), getFloatX(pos)); float x = buf.getFloat(); pos += 4; return x; }
246
247
void putLong(long x) { putLongX(pos, x); pos += 8; buf.putLong(x); }
248
void putInt(int x) { putIntX(pos, x); pos += 4; buf.putInt(x); }
249
void putShort(short x) { putShortX(pos, x); pos += 2; buf.putShort(x); }
250
void putChar(char x) { putShortX(pos, (short)x); pos += 2; buf.putChar(x); }
251
void putDouble(double x) { putLongX(pos, Double.doubleToRawLongBits(x)); pos += 8; buf.putDouble(x); }
252
void putFloat(float x) { putIntX(pos, Float.floatToRawIntBits(x)); pos += 4; buf.putFloat(x); }
253
254
// View accessors
255
256
long getLong(LongBuffer vb, int i) { ck(vb.get(i / 8), getLongX(i)); return vb.get(i / 8); }
257
int getInt(IntBuffer vb, int i) { ck(vb.get(i / 4), getIntX(i)); return vb.get(i / 4); }
258
short getShort(ShortBuffer vb, int i) { ck(vb.get(i / 2), getShortX(i)); return vb.get(i / 2); }
259
char getChar(CharBuffer vb, int i) { ck(vb.get(i / 2), (char)getShortX(i)); return vb.get(i / 2); }
260
double getDouble(DoubleBuffer vb, int i) { ck(vb.get(i / 8), getDoubleX(i)); return vb.get(i / 8); }
261
float getFloat(FloatBuffer vb, int i) { ck(vb.get(i / 4), getFloatX(i)); return vb.get(i / 4); }
262
263
void putLong(LongBuffer vb, int i, long x) { vb.put(i / 8, x); putLongX(i, x); }
264
void putInt(IntBuffer vb, int i, int x) { vb.put(i / 4, x); putIntX(i, x); }
265
void putShort(ShortBuffer vb, int i, short x) { vb.put(i / 2, x); putShortX(i, x); }
266
void putChar(CharBuffer vb, int i, char x) { vb.put(i / 2, x); putShortX(i, (short)x); }
267
void putDouble(DoubleBuffer vb, int i, double x) { vb.put(i / 8, x); putLongX(i, Double.doubleToRawLongBits(x)); }
268
void putFloat(FloatBuffer vb, int i, float x) { vb.put(i / 4, x); putIntX(i, Float.floatToRawIntBits(x)); }
269
270
long getLong(LongBuffer v) { ck(v.get(v.position()), getLongX(pos)); long x = v.get(); pos += 8; return x; }
271
int getInt(IntBuffer v) { ck(v.get(v.position()), getIntX(pos)); int x = v.get(); pos += 4; return x; }
272
short getShort(ShortBuffer v) { ck(v.get(v.position()), getShortX(pos)); short x = v.get(); pos += 2; return x; }
273
char getChar(CharBuffer v) { ck(v.get(v.position()), (char)getShortX(pos)); char x = v.get(); pos += 2; return x; }
274
double getDouble(DoubleBuffer v) { ck(v.get(v.position()), getDoubleX(pos)); double x = v.get(); pos += 8; return x; }
275
float getFloat(FloatBuffer v) { ck(v.get(v.position()), getFloatX(pos)); float x = v.get(); pos += 4; return x; }
276
277
void putLong(LongBuffer v, long x) { putLongX(pos, x); pos += 8; v.put(x); }
278
void putInt(IntBuffer v, int x) { putIntX(pos, x); pos += 4; v.put(x); }
279
void putShort(ShortBuffer v, short x) { putShortX(pos, x); pos += 2; v.put(x); }
280
void putChar(CharBuffer v, char x) { putShortX(pos, (short)x); pos += 2; v.put(x); }
281
void putDouble(DoubleBuffer v, double x) { putLongX(pos, Double.doubleToRawLongBits(x)); pos += 8; v.put(x); }
282
void putFloat(FloatBuffer v, float x) { putIntX(pos, Float.floatToRawIntBits(x)); pos += 4; v.put(x); }
283
284
void rewind() { pos = 0; buf.rewind(); }
285
}
286
287
public abstract class ByteBufferTest implements Runnable {
288
289
Random random = Utils.getRandomInstance();
290
MyByteBuffer data;
291
292
static int randomOffset(Random r, MyByteBuffer buf, int size) {
293
return r.nextInt(buf.capacity() - size);
294
}
295
296
static int randomAlignedOffset(Random r, MyByteBuffer buf, int unitSize) {
297
return r.nextInt(buf.capacity() / unitSize) * unitSize;
298
}
299
300
long iterations;
301
302
ByteBufferTest(long iterations, boolean direct) {
303
this.iterations = iterations;
304
data = direct
305
? MyByteBuffer.allocateDirect(1024)
306
: MyByteBuffer.allocate(1024);
307
}
308
309
// The core of the test. Walk over the buffer reading and writing
310
// random data, XORing it as we go. We can detect writes in the
311
// wrong place, writes which are too long or too short, and reads
312
// or writes of the wrong data,
313
void step(Random r) {
314
stepUsingAccessors(r);
315
stepUsingViews(r);
316
}
317
318
void stepUsingAccessors(Random r) {
319
data.order((r.nextInt() & 1) != 0 ? BIG_ENDIAN : LITTLE_ENDIAN);
320
321
data.rewind();
322
while (data.position() < data.capacity())
323
data.putLong(data.getLong() ^ random.nextLong());
324
325
data.rewind();
326
while (data.position() < data.capacity())
327
data.putInt(data.getInt() ^ random.nextInt());
328
329
data.rewind();
330
while (data.position() < data.capacity())
331
data.putShort((short)(data.getShort() ^ random.nextInt()));
332
333
data.rewind();
334
while (data.position() < data.capacity())
335
data.putChar((char)(data.getChar() ^ random.nextInt()));
336
337
data.rewind();
338
while (data.position() < data.capacity())
339
data.putDouble(combine(data.getDouble(), random.nextLong()));
340
341
data.rewind();
342
while (data.position() < data.capacity())
343
data.putFloat(combine(data.getFloat(), random.nextInt()));
344
345
for (int i = 0; i < 100; i++) {
346
int offset = randomOffset(r, data, Long.BYTES);
347
data.putLong(offset, data.getLong(offset) ^ random.nextLong());
348
}
349
for (int i = 0; i < 100; i++) {
350
int offset = randomOffset(r, data, Integer.BYTES);
351
data.putInt(offset, data.getInt(offset) ^ random.nextInt());
352
}
353
for (int i = 0; i < 100; i++) {
354
int offset = randomOffset(r, data, Short.BYTES);
355
data.putShort(offset, (short)(data.getShort(offset) ^ random.nextInt()));
356
}
357
for (int i = 0; i < 100; i++) {
358
int offset = randomOffset(r, data, Character.BYTES);
359
data.putChar(offset, (char)(data.getChar(offset) ^ random.nextInt()));
360
}
361
for (int i = 0; i < 100; i++) {
362
int offset = randomOffset(r, data, Double.BYTES);
363
data.putDouble(offset, combine(data.getDouble(offset), random.nextLong()));
364
}
365
for (int i = 0; i < 100; i++) {
366
int offset = randomOffset(r, data, Float.BYTES);
367
data.putFloat(offset, combine(data.getFloat(offset), random.nextInt()));
368
}
369
}
370
371
void stepUsingViews(Random r) {
372
data.order((r.nextInt() & 1) != 0 ? BIG_ENDIAN : LITTLE_ENDIAN);
373
374
data.rewind();
375
LongBuffer lbuf = data.buf.asLongBuffer();
376
while (lbuf.position() < data.capacity() / Long.BYTES)
377
data.putLong(lbuf, data.getLong(lbuf) ^ random.nextLong());
378
379
data.rewind();
380
IntBuffer ibuf = data.buf.asIntBuffer();
381
while (ibuf.position() < data.capacity() / Integer.BYTES)
382
data.putInt(ibuf, data.getInt(ibuf) ^ random.nextInt());
383
384
data.rewind();
385
ShortBuffer sbuf = data.buf.asShortBuffer();
386
while (sbuf.position() < data.capacity() / Short.BYTES)
387
data.putShort(sbuf, (short)(data.getShort(sbuf) ^ random.nextInt()));
388
389
data.rewind();
390
CharBuffer cbuf = data.buf.asCharBuffer();
391
while (cbuf.position() < data.capacity() / Character.BYTES)
392
data.putChar(cbuf, (char)(data.getChar(cbuf) ^ random.nextInt()));
393
394
data.rewind();
395
DoubleBuffer dbuf = data.buf.asDoubleBuffer();
396
while (dbuf.position() < data.capacity() / Double.BYTES)
397
data.putDouble(dbuf, combine(data.getDouble(dbuf), random.nextLong()));
398
399
data.rewind();
400
FloatBuffer fbuf = data.buf.asFloatBuffer();
401
while (fbuf.position() < data.capacity() / Float.BYTES)
402
data.putFloat(fbuf, combine(data.getFloat(fbuf), random.nextInt()));
403
404
for (int i = 0; i < 100; i++) {
405
int offset = randomAlignedOffset(r, data, Long.BYTES);
406
data.putLong(lbuf, offset, data.getLong(lbuf, offset) ^ random.nextLong());
407
}
408
for (int i = 0; i < 100; i++) {
409
int offset = randomAlignedOffset(r, data, Integer.BYTES);
410
data.putInt(ibuf, offset, data.getInt(ibuf, offset) ^ random.nextInt());
411
}
412
for (int i = 0; i < 100; i++) {
413
int offset = randomAlignedOffset(r, data, Short.BYTES);
414
data.putShort(sbuf, offset, (short)(data.getShort(sbuf, offset) ^ random.nextInt()));
415
}
416
for (int i = 0; i < 100; i++) {
417
int offset = randomAlignedOffset(r, data, Character.BYTES);
418
data.putChar(cbuf, offset, (char)(data.getChar(cbuf, offset) ^ random.nextInt()));
419
}
420
for (int i = 0; i < 100; i++) {
421
int offset = randomAlignedOffset(r, data, Double.BYTES);
422
data.putDouble(dbuf, offset, combine(data.getDouble(dbuf, offset), random.nextLong()));
423
}
424
for (int i = 0; i < 100; i++) {
425
int offset = randomAlignedOffset(r, data, Float.BYTES);
426
data.putFloat(fbuf, offset, combine(data.getFloat(fbuf, offset), random.nextInt()));
427
}
428
}
429
430
// XOR the bit pattern of a double and a long, returning the
431
// result as a double.
432
//
433
// We convert signalling NaNs to quiet NaNs. We need to do this
434
// because some platforms (in particular legacy 80x87) do not
435
// provide transparent conversions between integer and
436
// floating-point types even when using raw conversions but
437
// quietly convert sNaN to qNaN. This causes spurious test
438
// failures when the template interpreter uses 80x87 and the JITs
439
// use XMM registers.
440
//
441
public double combine(double prev, long bits) {
442
bits ^= Double.doubleToRawLongBits(prev);
443
double result = Double.longBitsToDouble(bits);
444
if (Double.isNaN(result)) {
445
result = Double.longBitsToDouble(bits | 0x8000000000000l);
446
}
447
return result;
448
}
449
450
// XOR the bit pattern of a float and an int, returning the result
451
// as a float. Convert sNaNs to qNaNs.
452
public Float combine(float prev, int bits) {
453
bits ^= Float.floatToRawIntBits(prev);
454
Float result = Float.intBitsToFloat(bits);
455
if (Float.isNaN(result)) {
456
result = Float.intBitsToFloat(bits | 0x400000);
457
}
458
return result;
459
}
460
461
enum PrimitiveType {
462
BYTE(1), CHAR(2), SHORT(2), INT(4), LONG(8), FLOAT(4), DOUBLE(8);
463
464
public final int size;
465
PrimitiveType(int size) {
466
this.size = size;
467
}
468
}
469
470
Buffer asView(ByteBuffer b, PrimitiveType t) {
471
switch (t) {
472
case BYTE: return b;
473
case CHAR: return b.asCharBuffer();
474
case SHORT: return b.asShortBuffer();
475
case INT: return b.asIntBuffer();
476
case LONG: return b.asLongBuffer();
477
case FLOAT: return b.asFloatBuffer();
478
case DOUBLE: return b.asDoubleBuffer();
479
}
480
throw new InternalError("Should not reach here");
481
}
482
483
void getOne(ByteBuffer b, PrimitiveType t) {
484
switch (t) {
485
case BYTE: b.get(); break;
486
case CHAR: b.getChar(); break;
487
case SHORT: b.getShort(); break;
488
case INT: b.getInt(); break;
489
case LONG: b.getLong(); break;
490
case FLOAT: b.getFloat(); break;
491
case DOUBLE: b.getDouble(); break;
492
}
493
}
494
495
void putOne(ByteBuffer b, PrimitiveType t) {
496
switch (t) {
497
case BYTE: b.put((byte)0); break;
498
case CHAR: b.putChar('0'); break;
499
case SHORT: b.putShort((short)0); break;
500
case INT: b.putInt(0); break;
501
case LONG: b.putLong(0); break;
502
case FLOAT: b.putFloat(0); break;
503
case DOUBLE: b.putDouble(0); break;
504
}
505
}
506
507
void asViewGetOne(ByteBuffer b, PrimitiveType t) {
508
switch (t) {
509
case BYTE: b.get(); break;
510
case CHAR: b.asCharBuffer().get(); break;
511
case SHORT: b.asShortBuffer().get(); break;
512
case INT: b.asIntBuffer().get(); break;
513
case LONG: b.asLongBuffer().get(); break;
514
case FLOAT: b.asFloatBuffer().get(); break;
515
case DOUBLE: b.asDoubleBuffer().get(); break;
516
}
517
}
518
519
void asViewPutOne(ByteBuffer b, PrimitiveType t) {
520
switch (t) {
521
case BYTE: b.put((byte)0); break;
522
case CHAR: b.asCharBuffer().put('0'); break;
523
case SHORT: b.asShortBuffer().put((short)0); break;
524
case INT: b.asIntBuffer().put(0); break;
525
case LONG: b.asLongBuffer().put(0); break;
526
case FLOAT: b.asFloatBuffer().put(0); break;
527
case DOUBLE: b.asDoubleBuffer().put(0); break;
528
}
529
}
530
531
void getOne(ByteBuffer b, PrimitiveType t, int index) {
532
switch (t) {
533
case BYTE: b.get(index); break;
534
case CHAR: b.getChar(index); break;
535
case SHORT: b.getShort(index); break;
536
case INT: b.getInt(index); break;
537
case LONG: b.getLong(index); break;
538
case FLOAT: b.getFloat(index); break;
539
case DOUBLE: b.getDouble(index); break;
540
}
541
}
542
543
void putOne(ByteBuffer b, PrimitiveType t, int index) {
544
switch (t) {
545
case BYTE: b.put(index, (byte)0); break;
546
case CHAR: b.putChar(index, '0'); break;
547
case SHORT: b.putShort(index, (short)0); break;
548
case INT: b.putInt(index, 0); break;
549
case LONG: b.putLong(index, 0); break;
550
case FLOAT: b.putFloat(index, 0); break;
551
case DOUBLE: b.putDouble(index, 0); break;
552
}
553
}
554
555
void asViewGetOne(Buffer v, PrimitiveType t, int index) {
556
switch (t) {
557
case BYTE: ((ByteBuffer) v).get(index); break;
558
case CHAR: ((CharBuffer) v).get(index); break;
559
case SHORT: ((ShortBuffer) v).get(index); break;
560
case INT: ((IntBuffer) v).get(index); break;
561
case LONG: ((LongBuffer) v).get(index); break;
562
case FLOAT: ((FloatBuffer) v).get(index); break;
563
case DOUBLE: ((DoubleBuffer) v).get(index); break;
564
}
565
}
566
567
void asViewPutOne(Buffer v, PrimitiveType t, int index) {
568
switch (t) {
569
case BYTE: ((ByteBuffer) v).put(index, (byte)0); break;
570
case CHAR: ((CharBuffer) v).put(index, '0'); break;
571
case SHORT: ((ShortBuffer) v).put(index, (short)0); break;
572
case INT: ((IntBuffer) v).put(index, 0); break;
573
case LONG: ((LongBuffer) v).put(index, 0); break;
574
case FLOAT: ((FloatBuffer) v).put(index, 0); break;
575
case DOUBLE: ((DoubleBuffer) v).put(index, 0); break;
576
}
577
}
578
579
void checkBoundaryConditions() {
580
for (int i = 0; i < 100; i++) {
581
int bufSize = random.nextInt(16);
582
ByteBuffer buf = data.buf.isDirect()
583
? ByteBuffer.allocateDirect(bufSize)
584
: ByteBuffer.allocate(bufSize);
585
for (PrimitiveType t : PrimitiveType.values()) {
586
buf.rewind();
587
Buffer viewBuf = asView(buf, t);
588
for (int j = 0; j < 100; j++) {
589
int offset = random.nextInt(32) - 8;
590
int threw = 0;
591
int checks = 6;
592
try {
593
try {
594
buf.position(offset);
595
getOne(buf, t);
596
}
597
catch (BufferUnderflowException e) {
598
if (offset + t.size < bufSize)
599
throw new RuntimeException
600
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
601
threw++;
602
}
603
catch (IllegalArgumentException e) {
604
if (offset >= 0 && offset + t.size < bufSize)
605
throw new RuntimeException
606
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
607
threw++;
608
}
609
610
try {
611
buf.position(offset);
612
asViewGetOne(buf, t);
613
}
614
catch (BufferUnderflowException e) {
615
if (offset + t.size < bufSize)
616
throw new RuntimeException
617
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
618
threw++;
619
}
620
catch (IllegalArgumentException e) {
621
if (offset >= 0 && offset + t.size < bufSize)
622
throw new RuntimeException
623
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
624
threw++;
625
}
626
627
try {
628
buf.position(offset);
629
putOne(buf, t);
630
}
631
catch (BufferOverflowException e) {
632
if (offset + t.size < bufSize)
633
throw new RuntimeException
634
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
635
threw++;
636
}
637
catch (IllegalArgumentException e) {
638
if (offset >= 0 && offset + t.size < bufSize)
639
throw new RuntimeException
640
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
641
threw++;
642
}
643
644
try {
645
buf.position(offset);
646
asViewPutOne(buf, t);
647
}
648
catch (BufferOverflowException e) {
649
if (offset + t.size < bufSize)
650
throw new RuntimeException
651
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
652
threw++;
653
}
654
catch (IllegalArgumentException e) {
655
if (offset >= 0 && offset + t.size < bufSize)
656
throw new RuntimeException
657
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
658
threw++;
659
}
660
661
try {
662
putOne(buf, t, offset);
663
}
664
catch (IndexOutOfBoundsException e) {
665
if (offset >= 0 && offset + t.size < bufSize)
666
throw new RuntimeException
667
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
668
threw++;
669
}
670
671
try {
672
getOne(buf, t, offset);
673
}
674
catch (IndexOutOfBoundsException e) {
675
if (offset >= 0 && offset + t.size < bufSize)
676
throw new RuntimeException
677
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
678
threw++;
679
}
680
681
// If offset is aligned access using the view
682
if (offset % t.size == 0) {
683
checks = 8;
684
int viewOffset = offset / t.size;
685
686
687
try {
688
asViewPutOne(viewBuf, t, viewOffset);
689
}
690
catch (IndexOutOfBoundsException e) {
691
if (offset >= 0 && offset + t.size < bufSize)
692
throw new RuntimeException
693
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
694
threw++;
695
}
696
697
try {
698
asViewGetOne(viewBuf, t, viewOffset);
699
}
700
catch (IndexOutOfBoundsException e) {
701
if (offset >= 0 && offset + t.size < bufSize)
702
throw new RuntimeException
703
("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
704
threw++;
705
}
706
}
707
708
if (threw == 0) {
709
// Make sure that we should not have thrown.
710
if (offset < 0 || offset + t.size > bufSize) {
711
throw new RuntimeException
712
("should have thrown but did not, type = " + t
713
+ ", offset = " + offset + ", bufSize = " + bufSize);
714
}
715
}
716
else if (threw != checks) {
717
// If one of the {get,put} operations threw
718
// due to an invalid offset then all four of
719
// them should have thrown.
720
throw new RuntimeException
721
("should have thrown but at least one did not, type = " + t
722
+ ", offset = " + offset + ", bufSize = " + bufSize);
723
}
724
}
725
catch (Throwable th) {
726
throw new RuntimeException
727
("unexpected throw: type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, th);
728
729
}
730
}
731
}
732
}
733
}
734
735
public void run() {
736
checkBoundaryConditions();
737
738
for (int i = 0; i < data.capacity(); i += 8) {
739
data.putLong(i, random.nextLong());
740
}
741
742
for (int i = 0; i < iterations; i++) {
743
step(random);
744
}
745
746
if (!Arrays.equals(data.actualArray(), data.expectedArray())) {
747
throw new RuntimeException();
748
}
749
}
750
}
751
752