Projects
Mega:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:fast-serializer-jdk8.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:fast-serializer-jdk8.patch of Package openjdk-1.8.0
commit 3ece3b6a87e4bf61a1f786c12d796012becce313 Date: Thu May 28 10:30:20 2020 +0800 Add FastSerializer Summary:<core-libs>: Add FastSerializer LLT: jtreg Bug url: NA diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp index cdb72c0d5..d50041635 100644 --- a/hotspot/src/share/vm/prims/unsafe.cpp +++ b/hotspot/src/share/vm/prims/unsafe.cpp @@ -1361,6 +1361,10 @@ UNSAFE_ENTRY(void, Unsafe_PrefetchWrite(JNIEnv* env, jclass ignored, jobject obj Prefetch::write(addr, (intx)offset); UNSAFE_END +UNSAFE_ENTRY(jboolean, Unsafe_GetUseFastSerializer(JNIEnv *env, jobject unsafe)) { + return UseFastSerializer; +} +UNSAFE_END /// JVM_RegisterUnsafeMethods @@ -1447,7 +1451,8 @@ static JNINativeMethod methods_140[] = { {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)}, {CC "monitorEnter", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorEnter)}, {CC "monitorExit", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorExit)}, - {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)} + {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)}, + {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)} }; // These are the methods prior to the JSR 166 changes in 1.5.0 @@ -1493,8 +1498,8 @@ static JNINativeMethod methods_141[] = { {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)}, {CC "monitorEnter", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorEnter)}, {CC "monitorExit", CC "(" OBJ ")V", FN_PTR(Unsafe_MonitorExit)}, - {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)} - + {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)}, + {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)} }; // These are the methods prior to the JSR 166 changes in 1.6.0 @@ -1548,7 +1553,8 @@ static JNINativeMethod methods_15[] = { {CC "compareAndSwapInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, {CC "compareAndSwapLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)}, - {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)} + {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}, + {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)} }; @@ -1606,7 +1612,8 @@ static JNINativeMethod methods_16[] = { {CC "putOrderedInt", CC "(" OBJ "JI)V", FN_PTR(Unsafe_SetOrderedInt)}, {CC "putOrderedLong", CC "(" OBJ "JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)}, - {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)} + {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}, + {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)} }; // These are the methods for 1.8.0 @@ -1662,7 +1669,8 @@ static JNINativeMethod methods_18[] = { {CC "putOrderedInt", CC "(" OBJ "JI)V", FN_PTR(Unsafe_SetOrderedInt)}, {CC "putOrderedLong", CC "(" OBJ "JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)}, - {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)} + {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}, + {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)} }; JNINativeMethod loadavg_method[] = { diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 2e6ff26ed..0a6ebfae1 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -553,6 +553,10 @@ class CommandLineFlags { "Enable normal processing of flags relating to experimental " \ "features") \ \ + experimental(bool, UseFastSerializer, false, \ + "Cache-based serialization.It is extremely fast, but it can only" \ + "be effective in certain scenarios.") \ + \ product(bool, JavaMonitorsInStackTrace, true, \ "Print information about Java monitor locks when the stacks are" \ "dumped") \ diff --git a/jdk/src/share/classes/java/io/ObjectInputStream.java b/jdk/src/share/classes/java/io/ObjectInputStream.java index 5d30f2a01..b67f01719 100644 --- a/jdk/src/share/classes/java/io/ObjectInputStream.java +++ b/jdk/src/share/classes/java/io/ObjectInputStream.java @@ -52,6 +52,7 @@ import sun.misc.JavaOISAccess; import sun.util.logging.PlatformLogger; import sun.security.action.GetBooleanAction; import sun.security.action.GetIntegerAction; +import sun.misc.Unsafe; /** * An ObjectInputStream deserializes primitive data and objects previously @@ -284,6 +285,22 @@ public class ObjectInputStream traceLogger = (filterLog != null && filterLog.isLoggable(PlatformLogger.Level.FINER)) ? filterLog : null; } + + /* + * Logger for FastSerializer. + * Setup the FastSerializer logger if it is set to FINE + * (Assuming it will not change). + */ + private static final PlatformLogger fastSerLogger; + static { + if (printFastSerializer) { + PlatformLogger fastSerLog = PlatformLogger.getLogger("fastSerializer"); + fastSerLogger = (fastSerLog != null && + fastSerLog.isLoggable(PlatformLogger.Level.FINE)) ? fastSerLog : null; + } else { + fastSerLogger = null; + } + } } /** filter stream for handling block data conversion */ @@ -312,6 +329,9 @@ public class ObjectInputStream /** if true, invoke resolveObject() */ private boolean enableResolve; + /** Used to get the commandline option: useFastSerializer */ + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + /** * Context during upcalls to class-defined readObject methods; holds * object currently being deserialized and descriptor for current class. @@ -325,6 +345,38 @@ public class ObjectInputStream */ private ObjectInputFilter serialFilter; + /** + * value of "useFastSerializer" property + */ + private static final boolean defaultFastSerializer = UNSAFE.getUseFastSerializer(); + + /** + * true or false for open FastSerilizer + * May be changed in readStreamHeader + */ + private boolean useFastSerializer = defaultFastSerializer; + + /** + * Value of "fastSerializerEscapeMode" property. It can be turned on + * when useFastSerializer is true. + */ + private static final boolean fastSerializerEscapeMode = java.security.AccessController.doPrivileged( + new sun.security.action.GetBooleanAction( + "fastSerializerEscapeMode")).booleanValue(); + + /** + * value of "printFastSerializer" property, + * as true or false for printing FastSerializer logs. + */ + private static final boolean printFastSerializer = java.security.AccessController.doPrivileged( + new sun.security.action.GetBooleanAction( + "printFastSerializer")).booleanValue(); + + /** + * Magic number that is written to the stream header when using fastserilizer. + */ + private static final short STREAM_MAGIC_FAST = (short)0xdeca; + /** * Creates an ObjectInputStream that reads from the specified InputStream. * A serialization stream header is read from the stream and verified. @@ -396,6 +443,9 @@ public class ObjectInputStream * transitively so that a complete equivalent graph of objects is * reconstructed by readObject. * + * The difference between fastSerialzation and default serialization is the + * descriptor serialization. The data serialization is same with each other. + * * <p>The root object is completely restored when all of its fields and the * objects it references are completely restored. At this point the object * validation callbacks are executed in order based on their registered @@ -670,11 +720,20 @@ public class ObjectInputStream vlist.register(obj, prio); } + /** + * Cache the class meta during serialization. + * Only used in FastSerilizer. + */ + protected static ConcurrentHashMap<String,Class<?>> nameToClass = new ConcurrentHashMap<>(); + /** * Load the local class equivalent of the specified stream class * description. Subclasses may implement this method to allow classes to * be fetched from an alternate source. * + * When fastSerializer is turned on, fields of desc will be null except + * name. When resolveClass is override, this may cause null pointer exception. + * * <p>The corresponding method in <code>ObjectOutputStream</code> is * <code>annotateClass</code>. This method will be invoked only once for * each unique class in the stream. This method can be implemented by @@ -715,16 +774,27 @@ public class ObjectInputStream throws IOException, ClassNotFoundException { String name = desc.getName(); + Class<?> cl = null; + + if (useFastSerializer) { + cl = nameToClass.get(name); + if (cl != null) { + return cl; + } + } try { - return Class.forName(name, false, latestUserDefinedLoader()); + cl = Class.forName(name, false, latestUserDefinedLoader()); } catch (ClassNotFoundException ex) { - Class<?> cl = primClasses.get(name); - if (cl != null) { - return cl; - } else { + cl = primClasses.get(name); + if (cl == null) { throw ex; } } + if (useFastSerializer) { + nameToClass.put(name, cl); + } + + return cl; } /** @@ -894,9 +964,34 @@ public class ObjectInputStream { short s0 = bin.readShort(); short s1 = bin.readShort(); - if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) { - throw new StreamCorruptedException( - String.format("invalid stream header: %04X%04X", s0, s1)); + if (useFastSerializer) { + if (s0 != STREAM_MAGIC_FAST || s1 != STREAM_VERSION) { + + if (s0 != STREAM_MAGIC) { + throw new StreamCorruptedException( + String.format("invalid stream header: %04X%04X, and FastSerializer is activated", s0, s1)); + } + + if (!fastSerializerEscapeMode) { + throw new StreamCorruptedException( + String.format("invalid stream header: %04X%04X.Fast serialization does not support " + + "original serialized files", s0, s1)); + } + + // Escape to default serialization + useFastSerializer = false; + if (Logging.fastSerLogger != null) { + Logging.fastSerLogger.fine("[Deserialize]: Escape and disable FastSerializer"); + } + } + } else if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) { + if (s0 == STREAM_MAGIC_FAST && s1 == STREAM_VERSION) { + throw new StreamCorruptedException( + String.format("invalid stream header: %04X%04X, and it is a FastSerializer stream", s0, s1)); + } else { + throw new StreamCorruptedException( + String.format("invalid stream header: %04X%04X", s0, s1)); + } } } @@ -910,6 +1005,11 @@ public class ObjectInputStream * this method reads class descriptors according to the format defined in * the Object Serialization specification. * + * In fastSerialize mode, the descriptor is obtained by lookup method. And + * the resolveClass method is called here to get the classmeta. Since the + * descriptor is obtained by lookup, the descriptor is same as localdesc. + * So we cann't distinguish the receiver desc and local desc. + * * @return the class descriptor read * @throws IOException If an I/O error has occurred. * @throws ClassNotFoundException If the Class of a serialized object used @@ -920,6 +1020,27 @@ public class ObjectInputStream protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { + // fastSerializer + if (useFastSerializer) { + String name = readUTF(); + Class<?> cl = null; + ObjectStreamClass desc = new ObjectStreamClass(name); + try { + // In order to match this method, we add an annotateClass method in + // writeClassDescriptor. + cl = resolveClass(desc); + } catch (ClassNotFoundException ex) { + // resolveClass is just used to obtain Class which required by lookup method + // and it will be called again later, so we don't throw ClassNotFoundException here. + return desc; + } + if (cl != null) { + desc = ObjectStreamClass.lookup(cl, true); + } + return desc; + } + + // Default deserialization. If the Class cannot be found, throw ClassNotFoundException. ObjectStreamClass desc = new ObjectStreamClass(); desc.readNonProxy(this); return desc; @@ -1996,41 +2090,64 @@ private ObjectStreamClass readNonProxyDesc(boolean unshared) skipCustomData(); - try { - totalObjectRefs++; - depth++; - desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); - - if (cl != null) { - // Check that serial filtering has been done on the local class descriptor's superclass, - // in case it does not appear in the stream. - - // Find the next super descriptor that has a local class descriptor. - // Descriptors for which there is no local class are ignored. - ObjectStreamClass superLocal = null; - for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) { - if ((superLocal = sDesc.getLocalDesc()) != null) { - break; - } - } - - // Scan local descriptor superclasses for a match with the local descriptor of the super found above. - // For each super descriptor before the match, invoke the serial filter on the class. - // The filter is invoked for each class that has not already been filtered - // but would be filtered if the instance had been serialized by this Java runtime. - for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc(); - lDesc != null && lDesc != superLocal; - lDesc = lDesc.getSuperDesc()) { - filterCheck(lDesc.forClass(), -1); - } - } - } finally { - depth--; + totalObjectRefs++; + depth++; + + if (useFastSerializer) { + desc.initNonProxyFast(readDesc, resolveEx); + ObjectStreamClass superDesc = desc.getSuperDesc(); + long originDepth = depth - 1; + // Since desc is obtained from the lookup method, we will lose the depth and + // totalObjectRefs of superDesc. So we add a loop here to compute the depth + // and objectRef of superDesc. + while (superDesc != null && superDesc.forClass() != null) { + filterCheck(superDesc.forClass(), -1); + superDesc = superDesc.getSuperDesc(); + totalObjectRefs++; + depth++; + } + depth = originDepth; + } else { + try { + desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); + + if (cl != null) { + // Check that serial filtering has been done on the local class descriptor's superclass, + // in case it does not appear in the stream. + + // Find the next super descriptor that has a local class descriptor. + // Descriptors for which there is no local class are ignored. + ObjectStreamClass superLocal = null; + for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) { + if ((superLocal = sDesc.getLocalDesc()) != null) { + break; + } + } + + // Scan local descriptor superclasses for a match with the local descriptor of the super found above. + // For each super descriptor before the match, invoke the serial filter on the class. + // The filter is invoked for each class that has not already been filtered + // but would be filtered if the instance had been serialized by this Java runtime. + for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc(); + lDesc != null && lDesc != superLocal; + lDesc = lDesc.getSuperDesc()) { + filterCheck(lDesc.forClass(), -1); + } + } + } finally { + depth--; + } } handles.finish(descHandle); passHandle = descHandle; + if (Logging.fastSerLogger != null) { + Logging.fastSerLogger.fine( + "[Deserialize] useFastSerializer:{0}, Class name:{1}, SerialVersionUID:{2}, flags:{3}", + useFastSerializer, desc.getName(), desc.getSerialVersionUID(), desc.getFlags(this)); + } + return desc; } @@ -2334,21 +2478,25 @@ public class ObjectInputStream 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(Object.class, f.isUnshared()); - if (f.getField() != null) { - handles.markDependency(objHandle, passHandle); + Object[] objVals = null; + int numObjFields = desc.getNumObjFields(); + if (numObjFields > 0) { + int objHandle = passHandle; + ObjectStreamField[] fields = desc.getFields(false); + 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(Object.class, f.isUnshared()); + if (f.getField() != null) { + handles.markDependency(objHandle, passHandle); + } } + if (obj != null) { + desc.setObjFieldValues(obj, objVals); + } + passHandle = objHandle; } - if (obj != null) { - desc.setObjFieldValues(obj, objVals); - } - passHandle = objHandle; } /** diff --git a/jdk/src/share/classes/java/io/ObjectOutputStream.java b/jdk/src/share/classes/java/io/ObjectOutputStream.java index 6d29e3a1f..3890efc3e 100644 --- a/jdk/src/share/classes/java/io/ObjectOutputStream.java +++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java @@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentMap; import static java.io.ObjectStreamClass.processQueue; import java.io.SerialCallbackContext; import sun.reflect.misc.ReflectUtil; +import sun.misc.Unsafe; +import sun.util.logging.PlatformLogger; /** * An ObjectOutputStream writes primitive data types and graphs of Java objects @@ -173,6 +175,24 @@ public class ObjectOutputStream new ReferenceQueue<>(); } + private static class Logging { + /* + * Logger for FastSerializer. + * Setup the FastSerializer logger if it is set to FINE. + * (Assuming it will not change). + */ + static final PlatformLogger fastSerLogger; + static { + if (printFastSerializer) { + PlatformLogger fastSerLog = PlatformLogger.getLogger("fastSerializer"); + fastSerLogger = (fastSerLog != null && + fastSerLog.isLoggable(PlatformLogger.Level.FINE)) ? fastSerLog : null; + } else { + fastSerLogger = null; + } + } + } + /** filter stream for handling block data conversion */ private final BlockDataOutputStream bout; /** obj -> wire handle map */ @@ -214,6 +234,27 @@ public class ObjectOutputStream new sun.security.action.GetBooleanAction( "sun.io.serialization.extendedDebugInfo")).booleanValue(); + /** + * Magic number that is written to the stream header when using fastserilizer. + */ + private static final short STREAM_MAGIC_FAST = (short)0xdeca; + + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + /** + * Value of "UseFastSerializer" property. The fastSerializer is turned + * on when it is true. + */ + private static final boolean useFastSerializer = UNSAFE.getUseFastSerializer(); + + /** + * value of "printFastSerializer" property, + * as true or false for printing FastSerializer logs. + */ + private static final boolean printFastSerializer = java.security.AccessController.doPrivileged( + new sun.security.action.GetBooleanAction( + "printFastSerializer")).booleanValue(); + /** * Creates an ObjectOutputStream that writes to the specified OutputStream. * This constructor writes the serialization stream header to the @@ -327,6 +363,9 @@ public class ObjectOutputStream * object are written transitively so that a complete equivalent graph of * objects can be reconstructed by an ObjectInputStream. * + * The difference between fastSerialzation and default serialization is the + * descriptor serialization. The data serialization is same with each other. + * * <p>Exceptions are thrown for problems with the OutputStream and for * classes that should not be serialized. All exceptions are fatal to the * OutputStream, which is left in an indeterminate state, and it is up to @@ -633,7 +672,11 @@ public class ObjectOutputStream * stream */ protected void writeStreamHeader() throws IOException { - bout.writeShort(STREAM_MAGIC); + if (useFastSerializer) { + bout.writeShort(STREAM_MAGIC_FAST); + } else { + bout.writeShort(STREAM_MAGIC); + } bout.writeShort(STREAM_VERSION); } @@ -648,6 +691,9 @@ public class ObjectOutputStream * By default, this method writes class descriptors according to the format * defined in the Object Serialization specification. * + * In fastSerializer mode, we will only write the classname to the stream. + * The annotateClass is used to match the resolveClass in readClassDescriptor. + * * <p>Note that this method will only be called if the ObjectOutputStream * is not using the old serialization stream format (set by calling * ObjectOutputStream's <code>useProtocolVersion</code> method). If this @@ -665,7 +711,14 @@ public class ObjectOutputStream protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { - desc.writeNonProxy(this); + if (useFastSerializer) { + writeUTF(desc.getName()); + // The annotateClass is used to match the resolveClass called in + // readClassDescriptor. + annotateClass(desc.forClass()); + } else { + desc.writeNonProxy(this); + } } /** @@ -1275,9 +1328,21 @@ public class ObjectOutputStream bout.writeByte(TC_CLASSDESC); handles.assign(unshared ? null : desc); + if (Logging.fastSerLogger != null) { + Logging.fastSerLogger.fine( + "[Serialize] useFastSerializer:{0}, Class name:{1}, SerialVersionUID:{2}, flags:{3}, protocol:{4}", + useFastSerializer, desc.getName(), desc.getSerialVersionUID(), desc.getFlags(this), protocol); + } + if (protocol == PROTOCOL_VERSION_1) { // do not invoke class descriptor write hook with old protocol - desc.writeNonProxy(this); + if (useFastSerializer) { + // only write name and annotate class when using FastSerializer + writeUTF(desc.getName()); + annotateClass(desc.forClass()); + } else { + desc.writeNonProxy(this); + } } else { writeClassDescriptor(desc); } @@ -1291,7 +1356,9 @@ public class ObjectOutputStream bout.setBlockDataMode(false); bout.writeByte(TC_ENDBLOCKDATA); - writeClassDesc(desc.getSuperDesc(), false); + if (!useFastSerializer) { + writeClassDesc(desc.getSuperDesc(), false); + } } /** diff --git a/jdk/src/share/classes/java/io/ObjectStreamClass.java b/jdk/src/share/classes/java/io/ObjectStreamClass.java index 64453b25a..fce3c3475 100644 --- a/jdk/src/share/classes/java/io/ObjectStreamClass.java +++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java @@ -280,6 +280,40 @@ public class ObjectStreamClass implements Serializable { return suid.longValue(); } + /** + * Return the flags for this class described by this descriptor. The flags + * means a set of bit masks for ObjectStreamClass, which indicate the status + * of SC_WRITE_METHOD, SC_SERIALIZABLE, SC_EXTERNALIZABLE, SC_BLOCK_DATA and + * SC_ENUM. + * + * @param serialStream ObjectOutputStream or ObjectInputStream + * + * @return the flags for this class described by this descriptor + */ + byte getFlags(Object serialStream) { + byte flags = 0; + if (externalizable) { + flags |= ObjectStreamConstants.SC_EXTERNALIZABLE; + if (serialStream instanceof ObjectOutputStream) { + int protocol = ((ObjectOutputStream)serialStream).getProtocolVersion(); + if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) { + flags |= ObjectStreamConstants.SC_BLOCK_DATA; + } + } else if (serialStream instanceof ObjectInputStream) { + flags |= ObjectStreamConstants.SC_BLOCK_DATA; + } + } else if (serializable) { + flags |= ObjectStreamConstants.SC_SERIALIZABLE; + } + if (hasWriteObjectData) { + flags |= ObjectStreamConstants.SC_WRITE_METHOD; + } + if (isEnum) { + flags |= ObjectStreamConstants.SC_ENUM; + } + return flags; + } + /** * Return the class in the local VM that this version is mapped to. Null * is returned if there is no corresponding local class. @@ -570,6 +604,15 @@ public class ObjectStreamClass implements Serializable { ObjectStreamClass() { } + /** + * Create a blank class descriptor with name. It is only used + * in fastSerialize path. + * @param name class name + */ + ObjectStreamClass(String name) { + this.name = name; + } + /** * Creates a PermissionDomain that grants no permission. */ @@ -756,6 +799,44 @@ public class ObjectStreamClass implements Serializable { initialized = true; } + /** + * Initializes class descriptor representing a non-proxy class. + * Used in fast serialization mode. + */ + void initNonProxyFast(ObjectStreamClass model, + ClassNotFoundException resolveEx) + { + this.cl = model.cl; + this.resolveEx = resolveEx; + this.superDesc = model.superDesc; + name = model.name; + this.suid = model.suid; + isProxy = false; + isEnum = model.isEnum; + serializable = model.serializable; + externalizable = model.externalizable; + hasBlockExternalData = model.hasBlockExternalData; + hasWriteObjectData = model.hasWriteObjectData; + fields = model.fields; + primDataSize = model.primDataSize; + numObjFields = model.numObjFields; + + writeObjectMethod = model.writeObjectMethod; + readObjectMethod = model.readObjectMethod; + readObjectNoDataMethod = model.readObjectNoDataMethod; + writeReplaceMethod = model.writeReplaceMethod; + readResolveMethod = model.readResolveMethod; + if (deserializeEx == null) { + deserializeEx = model.deserializeEx; + } + domains = model.domains; + cons = model.cons; + fieldRefl = model.fieldRefl; + localDesc = model; + + initialized = true; + } + /** * Reads non-proxy class descriptor information from given input stream. * The resulting class descriptor is not fully functional; it can only be diff --git a/jdk/src/share/classes/sun/misc/Unsafe.java b/jdk/src/share/classes/sun/misc/Unsafe.java index 99e465802..92fb01669 100644 --- a/jdk/src/share/classes/sun/misc/Unsafe.java +++ b/jdk/src/share/classes/sun/misc/Unsafe.java @@ -433,6 +433,8 @@ public final class Unsafe { /** @see #putByte(long, byte) */ public native void putDouble(long address, double x); + public native boolean getUseFastSerializer(); + /** * Fetches a native pointer from a given memory address. If the address is * zero, or does not point into a block obtained from {@link
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2