src/share/classes/java/io/ObjectInputStream.java
Print this page
*** 37,47 ****
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
- import java.util.concurrent.atomic.AtomicBoolean;
import static java.io.ObjectStreamClass.processQueue;
import sun.reflect.misc.ReflectUtil;
/**
* An ObjectInputStream deserializes primitive data and objects previously
--- 37,46 ----
*** 532,542 ****
{
SerialCallbackContext ctx = curContext;
if (ctx == null) {
throw new NotActiveException("not in call to readObject");
}
! Object curObj = ctx.getObj();
ObjectStreamClass curDesc = ctx.getDesc();
bin.setBlockDataMode(false);
GetFieldImpl getField = new GetFieldImpl(curDesc);
getField.readFields();
bin.setBlockDataMode(true);
--- 531,541 ----
{
SerialCallbackContext ctx = curContext;
if (ctx == null) {
throw new NotActiveException("not in call to readObject");
}
! ctx.checkAndSetUsed();
ObjectStreamClass curDesc = ctx.getDesc();
bin.setBlockDataMode(false);
GetFieldImpl getField = new GetFieldImpl(curDesc);
getField.readFields();
bin.setBlockDataMode(true);
*** 1595,1605 ****
ObjectStreamClass desc = new ObjectStreamClass();
int descHandle = handles.assign(unshared ? unsharedMarker : desc);
passHandle = NULL_HANDLE;
! ObjectStreamClass readDesc = null;
try {
readDesc = readClassDescriptor();
} catch (ClassNotFoundException ex) {
throw (IOException) new InvalidClassException(
"failed to read class descriptor").initCause(ex);
--- 1594,1604 ----
ObjectStreamClass desc = new ObjectStreamClass();
int descHandle = handles.assign(unshared ? unsharedMarker : desc);
passHandle = NULL_HANDLE;
! ObjectStreamClass readDesc;
try {
readDesc = readClassDescriptor();
} catch (ClassNotFoundException ex) {
throw (IOException) new InvalidClassException(
"failed to read class descriptor").initCause(ex);
*** 1974,1994 ****
if (cl != null && obj != null && !cl.isInstance(obj)) {
throw new ClassCastException();
}
int primDataSize = desc.getPrimDataSize();
if (primVals == null || primVals.length < primDataSize) {
primVals = new byte[primDataSize];
}
bin.readFully(primVals, 0, primDataSize, false);
if (obj != null) {
desc.setPrimFieldValues(obj, primVals);
}
int objHandle = passHandle;
ObjectStreamField[] fields = desc.getFields(false);
! Object[] objVals = new Object[desc.getNumObjFields()];
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
ObjectStreamField f = fields[numPrimFields + i];
objVals[i] = readObject0(f.isUnshared());
if (f.getField() != null) {
--- 1973,1997 ----
if (cl != null && obj != null && !cl.isInstance(obj)) {
throw new ClassCastException();
}
int primDataSize = desc.getPrimDataSize();
+ if (primDataSize > 0) {
if (primVals == null || primVals.length < primDataSize) {
primVals = new byte[primDataSize];
}
bin.readFully(primVals, 0, primDataSize, false);
if (obj != null) {
desc.setPrimFieldValues(obj, primVals);
}
+ }
+ int numObjFields = desc.getNumObjFields();
+ if (numObjFields > 0) {
int objHandle = passHandle;
ObjectStreamField[] fields = desc.getFields(false);
! Object[] objVals = new Object[numObjFields];
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
ObjectStreamField f = fields[numPrimFields + i];
objVals[i] = readObject0(f.isUnshared());
if (f.getField() != null) {
*** 1998,2007 ****
--- 2001,2011 ----
if (obj != null) {
desc.setObjFieldValues(obj, objVals);
}
passHandle = objHandle;
}
+ }
/**
* Reads in and returns IOException that caused serialization to abort.
* All stream state is discarded prior to reading in fatal exception. Sets
* passHandle to fatal exception's handle.
*** 2375,2386 ****
/** buffer for reading general/block data */
private final byte[] buf = new byte[MAX_BLOCK_SIZE];
/** buffer for reading block data headers */
private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
! /** char buffer for fast string reads */
private final char[] cbuf = new char[CHAR_BUF_SIZE];
/** block data mode */
private boolean blkmode = false;
// block data state fields; values meaningful only when blkmode true
--- 2379,2394 ----
/** buffer for reading general/block data */
private final byte[] buf = new byte[MAX_BLOCK_SIZE];
/** buffer for reading block data headers */
private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
! /** char buffer for fast string reads - used by {@link #readUTFSpan(long)} */
private final char[] cbuf = new char[CHAR_BUF_SIZE];
+ /** shared string builder for less object allocations - used by
+ * {@link #readUTFBody(long)}, {@link #readUTFChar(long)} and
+ * {@link #readUTFSpan(long)} */
+ private final StringBuilder sbuf = new StringBuilder(CHAR_BUF_SIZE);
/** block data mode */
private boolean blkmode = false;
// block data state fields; values meaningful only when blkmode true
*** 3042,3064 ****
* Reads in the "body" (i.e., the UTF representation minus the 2-byte
* or 8-byte length header) of a UTF encoding, which occupies the next
* utflen bytes.
*/
private String readUTFBody(long utflen) throws IOException {
- StringBuilder sbuf = new StringBuilder();
if (!blkmode) {
end = pos = 0;
}
while (utflen > 0) {
int avail = end - pos;
if (avail >= 3 || (long) avail == utflen) {
! utflen -= readUTFSpan(sbuf, utflen);
} else {
if (blkmode) {
// near block boundary, read one byte at a time
! utflen -= readUTFChar(sbuf, utflen);
} else {
// shift and refill buffer manually
if (avail > 0) {
System.arraycopy(buf, pos, buf, 0, avail);
}
--- 3050,3072 ----
* Reads in the "body" (i.e., the UTF representation minus the 2-byte
* or 8-byte length header) of a UTF encoding, which occupies the next
* utflen bytes.
*/
private String readUTFBody(long utflen) throws IOException {
if (!blkmode) {
end = pos = 0;
}
+ sbuf.setLength(0);
while (utflen > 0) {
int avail = end - pos;
if (avail >= 3 || (long) avail == utflen) {
! utflen -= readUTFSpan(utflen);
} else {
if (blkmode) {
// near block boundary, read one byte at a time
! utflen -= readUTFChar(utflen);
} else {
// shift and refill buffer manually
if (avail > 0) {
System.arraycopy(buf, pos, buf, 0, avail);
}
*** 3074,3086 ****
/**
* Reads span of UTF-encoded characters out of internal buffer
* (starting at offset pos and ending at or before offset end),
* consuming no more than utflen bytes. Appends read characters to
! * sbuf. Returns the number of bytes consumed.
*/
! private long readUTFSpan(StringBuilder sbuf, long utflen)
throws IOException
{
int cpos = 0;
int start = pos;
int avail = Math.min(end - pos, CHAR_BUF_SIZE);
--- 3082,3094 ----
/**
* Reads span of UTF-encoded characters out of internal buffer
* (starting at offset pos and ending at or before offset end),
* consuming no more than utflen bytes. Appends read characters to
! * {@link #sbuf}. Returns the number of bytes consumed.
*/
! private long readUTFSpan(long utflen)
throws IOException
{
int cpos = 0;
int start = pos;
int avail = Math.min(end - pos, CHAR_BUF_SIZE);
*** 3148,3163 ****
return pos - start;
}
/**
* Reads in single UTF-encoded character one byte at a time, appends
! * the character to sbuf, and returns the number of bytes consumed.
* This method is used when reading in UTF strings written in block
* data mode to handle UTF-encoded characters which (potentially)
* straddle block-data boundaries.
*/
! private int readUTFChar(StringBuilder sbuf, long utflen)
throws IOException
{
int b1, b2, b3;
b1 = readByte() & 0xFF;
switch (b1 >> 4) {
--- 3156,3171 ----
return pos - start;
}
/**
* Reads in single UTF-encoded character one byte at a time, appends
! * the character to {@link #sbuf}, and returns the number of bytes consumed.
* This method is used when reading in UTF strings written in block
* data mode to handle UTF-encoded characters which (potentially)
* straddle block-data boundaries.
*/
! private int readUTFChar(long utflen)
throws IOException
{
int b1, b2, b3;
b1 = readByte() & 0xFF;
switch (b1 >> 4) {