!10 add fast-serializer-jdk11.patch
Merge pull request !10 from jdkboy/master
This commit is contained in:
commit
cf68b41a89
628
fast-serializer-jdk11.patch
Normal file
628
fast-serializer-jdk11.patch
Normal file
@ -0,0 +1,628 @@
|
||||
commit cbbef85e20818d23651e553ad9915ec8225a3456
|
||||
Author: hexuejin <hexuejin2@huawei.com>
|
||||
Date: Thu May 28 11:04:16 2020 +0800
|
||||
|
||||
Add FastSerializer
|
||||
|
||||
DTS/AR: AR.SR.IREQ02369011.001.001
|
||||
Summary:<core-libs>: Add FastSerializer
|
||||
LLT: jtreg
|
||||
Patch Type: huawei
|
||||
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);
|
||||
157
generate_source_tarball.sh
Executable file
157
generate_source_tarball.sh
Executable file
@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
# Generates the 'source tarball' for JDK projects.
|
||||
#
|
||||
# Example:
|
||||
# When used from local repo set REPO_ROOT pointing to file:// with your repo
|
||||
# If your local repo follows upstream forests conventions, it may be enough to set OPENJDK_URL
|
||||
# If you want to use a local copy of patch PR3751, set the path to it in the PR3751 variable
|
||||
#
|
||||
# In any case you have to set PROJECT_NAME REPO_NAME and VERSION. eg:
|
||||
# PROJECT_NAME=jdk
|
||||
# REPO_NAME=jdk
|
||||
# VERSION=tip
|
||||
# or to eg prepare systemtap:
|
||||
# icedtea7's jstack and other tapsets
|
||||
# VERSION=6327cf1cea9e
|
||||
# REPO_NAME=icedtea7-2.6
|
||||
# PROJECT_NAME=release
|
||||
# OPENJDK_URL=http://icedtea.classpath.org/hg/
|
||||
# TO_COMPRESS="*/tapset"
|
||||
#
|
||||
# They are used to create correct name and are used in construction of sources url (unless REPO_ROOT is set)
|
||||
|
||||
# This script creates a single source tarball out of the repository
|
||||
# based on the given tag and removes code not allowed in fedora/rhel. For
|
||||
# consistency, the source tarball will always contain 'openjdk' as the top
|
||||
# level folder, name is created, based on parameter
|
||||
#
|
||||
|
||||
if [ ! "x$PR3751" = "x" ] ; then
|
||||
if [ ! -f "$PR3751" ] ; then
|
||||
echo "You have specified PR3751 as $PR3751 but it does not exist. Exiting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
OPENJDK_URL_DEFAULT=http://hg.openjdk.java.net
|
||||
COMPRESSION_DEFAULT=xz
|
||||
|
||||
if [ "x$1" = "xhelp" ] ; then
|
||||
echo -e "Behaviour may be specified by setting the following variables:\n"
|
||||
echo "VERSION - the version of the specified OpenJDK project"
|
||||
echo "PROJECT_NAME -- the name of the OpenJDK project being archived (optional; only needed by defaults)"
|
||||
echo "REPO_NAME - the name of the OpenJDK repository (optional; only needed by defaults)"
|
||||
echo "OPENJDK_URL - the URL to retrieve code from (optional; defaults to ${OPENJDK_URL_DEFAULT})"
|
||||
echo "COMPRESSION - the compression type to use (optional; defaults to ${COMPRESSION_DEFAULT})"
|
||||
echo "FILE_NAME_ROOT - name of the archive, minus extensions (optional; defaults to PROJECT_NAME-REPO_NAME-VERSION)"
|
||||
echo "REPO_ROOT - the location of the Mercurial repository to archive (optional; defaults to OPENJDK_URL/PROJECT_NAME/REPO_NAME)"
|
||||
echo "TO_COMPRESS - what part of clone to pack (default is openjdk)"
|
||||
echo "PR3751 - the path to the PR3751 patch to apply (optional; downloaded if unavailable)"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
|
||||
if [ "x$VERSION" = "x" ] ; then
|
||||
echo "No VERSION specified"
|
||||
exit -2
|
||||
fi
|
||||
echo "Version: ${VERSION}"
|
||||
|
||||
# REPO_NAME is only needed when we default on REPO_ROOT and FILE_NAME_ROOT
|
||||
if [ "x$FILE_NAME_ROOT" = "x" -o "x$REPO_ROOT" = "x" ] ; then
|
||||
if [ "x$PROJECT_NAME" = "x" ] ; then
|
||||
echo "No PROJECT_NAME specified"
|
||||
exit -1
|
||||
fi
|
||||
echo "Project name: ${PROJECT_NAME}"
|
||||
if [ "x$REPO_NAME" = "x" ] ; then
|
||||
echo "No REPO_NAME specified"
|
||||
exit -3
|
||||
fi
|
||||
echo "Repository name: ${REPO_NAME}"
|
||||
fi
|
||||
|
||||
if [ "x$OPENJDK_URL" = "x" ] ; then
|
||||
OPENJDK_URL=${OPENJDK_URL_DEFAULT}
|
||||
echo "No OpenJDK URL specified; defaulting to ${OPENJDK_URL}"
|
||||
else
|
||||
echo "OpenJDK URL: ${OPENJDK_URL}"
|
||||
fi
|
||||
|
||||
if [ "x$COMPRESSION" = "x" ] ; then
|
||||
# rhel 5 needs tar.gz
|
||||
COMPRESSION=${COMPRESSION_DEFAULT}
|
||||
fi
|
||||
echo "Creating a tar.${COMPRESSION} archive"
|
||||
|
||||
if [ "x$FILE_NAME_ROOT" = "x" ] ; then
|
||||
FILE_NAME_ROOT=${PROJECT_NAME}-${REPO_NAME}-${VERSION}
|
||||
echo "No file name root specified; default to ${FILE_NAME_ROOT}"
|
||||
fi
|
||||
if [ "x$REPO_ROOT" = "x" ] ; then
|
||||
REPO_ROOT="${OPENJDK_URL}/${PROJECT_NAME}/${REPO_NAME}"
|
||||
echo "No repository root specified; default to ${REPO_ROOT}"
|
||||
fi;
|
||||
|
||||
if [ "x$TO_COMPRESS" = "x" ] ; then
|
||||
TO_COMPRESS="openjdk"
|
||||
echo "No to be compressed targets specified, ; default to ${TO_COMPRESS}"
|
||||
fi;
|
||||
|
||||
if [ -d ${FILE_NAME_ROOT} ] ; then
|
||||
echo "exists exists exists exists exists exists exists "
|
||||
echo "reusing reusing reusing reusing reusing reusing "
|
||||
echo ${FILE_NAME_ROOT}
|
||||
else
|
||||
mkdir "${FILE_NAME_ROOT}"
|
||||
pushd "${FILE_NAME_ROOT}"
|
||||
echo "Cloning ${VERSION} root repository from ${REPO_ROOT}"
|
||||
hg clone ${REPO_ROOT} openjdk -r ${VERSION}
|
||||
popd
|
||||
fi
|
||||
pushd "${FILE_NAME_ROOT}"
|
||||
if [ -d openjdk/src ]; then
|
||||
pushd openjdk
|
||||
echo "Removing EC source code we don't build"
|
||||
CRYPTO_PATH=src/jdk.crypto.ec/share/native/libsunec/impl
|
||||
rm -vf ${CRYPTO_PATH}/ec2.h
|
||||
rm -vf ${CRYPTO_PATH}/ec2_163.c
|
||||
rm -vf ${CRYPTO_PATH}/ec2_193.c
|
||||
rm -vf ${CRYPTO_PATH}/ec2_233.c
|
||||
rm -vf ${CRYPTO_PATH}/ec2_aff.c
|
||||
rm -vf ${CRYPTO_PATH}/ec2_mont.c
|
||||
rm -vf ${CRYPTO_PATH}/ecp_192.c
|
||||
rm -vf ${CRYPTO_PATH}/ecp_224.c
|
||||
|
||||
echo "Syncing EC list with NSS"
|
||||
if [ "x$PR3751" = "x" ] ; then
|
||||
# get pr3751.patch (from http://icedtea.classpath.org/hg/icedtea11) from most correct tag
|
||||
# Do not push it or publish it (see http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=3751)
|
||||
echo "PR3751 not found. Downloading..."
|
||||
wget http://icedtea.classpath.org/hg/icedtea11/raw-file/tip/patches/pr3751.patch
|
||||
echo "Applying ${PWD}/pr3751.patch"
|
||||
patch -Np1 < pr3751.patch
|
||||
rm pr3751.patch
|
||||
else
|
||||
echo "Applying ${PR3751}"
|
||||
patch -Np1 < $PR3751
|
||||
fi;
|
||||
find . -name '*.orig' -exec rm -vf '{}' ';'
|
||||
popd
|
||||
fi
|
||||
|
||||
echo "Compressing remaining forest"
|
||||
if [ "X$COMPRESSION" = "Xxz" ] ; then
|
||||
SWITCH=cJf
|
||||
else
|
||||
SWITCH=czf
|
||||
fi
|
||||
TARBALL_NAME=${FILE_NAME_ROOT}.tar.${COMPRESSION}
|
||||
tar --exclude-vcs -$SWITCH ${TARBALL_NAME} $TO_COMPRESS
|
||||
mv ${TARBALL_NAME} ..
|
||||
popd
|
||||
echo "Done. You may want to remove the uncompressed version - $FILE_NAME_ROOT."
|
||||
|
||||
|
||||
@ -131,10 +131,15 @@
|
||||
%global top_level_dir_name %{origin}
|
||||
%global minorver 0
|
||||
%global buildver 10
|
||||
|
||||
%global project jdk-updates
|
||||
%global repo jdk11u
|
||||
%global revision jdk-11.0.8-ga
|
||||
%global full_revision %{project}-%{repo}-%{revision}
|
||||
# priority must be 7 digits in total
|
||||
# setting to 1, so debug ones can have 0
|
||||
%global priority 00000%{minorver}1
|
||||
%global fulljavaver %{majorver}.%{minorver}.%{securityver}
|
||||
%global newjavaver %{majorver}.%{minorver}.%{securityver}
|
||||
|
||||
%global javaver %{majorver}
|
||||
|
||||
@ -729,8 +734,8 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release}
|
||||
}
|
||||
|
||||
Name: java-%{javaver}-%{origin}
|
||||
Version: %{fulljavaver}.%{buildver}
|
||||
Release: 1
|
||||
Version: %{newjavaver}.%{buildver}
|
||||
Release: 2
|
||||
# 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
|
||||
# also included the epoch in their virtual provides. This created a
|
||||
@ -763,7 +768,7 @@ License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv
|
||||
URL: http://openjdk.java.net/
|
||||
|
||||
|
||||
Source0: openjdk-%{fulljavaver}-ga.tar.xz
|
||||
Source0: %{full_revision}.tar.xz
|
||||
|
||||
# Use 'icedtea_sync.sh' to update the following
|
||||
# They are based on code contained in the IcedTea project (3.x).
|
||||
@ -810,7 +815,7 @@ Patch26: ZGC-aarch64-fix-system-call-number-of-memfd_create.patch
|
||||
Patch27: ZGC-aarch64-fix-not-using-load-store-Pre-index.patch
|
||||
Patch28: address-s-offset-may-exceed-the-limit-of-ldrw-instru.patch
|
||||
Patch29: ZGC-reuse-entries-of-ResolvedMethodTable.patch
|
||||
|
||||
Patch30: fast-serializer-jdk11.patch
|
||||
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: alsa-lib-devel
|
||||
@ -843,7 +848,7 @@ BuildRequires: zip
|
||||
BuildRequires: unzip
|
||||
BuildRequires: javapackages-filesystem
|
||||
BuildRequires: java-%{buildjdkver}-openjdk-devel
|
||||
BuildRequires: tzdata-java >= 2019c
|
||||
BuildRequires: tzdata-java >= 2020a
|
||||
# Earlier versions have a bug in tree vectorization on PPC
|
||||
BuildRequires: gcc >= 4.8.3-8
|
||||
# Build requirements for SunEC system NSS support
|
||||
@ -1059,6 +1064,7 @@ pushd %{top_level_dir_name}
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
popd # openjdk
|
||||
|
||||
%patch1000
|
||||
@ -1352,7 +1358,7 @@ if ! echo $suffix | grep -q "debug" ; then
|
||||
# Install Javadoc documentation
|
||||
install -d -m 755 $RPM_BUILD_ROOT%{_javadocdir}
|
||||
cp -a %{buildoutputdir -- $suffix}/images/docs $RPM_BUILD_ROOT%{_javadocdir}/%{uniquejavadocdir -- $suffix}
|
||||
cp -a %{buildoutputdir -- $suffix}/bundles/jdk-%{fulljavaver}+%{buildver}-docs.zip $RPM_BUILD_ROOT%{_javadocdir}/%{uniquejavadocdir -- $suffix}.zip
|
||||
cp -a %{buildoutputdir -- $suffix}/bundles/jdk-%{newjavaver}+%{buildver}-docs.zip $RPM_BUILD_ROOT%{_javadocdir}/%{uniquejavadocdir -- $suffix}.zip
|
||||
fi
|
||||
|
||||
# Install icons and menu entries
|
||||
@ -1561,6 +1567,9 @@ require "copy_jdk_configs.lua"
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Jul 20 2020 jdkboy <guoge1@huawei.com> - 1:11.0.8.10-2
|
||||
- add fast-serializer-jdk11.patch
|
||||
|
||||
* Mon Jul 20 2020 noah <hedongbo@huawei.com> - 1:11.0.8.10-1
|
||||
- add ZGC-aarch64-fix-not-using-load-store-Pre-index.patch
|
||||
- add address-s-offset-may-exceed-the-limit-of-ldrw-instru.patch
|
||||
|
||||
BIN
jdk-updates-jdk11u-jdk-11.0.8-ga.tar.xz
Normal file
BIN
jdk-updates-jdk11u-jdk-11.0.8-ga.tar.xz
Normal file
Binary file not shown.
2
sources
Normal file
2
sources
Normal file
@ -0,0 +1,2 @@
|
||||
SHA512 (tapsets-icedtea-3.15.0.tar.xz) = c752a197cb3d812d50c35e11e4722772be40096c81d2a57933e0d9b8a3c708b9c157b8108a4e33a06ca7bb81648170994408c75d6f69d5ff12785d0c31009671
|
||||
SHA512 (jdk-updates-jdk11u-jdk-11.0.8-ga.tar.xz) = a78914b08fd4b935665a808bd383afa8ee8517454779df0aa1f2d83984cb230b5edff2d7826daaadc0891d3463e49911d90614523d6a42ad430b367a2e33093f
|
||||
42
update_package.sh
Normal file
42
update_package.sh
Normal file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash -x
|
||||
# this file contains defaults for currently generated source tarballs
|
||||
|
||||
set -e
|
||||
|
||||
# OpenJDK from Shenandoah project
|
||||
export PROJECT_NAME="jdk-updates"
|
||||
export REPO_NAME="jdk11u"
|
||||
# warning, clonning without shenadnaoh prefix, you will clone pure jdk - thus without shenandaoh GC
|
||||
export VERSION="jdk-11.0.8-ga"
|
||||
export COMPRESSION=xz
|
||||
# unset tapsets overrides
|
||||
export OPENJDK_URL=""
|
||||
export TO_COMPRESS=""
|
||||
# warning, filename and filenameroot creation is duplicated here from generate_source_tarball.sh
|
||||
export FILE_NAME_ROOT=${PROJECT_NAME}-${REPO_NAME}-${VERSION}
|
||||
FILENAME=${FILE_NAME_ROOT}.tar.${COMPRESSION}
|
||||
|
||||
if [ ! -f ${FILENAME} ] ; then
|
||||
echo "Generating ${FILENAME}"
|
||||
sh ./generate_source_tarball.sh
|
||||
else
|
||||
echo "exists exists exists exists exists exists exists "
|
||||
echo "reusing reusing reusing reusing reusing reusing "
|
||||
echo ${FILENAME}
|
||||
fi
|
||||
|
||||
set +e
|
||||
|
||||
major=`echo $REPO_NAME | sed 's/[a-zA-Z]*//g'`
|
||||
build=`echo $VERSION | sed 's/.*+//g'`
|
||||
name_helper=`echo $FILENAME | sed s/$major/'%{majorver}'/g `
|
||||
name_helper=`echo $name_helper | sed s/$build/'%{buildver}'/g `
|
||||
echo "align specfile acordingly:"
|
||||
echo " sed 's/^Source0:.*/Source0: $name_helper/' -i *.spec"
|
||||
echo " sed 's/^Source8:.*/Source8: $TAPSET/' -i *.spec"
|
||||
echo " sed 's/^%global buildver.*/%global buildver $build/' -i *.spec"
|
||||
echo " sed 's/Release:.*/Release: 1%{?dist}/' -i *.spec"
|
||||
echo "and maybe others...."
|
||||
echo "you should fedpkg/rhpkg new-sources $TAPSET $FILENAME"
|
||||
echo "you should fedpkg/rhpkg prep --arch XXXX on all architectures: x86_64 i386 i586 i686 ppc ppc64 ppc64le s390 s390x aarch64 armv7hl"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user