commit
16d3c82cc1
625
fast-serializer-jdk11.patch
Normal file
625
fast-serializer-jdk11.patch
Normal file
@ -0,0 +1,625 @@
|
|||||||
|
commit cbbef85e20818d23651e553ad9915ec8225a3456
|
||||||
|
Date: Thu May 28 11:04:16 2020 +0800
|
||||||
|
|
||||||
|
Add FastSerializer
|
||||||
|
|
||||||
|
Summary:<core-libs>: Add FastSerializer
|
||||||
|
LLT: jtreg
|
||||||
|
Bug url: NA
|
||||||
|
|
||||||
|
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
|
||||||
|
index 2f14e01ce..2f7f96aee 100644
|
||||||
|
--- a/src/hotspot/share/prims/unsafe.cpp
|
||||||
|
+++ b/src/hotspot/share/prims/unsafe.cpp
|
||||||
|
@@ -1019,6 +1019,11 @@ UNSAFE_ENTRY(jint, Unsafe_GetLoadAverage0(JNIEnv *env, jobject unsafe, jdoubleAr
|
||||||
|
} UNSAFE_END
|
||||||
|
|
||||||
|
|
||||||
|
+UNSAFE_ENTRY(jboolean, Unsafe_GetUseFastSerializer(JNIEnv *env, jobject unsafe)) {
|
||||||
|
+ return UseFastSerializer;
|
||||||
|
+}
|
||||||
|
+UNSAFE_END
|
||||||
|
+
|
||||||
|
/// JVM_RegisterUnsafeMethods
|
||||||
|
|
||||||
|
#define ADR "J"
|
||||||
|
@@ -1102,6 +1107,7 @@ static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
|
||||||
|
{CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
|
||||||
|
|
||||||
|
{CC "isBigEndian0", CC "()Z", FN_PTR(Unsafe_isBigEndian0)},
|
||||||
|
+ {CC "getUseFastSerializer", CC "()Z", FN_PTR(Unsafe_GetUseFastSerializer)},
|
||||||
|
{CC "unalignedAccess0", CC "()Z", FN_PTR(Unsafe_unalignedAccess0)}
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
|
||||||
|
index 1e2408b4b..7fc3c1fb7 100644
|
||||||
|
--- a/src/hotspot/share/runtime/globals.hpp
|
||||||
|
+++ b/src/hotspot/share/runtime/globals.hpp
|
||||||
|
@@ -2670,6 +2670,10 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
||||||
|
JFR_ONLY(product(ccstr, StartFlightRecording, NULL, \
|
||||||
|
"Start flight recording with options")) \
|
||||||
|
\
|
||||||
|
+ experimental(bool, UseFastSerializer, false, \
|
||||||
|
+ "Cache-based serialization.It is extremely fast, but it can only" \
|
||||||
|
+ "be effective in certain scenarios.") \
|
||||||
|
+ \
|
||||||
|
experimental(bool, UseFastUnorderedTimeStamps, false, \
|
||||||
|
"Use platform unstable time where supported for timestamps only")
|
||||||
|
|
||||||
|
diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java
|
||||||
|
index 3386b1a08..d71d44a98 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java
|
||||||
|
@@ -295,6 +295,23 @@ public class ObjectInputStream
|
||||||
|
filterLogger = (filterLog.isLoggable(Logger.Level.DEBUG)
|
||||||
|
|| filterLog.isLoggable(Logger.Level.TRACE)) ? filterLog : null;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Logger for FastSerializer.
|
||||||
|
+ * Setup the FastSerializer logger if it is set to DEBUG.
|
||||||
|
+ * (Assuming it will not change).
|
||||||
|
+ */
|
||||||
|
+ static final System.Logger fastSerLogger;
|
||||||
|
+
|
||||||
|
+ static {
|
||||||
|
+ if (printFastSerializer) {
|
||||||
|
+ Logger fastSerLog = System.getLogger("fastSerializer");
|
||||||
|
+ fastSerLogger = (fastSerLog.isLoggable(Logger.Level.DEBUG))
|
||||||
|
+ ? fastSerLog : null;
|
||||||
|
+ } else {
|
||||||
|
+ fastSerLogger = null;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** filter stream for handling block data conversion */
|
||||||
|
@@ -320,6 +337,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.
|
||||||
|
@@ -333,6 +353,33 @@ 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();
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Creates an ObjectInputStream that reads from the specified InputStream.
|
||||||
|
* A serialization stream header is read from the stream and verified.
|
||||||
|
@@ -410,6 +457,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
|
||||||
|
@@ -698,11 +748,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
|
||||||
|
@@ -741,18 +800,33 @@ public class ObjectInputStream
|
||||||
|
throws IOException, ClassNotFoundException
|
||||||
|
{
|
||||||
|
String name = desc.getName();
|
||||||
|
- try {
|
||||||
|
- return Class.forName(name, false, latestUserDefinedLoader());
|
||||||
|
- } catch (ClassNotFoundException ex) {
|
||||||
|
- Class<?> cl = primClasses.get(name);
|
||||||
|
+ Class<?> cl = null;
|
||||||
|
+
|
||||||
|
+ if (useFastSerializer) {
|
||||||
|
+ cl = nameToClass.get(name);
|
||||||
|
if (cl != null) {
|
||||||
|
return cl;
|
||||||
|
- } else {
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ try {
|
||||||
|
+ cl = Class.forName(name, false, latestUserDefinedLoader());
|
||||||
|
+ } catch (ClassNotFoundException ex) {
|
||||||
|
+ cl = primClasses.get(name);
|
||||||
|
+ if (cl == null) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (useFastSerializer) {
|
||||||
|
+ nameToClass.put(name, cl);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return cl;
|
||||||
|
+
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Returns a proxy class that implements the interfaces named in a proxy
|
||||||
|
* class descriptor; subclasses may implement this method to read custom
|
||||||
|
@@ -924,9 +998,33 @@ 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.log(Logger.Level.DEBUG, "[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));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -940,6 +1038,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
|
||||||
|
@@ -950,6 +1053,29 @@ 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) {
|
||||||
|
+ // This desc is localDesc. It may be different from the descriptor
|
||||||
|
+ // obtained from the stream.
|
||||||
|
+ 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;
|
||||||
|
@@ -1946,10 +2072,12 @@ public class ObjectInputStream
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectStreamClass desc = new ObjectStreamClass();
|
||||||
|
+
|
||||||
|
int descHandle = handles.assign(unshared ? unsharedMarker : desc);
|
||||||
|
passHandle = NULL_HANDLE;
|
||||||
|
|
||||||
|
ObjectStreamClass readDesc;
|
||||||
|
+
|
||||||
|
try {
|
||||||
|
readDesc = readClassDescriptor();
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
@@ -1976,17 +2104,40 @@ public class ObjectInputStream
|
||||||
|
|
||||||
|
skipCustomData();
|
||||||
|
|
||||||
|
- try {
|
||||||
|
- totalObjectRefs++;
|
||||||
|
- depth++;
|
||||||
|
- desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
|
||||||
|
- } 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));
|
||||||
|
+ } finally {
|
||||||
|
+ depth--;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
handles.finish(descHandle);
|
||||||
|
passHandle = descHandle;
|
||||||
|
|
||||||
|
+ if (Logging.fastSerLogger != null) {
|
||||||
|
+ Logging.fastSerLogger.log(Logger.Level.DEBUG,
|
||||||
|
+ "[Deserialize] useFastSerializer:{0}, Class name:{1}, SerialVersionUID:{2}, flags:{3}",
|
||||||
|
+ useFastSerializer, desc.getName(), desc.getSerialVersionUID(), desc.getFlags(this));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2873,7 +3024,6 @@ public class ObjectInputStream
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a "freeze" action, required to adhere to final field semantics.
|
||||||
|
diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
||||||
|
index 135e5645a..8935e61dc 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
||||||
|
@@ -36,6 +36,7 @@ import java.util.StringJoiner;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import static java.io.ObjectStreamClass.processQueue;
|
||||||
|
+import jdk.internal.misc.Unsafe;
|
||||||
|
import sun.reflect.misc.ReflectUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -174,6 +175,25 @@ public class ObjectOutputStream
|
||||||
|
new ReferenceQueue<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private static class Logging {
|
||||||
|
+ /*
|
||||||
|
+ * Logger for FastSerializer.
|
||||||
|
+ * Setup the FastSerializer logger if it is set to DEBUG.
|
||||||
|
+ * (Assuming it will not change).
|
||||||
|
+ */
|
||||||
|
+ static final System.Logger fastSerLogger;
|
||||||
|
+
|
||||||
|
+ static {
|
||||||
|
+ if (printFastSerializer) {
|
||||||
|
+ System.Logger fastSerLog = System.getLogger("fastSerializer");
|
||||||
|
+ fastSerLogger = (fastSerLog.isLoggable(System.Logger.Level.DEBUG))
|
||||||
|
+ ? fastSerLog : null;
|
||||||
|
+ } else {
|
||||||
|
+ fastSerLogger = null;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/** filter stream for handling block data conversion */
|
||||||
|
private final BlockDataOutputStream bout;
|
||||||
|
/** obj -> wire handle map */
|
||||||
|
@@ -192,7 +212,6 @@ public class ObjectOutputStream
|
||||||
|
private final boolean enableOverride;
|
||||||
|
/** if true, invoke replaceObject() */
|
||||||
|
private boolean enableReplace;
|
||||||
|
-
|
||||||
|
// values below valid only during upcalls to writeObject()/writeExternal()
|
||||||
|
/**
|
||||||
|
* Context during upcalls to class-defined writeObject methods; holds
|
||||||
|
@@ -215,6 +234,22 @@ public class ObjectOutputStream
|
||||||
|
new sun.security.action.GetBooleanAction(
|
||||||
|
"sun.io.serialization.extendedDebugInfo")).booleanValue();
|
||||||
|
|
||||||
|
+ 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
|
||||||
|
@@ -328,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
|
||||||
|
@@ -636,7 +674,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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -651,6 +693,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
|
||||||
|
@@ -668,7 +713,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);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -1276,9 +1328,21 @@ public class ObjectOutputStream
|
||||||
|
bout.writeByte(TC_CLASSDESC);
|
||||||
|
handles.assign(unshared ? null : desc);
|
||||||
|
|
||||||
|
+ if (Logging.fastSerLogger != null) {
|
||||||
|
+ Logging.fastSerLogger.log(System.Logger.Level.DEBUG,
|
||||||
|
+ "[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,8 +1355,9 @@ public class ObjectOutputStream
|
||||||
|
annotateClass(cl);
|
||||||
|
bout.setBlockDataMode(false);
|
||||||
|
bout.writeByte(TC_ENDBLOCKDATA);
|
||||||
|
-
|
||||||
|
- writeClassDesc(desc.getSuperDesc(), false);
|
||||||
|
+ if (!useFastSerializer) {
|
||||||
|
+ writeClassDesc(desc.getSuperDesc(), false);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/src/java.base/share/classes/java/io/ObjectStreamClass.java b/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
||||||
|
index 17739cdc7..a5d7d2d75 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
||||||
|
@@ -270,6 +270,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
|
||||||
|
+ */
|
||||||
|
+ public 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.
|
||||||
|
@@ -560,6 +594,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.
|
||||||
|
*/
|
||||||
|
@@ -746,6 +789,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/src/java.base/share/classes/java/io/ObjectStreamConstants.java b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
||||||
|
index 43a480ce4..96157782a 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
||||||
|
@@ -38,6 +38,11 @@ public interface ObjectStreamConstants {
|
||||||
|
*/
|
||||||
|
static final short STREAM_MAGIC = (short)0xaced;
|
||||||
|
|
||||||
|
+ /**
|
||||||
|
+ * Magic number that is written to the stream header when using fastserilizer.
|
||||||
|
+ */
|
||||||
|
+ static final short STREAM_MAGIC_FAST = (short)0xdeca;
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Version number that is written to the stream header.
|
||||||
|
*/
|
||||||
|
diff --git a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
|
||||||
|
index 031b5aae5..d78caabdc 100644
|
||||||
|
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
|
||||||
|
+++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
|
||||||
|
@@ -3703,7 +3703,7 @@ public final class Unsafe {
|
||||||
|
private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; }
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
+ public native boolean getUseFastSerializer();
|
||||||
|
private native long allocateMemory0(long bytes);
|
||||||
|
private native long reallocateMemory0(long address, long bytes);
|
||||||
|
private native void freeMemory0(long address);
|
||||||
88
fix-jck-failure-on-FastSerializer.patch
Normal file
88
fix-jck-failure-on-FastSerializer.patch
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
From cd63946e80ceb3f9de8a1ee02b38548c06cf532a Mon Sep 17 00:00:00 2001
|
||||||
|
Date: Thu, 23 Jul 2020 16:40:31 +0800
|
||||||
|
Subject: [PATCH] fix jck failure on FastSerializer
|
||||||
|
|
||||||
|
Summary: <core-libs>: <fix jck failure on FastSerializer>
|
||||||
|
LLT: jck
|
||||||
|
Bug url: NA
|
||||||
|
---
|
||||||
|
src/java.base/share/classes/java/io/ObjectInputStream.java | 7 ++++++-
|
||||||
|
src/java.base/share/classes/java/io/ObjectOutputStream.java | 5 +++++
|
||||||
|
src/java.base/share/classes/java/io/ObjectStreamClass.java | 2 +-
|
||||||
|
src/java.base/share/classes/java/io/ObjectStreamConstants.java | 5 -----
|
||||||
|
4 files changed, 12 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java
|
||||||
|
index d71d44a..a48e50c 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java
|
||||||
|
@@ -381,6 +381,11 @@ public class ObjectInputStream
|
||||||
|
"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.
|
||||||
|
* This constructor will block until the corresponding ObjectOutputStream
|
||||||
|
@@ -752,7 +757,7 @@ public class ObjectInputStream
|
||||||
|
* Cache the class meta during serialization.
|
||||||
|
* Only used in FastSerilizer.
|
||||||
|
*/
|
||||||
|
- protected static ConcurrentHashMap<String,Class<?>> nameToClass = new ConcurrentHashMap<>();
|
||||||
|
+ private static ConcurrentHashMap<String,Class<?>> nameToClass = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the local class equivalent of the specified stream class
|
||||||
|
diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
||||||
|
index 8935e61..0e54763 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java
|
||||||
|
@@ -251,6 +251,11 @@ public class ObjectOutputStream
|
||||||
|
"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 ObjectOutputStream that writes to the specified OutputStream.
|
||||||
|
* This constructor writes the serialization stream header to the
|
||||||
|
* underlying stream; callers may wish to flush the stream immediately to
|
||||||
|
diff --git a/src/java.base/share/classes/java/io/ObjectStreamClass.java b/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
||||||
|
index a5d7d2d..e37a784 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java
|
||||||
|
@@ -280,7 +280,7 @@ public class ObjectStreamClass implements Serializable {
|
||||||
|
*
|
||||||
|
* @return the flags for this class described by this descriptor
|
||||||
|
*/
|
||||||
|
- public byte getFlags(Object serialStream) {
|
||||||
|
+ byte getFlags(Object serialStream) {
|
||||||
|
byte flags = 0;
|
||||||
|
if (externalizable) {
|
||||||
|
flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
|
||||||
|
diff --git a/src/java.base/share/classes/java/io/ObjectStreamConstants.java b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
||||||
|
index 9615778..43a480c 100644
|
||||||
|
--- a/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
||||||
|
+++ b/src/java.base/share/classes/java/io/ObjectStreamConstants.java
|
||||||
|
@@ -39,11 +39,6 @@ public interface ObjectStreamConstants {
|
||||||
|
static final short STREAM_MAGIC = (short)0xaced;
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Magic number that is written to the stream header when using fastserilizer.
|
||||||
|
- */
|
||||||
|
- static final short STREAM_MAGIC_FAST = (short)0xdeca;
|
||||||
|
-
|
||||||
|
- /**
|
||||||
|
* Version number that is written to the stream header.
|
||||||
|
*/
|
||||||
|
static final short STREAM_VERSION = 5;
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
|
|
||||||
@ -735,7 +735,7 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release}
|
|||||||
|
|
||||||
Name: java-%{javaver}-%{origin}
|
Name: java-%{javaver}-%{origin}
|
||||||
Version: %{newjavaver}.%{buildver}
|
Version: %{newjavaver}.%{buildver}
|
||||||
Release: 5
|
Release: 6
|
||||||
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
|
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
|
||||||
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
|
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
|
||||||
# also included the epoch in their virtual provides. This created a
|
# also included the epoch in their virtual provides. This created a
|
||||||
@ -823,6 +823,8 @@ Patch34: 8210461-AArch64-Math.cos-intrinsic-gives-incorrect-results.patch
|
|||||||
Patch35: NUMA-Aware-Implementation-humongous-region.patch
|
Patch35: NUMA-Aware-Implementation-humongous-region.patch
|
||||||
Patch36: ZGC-in-c1-load-barrier-d0-and-d1-registers-miss-restoring.patch
|
Patch36: ZGC-in-c1-load-barrier-d0-and-d1-registers-miss-restoring.patch
|
||||||
Patch37: fix-compile-error-without-disable-precompiled-headers.patch
|
Patch37: fix-compile-error-without-disable-precompiled-headers.patch
|
||||||
|
Patch38: fast-serializer-jdk11.patch
|
||||||
|
Patch39: fix-jck-failure-on-FastSerializer.patch
|
||||||
|
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: alsa-lib-devel
|
BuildRequires: alsa-lib-devel
|
||||||
@ -1077,6 +1079,8 @@ pushd %{top_level_dir_name}
|
|||||||
%patch35 -p1
|
%patch35 -p1
|
||||||
%patch36 -p1
|
%patch36 -p1
|
||||||
%patch37 -p1
|
%patch37 -p1
|
||||||
|
%patch38 -p1
|
||||||
|
%patch39 -p1
|
||||||
popd # openjdk
|
popd # openjdk
|
||||||
|
|
||||||
%patch1000
|
%patch1000
|
||||||
@ -1579,6 +1583,10 @@ require "copy_jdk_configs.lua"
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Sep 8 2020 noah <hedongbo@huawei.com> - 1:11.0.8.10-6
|
||||||
|
- add fast-serializer-jdk11.patch
|
||||||
|
- add fix-jck-failure-on-FastSerializer.patch
|
||||||
|
|
||||||
* Mon Sep 7 2020 noah <hedongbo@huawei.com> - 1:11.0.8.10-5
|
* Mon Sep 7 2020 noah <hedongbo@huawei.com> - 1:11.0.8.10-5
|
||||||
- Delete some file header information
|
- Delete some file header information
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user