8033778: ObjectIn/OutputStream improvements
authorchegar
Thu, 06 Feb 2014 14:45:12 +0000
changeset 22936 1263cd9144d7
parent 22935 4322bab78de4
child 22937 f28798de1e6f
8033778: ObjectIn/OutputStream improvements Reviewed-by: smarks, psandoz, mduigou, plevart Contributed-by: Robert Stupp <snazy@gmx.de>, Chris Hegarty <chris.hegarty@oracle.com>
jdk/src/share/classes/java/io/ObjectInputStream.java
jdk/src/share/classes/java/io/ObjectOutputStream.java
jdk/src/share/classes/java/io/ObjectStreamClass.java
jdk/src/share/classes/java/io/ObjectStreamField.java
jdk/src/share/classes/java/io/SerialCallbackContext.java
--- 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");