--- old/src/share/classes/java/io/ObjectInputStream.java 2014-01-31 14:00:19.364068476 +0000 +++ new/src/share/classes/java/io/ObjectInputStream.java 2014-01-31 14:00:19.180068483 +0000 @@ -39,7 +39,6 @@ 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; @@ -534,7 +533,7 @@ if (ctx == null) { throw new NotActiveException("not in call to readObject"); } - Object curObj = ctx.getObj(); + ctx.checkAndSetUsed(); ObjectStreamClass curDesc = ctx.getDesc(); bin.setBlockDataMode(false); GetFieldImpl getField = new GetFieldImpl(curDesc); @@ -1597,7 +1596,7 @@ int descHandle = handles.assign(unshared ? unsharedMarker : desc); passHandle = NULL_HANDLE; - ObjectStreamClass readDesc = null; + ObjectStreamClass readDesc; try { readDesc = readClassDescriptor(); } catch (ClassNotFoundException ex) { @@ -1976,29 +1975,34 @@ } int primDataSize = desc.getPrimDataSize(); - if (primVals == null || primVals.length < primDataSize) { + 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 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) { - handles.markDependency(objHandle, passHandle); + } + bin.readFully(primVals, 0, primDataSize, false); + if (obj != null) { + desc.setPrimFieldValues(obj, primVals); } } - if (obj != null) { - desc.setObjFieldValues(obj, objVals); + + 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) { + handles.markDependency(objHandle, passHandle); + } + } + if (obj != null) { + desc.setObjFieldValues(obj, objVals); + } + passHandle = objHandle; } - passHandle = objHandle; } /** @@ -2377,8 +2381,12 @@ 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 */ + /** 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; @@ -3044,19 +3052,19 @@ * utflen bytes. */ private String readUTFBody(long utflen) throws IOException { - StringBuilder sbuf = new StringBuilder(); if (!blkmode) { end = pos = 0; } + sbuf.setLength(0); while (utflen > 0) { int avail = end - pos; if (avail >= 3 || (long) avail == utflen) { - utflen -= readUTFSpan(sbuf, utflen); + utflen -= readUTFSpan(utflen); } else { if (blkmode) { // near block boundary, read one byte at a time - utflen -= readUTFChar(sbuf, utflen); + utflen -= readUTFChar(utflen); } else { // shift and refill buffer manually if (avail > 0) { @@ -3076,9 +3084,9 @@ * 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. + * {@link #sbuf}. Returns the number of bytes consumed. */ - private long readUTFSpan(StringBuilder sbuf, long utflen) + private long readUTFSpan(long utflen) throws IOException { int cpos = 0; @@ -3150,12 +3158,12 @@ /** * Reads in single UTF-encoded character one byte at a time, appends - * the character to sbuf, and returns the number of bytes consumed. + * 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(StringBuilder sbuf, long utflen) + private int readUTFChar(long utflen) throws IOException { int b1, b2, b3;