Skip to content

Commit 74e1a8b

Browse files
committedJan 25, 2023
8300236: Use VarHandle access in Data(Input | Output)Stream classes
Reviewed-by: rriggs, alanb
1 parent a5d8e12 commit 74e1a8b

File tree

11 files changed

+864
-359
lines changed

11 files changed

+864
-359
lines changed
 

‎src/java.base/share/classes/java/io/Bits.java

-120
This file was deleted.

‎src/java.base/share/classes/java/io/DataInputStream.java

+18-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
2525

2626
package java.io;
2727

28+
import jdk.internal.util.ByteArray;
29+
2830
import java.util.Objects;
2931

3032
/**
@@ -54,6 +56,8 @@ public DataInputStream(InputStream in) {
5456
super(in);
5557
}
5658

59+
private final byte[] readBuffer = new byte[8];
60+
5761
/**
5862
* working arrays initialized on demand by readUTF
5963
*/
@@ -309,7 +313,8 @@ public final int readUnsignedByte() throws IOException {
309313
* @see java.io.FilterInputStream#in
310314
*/
311315
public final short readShort() throws IOException {
312-
return (short) readUnsignedShort();
316+
readFully(readBuffer, 0, 2);
317+
return ByteArray.getShort(readBuffer, 0);
313318
}
314319

315320
/**
@@ -330,12 +335,8 @@ public final short readShort() throws IOException {
330335
* @see java.io.FilterInputStream#in
331336
*/
332337
public final int readUnsignedShort() throws IOException {
333-
InputStream in = this.in;
334-
int ch1 = in.read();
335-
int ch2 = in.read();
336-
if ((ch1 | ch2) < 0)
337-
throw new EOFException();
338-
return (ch1 << 8) + (ch2 << 0);
338+
readFully(readBuffer, 0, 2);
339+
return ByteArray.getUnsignedShort(readBuffer, 0);
339340
}
340341

341342
/**
@@ -356,7 +357,8 @@ public final int readUnsignedShort() throws IOException {
356357
* @see java.io.FilterInputStream#in
357358
*/
358359
public final char readChar() throws IOException {
359-
return (char) readUnsignedShort();
360+
readFully(readBuffer, 0, 2);
361+
return ByteArray.getChar(readBuffer, 0);
360362
}
361363

362364
/**
@@ -377,18 +379,10 @@ public final char readChar() throws IOException {
377379
* @see java.io.FilterInputStream#in
378380
*/
379381
public final int readInt() throws IOException {
380-
InputStream in = this.in;
381-
int ch1 = in.read();
382-
int ch2 = in.read();
383-
int ch3 = in.read();
384-
int ch4 = in.read();
385-
if ((ch1 | ch2 | ch3 | ch4) < 0)
386-
throw new EOFException();
387-
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
382+
readFully(readBuffer, 0, 4);
383+
return ByteArray.getInt(readBuffer, 0);
388384
}
389385

390-
private final byte[] readBuffer = new byte[8];
391-
392386
/**
393387
* See the general contract of the {@code readLong}
394388
* method of {@code DataInput}.
@@ -408,14 +402,7 @@ public final int readInt() throws IOException {
408402
*/
409403
public final long readLong() throws IOException {
410404
readFully(readBuffer, 0, 8);
411-
return (((long)readBuffer[0] << 56) +
412-
((long)(readBuffer[1] & 255) << 48) +
413-
((long)(readBuffer[2] & 255) << 40) +
414-
((long)(readBuffer[3] & 255) << 32) +
415-
((long)(readBuffer[4] & 255) << 24) +
416-
((readBuffer[5] & 255) << 16) +
417-
((readBuffer[6] & 255) << 8) +
418-
((readBuffer[7] & 255) << 0));
405+
return ByteArray.getLong(readBuffer, 0);
419406
}
420407

421408
/**
@@ -437,7 +424,8 @@ public final long readLong() throws IOException {
437424
* @see java.lang.Float#intBitsToFloat(int)
438425
*/
439426
public final float readFloat() throws IOException {
440-
return Float.intBitsToFloat(readInt());
427+
readFully(readBuffer, 0, 4);
428+
return ByteArray.getFloat(readBuffer, 0);
441429
}
442430

443431
/**
@@ -459,7 +447,8 @@ public final float readFloat() throws IOException {
459447
* @see java.lang.Double#longBitsToDouble(long)
460448
*/
461449
public final double readDouble() throws IOException {
462-
return Double.longBitsToDouble(readLong());
450+
readFully(readBuffer, 0, 8);
451+
return ByteArray.getDouble(readBuffer, 0);
463452
}
464453

465454
private char[] lineBuffer;

‎src/java.base/share/classes/java/io/DataOutputStream.java

+16-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
2525

2626
package java.io;
2727

28+
import jdk.internal.util.ByteArray;
29+
2830
/**
2931
* A data output stream lets an application write primitive Java data
3032
* types to an output stream in a portable way. An application can
@@ -170,8 +172,7 @@ public final void writeByte(int v) throws IOException {
170172
* @see java.io.FilterOutputStream#out
171173
*/
172174
public final void writeShort(int v) throws IOException {
173-
writeBuffer[0] = (byte)(v >>> 8);
174-
writeBuffer[1] = (byte)(v >>> 0);
175+
ByteArray.setUnsignedShort(writeBuffer, 0, v);
175176
out.write(writeBuffer, 0, 2);
176177
incCount(2);
177178
}
@@ -186,8 +187,7 @@ public final void writeShort(int v) throws IOException {
186187
* @see java.io.FilterOutputStream#out
187188
*/
188189
public final void writeChar(int v) throws IOException {
189-
writeBuffer[0] = (byte)(v >>> 8);
190-
writeBuffer[1] = (byte)(v >>> 0);
190+
ByteArray.setUnsignedShort(writeBuffer, 0, v);
191191
out.write(writeBuffer, 0, 2);
192192
incCount(2);
193193
}
@@ -202,10 +202,7 @@ public final void writeChar(int v) throws IOException {
202202
* @see java.io.FilterOutputStream#out
203203
*/
204204
public final void writeInt(int v) throws IOException {
205-
writeBuffer[0] = (byte)(v >>> 24);
206-
writeBuffer[1] = (byte)(v >>> 16);
207-
writeBuffer[2] = (byte)(v >>> 8);
208-
writeBuffer[3] = (byte)(v >>> 0);
205+
ByteArray.setInt(writeBuffer, 0, v);
209206
out.write(writeBuffer, 0, 4);
210207
incCount(4);
211208
}
@@ -220,14 +217,7 @@ public final void writeInt(int v) throws IOException {
220217
* @see java.io.FilterOutputStream#out
221218
*/
222219
public final void writeLong(long v) throws IOException {
223-
writeBuffer[0] = (byte)(v >>> 56);
224-
writeBuffer[1] = (byte)(v >>> 48);
225-
writeBuffer[2] = (byte)(v >>> 40);
226-
writeBuffer[3] = (byte)(v >>> 32);
227-
writeBuffer[4] = (byte)(v >>> 24);
228-
writeBuffer[5] = (byte)(v >>> 16);
229-
writeBuffer[6] = (byte)(v >>> 8);
230-
writeBuffer[7] = (byte)(v >>> 0);
220+
ByteArray.setLong(writeBuffer, 0, v);
231221
out.write(writeBuffer, 0, 8);
232222
incCount(8);
233223
}
@@ -246,7 +236,9 @@ public final void writeLong(long v) throws IOException {
246236
* @see java.lang.Float#floatToIntBits(float)
247237
*/
248238
public final void writeFloat(float v) throws IOException {
249-
writeInt(Float.floatToIntBits(v));
239+
ByteArray.setFloat(writeBuffer, 0, v);
240+
out.write(writeBuffer, 0, 4);
241+
incCount(4);
250242
}
251243

252244
/**
@@ -263,7 +255,9 @@ public final void writeFloat(float v) throws IOException {
263255
* @see java.lang.Double#doubleToLongBits(double)
264256
*/
265257
public final void writeDouble(double v) throws IOException {
266-
writeLong(Double.doubleToLongBits(v));
258+
ByteArray.setDouble(writeBuffer, 0, v);
259+
out.write(writeBuffer, 0, 8);
260+
incCount(8);
267261
}
268262

269263
/**
@@ -301,8 +295,7 @@ public final void writeChars(String s) throws IOException {
301295
int len = s.length();
302296
for (int i = 0 ; i < len ; i++) {
303297
int v = s.charAt(i);
304-
writeBuffer[0] = (byte)(v >>> 8);
305-
writeBuffer[1] = (byte)(v >>> 0);
298+
ByteArray.setUnsignedShort(writeBuffer, 0, v);
306299
out.write(writeBuffer, 0, 2);
307300
}
308301
incCount(len * 2);
@@ -379,9 +372,8 @@ static int writeUTF(String str, DataOutput out) throws IOException {
379372
}
380373

381374
int count = 0;
382-
bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
383-
bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
384-
375+
ByteArray.setUnsignedShort(bytearr, count, utflen);
376+
count += 2;
385377
int i = 0;
386378
for (i = 0; i < strlen; i++) { // optimized for initial run of ASCII
387379
int c = str.charAt(i);

‎src/java.base/share/classes/java/io/ObjectInputStream.java

+23-22
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import jdk.internal.access.SharedSecrets;
4646
import jdk.internal.event.DeserializationEvent;
4747
import jdk.internal.misc.Unsafe;
48+
import jdk.internal.util.ByteArray;
4849
import sun.reflect.misc.ReflectUtil;
4950
import sun.security.action.GetBooleanAction;
5051
import sun.security.action.GetIntegerAction;
@@ -2631,7 +2632,7 @@ public boolean defaulted(String name) {
26312632

26322633
public boolean get(String name, boolean val) {
26332634
int off = getFieldOffset(name, Boolean.TYPE);
2634-
return (off >= 0) ? Bits.getBoolean(primValues, off) : val;
2635+
return (off >= 0) ? ByteArray.getBoolean(primValues, off) : val;
26352636
}
26362637

26372638
public byte get(String name, byte val) {
@@ -2641,32 +2642,32 @@ public byte get(String name, byte val) {
26412642

26422643
public char get(String name, char val) {
26432644
int off = getFieldOffset(name, Character.TYPE);
2644-
return (off >= 0) ? Bits.getChar(primValues, off) : val;
2645+
return (off >= 0) ? ByteArray.getChar(primValues, off) : val;
26452646
}
26462647

26472648
public short get(String name, short val) {
26482649
int off = getFieldOffset(name, Short.TYPE);
2649-
return (off >= 0) ? Bits.getShort(primValues, off) : val;
2650+
return (off >= 0) ? ByteArray.getShort(primValues, off) : val;
26502651
}
26512652

26522653
public int get(String name, int val) {
26532654
int off = getFieldOffset(name, Integer.TYPE);
2654-
return (off >= 0) ? Bits.getInt(primValues, off) : val;
2655+
return (off >= 0) ? ByteArray.getInt(primValues, off) : val;
26552656
}
26562657

26572658
public float get(String name, float val) {
26582659
int off = getFieldOffset(name, Float.TYPE);
2659-
return (off >= 0) ? Bits.getFloat(primValues, off) : val;
2660+
return (off >= 0) ? ByteArray.getFloat(primValues, off) : val;
26602661
}
26612662

26622663
public long get(String name, long val) {
26632664
int off = getFieldOffset(name, Long.TYPE);
2664-
return (off >= 0) ? Bits.getLong(primValues, off) : val;
2665+
return (off >= 0) ? ByteArray.getLong(primValues, off) : val;
26652666
}
26662667

26672668
public double get(String name, double val) {
26682669
int off = getFieldOffset(name, Double.TYPE);
2669-
return (off >= 0) ? Bits.getDouble(primValues, off) : val;
2670+
return (off >= 0) ? ByteArray.getDouble(primValues, off) : val;
26702671
}
26712672

26722673
public Object get(String name, Object val) throws ClassNotFoundException {
@@ -3114,7 +3115,7 @@ private int readBlockHeader(boolean canBlock) throws IOException {
31143115
return HEADER_BLOCKED;
31153116
}
31163117
in.readFully(hbuf, 0, 5);
3117-
int len = Bits.getInt(hbuf, 1);
3118+
int len = ByteArray.getInt(hbuf, 1);
31183119
if (len < 0) {
31193120
throw new StreamCorruptedException(
31203121
"illegal block data header length: " +
@@ -3413,7 +3414,7 @@ public char readChar() throws IOException {
34133414
} else if (end - pos < 2) {
34143415
return din.readChar();
34153416
}
3416-
char v = Bits.getChar(buf, pos);
3417+
char v = ByteArray.getChar(buf, pos);
34173418
pos += 2;
34183419
return v;
34193420
}
@@ -3425,7 +3426,7 @@ public short readShort() throws IOException {
34253426
} else if (end - pos < 2) {
34263427
return din.readShort();
34273428
}
3428-
short v = Bits.getShort(buf, pos);
3429+
short v = ByteArray.getShort(buf, pos);
34293430
pos += 2;
34303431
return v;
34313432
}
@@ -3437,7 +3438,7 @@ public int readUnsignedShort() throws IOException {
34373438
} else if (end - pos < 2) {
34383439
return din.readUnsignedShort();
34393440
}
3440-
int v = Bits.getShort(buf, pos) & 0xFFFF;
3441+
int v = ByteArray.getShort(buf, pos) & 0xFFFF;
34413442
pos += 2;
34423443
return v;
34433444
}
@@ -3449,7 +3450,7 @@ public int readInt() throws IOException {
34493450
} else if (end - pos < 4) {
34503451
return din.readInt();
34513452
}
3452-
int v = Bits.getInt(buf, pos);
3453+
int v = ByteArray.getInt(buf, pos);
34533454
pos += 4;
34543455
return v;
34553456
}
@@ -3461,7 +3462,7 @@ public float readFloat() throws IOException {
34613462
} else if (end - pos < 4) {
34623463
return din.readFloat();
34633464
}
3464-
float v = Bits.getFloat(buf, pos);
3465+
float v = ByteArray.getFloat(buf, pos);
34653466
pos += 4;
34663467
return v;
34673468
}
@@ -3473,7 +3474,7 @@ public long readLong() throws IOException {
34733474
} else if (end - pos < 8) {
34743475
return din.readLong();
34753476
}
3476-
long v = Bits.getLong(buf, pos);
3477+
long v = ByteArray.getLong(buf, pos);
34773478
pos += 8;
34783479
return v;
34793480
}
@@ -3485,7 +3486,7 @@ public double readDouble() throws IOException {
34853486
} else if (end - pos < 8) {
34863487
return din.readDouble();
34873488
}
3488-
double v = Bits.getDouble(buf, pos);
3489+
double v = ByteArray.getDouble(buf, pos);
34893490
pos += 8;
34903491
return v;
34913492
}
@@ -3523,7 +3524,7 @@ void readBooleans(boolean[] v, int off, int len) throws IOException {
35233524
}
35243525

35253526
while (off < stop) {
3526-
v[off++] = Bits.getBoolean(buf, pos++);
3527+
v[off++] = ByteArray.getBoolean(buf, pos++);
35273528
}
35283529
}
35293530
}
@@ -3544,7 +3545,7 @@ void readChars(char[] v, int off, int len) throws IOException {
35443545
}
35453546

35463547
while (off < stop) {
3547-
v[off++] = Bits.getChar(buf, pos);
3548+
v[off++] = ByteArray.getChar(buf, pos);
35483549
pos += 2;
35493550
}
35503551
}
@@ -3566,7 +3567,7 @@ void readShorts(short[] v, int off, int len) throws IOException {
35663567
}
35673568

35683569
while (off < stop) {
3569-
v[off++] = Bits.getShort(buf, pos);
3570+
v[off++] = ByteArray.getShort(buf, pos);
35703571
pos += 2;
35713572
}
35723573
}
@@ -3588,7 +3589,7 @@ void readInts(int[] v, int off, int len) throws IOException {
35883589
}
35893590

35903591
while (off < stop) {
3591-
v[off++] = Bits.getInt(buf, pos);
3592+
v[off++] = ByteArray.getInt(buf, pos);
35923593
pos += 4;
35933594
}
35943595
}
@@ -3610,7 +3611,7 @@ void readFloats(float[] v, int off, int len) throws IOException {
36103611
}
36113612

36123613
while (off < stop) {
3613-
v[off++] = Bits.getFloat(buf, pos);
3614+
v[off++] = ByteArray.getFloat(buf, pos);
36143615
pos += 4;
36153616
}
36163617
}
@@ -3632,7 +3633,7 @@ void readLongs(long[] v, int off, int len) throws IOException {
36323633
}
36333634

36343635
while (off < stop) {
3635-
v[off++] = Bits.getLong(buf, pos);
3636+
v[off++] = ByteArray.getLong(buf, pos);
36363637
pos += 8;
36373638
}
36383639
}
@@ -3654,7 +3655,7 @@ void readDoubles(double[] v, int off, int len) throws IOException {
36543655
}
36553656

36563657
while (off < stop) {
3657-
v[off++] = Bits.getDouble(buf, pos);
3658+
v[off++] = ByteArray.getDouble(buf, pos);
36583659
pos += 8;
36593660
}
36603661
}

‎src/java.base/share/classes/java/io/ObjectOutputStream.java

+24-22
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import java.util.List;
3333
import java.util.Objects;
3434
import java.util.StringJoiner;
35+
36+
import jdk.internal.util.ByteArray;
3537
import sun.reflect.misc.ReflectUtil;
3638

3739
/**
@@ -1638,35 +1640,35 @@ private class PutFieldImpl extends PutField {
16381640
}
16391641

16401642
public void put(String name, boolean val) {
1641-
Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
1643+
ByteArray.setBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
16421644
}
16431645

16441646
public void put(String name, byte val) {
16451647
primVals[getFieldOffset(name, Byte.TYPE)] = val;
16461648
}
16471649

16481650
public void put(String name, char val) {
1649-
Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
1651+
ByteArray.setChar(primVals, getFieldOffset(name, Character.TYPE), val);
16501652
}
16511653

16521654
public void put(String name, short val) {
1653-
Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
1655+
ByteArray.setShort(primVals, getFieldOffset(name, Short.TYPE), val);
16541656
}
16551657

16561658
public void put(String name, int val) {
1657-
Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
1659+
ByteArray.setInt(primVals, getFieldOffset(name, Integer.TYPE), val);
16581660
}
16591661

16601662
public void put(String name, float val) {
1661-
Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
1663+
ByteArray.setFloat(primVals, getFieldOffset(name, Float.TYPE), val);
16621664
}
16631665

16641666
public void put(String name, long val) {
1665-
Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
1667+
ByteArray.setLong(primVals, getFieldOffset(name, Long.TYPE), val);
16661668
}
16671669

16681670
public void put(String name, double val) {
1669-
Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
1671+
ByteArray.setDouble(primVals, getFieldOffset(name, Double.TYPE), val);
16701672
}
16711673

16721674
public void put(String name, Object val) {
@@ -1908,7 +1910,7 @@ private void writeBlockHeader(int len) throws IOException {
19081910
out.write(hbuf, 0, 2);
19091911
} else {
19101912
hbuf[0] = TC_BLOCKDATALONG;
1911-
Bits.putInt(hbuf, 1, len);
1913+
ByteArray.setInt(hbuf, 1, len);
19121914
out.write(hbuf, 0, 5);
19131915
}
19141916
}
@@ -1925,7 +1927,7 @@ public void writeBoolean(boolean v) throws IOException {
19251927
if (pos >= MAX_BLOCK_SIZE) {
19261928
drain();
19271929
}
1928-
Bits.putBoolean(buf, pos++, v);
1930+
ByteArray.setBoolean(buf, pos++, v);
19291931
}
19301932

19311933
public void writeByte(int v) throws IOException {
@@ -1937,7 +1939,7 @@ public void writeByte(int v) throws IOException {
19371939

19381940
public void writeChar(int v) throws IOException {
19391941
if (pos + 2 <= MAX_BLOCK_SIZE) {
1940-
Bits.putChar(buf, pos, (char) v);
1942+
ByteArray.setChar(buf, pos, (char) v);
19411943
pos += 2;
19421944
} else {
19431945
dout.writeChar(v);
@@ -1946,7 +1948,7 @@ public void writeChar(int v) throws IOException {
19461948

19471949
public void writeShort(int v) throws IOException {
19481950
if (pos + 2 <= MAX_BLOCK_SIZE) {
1949-
Bits.putShort(buf, pos, (short) v);
1951+
ByteArray.setShort(buf, pos, (short) v);
19501952
pos += 2;
19511953
} else {
19521954
dout.writeShort(v);
@@ -1955,7 +1957,7 @@ public void writeShort(int v) throws IOException {
19551957

19561958
public void writeInt(int v) throws IOException {
19571959
if (pos + 4 <= MAX_BLOCK_SIZE) {
1958-
Bits.putInt(buf, pos, v);
1960+
ByteArray.setInt(buf, pos, v);
19591961
pos += 4;
19601962
} else {
19611963
dout.writeInt(v);
@@ -1964,7 +1966,7 @@ public void writeInt(int v) throws IOException {
19641966

19651967
public void writeFloat(float v) throws IOException {
19661968
if (pos + 4 <= MAX_BLOCK_SIZE) {
1967-
Bits.putFloat(buf, pos, v);
1969+
ByteArray.setFloat(buf, pos, v);
19681970
pos += 4;
19691971
} else {
19701972
dout.writeFloat(v);
@@ -1973,7 +1975,7 @@ public void writeFloat(float v) throws IOException {
19731975

19741976
public void writeLong(long v) throws IOException {
19751977
if (pos + 8 <= MAX_BLOCK_SIZE) {
1976-
Bits.putLong(buf, pos, v);
1978+
ByteArray.setLong(buf, pos, v);
19771979
pos += 8;
19781980
} else {
19791981
dout.writeLong(v);
@@ -1982,7 +1984,7 @@ public void writeLong(long v) throws IOException {
19821984

19831985
public void writeDouble(double v) throws IOException {
19841986
if (pos + 8 <= MAX_BLOCK_SIZE) {
1985-
Bits.putDouble(buf, pos, v);
1987+
ByteArray.setDouble(buf, pos, v);
19861988
pos += 8;
19871989
} else {
19881990
dout.writeDouble(v);
@@ -2042,7 +2044,7 @@ void writeBooleans(boolean[] v, int off, int len) throws IOException {
20422044
}
20432045
int stop = Math.min(endoff, off + (MAX_BLOCK_SIZE - pos));
20442046
while (off < stop) {
2045-
Bits.putBoolean(buf, pos++, v[off++]);
2047+
ByteArray.setBoolean(buf, pos++, v[off++]);
20462048
}
20472049
}
20482050
}
@@ -2055,7 +2057,7 @@ void writeChars(char[] v, int off, int len) throws IOException {
20552057
int avail = (MAX_BLOCK_SIZE - pos) >> 1;
20562058
int stop = Math.min(endoff, off + avail);
20572059
while (off < stop) {
2058-
Bits.putChar(buf, pos, v[off++]);
2060+
ByteArray.setChar(buf, pos, v[off++]);
20592061
pos += 2;
20602062
}
20612063
} else {
@@ -2072,7 +2074,7 @@ void writeShorts(short[] v, int off, int len) throws IOException {
20722074
int avail = (MAX_BLOCK_SIZE - pos) >> 1;
20732075
int stop = Math.min(endoff, off + avail);
20742076
while (off < stop) {
2075-
Bits.putShort(buf, pos, v[off++]);
2077+
ByteArray.setShort(buf, pos, v[off++]);
20762078
pos += 2;
20772079
}
20782080
} else {
@@ -2089,7 +2091,7 @@ void writeInts(int[] v, int off, int len) throws IOException {
20892091
int avail = (MAX_BLOCK_SIZE - pos) >> 2;
20902092
int stop = Math.min(endoff, off + avail);
20912093
while (off < stop) {
2092-
Bits.putInt(buf, pos, v[off++]);
2094+
ByteArray.setInt(buf, pos, v[off++]);
20932095
pos += 4;
20942096
}
20952097
} else {
@@ -2106,7 +2108,7 @@ void writeFloats(float[] v, int off, int len) throws IOException {
21062108
int avail = (MAX_BLOCK_SIZE - pos) >> 2;
21072109
int stop = Math.min(endoff, off + avail);
21082110
while (off < stop) {
2109-
Bits.putFloat(buf, pos, v[off++]);
2111+
ByteArray.setFloat(buf, pos, v[off++]);
21102112
pos += 4;
21112113
}
21122114
} else {
@@ -2123,7 +2125,7 @@ void writeLongs(long[] v, int off, int len) throws IOException {
21232125
int avail = (MAX_BLOCK_SIZE - pos) >> 3;
21242126
int stop = Math.min(endoff, off + avail);
21252127
while (off < stop) {
2126-
Bits.putLong(buf, pos, v[off++]);
2128+
ByteArray.setLong(buf, pos, v[off++]);
21272129
pos += 8;
21282130
}
21292131
} else {
@@ -2140,7 +2142,7 @@ void writeDoubles(double[] v, int off, int len) throws IOException {
21402142
int avail = (MAX_BLOCK_SIZE - pos) >> 3;
21412143
int stop = Math.min(endoff, off + avail);
21422144
while (off < stop) {
2143-
Bits.putDouble(buf, pos, v[off++]);
2145+
ByteArray.setDouble(buf, pos, v[off++]);
21442146
pos += 8;
21452147
}
21462148
} else {

‎src/java.base/share/classes/java/io/ObjectStreamClass.java

+23-22
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import jdk.internal.reflect.ReflectionFactory;
6262
import jdk.internal.access.SharedSecrets;
6363
import jdk.internal.access.JavaSecurityAccess;
64+
import jdk.internal.util.ByteArray;
6465
import sun.reflect.misc.ReflectUtil;
6566

6667
/**
@@ -1986,14 +1987,14 @@ void getPrimFieldValues(Object obj, byte[] buf) {
19861987
long key = readKeys[i];
19871988
int off = offsets[i];
19881989
switch (typeCodes[i]) {
1989-
case 'Z' -> Bits.putBoolean(buf, off, UNSAFE.getBoolean(obj, key));
1990+
case 'Z' -> ByteArray.setBoolean(buf, off, UNSAFE.getBoolean(obj, key));
19901991
case 'B' -> buf[off] = UNSAFE.getByte(obj, key);
1991-
case 'C' -> Bits.putChar(buf, off, UNSAFE.getChar(obj, key));
1992-
case 'S' -> Bits.putShort(buf, off, UNSAFE.getShort(obj, key));
1993-
case 'I' -> Bits.putInt(buf, off, UNSAFE.getInt(obj, key));
1994-
case 'F' -> Bits.putFloat(buf, off, UNSAFE.getFloat(obj, key));
1995-
case 'J' -> Bits.putLong(buf, off, UNSAFE.getLong(obj, key));
1996-
case 'D' -> Bits.putDouble(buf, off, UNSAFE.getDouble(obj, key));
1992+
case 'C' -> ByteArray.setChar(buf, off, UNSAFE.getChar(obj, key));
1993+
case 'S' -> ByteArray.setShort(buf, off, UNSAFE.getShort(obj, key));
1994+
case 'I' -> ByteArray.setInt(buf, off, UNSAFE.getInt(obj, key));
1995+
case 'F' -> ByteArray.setFloat(buf, off, UNSAFE.getFloat(obj, key));
1996+
case 'J' -> ByteArray.setLong(buf, off, UNSAFE.getLong(obj, key));
1997+
case 'D' -> ByteArray.setDouble(buf, off, UNSAFE.getDouble(obj, key));
19971998
default -> throw new InternalError();
19981999
}
19992000
}
@@ -2015,14 +2016,14 @@ void setPrimFieldValues(Object obj, byte[] buf) {
20152016
}
20162017
int off = offsets[i];
20172018
switch (typeCodes[i]) {
2018-
case 'Z' -> UNSAFE.putBoolean(obj, key, Bits.getBoolean(buf, off));
2019+
case 'Z' -> UNSAFE.putBoolean(obj, key, ByteArray.getBoolean(buf, off));
20192020
case 'B' -> UNSAFE.putByte(obj, key, buf[off]);
2020-
case 'C' -> UNSAFE.putChar(obj, key, Bits.getChar(buf, off));
2021-
case 'S' -> UNSAFE.putShort(obj, key, Bits.getShort(buf, off));
2022-
case 'I' -> UNSAFE.putInt(obj, key, Bits.getInt(buf, off));
2023-
case 'F' -> UNSAFE.putFloat(obj, key, Bits.getFloat(buf, off));
2024-
case 'J' -> UNSAFE.putLong(obj, key, Bits.getLong(buf, off));
2025-
case 'D' -> UNSAFE.putDouble(obj, key, Bits.getDouble(buf, off));
2021+
case 'C' -> UNSAFE.putChar(obj, key, ByteArray.getChar(buf, off));
2022+
case 'S' -> UNSAFE.putShort(obj, key, ByteArray.getShort(buf, off));
2023+
case 'I' -> UNSAFE.putInt(obj, key, ByteArray.getInt(buf, off));
2024+
case 'F' -> UNSAFE.putFloat(obj, key, ByteArray.getFloat(buf, off));
2025+
case 'J' -> UNSAFE.putLong(obj, key, ByteArray.getLong(buf, off));
2026+
case 'D' -> UNSAFE.putDouble(obj, key, ByteArray.getDouble(buf, off));
20262027
default -> throw new InternalError();
20272028
}
20282029
}
@@ -2473,16 +2474,16 @@ private static MethodHandle streamFieldExtractor(String pName,
24732474
try {
24742475
PRIM_VALUE_EXTRACTORS = Map.of(
24752476
byte.class, MethodHandles.arrayElementGetter(byte[].class),
2476-
short.class, lkp.findStatic(Bits.class, "getShort", MethodType.methodType(short.class, byte[].class, int.class)),
2477-
int.class, lkp.findStatic(Bits.class, "getInt", MethodType.methodType(int.class, byte[].class, int.class)),
2478-
long.class, lkp.findStatic(Bits.class, "getLong", MethodType.methodType(long.class, byte[].class, int.class)),
2479-
float.class, lkp.findStatic(Bits.class, "getFloat", MethodType.methodType(float.class, byte[].class, int.class)),
2480-
double.class, lkp.findStatic(Bits.class, "getDouble", MethodType.methodType(double.class, byte[].class, int.class)),
2481-
char.class, lkp.findStatic(Bits.class, "getChar", MethodType.methodType(char.class, byte[].class, int.class)),
2482-
boolean.class, lkp.findStatic(Bits.class, "getBoolean", MethodType.methodType(boolean.class, byte[].class, int.class))
2477+
short.class, lkp.findStatic(ByteArray.class, "getShort", MethodType.methodType(short.class, byte[].class, int.class)),
2478+
int.class, lkp.findStatic(ByteArray.class, "getInt", MethodType.methodType(int.class, byte[].class, int.class)),
2479+
long.class, lkp.findStatic(ByteArray.class, "getLong", MethodType.methodType(long.class, byte[].class, int.class)),
2480+
float.class, lkp.findStatic(ByteArray.class, "getFloat", MethodType.methodType(float.class, byte[].class, int.class)),
2481+
double.class, lkp.findStatic(ByteArray.class, "getDouble", MethodType.methodType(double.class, byte[].class, int.class)),
2482+
char.class, lkp.findStatic(ByteArray.class, "getChar", MethodType.methodType(char.class, byte[].class, int.class)),
2483+
boolean.class, lkp.findStatic(ByteArray.class, "getBoolean", MethodType.methodType(boolean.class, byte[].class, int.class))
24832484
);
24842485
} catch (NoSuchMethodException | IllegalAccessException e) {
2485-
throw new InternalError("Can't lookup Bits.getXXX", e);
2486+
throw new InternalError("Can't lookup " + ByteArray.class.getName() + ".getXXX", e);
24862487
}
24872488
}
24882489
}

‎src/java.base/share/classes/java/io/RandomAccessFile.java

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
3030
import jdk.internal.access.JavaIORandomAccessFileAccess;
3131
import jdk.internal.access.SharedSecrets;
3232
import jdk.internal.misc.Blocker;
33+
import jdk.internal.util.ByteArray;
3334
import sun.nio.ch.FileChannelImpl;
3435

3536

@@ -884,7 +885,7 @@ public final char readChar() throws IOException {
884885
*/
885886
public final int readInt() throws IOException {
886887
readFully(buffer, 0, Integer.BYTES);
887-
return Bits.getInt(buffer, 0);
888+
return ByteArray.getInt(buffer, 0);
888889
}
889890

890891
/**
@@ -917,7 +918,7 @@ public final int readInt() throws IOException {
917918
*/
918919
public final long readLong() throws IOException {
919920
readFully(buffer, 0, Long.BYTES);
920-
return Bits.getLong(buffer, 0);
921+
return ByteArray.getLong(buffer, 0);
921922
}
922923

923924
/**
@@ -941,7 +942,7 @@ public final long readLong() throws IOException {
941942
*/
942943
public final float readFloat() throws IOException {
943944
readFully(buffer, 0, Float.BYTES);
944-
return Bits.getFloat(buffer, 0);
945+
return ByteArray.getFloat(buffer, 0);
945946
}
946947

947948
/**
@@ -965,7 +966,7 @@ public final float readFloat() throws IOException {
965966
*/
966967
public final double readDouble() throws IOException {
967968
readFully(buffer, 0, Double.BYTES);
968-
return Bits.getDouble(buffer, 0);
969+
return ByteArray.getDouble(buffer, 0);
969970
}
970971

971972
/**
@@ -1104,7 +1105,7 @@ public final void writeChar(int v) throws IOException {
11041105
* @throws IOException if an I/O error occurs.
11051106
*/
11061107
public final void writeInt(int v) throws IOException {
1107-
Bits.putInt(buffer, 0, v);
1108+
ByteArray.setInt(buffer, 0, v);
11081109
write(buffer, 0, Integer.BYTES);
11091110
//written += 4;
11101111
}
@@ -1117,7 +1118,7 @@ public final void writeInt(int v) throws IOException {
11171118
* @throws IOException if an I/O error occurs.
11181119
*/
11191120
public final void writeLong(long v) throws IOException {
1120-
Bits.putLong(buffer, 0, v);
1121+
ByteArray.setLong(buffer, 0, v);
11211122
write(buffer, 0, Long.BYTES);
11221123
}
11231124

@@ -1133,7 +1134,8 @@ public final void writeLong(long v) throws IOException {
11331134
* @see java.lang.Float#floatToIntBits(float)
11341135
*/
11351136
public final void writeFloat(float v) throws IOException {
1136-
writeInt(Float.floatToIntBits(v));
1137+
ByteArray.setFloat(buffer, 0, v);
1138+
write(buffer, 0, Float.BYTES);
11371139
}
11381140

11391141
/**
@@ -1148,7 +1150,8 @@ public final void writeFloat(float v) throws IOException {
11481150
* @see java.lang.Double#doubleToLongBits(double)
11491151
*/
11501152
public final void writeDouble(double v) throws IOException {
1151-
writeLong(Double.doubleToLongBits(v));
1153+
ByteArray.setDouble(buffer, 0, v);
1154+
write(buffer, 0, Double.BYTES);
11521155
}
11531156

11541157
/**

‎src/java.base/share/classes/jdk/internal/util/ByteArray.java

+424
Large diffs are not rendered by default.

‎test/jdk/java/io/Bits/java.base/java/io/BitsProxy.java

-88
This file was deleted.

‎test/jdk/java/io/Bits/ReadWriteValues.java ‎test/jdk/jdk/internal/util/ByteArray/ReadWriteValues.java

+174-23
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@
2424
/*
2525
* @test
2626
* @bug 8299576
27+
* @modules java.base/jdk.internal.util
2728
* @summary Verify that reads and writes of primitives are correct
28-
* @compile/module=java.base java/io/BitsProxy.java
2929
* @run junit ReadWriteValues
3030
*/
3131

32-
import java.io.BitsProxy;
32+
import jdk.internal.util.ByteArray;
33+
import org.junit.jupiter.api.*;
34+
3335
import java.util.concurrent.ThreadLocalRandom;
3436
import java.util.stream.DoubleStream;
3537
import java.util.stream.LongStream;
3638
import java.util.stream.Stream;
3739

38-
import org.junit.jupiter.api.*;
39-
4040
import static org.junit.jupiter.api.Assertions.*;
4141

4242
final class ReadWriteValues {
@@ -53,7 +53,7 @@ void testGetShort() {
5353
longs().forEach(l -> {
5454
short expected = (short) l;
5555
RefImpl.putShort(BUFF, OFFSET, expected);
56-
short actual = BitsProxy.getShort(BUFF, OFFSET);
56+
short actual = ByteArray.getShort(BUFF, OFFSET);
5757
assertEquals(expected, actual);
5858
});
5959
}
@@ -62,7 +62,7 @@ void testGetShort() {
6262
void testPutShort() {
6363
longs().forEach(l -> {
6464
short expected = (short) l;
65-
BitsProxy.putShort(BUFF, OFFSET, expected);
65+
ByteArray.setShort(BUFF, OFFSET, expected);
6666
short actual = RefImpl.getShort(BUFF, OFFSET);
6767
assertEquals(expected, actual);
6868
});
@@ -73,7 +73,7 @@ void testGetChar() {
7373
longs().forEach(l -> {
7474
char expected = (char) l;
7575
RefImpl.putChar(BUFF, OFFSET, expected);
76-
char actual = BitsProxy.getChar(BUFF, OFFSET);
76+
char actual = ByteArray.getChar(BUFF, OFFSET);
7777
assertEquals(expected, actual);
7878
});
7979
}
@@ -82,7 +82,7 @@ void testGetChar() {
8282
void testPutChar() {
8383
longs().forEach(l -> {
8484
char expected = (char) l;
85-
BitsProxy.putChar(BUFF, OFFSET, expected);
85+
ByteArray.setChar(BUFF, OFFSET, expected);
8686
char actual = RefImpl.getChar(BUFF, OFFSET);
8787
assertEquals(expected, actual);
8888
});
@@ -93,7 +93,7 @@ void testGetInt() {
9393
longs().forEach(l -> {
9494
int expected = (int) l;
9595
RefImpl.putInt(BUFF, OFFSET, expected);
96-
int actual = BitsProxy.getInt(BUFF, OFFSET);
96+
int actual = ByteArray.getInt(BUFF, OFFSET);
9797
assertEquals(expected, actual);
9898
});
9999
}
@@ -102,7 +102,7 @@ void testGetInt() {
102102
void testPutInt() {
103103
longs().forEach(l -> {
104104
int expected = (int) l;
105-
BitsProxy.putInt(BUFF, OFFSET, expected);
105+
ByteArray.setInt(BUFF, OFFSET, expected);
106106
int actual = RefImpl.getInt(BUFF, OFFSET);
107107
assertEquals(expected, actual);
108108
});
@@ -112,15 +112,15 @@ void testPutInt() {
112112
void testGetLong() {
113113
longs().forEach(expected -> {
114114
RefImpl.putLong(BUFF, OFFSET, expected);
115-
long actual = BitsProxy.getLong(BUFF, OFFSET);
115+
long actual = ByteArray.getLong(BUFF, OFFSET);
116116
assertEquals(expected, actual);
117117
});
118118
}
119119

120120
@Test
121121
void testPutLong() {
122122
longs().forEach(expected -> {
123-
BitsProxy.putLong(BUFF, OFFSET, expected);
123+
ByteArray.setLong(BUFF, OFFSET, expected);
124124
long actual = RefImpl.getLong(BUFF, OFFSET);
125125
assertEquals(expected, actual);
126126
});
@@ -130,15 +130,15 @@ void testPutLong() {
130130
void testGetFloat() {
131131
floats().forEach(expected -> {
132132
RefImpl.putFloat(BUFF, OFFSET, expected);
133-
float actual = BitsProxy.getFloat(BUFF, OFFSET);
133+
float actual = ByteArray.getFloat(BUFF, OFFSET);
134134
assertEquals(expected, actual);
135135
});
136136
}
137137

138138
@Test
139139
void testPutFloat() {
140140
floats().forEach(expected -> {
141-
BitsProxy.putFloat(BUFF, OFFSET, expected);
141+
ByteArray.setFloat(BUFF, OFFSET, expected);
142142
float actual = RefImpl.getFloat(BUFF, OFFSET);
143143
assertEquals(expected, actual);
144144
});
@@ -148,40 +148,192 @@ void testPutFloat() {
148148
void testGetDouble() {
149149
doubles().forEach(expected -> {
150150
RefImpl.putDouble(BUFF, OFFSET, expected);
151-
double actual = BitsProxy.getDouble(BUFF, OFFSET);
151+
double actual = ByteArray.getDouble(BUFF, OFFSET);
152152
assertEquals(expected, actual);
153153
});
154154
}
155155

156156
@Test
157157
void testPutDouble() {
158158
doubles().forEach(expected -> {
159-
BitsProxy.putDouble(BUFF, OFFSET, expected);
159+
ByteArray.setDouble(BUFF, OFFSET, expected);
160160
double actual = RefImpl.getDouble(BUFF, OFFSET);
161161
assertEquals(expected, actual);
162162
});
163163
}
164164

165+
@Test
166+
void testPutUnsignedShort() {
167+
longs().forEach(l -> {
168+
int expected = Short.toUnsignedInt((short) l);
169+
ByteArray.setUnsignedShort(BUFF, OFFSET, expected);
170+
int actual = Short.toUnsignedInt(RefImpl.getShort(BUFF, OFFSET));
171+
assertEquals(expected, actual);
172+
});
173+
}
174+
175+
165176
// Unusual cases
166177

167178
@Test
168179
void testNullArray() {
169-
assertThrowsOriginal(NullPointerException.class, () -> BitsProxy.getInt(null, OFFSET));
170-
assertThrowsOriginal(NullPointerException.class, () -> BitsProxy.putInt(null, OFFSET, 1));
180+
assertThrowsOriginal(NullPointerException.class, () -> ByteArray.getInt(null, OFFSET));
181+
assertThrowsOriginal(NullPointerException.class, () -> ByteArray.setInt(null, OFFSET, 1));
171182
}
172183

173184
@Test
174185
void testNegArg() {
175-
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> BitsProxy.getInt(BUFF, -1));
176-
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> BitsProxy.putInt(BUFF, -1, 1));
186+
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> ByteArray.getInt(BUFF, -1));
187+
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> ByteArray.setInt(BUFF, -1, 1));
177188
}
178189

179190
@Test
180191
void testOutOfBounds() {
181-
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> BitsProxy.getInt(BUFF, BUFF.length));
182-
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> BitsProxy.putInt(BUFF, BUFF.length, 1));
192+
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> ByteArray.getInt(BUFF, BUFF.length));
193+
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> ByteArray.setInt(BUFF, BUFF.length, 1));
194+
}
195+
196+
// At-zero methods
197+
198+
@Test
199+
void testGetShortAtZero() {
200+
longs().forEach(l -> {
201+
short expected = (short) l;
202+
RefImpl.putShort(BUFF, 0, expected);
203+
short actual = ByteArray.getShort(BUFF);
204+
assertEquals(expected, actual);
205+
});
206+
}
207+
208+
@Test
209+
void testPutShortAtZero() {
210+
longs().forEach(l -> {
211+
short expected = (short) l;
212+
ByteArray.setShort(BUFF, expected);
213+
short actual = RefImpl.getShort(BUFF, 0);
214+
assertEquals(expected, actual);
215+
});
216+
}
217+
218+
@Test
219+
void testGetCharAtZero() {
220+
longs().forEach(l -> {
221+
char expected = (char) l;
222+
RefImpl.putChar(BUFF, 0, expected);
223+
char actual = ByteArray.getChar(BUFF);
224+
assertEquals(expected, actual);
225+
});
226+
}
227+
228+
@Test
229+
void testPutCharAtZero() {
230+
longs().forEach(l -> {
231+
char expected = (char) l;
232+
ByteArray.setChar(BUFF, expected);
233+
char actual = RefImpl.getChar(BUFF, 0);
234+
assertEquals(expected, actual);
235+
});
236+
}
237+
238+
@Test
239+
void testGetIntAtZero() {
240+
longs().forEach(l -> {
241+
int expected = (int) l;
242+
RefImpl.putInt(BUFF, 0, expected);
243+
int actual = ByteArray.getInt(BUFF);
244+
assertEquals(expected, actual);
245+
});
246+
}
247+
248+
@Test
249+
void testPutIntAtZero() {
250+
longs().forEach(l -> {
251+
int expected = (int) l;
252+
ByteArray.setInt(BUFF, expected);
253+
int actual = RefImpl.getInt(BUFF, 0);
254+
assertEquals(expected, actual);
255+
});
256+
}
257+
258+
@Test
259+
void testGetLongAtZero() {
260+
longs().forEach(expected -> {
261+
RefImpl.putLong(BUFF, 0, expected);
262+
long actual = ByteArray.getLong(BUFF);
263+
assertEquals(expected, actual);
264+
});
183265
}
184266

267+
@Test
268+
void testPutLongAtZero() {
269+
longs().forEach(expected -> {
270+
ByteArray.setLong(BUFF, expected);
271+
long actual = RefImpl.getLong(BUFF, 0);
272+
assertEquals(expected, actual);
273+
});
274+
}
275+
276+
@Test
277+
void testGetFloatAtZero() {
278+
floats().forEach(expected -> {
279+
RefImpl.putFloat(BUFF, 0, expected);
280+
float actual = ByteArray.getFloat(BUFF);
281+
assertEquals(expected, actual);
282+
});
283+
}
284+
285+
@Test
286+
void testPutFloatAtZero() {
287+
floats().forEach(expected -> {
288+
ByteArray.setFloat(BUFF, expected);
289+
float actual = RefImpl.getFloat(BUFF, 0);
290+
assertEquals(expected, actual);
291+
});
292+
}
293+
294+
@Test
295+
void testGetDoubleAtZero() {
296+
doubles().forEach(expected -> {
297+
RefImpl.putDouble(BUFF, 0, expected);
298+
double actual = ByteArray.getDouble(BUFF);
299+
assertEquals(expected, actual);
300+
});
301+
}
302+
303+
@Test
304+
void testPutDoubleAtZero() {
305+
doubles().forEach(expected -> {
306+
ByteArray.setDouble(BUFF, expected);
307+
double actual = RefImpl.getDouble(BUFF, 0);
308+
assertEquals(expected, actual);
309+
});
310+
}
311+
312+
@Test
313+
void testPutUnsignedShortAtZero() {
314+
longs().forEach(l -> {
315+
int expected = Short.toUnsignedInt((short) l);
316+
ByteArray.setUnsignedShort(BUFF, expected);
317+
int actual = Short.toUnsignedInt(RefImpl.getShort(BUFF, 0));
318+
assertEquals(expected, actual);
319+
});
320+
}
321+
322+
// Unusual cases
323+
324+
@Test
325+
void testNullArrayAtZero() {
326+
assertThrowsOriginal(NullPointerException.class, () -> ByteArray.getInt(null));
327+
assertThrowsOriginal(NullPointerException.class, () -> ByteArray.setInt(null, 1));
328+
}
329+
330+
@Test
331+
void testOutOfBoundsAtZero() {
332+
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> ByteArray.getInt(new byte[1]));
333+
assertThrowsOriginal(IndexOutOfBoundsException.class, () -> ByteArray.setInt(new byte[1],1));
334+
}
335+
336+
185337
static LongStream longs() {
186338
return ThreadLocalRandom.current().longs(ITERATIONS);
187339
}
@@ -315,5 +467,4 @@ static void putDouble(byte[] b, int off, double val) {
315467
putLong(b, off, Double.doubleToLongBits(val));
316468
}
317469
}
318-
319470
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package org.openjdk.bench.java.io;
24+
25+
import org.openjdk.jmh.annotations.Benchmark;
26+
import org.openjdk.jmh.annotations.BenchmarkMode;
27+
import org.openjdk.jmh.annotations.Fork;
28+
import org.openjdk.jmh.annotations.Measurement;
29+
import org.openjdk.jmh.annotations.Mode;
30+
import org.openjdk.jmh.annotations.OutputTimeUnit;
31+
import org.openjdk.jmh.annotations.Scope;
32+
import org.openjdk.jmh.annotations.Setup;
33+
import org.openjdk.jmh.annotations.State;
34+
import org.openjdk.jmh.annotations.TearDown;
35+
import org.openjdk.jmh.annotations.Warmup;
36+
import org.openjdk.jmh.infra.Blackhole;
37+
import org.openjdk.jmh.runner.Runner;
38+
import org.openjdk.jmh.runner.options.Options;
39+
import org.openjdk.jmh.runner.options.OptionsBuilder;
40+
41+
import java.io.IOException;
42+
import java.io.ObjectOutputStream;
43+
import java.io.OutputStream;
44+
import java.io.Serializable;
45+
import java.util.concurrent.TimeUnit;
46+
47+
@BenchmarkMode(Mode.AverageTime)
48+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
49+
@Fork(2)
50+
@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS)
51+
@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS)
52+
@State(Scope.Thread)
53+
54+
public class PrimitiveFieldSerializationBenchmark {
55+
56+
public static void main(String[] args) throws Exception {
57+
58+
Options options = new OptionsBuilder()
59+
.include(PrimitiveFieldSerializationBenchmark.class.getSimpleName())
60+
.build();
61+
new Runner(options).run();
62+
}
63+
64+
@State(Scope.Benchmark)
65+
public static class Log {
66+
67+
MyData myData = new MyData((byte) 1, 'a', (short) 47, 1234, 0.01f, 1234L, 0.01d);
68+
MyRecord myRecord = new MyRecord((byte) 1, 'a', (short) 47, 1234, 0.01f, 1234L, 0.01d);
69+
}
70+
71+
private OutputStream bos;
72+
private ObjectOutputStream os;
73+
74+
@Setup
75+
public void setupStreams(Blackhole bh) throws IOException {
76+
bos = new BlackholeOutputStream(bh);
77+
os = new ObjectOutputStream(bos);
78+
}
79+
80+
@TearDown
81+
public void tearDownStreams() throws IOException {
82+
os.close();
83+
bos.close();
84+
}
85+
86+
private static final class MyData implements Serializable {
87+
byte b;
88+
char c;
89+
short s;
90+
int i;
91+
float f;
92+
long l;
93+
double d;
94+
95+
public MyData(byte b, char c, short s, int i, float f, long l, double d) {
96+
this.b = b;
97+
this.c = c;
98+
this.s = s;
99+
this.i = i;
100+
this.f = f;
101+
this.l = l;
102+
this.d = d;
103+
}
104+
}
105+
106+
private record MyRecord(byte b,
107+
char c,
108+
short s,
109+
int i,
110+
float f,
111+
long l,
112+
double d) implements Serializable {
113+
}
114+
115+
@Benchmark
116+
public void serializeData(Log input) throws IOException {
117+
os.writeObject(input.myData);
118+
}
119+
120+
@Benchmark
121+
public void serializeRecord(Log input) throws IOException {
122+
os.writeObject(input.myRecord);
123+
}
124+
125+
public static final class BlackholeOutputStream extends OutputStream {
126+
127+
private final Blackhole bh;
128+
129+
public BlackholeOutputStream(Blackhole bh) {
130+
this.bh = bh;
131+
}
132+
133+
@Override
134+
public void write(int b) {
135+
bh.consume(b);
136+
}
137+
138+
@Override
139+
public void write(byte[] b) {
140+
bh.consume(b);
141+
}
142+
143+
@Override
144+
public void write(byte[] b, int off, int len) {
145+
bh.consume(b);
146+
}
147+
}
148+
149+
150+
}

0 commit comments

Comments
 (0)
Please sign in to comment.