8300236: Use VarHandle access in Data(Input | Output)Stream classes

Reviewed-by: rriggs, alanb
This commit is contained in:
Per Minborg 2023-01-25 12:54:27 +00:00
parent a5d8e12872
commit 74e1a8bfa8
11 changed files with 869 additions and 364 deletions

View file

@ -1,120 +0,0 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;
/**
* Utility methods for packing/unpacking primitive values in/out of byte arrays
* using big-endian byte ordering (i.e. "Network Order").
*/
final class Bits {
private Bits() {}
private static final VarHandle SHORT = create(short[].class);
private static final VarHandle INT = create(int[].class);
private static final VarHandle LONG = create(long[].class);
/*
* Methods for unpacking primitive values from byte arrays starting at
* given offsets.
*/
static boolean getBoolean(byte[] b, int off) {
return b[off] != 0;
}
static char getChar(byte[] b, int off) {
return (char) (short) SHORT.get(b, off);
}
static short getShort(byte[] b, int off) {
return (short) SHORT.get(b, off);
}
static int getInt(byte[] b, int off) {
return (int) INT.get(b, off);
}
static float getFloat(byte[] b, int off) {
// Using Float.intBitsToFloat collapses NaN values to a single
// "canonical" NaN value
return Float.intBitsToFloat((int) INT.get(b, off));
}
static long getLong(byte[] b, int off) {
return (long) LONG.get(b, off);
}
static double getDouble(byte[] b, int off) {
// Using Double.longBitsToDouble collapses NaN values to a single
// "canonical" NaN value
return Double.longBitsToDouble((long) LONG.get(b, off));
}
/*
* Methods for packing primitive values into byte arrays starting at given
* offsets.
*/
static void putBoolean(byte[] b, int off, boolean val) {
b[off] = (byte) (val ? 1 : 0);
}
static void putChar(byte[] b, int off, char val) {
SHORT.set(b, off, (short) val);
}
static void putShort(byte[] b, int off, short val) {
SHORT.set(b, off, val);
}
static void putInt(byte[] b, int off, int val) {
INT.set(b, off, val);
}
static void putFloat(byte[] b, int off, float val) {
// Using Float.floatToIntBits collapses NaN values to a single
// "canonical" NaN value
INT.set(b, off, Float.floatToIntBits(val));
}
static void putLong(byte[] b, int off, long val) {
LONG.set(b, off, val);
}
static void putDouble(byte[] b, int off, double val) {
// Using Double.doubleToLongBits collapses NaN values to a single
// "canonical" NaN value
LONG.set(b, off, Double.doubleToLongBits(val));
}
private static VarHandle create(Class<?> viewArrayClass) {
return MethodHandles.byteArrayViewVarHandle(viewArrayClass, ByteOrder.BIG_ENDIAN);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,8 @@
package java.io;
import jdk.internal.util.ByteArray;
import java.util.Objects;
/**
@ -54,6 +56,8 @@ public class DataInputStream extends FilterInputStream implements DataInput {
super(in);
}
private final byte[] readBuffer = new byte[8];
/**
* working arrays initialized on demand by readUTF
*/
@ -309,7 +313,8 @@ public class DataInputStream extends FilterInputStream implements DataInput {
* @see java.io.FilterInputStream#in
*/
public final short readShort() throws IOException {
return (short) readUnsignedShort();
readFully(readBuffer, 0, 2);
return ByteArray.getShort(readBuffer, 0);
}
/**
@ -330,12 +335,8 @@ public class DataInputStream extends FilterInputStream implements DataInput {
* @see java.io.FilterInputStream#in
*/
public final int readUnsignedShort() throws IOException {
InputStream in = this.in;
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
readFully(readBuffer, 0, 2);
return ByteArray.getUnsignedShort(readBuffer, 0);
}
/**
@ -356,7 +357,8 @@ public class DataInputStream extends FilterInputStream implements DataInput {
* @see java.io.FilterInputStream#in
*/
public final char readChar() throws IOException {
return (char) readUnsignedShort();
readFully(readBuffer, 0, 2);
return ByteArray.getChar(readBuffer, 0);
}
/**
@ -377,18 +379,10 @@ public class DataInputStream extends FilterInputStream implements DataInput {
* @see java.io.FilterInputStream#in
*/
public final int readInt() throws IOException {
InputStream in = this.in;
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
readFully(readBuffer, 0, 4);
return ByteArray.getInt(readBuffer, 0);
}
private final byte[] readBuffer = new byte[8];
/**
* See the general contract of the {@code readLong}
* method of {@code DataInput}.
@ -408,14 +402,7 @@ public class DataInputStream extends FilterInputStream implements DataInput {
*/
public final long readLong() throws IOException {
readFully(readBuffer, 0, 8);
return (((long)readBuffer[0] << 56) +
((long)(readBuffer[1] & 255) << 48) +
((long)(readBuffer[2] & 255) << 40) +
((long)(readBuffer[3] & 255) << 32) +
((long)(readBuffer[4] & 255) << 24) +
((readBuffer[5] & 255) << 16) +
((readBuffer[6] & 255) << 8) +
((readBuffer[7] & 255) << 0));
return ByteArray.getLong(readBuffer, 0);
}
/**
@ -437,7 +424,8 @@ public class DataInputStream extends FilterInputStream implements DataInput {
* @see java.lang.Float#intBitsToFloat(int)
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
readFully(readBuffer, 0, 4);
return ByteArray.getFloat(readBuffer, 0);
}
/**
@ -459,7 +447,8 @@ public class DataInputStream extends FilterInputStream implements DataInput {
* @see java.lang.Double#longBitsToDouble(long)
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
readFully(readBuffer, 0, 8);
return ByteArray.getDouble(readBuffer, 0);
}
private char[] lineBuffer;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,8 @@
package java.io;
import jdk.internal.util.ByteArray;
/**
* A data output stream lets an application write primitive Java data
* types to an output stream in a portable way. An application can
@ -170,8 +172,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
* @see java.io.FilterOutputStream#out
*/
public final void writeShort(int v) throws IOException {
writeBuffer[0] = (byte)(v >>> 8);
writeBuffer[1] = (byte)(v >>> 0);
ByteArray.setUnsignedShort(writeBuffer, 0, v);
out.write(writeBuffer, 0, 2);
incCount(2);
}
@ -186,8 +187,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
* @see java.io.FilterOutputStream#out
*/
public final void writeChar(int v) throws IOException {
writeBuffer[0] = (byte)(v >>> 8);
writeBuffer[1] = (byte)(v >>> 0);
ByteArray.setUnsignedShort(writeBuffer, 0, v);
out.write(writeBuffer, 0, 2);
incCount(2);
}
@ -202,10 +202,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
* @see java.io.FilterOutputStream#out
*/
public final void writeInt(int v) throws IOException {
writeBuffer[0] = (byte)(v >>> 24);
writeBuffer[1] = (byte)(v >>> 16);
writeBuffer[2] = (byte)(v >>> 8);
writeBuffer[3] = (byte)(v >>> 0);
ByteArray.setInt(writeBuffer, 0, v);
out.write(writeBuffer, 0, 4);
incCount(4);
}
@ -220,14 +217,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
* @see java.io.FilterOutputStream#out
*/
public final void writeLong(long v) throws IOException {
writeBuffer[0] = (byte)(v >>> 56);
writeBuffer[1] = (byte)(v >>> 48);
writeBuffer[2] = (byte)(v >>> 40);
writeBuffer[3] = (byte)(v >>> 32);
writeBuffer[4] = (byte)(v >>> 24);
writeBuffer[5] = (byte)(v >>> 16);
writeBuffer[6] = (byte)(v >>> 8);
writeBuffer[7] = (byte)(v >>> 0);
ByteArray.setLong(writeBuffer, 0, v);
out.write(writeBuffer, 0, 8);
incCount(8);
}
@ -246,7 +236,9 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
* @see java.lang.Float#floatToIntBits(float)
*/
public final void writeFloat(float v) throws IOException {
writeInt(Float.floatToIntBits(v));
ByteArray.setFloat(writeBuffer, 0, v);
out.write(writeBuffer, 0, 4);
incCount(4);
}
/**
@ -263,7 +255,9 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
* @see java.lang.Double#doubleToLongBits(double)
*/
public final void writeDouble(double v) throws IOException {
writeLong(Double.doubleToLongBits(v));
ByteArray.setDouble(writeBuffer, 0, v);
out.write(writeBuffer, 0, 8);
incCount(8);
}
/**
@ -301,8 +295,7 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
int len = s.length();
for (int i = 0 ; i < len ; i++) {
int v = s.charAt(i);
writeBuffer[0] = (byte)(v >>> 8);
writeBuffer[1] = (byte)(v >>> 0);
ByteArray.setUnsignedShort(writeBuffer, 0, v);
out.write(writeBuffer, 0, 2);
}
incCount(len * 2);
@ -379,9 +372,8 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput {
}
int count = 0;
bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
ByteArray.setUnsignedShort(bytearr, count, utflen);
count += 2;
int i = 0;
for (i = 0; i < strlen; i++) { // optimized for initial run of ASCII
int c = str.charAt(i);

View file

@ -45,6 +45,7 @@ import java.util.Objects;
import jdk.internal.access.SharedSecrets;
import jdk.internal.event.DeserializationEvent;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.ByteArray;
import sun.reflect.misc.ReflectUtil;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetIntegerAction;
@ -2631,7 +2632,7 @@ public class ObjectInputStream
public boolean get(String name, boolean val) {
int off = getFieldOffset(name, Boolean.TYPE);
return (off >= 0) ? Bits.getBoolean(primValues, off) : val;
return (off >= 0) ? ByteArray.getBoolean(primValues, off) : val;
}
public byte get(String name, byte val) {
@ -2641,32 +2642,32 @@ public class ObjectInputStream
public char get(String name, char val) {
int off = getFieldOffset(name, Character.TYPE);
return (off >= 0) ? Bits.getChar(primValues, off) : val;
return (off >= 0) ? ByteArray.getChar(primValues, off) : val;
}
public short get(String name, short val) {
int off = getFieldOffset(name, Short.TYPE);
return (off >= 0) ? Bits.getShort(primValues, off) : val;
return (off >= 0) ? ByteArray.getShort(primValues, off) : val;
}
public int get(String name, int val) {
int off = getFieldOffset(name, Integer.TYPE);
return (off >= 0) ? Bits.getInt(primValues, off) : val;
return (off >= 0) ? ByteArray.getInt(primValues, off) : val;
}
public float get(String name, float val) {
int off = getFieldOffset(name, Float.TYPE);
return (off >= 0) ? Bits.getFloat(primValues, off) : val;
return (off >= 0) ? ByteArray.getFloat(primValues, off) : val;
}
public long get(String name, long val) {
int off = getFieldOffset(name, Long.TYPE);
return (off >= 0) ? Bits.getLong(primValues, off) : val;
return (off >= 0) ? ByteArray.getLong(primValues, off) : val;
}
public double get(String name, double val) {
int off = getFieldOffset(name, Double.TYPE);
return (off >= 0) ? Bits.getDouble(primValues, off) : val;
return (off >= 0) ? ByteArray.getDouble(primValues, off) : val;
}
public Object get(String name, Object val) throws ClassNotFoundException {
@ -3114,7 +3115,7 @@ public class ObjectInputStream
return HEADER_BLOCKED;
}
in.readFully(hbuf, 0, 5);
int len = Bits.getInt(hbuf, 1);
int len = ByteArray.getInt(hbuf, 1);
if (len < 0) {
throw new StreamCorruptedException(
"illegal block data header length: " +
@ -3413,7 +3414,7 @@ public class ObjectInputStream
} else if (end - pos < 2) {
return din.readChar();
}
char v = Bits.getChar(buf, pos);
char v = ByteArray.getChar(buf, pos);
pos += 2;
return v;
}
@ -3425,7 +3426,7 @@ public class ObjectInputStream
} else if (end - pos < 2) {
return din.readShort();
}
short v = Bits.getShort(buf, pos);
short v = ByteArray.getShort(buf, pos);
pos += 2;
return v;
}
@ -3437,7 +3438,7 @@ public class ObjectInputStream
} else if (end - pos < 2) {
return din.readUnsignedShort();
}
int v = Bits.getShort(buf, pos) & 0xFFFF;
int v = ByteArray.getShort(buf, pos) & 0xFFFF;
pos += 2;
return v;
}
@ -3449,7 +3450,7 @@ public class ObjectInputStream
} else if (end - pos < 4) {
return din.readInt();
}
int v = Bits.getInt(buf, pos);
int v = ByteArray.getInt(buf, pos);
pos += 4;
return v;
}
@ -3461,7 +3462,7 @@ public class ObjectInputStream
} else if (end - pos < 4) {
return din.readFloat();
}
float v = Bits.getFloat(buf, pos);
float v = ByteArray.getFloat(buf, pos);
pos += 4;
return v;
}
@ -3473,7 +3474,7 @@ public class ObjectInputStream
} else if (end - pos < 8) {
return din.readLong();
}
long v = Bits.getLong(buf, pos);
long v = ByteArray.getLong(buf, pos);
pos += 8;
return v;
}
@ -3485,7 +3486,7 @@ public class ObjectInputStream
} else if (end - pos < 8) {
return din.readDouble();
}
double v = Bits.getDouble(buf, pos);
double v = ByteArray.getDouble(buf, pos);
pos += 8;
return v;
}
@ -3523,7 +3524,7 @@ public class ObjectInputStream
}
while (off < stop) {
v[off++] = Bits.getBoolean(buf, pos++);
v[off++] = ByteArray.getBoolean(buf, pos++);
}
}
}
@ -3544,7 +3545,7 @@ public class ObjectInputStream
}
while (off < stop) {
v[off++] = Bits.getChar(buf, pos);
v[off++] = ByteArray.getChar(buf, pos);
pos += 2;
}
}
@ -3566,7 +3567,7 @@ public class ObjectInputStream
}
while (off < stop) {
v[off++] = Bits.getShort(buf, pos);
v[off++] = ByteArray.getShort(buf, pos);
pos += 2;
}
}
@ -3588,7 +3589,7 @@ public class ObjectInputStream
}
while (off < stop) {
v[off++] = Bits.getInt(buf, pos);
v[off++] = ByteArray.getInt(buf, pos);
pos += 4;
}
}
@ -3610,7 +3611,7 @@ public class ObjectInputStream
}
while (off < stop) {
v[off++] = Bits.getFloat(buf, pos);
v[off++] = ByteArray.getFloat(buf, pos);
pos += 4;
}
}
@ -3632,7 +3633,7 @@ public class ObjectInputStream
}
while (off < stop) {
v[off++] = Bits.getLong(buf, pos);
v[off++] = ByteArray.getLong(buf, pos);
pos += 8;
}
}
@ -3654,7 +3655,7 @@ public class ObjectInputStream
}
while (off < stop) {
v[off++] = Bits.getDouble(buf, pos);
v[off++] = ByteArray.getDouble(buf, pos);
pos += 8;
}
}

View file

@ -32,6 +32,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
import jdk.internal.util.ByteArray;
import sun.reflect.misc.ReflectUtil;
/**
@ -1638,7 +1640,7 @@ public class ObjectOutputStream
}
public void put(String name, boolean val) {
Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
ByteArray.setBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
}
public void put(String name, byte val) {
@ -1646,27 +1648,27 @@ public class ObjectOutputStream
}
public void put(String name, char val) {
Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
ByteArray.setChar(primVals, getFieldOffset(name, Character.TYPE), val);
}
public void put(String name, short val) {
Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
ByteArray.setShort(primVals, getFieldOffset(name, Short.TYPE), val);
}
public void put(String name, int val) {
Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
ByteArray.setInt(primVals, getFieldOffset(name, Integer.TYPE), val);
}
public void put(String name, float val) {
Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
ByteArray.setFloat(primVals, getFieldOffset(name, Float.TYPE), val);
}
public void put(String name, long val) {
Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
ByteArray.setLong(primVals, getFieldOffset(name, Long.TYPE), val);
}
public void put(String name, double val) {
Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
ByteArray.setDouble(primVals, getFieldOffset(name, Double.TYPE), val);
}
public void put(String name, Object val) {
@ -1908,7 +1910,7 @@ public class ObjectOutputStream
out.write(hbuf, 0, 2);
} else {
hbuf[0] = TC_BLOCKDATALONG;
Bits.putInt(hbuf, 1, len);
ByteArray.setInt(hbuf, 1, len);
out.write(hbuf, 0, 5);
}
}
@ -1925,7 +1927,7 @@ public class ObjectOutputStream
if (pos >= MAX_BLOCK_SIZE) {
drain();
}
Bits.putBoolean(buf, pos++, v);
ByteArray.setBoolean(buf, pos++, v);
}
public void writeByte(int v) throws IOException {
@ -1937,7 +1939,7 @@ public class ObjectOutputStream
public void writeChar(int v) throws IOException {
if (pos + 2 <= MAX_BLOCK_SIZE) {
Bits.putChar(buf, pos, (char) v);
ByteArray.setChar(buf, pos, (char) v);
pos += 2;
} else {
dout.writeChar(v);
@ -1946,7 +1948,7 @@ public class ObjectOutputStream
public void writeShort(int v) throws IOException {
if (pos + 2 <= MAX_BLOCK_SIZE) {
Bits.putShort(buf, pos, (short) v);
ByteArray.setShort(buf, pos, (short) v);
pos += 2;
} else {
dout.writeShort(v);
@ -1955,7 +1957,7 @@ public class ObjectOutputStream
public void writeInt(int v) throws IOException {
if (pos + 4 <= MAX_BLOCK_SIZE) {
Bits.putInt(buf, pos, v);
ByteArray.setInt(buf, pos, v);
pos += 4;
} else {
dout.writeInt(v);
@ -1964,7 +1966,7 @@ public class ObjectOutputStream
public void writeFloat(float v) throws IOException {
if (pos + 4 <= MAX_BLOCK_SIZE) {
Bits.putFloat(buf, pos, v);
ByteArray.setFloat(buf, pos, v);
pos += 4;
} else {
dout.writeFloat(v);
@ -1973,7 +1975,7 @@ public class ObjectOutputStream
public void writeLong(long v) throws IOException {
if (pos + 8 <= MAX_BLOCK_SIZE) {
Bits.putLong(buf, pos, v);
ByteArray.setLong(buf, pos, v);
pos += 8;
} else {
dout.writeLong(v);
@ -1982,7 +1984,7 @@ public class ObjectOutputStream
public void writeDouble(double v) throws IOException {
if (pos + 8 <= MAX_BLOCK_SIZE) {
Bits.putDouble(buf, pos, v);
ByteArray.setDouble(buf, pos, v);
pos += 8;
} else {
dout.writeDouble(v);
@ -2042,7 +2044,7 @@ public class ObjectOutputStream
}
int stop = Math.min(endoff, off + (MAX_BLOCK_SIZE - pos));
while (off < stop) {
Bits.putBoolean(buf, pos++, v[off++]);
ByteArray.setBoolean(buf, pos++, v[off++]);
}
}
}
@ -2055,7 +2057,7 @@ public class ObjectOutputStream
int avail = (MAX_BLOCK_SIZE - pos) >> 1;
int stop = Math.min(endoff, off + avail);
while (off < stop) {
Bits.putChar(buf, pos, v[off++]);
ByteArray.setChar(buf, pos, v[off++]);
pos += 2;
}
} else {
@ -2072,7 +2074,7 @@ public class ObjectOutputStream
int avail = (MAX_BLOCK_SIZE - pos) >> 1;
int stop = Math.min(endoff, off + avail);
while (off < stop) {
Bits.putShort(buf, pos, v[off++]);
ByteArray.setShort(buf, pos, v[off++]);
pos += 2;
}
} else {
@ -2089,7 +2091,7 @@ public class ObjectOutputStream
int avail = (MAX_BLOCK_SIZE - pos) >> 2;
int stop = Math.min(endoff, off + avail);
while (off < stop) {
Bits.putInt(buf, pos, v[off++]);
ByteArray.setInt(buf, pos, v[off++]);
pos += 4;
}
} else {
@ -2106,7 +2108,7 @@ public class ObjectOutputStream
int avail = (MAX_BLOCK_SIZE - pos) >> 2;
int stop = Math.min(endoff, off + avail);
while (off < stop) {
Bits.putFloat(buf, pos, v[off++]);
ByteArray.setFloat(buf, pos, v[off++]);
pos += 4;
}
} else {
@ -2123,7 +2125,7 @@ public class ObjectOutputStream
int avail = (MAX_BLOCK_SIZE - pos) >> 3;
int stop = Math.min(endoff, off + avail);
while (off < stop) {
Bits.putLong(buf, pos, v[off++]);
ByteArray.setLong(buf, pos, v[off++]);
pos += 8;
}
} else {
@ -2140,7 +2142,7 @@ public class ObjectOutputStream
int avail = (MAX_BLOCK_SIZE - pos) >> 3;
int stop = Math.min(endoff, off + avail);
while (off < stop) {
Bits.putDouble(buf, pos, v[off++]);
ByteArray.setDouble(buf, pos, v[off++]);
pos += 8;
}
} else {

View file

@ -61,6 +61,7 @@ import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaSecurityAccess;
import jdk.internal.util.ByteArray;
import sun.reflect.misc.ReflectUtil;
/**
@ -1986,14 +1987,14 @@ public final class ObjectStreamClass implements Serializable {
long key = readKeys[i];
int off = offsets[i];
switch (typeCodes[i]) {
case 'Z' -> Bits.putBoolean(buf, off, UNSAFE.getBoolean(obj, key));
case 'Z' -> ByteArray.setBoolean(buf, off, UNSAFE.getBoolean(obj, key));
case 'B' -> buf[off] = UNSAFE.getByte(obj, key);
case 'C' -> Bits.putChar(buf, off, UNSAFE.getChar(obj, key));
case 'S' -> Bits.putShort(buf, off, UNSAFE.getShort(obj, key));
case 'I' -> Bits.putInt(buf, off, UNSAFE.getInt(obj, key));
case 'F' -> Bits.putFloat(buf, off, UNSAFE.getFloat(obj, key));
case 'J' -> Bits.putLong(buf, off, UNSAFE.getLong(obj, key));
case 'D' -> Bits.putDouble(buf, off, UNSAFE.getDouble(obj, key));
case 'C' -> ByteArray.setChar(buf, off, UNSAFE.getChar(obj, key));
case 'S' -> ByteArray.setShort(buf, off, UNSAFE.getShort(obj, key));
case 'I' -> ByteArray.setInt(buf, off, UNSAFE.getInt(obj, key));
case 'F' -> ByteArray.setFloat(buf, off, UNSAFE.getFloat(obj, key));
case 'J' -> ByteArray.setLong(buf, off, UNSAFE.getLong(obj, key));
case 'D' -> ByteArray.setDouble(buf, off, UNSAFE.getDouble(obj, key));
default -> throw new InternalError();
}
}
@ -2015,14 +2016,14 @@ public final class ObjectStreamClass implements Serializable {
}
int off = offsets[i];
switch (typeCodes[i]) {
case 'Z' -> UNSAFE.putBoolean(obj, key, Bits.getBoolean(buf, off));
case 'Z' -> UNSAFE.putBoolean(obj, key, ByteArray.getBoolean(buf, off));
case 'B' -> UNSAFE.putByte(obj, key, buf[off]);
case 'C' -> UNSAFE.putChar(obj, key, Bits.getChar(buf, off));
case 'S' -> UNSAFE.putShort(obj, key, Bits.getShort(buf, off));
case 'I' -> UNSAFE.putInt(obj, key, Bits.getInt(buf, off));
case 'F' -> UNSAFE.putFloat(obj, key, Bits.getFloat(buf, off));
case 'J' -> UNSAFE.putLong(obj, key, Bits.getLong(buf, off));
case 'D' -> UNSAFE.putDouble(obj, key, Bits.getDouble(buf, off));
case 'C' -> UNSAFE.putChar(obj, key, ByteArray.getChar(buf, off));
case 'S' -> UNSAFE.putShort(obj, key, ByteArray.getShort(buf, off));
case 'I' -> UNSAFE.putInt(obj, key, ByteArray.getInt(buf, off));
case 'F' -> UNSAFE.putFloat(obj, key, ByteArray.getFloat(buf, off));
case 'J' -> UNSAFE.putLong(obj, key, ByteArray.getLong(buf, off));
case 'D' -> UNSAFE.putDouble(obj, key, ByteArray.getDouble(buf, off));
default -> throw new InternalError();
}
}
@ -2473,16 +2474,16 @@ public final class ObjectStreamClass implements Serializable {
try {
PRIM_VALUE_EXTRACTORS = Map.of(
byte.class, MethodHandles.arrayElementGetter(byte[].class),
short.class, lkp.findStatic(Bits.class, "getShort", MethodType.methodType(short.class, byte[].class, int.class)),
int.class, lkp.findStatic(Bits.class, "getInt", MethodType.methodType(int.class, byte[].class, int.class)),
long.class, lkp.findStatic(Bits.class, "getLong", MethodType.methodType(long.class, byte[].class, int.class)),
float.class, lkp.findStatic(Bits.class, "getFloat", MethodType.methodType(float.class, byte[].class, int.class)),
double.class, lkp.findStatic(Bits.class, "getDouble", MethodType.methodType(double.class, byte[].class, int.class)),
char.class, lkp.findStatic(Bits.class, "getChar", MethodType.methodType(char.class, byte[].class, int.class)),
boolean.class, lkp.findStatic(Bits.class, "getBoolean", MethodType.methodType(boolean.class, byte[].class, int.class))
short.class, lkp.findStatic(ByteArray.class, "getShort", MethodType.methodType(short.class, byte[].class, int.class)),
int.class, lkp.findStatic(ByteArray.class, "getInt", MethodType.methodType(int.class, byte[].class, int.class)),
long.class, lkp.findStatic(ByteArray.class, "getLong", MethodType.methodType(long.class, byte[].class, int.class)),
float.class, lkp.findStatic(ByteArray.class, "getFloat", MethodType.methodType(float.class, byte[].class, int.class)),
double.class, lkp.findStatic(ByteArray.class, "getDouble", MethodType.methodType(double.class, byte[].class, int.class)),
char.class, lkp.findStatic(ByteArray.class, "getChar", MethodType.methodType(char.class, byte[].class, int.class)),
boolean.class, lkp.findStatic(ByteArray.class, "getBoolean", MethodType.methodType(boolean.class, byte[].class, int.class))
);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new InternalError("Can't lookup Bits.getXXX", e);
throw new InternalError("Can't lookup " + ByteArray.class.getName() + ".getXXX", e);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@ import java.nio.channels.FileChannel;
import jdk.internal.access.JavaIORandomAccessFileAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.Blocker;
import jdk.internal.util.ByteArray;
import sun.nio.ch.FileChannelImpl;
@ -884,7 +885,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
*/
public final int readInt() throws IOException {
readFully(buffer, 0, Integer.BYTES);
return Bits.getInt(buffer, 0);
return ByteArray.getInt(buffer, 0);
}
/**
@ -917,7 +918,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
*/
public final long readLong() throws IOException {
readFully(buffer, 0, Long.BYTES);
return Bits.getLong(buffer, 0);
return ByteArray.getLong(buffer, 0);
}
/**
@ -941,7 +942,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
*/
public final float readFloat() throws IOException {
readFully(buffer, 0, Float.BYTES);
return Bits.getFloat(buffer, 0);
return ByteArray.getFloat(buffer, 0);
}
/**
@ -965,7 +966,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
*/
public final double readDouble() throws IOException {
readFully(buffer, 0, Double.BYTES);
return Bits.getDouble(buffer, 0);
return ByteArray.getDouble(buffer, 0);
}
/**
@ -1104,7 +1105,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
* @throws IOException if an I/O error occurs.
*/
public final void writeInt(int v) throws IOException {
Bits.putInt(buffer, 0, v);
ByteArray.setInt(buffer, 0, v);
write(buffer, 0, Integer.BYTES);
//written += 4;
}
@ -1117,7 +1118,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
* @throws IOException if an I/O error occurs.
*/
public final void writeLong(long v) throws IOException {
Bits.putLong(buffer, 0, v);
ByteArray.setLong(buffer, 0, v);
write(buffer, 0, Long.BYTES);
}
@ -1133,7 +1134,8 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
* @see java.lang.Float#floatToIntBits(float)
*/
public final void writeFloat(float v) throws IOException {
writeInt(Float.floatToIntBits(v));
ByteArray.setFloat(buffer, 0, v);
write(buffer, 0, Float.BYTES);
}
/**
@ -1148,7 +1150,8 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
* @see java.lang.Double#doubleToLongBits(double)
*/
public final void writeDouble(double v) throws IOException {
writeLong(Double.doubleToLongBits(v));
ByteArray.setDouble(buffer, 0, v);
write(buffer, 0, Double.BYTES);
}
/**