8033778: ObjectIn/OutputStream improvements

Co-authored-by: Robert Stupp <snazy@gmx.de>
Reviewed-by: smarks, psandoz, mduigou, plevart
This commit is contained in:
Chris Hegarty 2014-02-06 14:45:12 +00:00
parent 5911461228
commit 2ffde4a993
5 changed files with 107 additions and 121 deletions

View File

@ -39,7 +39,6 @@ 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;
@ -534,7 +533,7 @@ public class ObjectInputStream
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 @@ public class ObjectInputStream
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 @@ public class ObjectInputStream
}
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;
}
/**

View File

@ -35,7 +35,6 @@ import java.util.List;
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 @@ public class ObjectOutputStream
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 @@ public class ObjectOutputStream
desc.checkDefaultSerialize();
int primDataSize = desc.getPrimDataSize();
if (primVals == null || primVals.length < primDataSize) {
primVals = new byte[primDataSize];
}
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() + "\")");
if (primDataSize > 0) {
if (primVals == null || primVals.length < primDataSize) {
primVals = new byte[primDataSize];
}
try {
writeObject0(objVals[i],
fields[numPrimFields + i].isUnshared());
} finally {
desc.getPrimFieldValues(obj, primVals);
bout.write(primVals, 0, primDataSize, false);
}
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 @@ public class ObjectOutputStream
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();

View File

@ -1471,43 +1471,56 @@ public class ObjectStreamClass implements Serializable {
return name1.equals(name2);
}
/**
* 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 @@ public class ObjectStreamClass implements Serializable {
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();
}

View File

@ -91,7 +91,7 @@ public class ObjectStreamField
this.name = name;
this.type = type;
this.unshared = unshared;
signature = getClassSignature(type).intern();
signature = ObjectStreamClass.getClassSignature(type).intern();
field = null;
}
@ -137,7 +137,7 @@ public class ObjectStreamField
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 @@ public class ObjectStreamField
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();
}
}

View File

@ -60,7 +60,7 @@ final class SerialCallbackContext {
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");