diff --git a/8080289-8040213-8189067-move-the-store-out-of-the-loop.patch b/8080289-8040213-8189067-move-the-store-out-of-the-loop.patch index 7697d4ec50397d6fa319702c96fcde79e966f65d..70b841b8bac5db2881372a73c4c8f78f1e25d080 100644 --- a/8080289-8040213-8189067-move-the-store-out-of-the-loop.patch +++ b/8080289-8040213-8189067-move-the-store-out-of-the-loop.patch @@ -1,12 +1,9 @@ From c2d7c271a60a6892bbbf7a2d585aa5b50c85bef1 Mon Sep 17 00:00:00 2001 -From: sunjianye Date: Sat, 23 May 2020 17:40:00 +0800 Subject: [PATCH] 8080289 8040213 8189067: move the store out of the loop -DTS/AR: AR.SR.IREQ02373832.002.001 Summary: : move the store out of the loop LLT: NA -Patch Type: backport Bug url: https://bugs.openjdk.java.net/browse/JDK-8080289 https://bugs.openjdk.java.net/browse/JDK-8040213 https://bugs.openjdk.java.net/browse/JDK-8189067 --- hotspot/src/share/vm/opto/loopnode.cpp | 2 +- diff --git a/8144993-Elide-redundant-memory-barrier-after-AllocationNode.patch b/8144993-Elide-redundant-memory-barrier-after-AllocationNode.patch index 424fd7b28b27e4edd1e9b76a1dd8eb4c3814222e..0254e94d68afe7d90e15e6a2dea4aea311b87c4f 100644 --- a/8144993-Elide-redundant-memory-barrier-after-AllocationNode.patch +++ b/8144993-Elide-redundant-memory-barrier-after-AllocationNode.patch @@ -1,13 +1,10 @@ From e938b66397096f88ef40f4fc3522a543f938267d Mon Sep 17 00:00:00 2001 -From: sunjianye Date: Sat, 23 May 2020 18:10:45 +0800 Subject: [PATCH] 8144993:Elide redundant memory barrier after AllocationNode and JDK:8139758 -DTS/AR: AR.SR.IREQ02373832.002.001 Summary: : Elide redundant memory barrier after AllocationNode LLT: NA -Patch Type: backport Bug url: https://bugs.openjdk.java.net/browse/JDK-8144993 https://bugs.openjdk.java.net/browse/JDK-8139758 --- hotspot/src/share/vm/opto/callnode.cpp | 18 ++++ diff --git a/8223504-improve-performance-of-forall-loops-by-better.patch b/8223504-improve-performance-of-forall-loops-by-better.patch index c142025c74f398dd5f278dfff0f9c2c84a925f94..ec574cd8a4b512d32008caaf03c06bf4029a3002 100644 --- a/8223504-improve-performance-of-forall-loops-by-better.patch +++ b/8223504-improve-performance-of-forall-loops-by-better.patch @@ -1,13 +1,10 @@ From c1d5b7c044ba418848c98d36ec21358a1dac568e Mon Sep 17 00:00:00 2001 -From: sunjianye Date: Sat, 23 May 2020 17:18:39 +0800 Subject: [PATCH] 8223504:improve performance of forall loops by better inlining of "iterator()" methods -DTS/AR: AR.SR.IREQ02373832.002.001 Summary: : improve performance of forall loops by better inlining of "iterator()" methods LLT: NA -Patch Type: backport Bug url: https://bugs.openjdk.java.net/browse/JDK-8223504 --- hotspot/src/share/vm/classfile/systemDictionary.hpp | 3 +++ diff --git a/add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch b/add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch index 4a879c5bda27c37903bed2af9978d29f7ad7e8a9..13233893e3560ae7f83057d6aacfe8751802c80b 100644 --- a/add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch +++ b/add-vm-option-BoxTypeCachedMax-for-Integer-and-Long-cache.patch @@ -1,12 +1,9 @@ From b5c192bb3dc57021996545b0bac822d73c75ec19 Mon Sep 17 00:00:00 2001 -From: sunjianye Date: Thu, 23 Apr 2020 16:12:34 +0800 Subject: [PATCH] add vm option BoxTypeCachedMax for Integer and Long cache -DTS/AR: AR.SR.IREQ02373832.002.001 Summary: < JDK> : add vm option BoxTypeCachedMax for Integer and Long cache LLT: NA -Patch Type: huawei Bug url: NA --- hotspot/src/share/vm/opto/c2_globals.hpp | 3 ++ diff --git a/fast-serializer-jdk8.patch b/fast-serializer-jdk8.patch new file mode 100644 index 0000000000000000000000000000000000000000..bf263ca7f0ce14bbed5a13c1008e7303071f466d --- /dev/null +++ b/fast-serializer-jdk8.patch @@ -0,0 +1,676 @@ +commit 3ece3b6a87e4bf61a1f786c12d796012becce313 +Date: Thu May 28 10:30:20 2020 +0800 + + Add FastSerializer + + Summary:: 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 +@@ -49,6 +49,7 @@ import sun.misc.SharedSecrets; + import sun.misc.JavaOISAccess; + import sun.util.logging.PlatformLogger; + import sun.security.action.GetBooleanAction; ++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,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. +@@ -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. ++ * + *

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> 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. ++ * + *

The corresponding method in ObjectOutputStream is + * annotateClass. 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; +@@ -1935,17 +2056,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.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,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 +@@ -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. ++ * + *

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. ++ * + *

Note that this method will only be called if the ObjectOutputStream + * is not using the old serialization stream format (set by calling + * ObjectOutputStream's useProtocolVersion 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 ++ */ ++ 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. +@@ -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/java/io/ObjectStreamConstants.java b/jdk/src/share/classes/java/io/ObjectStreamConstants.java +index 23f72b436..59179a6ec 100644 +--- a/jdk/src/share/classes/java/io/ObjectStreamConstants.java ++++ b/jdk/src/share/classes/java/io/ObjectStreamConstants.java +@@ -38,6 +38,11 @@ public interface ObjectStreamConstants { + */ + final static 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/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 diff --git a/java-1.8.0-openjdk.spec b/java-1.8.0-openjdk.spec index d466692ed6b4e03e9c5f334be1e459410f7842ca..0e99c0f2d677f1562b5a16322d977479ef7a087e 100644 --- a/java-1.8.0-openjdk.spec +++ b/java-1.8.0-openjdk.spec @@ -915,7 +915,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 2 +Release: 4 # 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 @@ -1043,6 +1043,7 @@ Patch102: fix-LongCache-s-range-when-BoxTypeCachedMax-number-is-bigger-than-Inte Patch103: Ddot-intrinsic-implement.patch Patch104: 8234003-Improve-IndexSet-iteration.patch Patch105: 8220159-Optimize-various-RegMask-operations-by-introducing-watermarks.patch +Patch106: fast-serializer-jdk8.patch ############################################# # @@ -1444,6 +1445,7 @@ pushd %{top_level_dir_name} %patch103 -p1 %patch104 -p1 %patch105 -p1 +%patch106 -p1 popd @@ -2064,6 +2066,12 @@ require "copy_jdk_configs.lua" %endif %changelog +* Tue Sep 8 2020 noah - 1:1.8.0.265-b10.4 +- add fast-serializer-jdk8.patch + +* Mon Sep 7 2020 noah - 1:1.8.0.265-b10.3 +- Delete some file header information + * Mon Sep 1 2020 jdkboy - 1:1.8.0.265-b10.2 - Remove fast-serializer-jdk8.patch