8033778: ObjectIn/OutputStream improvements
Reviewed-by: smarks, psandoz, mduigou, plevart
Contributed-by: Robert Stupp <snazy@gmx.de>, Chris Hegarty <chris.hegarty@oracle.com>
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java Thu Feb 06 12:24:42 2014 +0000
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java Thu Feb 06 14:45:12 2014 +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) {
- 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);
+ 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);
}
}
- 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;
}
/**
--- a/jdk/src/share/classes/java/io/ObjectOutputStream.java Thu Feb 06 12:24:42 2014 +0000
+++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java Thu Feb 06 14:45:12 2014 +0000
@@ -35,7 +35,6 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
-import java.io.SerialCallbackContext;
import sun.reflect.misc.ReflectUtil;
/**
@@ -458,7 +457,7 @@
if (ctx == null) {
throw new NotActiveException("not in call to writeObject");
}
- Object curObj = ctx.getObj();
+ ctx.checkAndSetUsed();
ObjectStreamClass curDesc = ctx.getDesc();
curPut = new PutFieldImpl(curDesc);
}
@@ -1527,29 +1526,34 @@
desc.checkDefaultSerialize();
int primDataSize = desc.getPrimDataSize();
- if (primVals == null || primVals.length < primDataSize) {
- primVals = new byte[primDataSize];
+ if (primDataSize > 0) {
+ if (primVals == null || primVals.length < primDataSize) {
+ primVals = new byte[primDataSize];
+ }
+ desc.getPrimFieldValues(obj, primVals);
+ bout.write(primVals, 0, primDataSize, false);
}
- desc.getPrimFieldValues(obj, primVals);
- bout.write(primVals, 0, primDataSize, false);
- ObjectStreamField[] fields = desc.getFields(false);
- Object[] objVals = new Object[desc.getNumObjFields()];
- int numPrimFields = fields.length - objVals.length;
- desc.getObjFieldValues(obj, objVals);
- for (int i = 0; i < objVals.length; i++) {
- if (extendedDebugInfo) {
- debugInfoStack.push(
- "field (class \"" + desc.getName() + "\", name: \"" +
- fields[numPrimFields + i].getName() + "\", type: \"" +
- fields[numPrimFields + i].getType() + "\")");
- }
- try {
- writeObject0(objVals[i],
- fields[numPrimFields + i].isUnshared());
- } finally {
+ int numObjFields = desc.getNumObjFields();
+ if (numObjFields > 0) {
+ ObjectStreamField[] fields = desc.getFields(false);
+ Object[] objVals = new Object[numObjFields];
+ int numPrimFields = fields.length - objVals.length;
+ desc.getObjFieldValues(obj, objVals);
+ for (int i = 0; i < objVals.length; i++) {
if (extendedDebugInfo) {
- debugInfoStack.pop();
+ debugInfoStack.push(
+ "field (class \"" + desc.getName() + "\", name: \"" +
+ fields[numPrimFields + i].getName() + "\", type: \"" +
+ fields[numPrimFields + i].getType() + "\")");
+ }
+ try {
+ writeObject0(objVals[i],
+ fields[numPrimFields + i].isUnshared());
+ } finally {
+ if (extendedDebugInfo) {
+ debugInfoStack.pop();
+ }
}
}
}
@@ -2464,7 +2468,9 @@
StringBuilder buffer = new StringBuilder();
if (!stack.isEmpty()) {
for(int i = stack.size(); i > 0; i-- ) {
- buffer.append(stack.get(i-1) + ((i != 1) ? "\n" : ""));
+ buffer.append(stack.get(i - 1));
+ if (i != 1)
+ buffer.append('\n');
}
}
return buffer.toString();
--- a/jdk/src/share/classes/java/io/ObjectStreamClass.java Thu Feb 06 12:24:42 2014 +0000
+++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java Thu Feb 06 14:45:12 2014 +0000
@@ -1472,42 +1472,55 @@
}
/**
+ * Returns JVM type signature for given primitive.
+ */
+ private static String getPrimitiveSignature(Class<?> cl) {
+ if (cl == Integer.TYPE)
+ return "I";
+ else if (cl == Byte.TYPE)
+ return "B";
+ else if (cl == Long.TYPE)
+ return "J";
+ else if (cl == Float.TYPE)
+ return "F";
+ else if (cl == Double.TYPE)
+ return "D";
+ else if (cl == Short.TYPE)
+ return "S";
+ else if (cl == Character.TYPE)
+ return "C";
+ else if (cl == Boolean.TYPE)
+ return "Z";
+ else if (cl == Void.TYPE)
+ return "V";
+ else
+ throw new InternalError();
+ }
+
+ /**
* Returns JVM type signature for given class.
*/
- private static String getClassSignature(Class<?> cl) {
- StringBuilder sbuf = new StringBuilder();
- while (cl.isArray()) {
- sbuf.append('[');
- cl = cl.getComponentType();
- }
- if (cl.isPrimitive()) {
- if (cl == Integer.TYPE) {
- sbuf.append('I');
- } else if (cl == Byte.TYPE) {
- sbuf.append('B');
- } else if (cl == Long.TYPE) {
- sbuf.append('J');
- } else if (cl == Float.TYPE) {
- sbuf.append('F');
- } else if (cl == Double.TYPE) {
- sbuf.append('D');
- } else if (cl == Short.TYPE) {
- sbuf.append('S');
- } else if (cl == Character.TYPE) {
- sbuf.append('C');
- } else if (cl == Boolean.TYPE) {
- sbuf.append('Z');
- } else if (cl == Void.TYPE) {
- sbuf.append('V');
- } else {
- throw new InternalError();
- }
- } else {
- sbuf.append('L' + cl.getName().replace('.', '/') + ';');
- }
- return sbuf.toString();
+ static String getClassSignature(Class<?> cl) {
+ if (cl.isPrimitive())
+ return getPrimitiveSignature(cl);
+ else
+ return appendClassSignature(new StringBuilder(), cl).toString();
}
+ private static StringBuilder appendClassSignature(StringBuilder sbuf, Class<?> cl) {
+ while (cl.isArray()) {
+ sbuf.append('[');
+ cl = cl.getComponentType();
+ }
+
+ if (cl.isPrimitive())
+ sbuf.append(getPrimitiveSignature(cl));
+ else
+ sbuf.append('L').append(cl.getName().replace('.', '/')).append(';');
+
+ return sbuf;
+ }
+
/**
* Returns JVM type signature for given list of parameters and return type.
*/
@@ -1517,10 +1530,10 @@
StringBuilder sbuf = new StringBuilder();
sbuf.append('(');
for (int i = 0; i < paramTypes.length; i++) {
- sbuf.append(getClassSignature(paramTypes[i]));
+ appendClassSignature(sbuf, paramTypes[i]);
}
sbuf.append(')');
- sbuf.append(getClassSignature(retType));
+ appendClassSignature(sbuf, retType);
return sbuf.toString();
}
--- a/jdk/src/share/classes/java/io/ObjectStreamField.java Thu Feb 06 12:24:42 2014 +0000
+++ b/jdk/src/share/classes/java/io/ObjectStreamField.java Thu Feb 06 14:45:12 2014 +0000
@@ -91,7 +91,7 @@
this.name = name;
this.type = type;
this.unshared = unshared;
- signature = getClassSignature(type).intern();
+ signature = ObjectStreamClass.getClassSignature(type).intern();
field = null;
}
@@ -137,7 +137,7 @@
name = field.getName();
Class<?> ftype = field.getType();
type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
- signature = getClassSignature(ftype).intern();
+ signature = ObjectStreamClass.getClassSignature(ftype).intern();
}
/**
@@ -286,41 +286,4 @@
String getSignature() {
return signature;
}
-
- /**
- * Returns JVM type signature for given class.
- */
- private static String getClassSignature(Class<?> cl) {
- StringBuilder sbuf = new StringBuilder();
- while (cl.isArray()) {
- sbuf.append('[');
- cl = cl.getComponentType();
- }
- if (cl.isPrimitive()) {
- if (cl == Integer.TYPE) {
- sbuf.append('I');
- } else if (cl == Byte.TYPE) {
- sbuf.append('B');
- } else if (cl == Long.TYPE) {
- sbuf.append('J');
- } else if (cl == Float.TYPE) {
- sbuf.append('F');
- } else if (cl == Double.TYPE) {
- sbuf.append('D');
- } else if (cl == Short.TYPE) {
- sbuf.append('S');
- } else if (cl == Character.TYPE) {
- sbuf.append('C');
- } else if (cl == Boolean.TYPE) {
- sbuf.append('Z');
- } else if (cl == Void.TYPE) {
- sbuf.append('V');
- } else {
- throw new InternalError();
- }
- } else {
- sbuf.append('L' + cl.getName().replace('.', '/') + ';');
- }
- return sbuf.toString();
- }
}
--- a/jdk/src/share/classes/java/io/SerialCallbackContext.java Thu Feb 06 12:24:42 2014 +0000
+++ b/jdk/src/share/classes/java/io/SerialCallbackContext.java Thu Feb 06 14:45:12 2014 +0000
@@ -60,7 +60,7 @@
return desc;
}
- private void checkAndSetUsed() throws NotActiveException {
+ public void checkAndSetUsed() throws NotActiveException {
if (thread != Thread.currentThread()) {
throw new NotActiveException(
"not in readObject invocation or fields already read");