diff --git a/6896810-Pin.java-fails-with-OOME-during-System.out.p.patch b/6896810-Pin.java-fails-with-OOME-during-System.out.p.patch new file mode 100644 index 0000000000000000000000000000000000000000..e3f41f0642c1071839b48ad04cf2f79293befe65 --- /dev/null +++ b/6896810-Pin.java-fails-with-OOME-during-System.out.p.patch @@ -0,0 +1,26 @@ +From 5462717718cd9d3bed0d866ae47fe5ab9fdcf5e6 Mon Sep 17 00:00:00 2001 +Date: Fri, 28 Aug 2020 15:02:16 +0800 +Subject: [PATCH] 6896810: Pin.java fails with OOME during System.out.println + +Summary: : Pin.java fails with OOME during System.out.println +LLT: jdk8u/jdk/test/java/lang/ref/SoftReference/Pin.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-6896810 huaweijdk/jdk8u-dev#2472 +--- + jdk/test/java/lang/ref/SoftReference/Pin.java | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/jdk/test/java/lang/ref/SoftReference/Pin.java b/jdk/test/java/lang/ref/SoftReference/Pin.java +index dbdf9be1b..38cd56da2 100644 +--- a/jdk/test/java/lang/ref/SoftReference/Pin.java ++++ b/jdk/test/java/lang/ref/SoftReference/Pin.java +@@ -76,6 +76,7 @@ public class Pin { + Thread.sleep(100); // yield, for what it's worth + } + } catch (OutOfMemoryError e) { ++ chain = null; // Free memory for further work. + System.err.println("Got OutOfMemoryError, as expected."); + } + +-- +2.12.3 + diff --git a/8046294-Generate-the-4-byte-timestamp-randomly.patch b/8046294-Generate-the-4-byte-timestamp-randomly.patch deleted file mode 100644 index c0477ed090c392f6198df05cbff97293d89b704c..0000000000000000000000000000000000000000 --- a/8046294-Generate-the-4-byte-timestamp-randomly.patch +++ /dev/null @@ -1,87 +0,0 @@ -diff --git a/jdk/src/share/classes/sun/security/ssl/RandomCookie.java b/jdk/src/share/classes/sun/security/ssl/RandomCookie.java -index 5f414c408..ce27f0df4 100644 ---- a/jdk/src/share/classes/sun/security/ssl/RandomCookie.java -+++ b/jdk/src/share/classes/sun/security/ssl/RandomCookie.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -41,21 +41,8 @@ final class RandomCookie { - byte random_bytes[]; // exactly 32 bytes - - RandomCookie(SecureRandom generator) { -- long temp = System.currentTimeMillis() / 1000; -- int gmt_unix_time; -- if (temp < Integer.MAX_VALUE) { -- gmt_unix_time = (int) temp; -- } else { -- gmt_unix_time = Integer.MAX_VALUE; // Whoops! -- } -- - random_bytes = new byte[32]; - generator.nextBytes(random_bytes); -- -- random_bytes[0] = (byte)(gmt_unix_time >> 24); -- random_bytes[1] = (byte)(gmt_unix_time >> 16); -- random_bytes[2] = (byte)(gmt_unix_time >> 8); -- random_bytes[3] = (byte)gmt_unix_time; - } - - RandomCookie(HandshakeInStream m) throws IOException { -@@ -68,22 +55,15 @@ final class RandomCookie { - } - - void print(PrintStream s) { -- int i, gmt_unix_time; -- -- gmt_unix_time = random_bytes[0] << 24; -- gmt_unix_time += random_bytes[1] << 16; -- gmt_unix_time += random_bytes[2] << 8; -- gmt_unix_time += random_bytes[3]; -- -- s.print("GMT: " + gmt_unix_time + " "); -- s.print("bytes = { "); -- -- for (i = 4; i < 32; i++) { -- if (i != 4) { -- s.print(", "); -+ s.print("random_bytes = {"); -+ for (int i = 0; i < 32; i++) { -+ int k = random_bytes[i] & 0xFF; -+ if (i != 0) { -+ s.print(' '); - } -- s.print(random_bytes[i] & 0x0ff); -+ s.print(Utilities.hexDigits[k >>> 4]); -+ s.print(Utilities.hexDigits[k & 0xf]); - } -- s.println(" }"); -+ s.println("}"); - } - } -diff --git a/jdk/src/share/classes/sun/security/ssl/Utilities.java b/jdk/src/share/classes/sun/security/ssl/Utilities.java -index aefb02c9a..9b267f6e1 100644 ---- a/jdk/src/share/classes/sun/security/ssl/Utilities.java -+++ b/jdk/src/share/classes/sun/security/ssl/Utilities.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -33,6 +33,11 @@ import sun.net.util.IPAddressUtil; - * A utility class to share the static methods. - */ - final class Utilities { -+ /** -+ * hex digits -+ */ -+ static final char[] hexDigits = "0123456789ABCDEF".toCharArray(); -+ - /** - * Puts {@code hostname} into the {@code serverNames} list. - *

diff --git a/8048210-8056152-fix-assert-fail-for-an-InnocuousThre.patch b/8048210-8056152-fix-assert-fail-for-an-InnocuousThre.patch new file mode 100644 index 0000000000000000000000000000000000000000..a58ee5d6cb11b5d618d8ad3a2a00adb2ee748c7e --- /dev/null +++ b/8048210-8056152-fix-assert-fail-for-an-InnocuousThre.patch @@ -0,0 +1,39 @@ +From d4fc164f500d86fcec9302d9b71a830c34888680 Mon Sep 17 00:00:00 2001 +Date: Wed, 12 Aug 2020 15:26:59 +0000 +Subject: [PATCH] 8048210 8056152: fix assert fail for an InnocuousThread + +Summary: : fix assert fail for an InnocuousThread +LLT: jdk8u/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8048210 https://bugs.openjdk.java.net/browse/JDK-8056152 +--- + jdk/src/share/classes/sun/misc/InnocuousThread.java | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/jdk/src/share/classes/sun/misc/InnocuousThread.java b/jdk/src/share/classes/sun/misc/InnocuousThread.java +index 3acd9424c..e585a9c0b 100644 +--- a/jdk/src/share/classes/sun/misc/InnocuousThread.java ++++ b/jdk/src/share/classes/sun/misc/InnocuousThread.java +@@ -70,6 +70,7 @@ public final class InnocuousThread extends Thread { + public InnocuousThread(Runnable target) { + super(INNOCUOUSTHREADGROUP, target, newName()); + UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); ++ UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader()); + eraseThreadLocals(); + } + +@@ -81,12 +82,6 @@ public final class InnocuousThread extends Thread { + } + + @Override +- public ClassLoader getContextClassLoader() { +- // always report system class loader +- return ClassLoader.getSystemClassLoader(); +- } +- +- @Override + public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { + // silently fail + } +-- +2.12.3 + 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/8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch b/8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch deleted file mode 100644 index 47340d046a525635f1e339a226338360c0477712..0000000000000000000000000000000000000000 --- a/8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch +++ /dev/null @@ -1,180 +0,0 @@ -From be0206e834bab370da41cf9ec9e6b9be710e1987 Mon Sep 17 00:00:00 2001 -Date: Fri, 19 Apr 2019 17:40:19 +0000 -Subject: [PATCH] 8148754: C2 loop unrolling fails due to unexpected graph shape - -Summary: C2 loop unrolling fails due to unexpected graph shape -Bug url: https://bugs.openjdk.java.net/browse/JDK-8148754 ---- - hotspot/src/share/vm/opto/loopTransform.cpp | 44 ++++++++------------- - hotspot/src/share/vm/opto/loopnode.cpp | 36 +++++++++++++++++ - hotspot/src/share/vm/opto/loopnode.hpp | 3 ++ - hotspot/src/share/vm/opto/superword.cpp | 18 +++------ - 4 files changed, 61 insertions(+), 40 deletions(-) - -diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp -index e3637b652..f6783b910 100644 ---- a/hotspot/src/share/vm/opto/loopTransform.cpp -+++ b/hotspot/src/share/vm/opto/loopTransform.cpp -@@ -1222,21 +1222,14 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad - - Node *opaq = NULL; - if (adjust_min_trip) { // If not maximally unrolling, need adjustment -- // Search for zero-trip guard. -- assert( loop_head->is_main_loop(), "" ); -- assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); -- Node *iff = ctrl->in(0); -- assert( iff->Opcode() == Op_If, "" ); -- Node *bol = iff->in(1); -- assert( bol->Opcode() == Op_Bool, "" ); -- Node *cmp = bol->in(1); -- assert( cmp->Opcode() == Op_CmpI, "" ); -- opaq = cmp->in(2); -- // Occasionally it's possible for a zero-trip guard Opaque1 node to be -- // optimized away and then another round of loop opts attempted. -- // We can not optimize this particular loop in that case. -- if (opaq->Opcode() != Op_Opaque1) -- return; // Cannot find zero-trip guard! Bail out! -+ // Check the shape of the graph at the loop entry. If an inappropriate -+ // graph shape is encountered, the compiler bails out loop unrolling; -+ // compilation of the method will still succeed. -+ if (!is_canonical_main_loop_entry(loop_head)) { -+ return; -+ } -+ // get a not shared opaque' node for Zero-trip test -+ opaq = ctrl->in(0)->in(1)->in(1)->in(2); - // Zero-trip test uses an 'opaque' node which is not shared. - assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); - } -@@ -1806,7 +1799,6 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { - #endif - assert(RangeCheckElimination, ""); - CountedLoopNode *cl = loop->_head->as_CountedLoop(); -- assert(cl->is_main_loop(), ""); - - // protect against stride not being a constant - if (!cl->stride_is_con()) -@@ -1818,20 +1810,18 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { - // to not ever trip end tests - Node *main_limit = cl->limit(); - -+ // Check graph shape. Cannot optimize a loop if zero-trip -+ // Opaque1 node is optimized away and then another round -+ // of loop opts attempted. -+ if (!is_canonical_main_loop_entry(cl)) { -+ return; -+ } -+ - // Need to find the main-loop zero-trip guard - Node *ctrl = cl->in(LoopNode::EntryControl); -- assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); - Node *iffm = ctrl->in(0); -- assert(iffm->Opcode() == Op_If, ""); -- Node *bolzm = iffm->in(1); -- assert(bolzm->Opcode() == Op_Bool, ""); -- Node *cmpzm = bolzm->in(1); -- assert(cmpzm->is_Cmp(), ""); -- Node *opqzm = cmpzm->in(2); -- // Can not optimize a loop if zero-trip Opaque1 node is optimized -- // away and then another round of loop opts attempted. -- if (opqzm->Opcode() != Op_Opaque1) -- return; -+ // get the zero-trip Opaque1 node for testing the main limits -+ Node *opqzm = iffm->in(1)->in(1)->in(2); - assert(opqzm->in(1) == main_limit, "do not understand situation"); - - // Find the pre-loop limit; we will expand it's iterations to -diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp -index 37c56681d..e2c0645cf 100644 ---- a/hotspot/src/share/vm/opto/loopnode.cpp -+++ b/hotspot/src/share/vm/opto/loopnode.cpp -@@ -3284,6 +3284,42 @@ Node* PhaseIdealLoop::compute_lca_of_uses(Node* n, Node* early, bool verify) { - return LCA; - } - -+// Check the shape of the graph at the loop entry. In some cases, -+// the shape of the graph does not match the shape outlined below. -+// That is caused by the Opaque1 node "protecting" the shape of -+// the graph being removed by, for example, the IGVN performed -+// in PhaseIdealLoop::build_and_optimize(). -+// -+// After the Opaque1 node has been removed, optimizations (e.g., split-if, -+// loop unswitching, and IGVN, or a combination of them) can freely change -+// the graph's shape. As a result, the graph shape outlined below cannot -+// be guaranteed anymore. -+bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { -+ assert(cl->is_main_loop(), "check should be applied to main loops"); -+ Node* ctrl = cl->in(LoopNode::EntryControl); -+ if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { -+ return false; -+ } -+ Node* iffm = ctrl->in(0); -+ if (iffm == NULL || !iffm->is_If()) { -+ return false; -+ } -+ Node* bolzm = iffm->in(1); -+ if (bolzm == NULL || !bolzm->is_Bool()) { -+ return false; -+ } -+ Node* cmpzm = bolzm->in(1); -+ if (cmpzm == NULL || !cmpzm->is_Cmp()) { -+ return false; -+ } -+ // get the compare node, if null or not return false -+ Node* opqzm = cmpzm->in(2); -+ if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { -+ return false; -+ } -+ return true; -+} -+ - //------------------------------get_late_ctrl---------------------------------- - // Compute latest legal control. - Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) { -diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp -index 150d1be0f..558b10504 100644 ---- a/hotspot/src/share/vm/opto/loopnode.hpp -+++ b/hotspot/src/share/vm/opto/loopnode.hpp -@@ -621,6 +621,9 @@ private: - bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); - - public: -+ -+ static bool is_canonical_main_loop_entry(CountedLoopNode* cl); -+ - bool has_node( Node* n ) const { - guarantee(n != NULL, "No Node."); - return _nodes[n->_idx] != NULL; -diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp -index 0bc171b5c..a14210ee2 100644 ---- a/hotspot/src/share/vm/opto/superword.cpp -+++ b/hotspot/src/share/vm/opto/superword.cpp -@@ -2209,21 +2209,13 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) { - //----------------------------get_pre_loop_end--------------------------- - // Find pre loop end from main loop. Returns null if none. - CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { -- Node* ctrl = cl->in(LoopNode::EntryControl); -- if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; -- Node* iffm = ctrl->in(0); -- if (!iffm->is_If()) return NULL; -- Node* bolzm = iffm->in(1); -- if (!bolzm->is_Bool()) return NULL; -- Node* cmpzm = bolzm->in(1); -- if (!cmpzm->is_Cmp()) return NULL; -- Node* opqzm = cmpzm->in(2); -- // Can not optimize a loop if zero-trip Opaque1 node is optimized -- // away and then another round of loop opts attempted. -- if (opqzm->Opcode() != Op_Opaque1) { -+ // The loop cannot be optimized if the graph shape at -+ // the loop entry is inappropriate. -+ if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { - return NULL; - } -- Node* p_f = iffm->in(0); -+ -+ Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); - if (!p_f->is_IfFalse()) return NULL; - if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; - CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); --- -2.19.0 - diff --git a/8151788.patch b/8151788.patch deleted file mode 100644 index 4a91f72c9228cd20e9a42bc874d322f9736e4f5d..0000000000000000000000000000000000000000 --- a/8151788.patch +++ /dev/null @@ -1,93 +0,0 @@ -From bf24abe7a9499638a43dfd03fecfbfb763430a63 Mon Sep 17 00:00:00 2001 -Date: Thu, 27 Jun 2019 11:24:39 +0000 -Subject: [PATCH] Backport of JDK-8151788 - -summary: NullPointerException from ntlm.Client.type3 -LLT: -Bug url: https://bugs.openjdk.java.net/browse/JDK-8151788 ---- - .../classes/com/sun/security/ntlm/NTLM.java | 2 +- - .../www/protocol/http/NULLTargetInfoTest.java | 58 +++++++++++++++++++ - 2 files changed, 59 insertions(+), 1 deletion(-) - create mode 100644 jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java - -diff --git a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java -index da18e2199a..249cd226c4 100644 ---- a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java -+++ b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java -@@ -167,7 +167,7 @@ class NTLM { - - byte[] readSecurityBuffer(int offset) throws NTLMException { - int pos = readInt(offset+4); -- if (pos == 0) return null; -+ if (pos == 0) return new byte[0]; - try { - return Arrays.copyOfRange( - internal, pos, pos + readShort(offset)); -diff --git a/jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java b/jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java -new file mode 100644 -index 0000000000..d8e88554f8 ---- /dev/null -+++ b/jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+/* -+ * @test -+ * @bug 8151788 -+ * @summary NullPointerException from ntlm.Client.type3 -+ * @modules java.base/com.sun.security.ntlm -+ * @run main NULLTargetInfoTest -+ */ -+import com.sun.security.ntlm.Client; -+ -+public class NULLTargetInfoTest { -+ -+ public static void main(String[] args) throws Exception { -+ Client c = new Client(null, "host", "user", "domain", "pass".toCharArray()); -+ c.type1(); -+ // this input does have the 0x800000 bit(NTLMSSP_NEGOTIATE_TARGET_INFO) set -+ // but after offset 40 all eight bytes are all zero which means there is no -+ // security buffer for target info. -+ byte[] type2 = hex( -+ "4E 54 4C 4D 53 53 50 00 02 00 00 00 00 00 00 00" -+ + "00 00 00 00 05 82 89 00 0B 87 81 B6 2D 6E 8B C1" -+ + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); -+ byte[] nonce = new byte[10]; -+ c.type3(type2, nonce); -+ } -+ -+ private static byte[] hex(String str) { -+ str = str.replaceAll("\\s", ""); -+ byte[] response = new byte[str.length() / 2]; -+ int index = 0; -+ for (int i = 0; i < str.length(); i += 2) { -+ response[index++] = Integer.valueOf(str.substring(i, i + 2), 16).byteValue(); -+ } -+ return response; -+ } -+} --- -2.19.0-rc1 - diff --git a/8160425-Vectorization-with-signalling-NaN-returns-wr.patch b/8160425-Vectorization-with-signalling-NaN-returns-wr.patch new file mode 100644 index 0000000000000000000000000000000000000000..45e07389985f2df94206b58f55fde48fdc2845f0 --- /dev/null +++ b/8160425-Vectorization-with-signalling-NaN-returns-wr.patch @@ -0,0 +1,257 @@ +From c10681e2567e34426759a73a7af8fe6809a8db09 Mon Sep 17 00:00:00 2001 +Date: Fri, 28 Aug 2020 09:51:37 +0800 +Subject: [PATCH] 8160425: Vectorization with signalling NaN returns wrong + result + +Summary: : Should not use doubles/floats for vector constants in the C code +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8160425 +--- + hotspot/src/cpu/sparc/vm/sparc.ad | 10 ++- + hotspot/src/cpu/x86/vm/x86.ad | 10 ++- + hotspot/src/share/vm/asm/assembler.hpp | 9 +++ + hotspot/src/share/vm/opto/compile.cpp | 3 + + hotspot/src/share/vm/opto/compile.hpp | 9 +++ + .../test/compiler/vectorization/TestNaNVector.java | 84 ++++++++++++++++++++++ + 6 files changed, 113 insertions(+), 12 deletions(-) + create mode 100644 hotspot/test/compiler/vectorization/TestNaNVector.java + +diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad +index 20ec462a7..c8763c411 100644 +--- a/hotspot/src/cpu/sparc/vm/sparc.ad ++++ b/hotspot/src/cpu/sparc/vm/sparc.ad +@@ -720,7 +720,7 @@ intptr_t get_offset_from_base_2(const MachNode* n, const TypePtr* atype, int dis + return offset; + } + +-static inline jdouble replicate_immI(int con, int count, int width) { ++static inline jlong replicate_immI(int con, int count, int width) { + // Load a constant replicated "count" times with width "width" + assert(count*width == 8 && width <= 4, "sanity"); + int bit_width = width * 8; +@@ -729,17 +729,15 @@ static inline jdouble replicate_immI(int con, int count, int width) { + for (int i = 0; i < count - 1; i++) { + val |= (val << bit_width); + } +- jdouble dval = *((jdouble*) &val); // coerce to double type +- return dval; ++ return val; + } + +-static inline jdouble replicate_immF(float con) { ++static inline jlong replicate_immF(float con) { + // Replicate float con 2 times and pack into vector. + int val = *((int*)&con); + jlong lval = val; + lval = (lval << 32) | (lval & 0xFFFFFFFFl); +- jdouble dval = *((jdouble*) &lval); // coerce to double type +- return dval; ++ return lval; + } + + // Standard Sparc opcode form2 field breakdown +diff --git a/hotspot/src/cpu/x86/vm/x86.ad b/hotspot/src/cpu/x86/vm/x86.ad +index 36d6d96ae..48a0b95b4 100644 +--- a/hotspot/src/cpu/x86/vm/x86.ad ++++ b/hotspot/src/cpu/x86/vm/x86.ad +@@ -856,7 +856,7 @@ static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, + return 5+offset_size; + } + +-static inline jfloat replicate4_imm(int con, int width) { ++static inline jint replicate4_imm(int con, int width) { + // Load a constant of "width" (in bytes) and replicate it to fill 32bit. + assert(width == 1 || width == 2, "only byte or short types here"); + int bit_width = width * 8; +@@ -866,11 +866,10 @@ static inline jfloat replicate4_imm(int con, int width) { + val |= (val << bit_width); + bit_width <<= 1; + } +- jfloat fval = *((jfloat*) &val); // coerce to float type +- return fval; ++ return val; + } + +-static inline jdouble replicate8_imm(int con, int width) { ++static inline jlong replicate8_imm(int con, int width) { + // Load a constant of "width" (in bytes) and replicate it to fill 64bit. + assert(width == 1 || width == 2 || width == 4, "only byte, short or int types here"); + int bit_width = width * 8; +@@ -880,8 +879,7 @@ static inline jdouble replicate8_imm(int con, int width) { + val |= (val << bit_width); + bit_width <<= 1; + } +- jdouble dval = *((jdouble*) &val); // coerce to double type +- return dval; ++ return val; + } + + #ifndef PRODUCT +diff --git a/hotspot/src/share/vm/asm/assembler.hpp b/hotspot/src/share/vm/asm/assembler.hpp +index 889dd361d..ec72bc3a1 100644 +--- a/hotspot/src/share/vm/asm/assembler.hpp ++++ b/hotspot/src/share/vm/asm/assembler.hpp +@@ -368,6 +368,15 @@ class AbstractAssembler : public ResourceObj { + // + // We must remember the code section (insts or stubs) in c1 + // so we can reset to the proper section in end_a_const(). ++ address int_constant(jint c) { ++ CodeSection* c1 = _code_section; ++ address ptr = start_a_const(sizeof(c), sizeof(c)); ++ if (ptr != NULL) { ++ emit_int32(c); ++ end_a_const(c1); ++ } ++ return ptr; ++ } + address long_constant(jlong c) { + CodeSection* c1 = _code_section; + address ptr = start_a_const(sizeof(c), sizeof(c)); +diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp +index 8e14f1d5a..34e97286e 100644 +--- a/hotspot/src/share/vm/opto/compile.cpp ++++ b/hotspot/src/share/vm/opto/compile.cpp +@@ -3739,6 +3739,7 @@ bool Compile::Constant::operator==(const Constant& other) { + if (can_be_reused() != other.can_be_reused()) return false; + // For floating point values we compare the bit pattern. + switch (type()) { ++ case T_INT: + case T_FLOAT: return (_v._value.i == other._v._value.i); + case T_LONG: + case T_DOUBLE: return (_v._value.j == other._v._value.j); +@@ -3753,6 +3754,7 @@ bool Compile::Constant::operator==(const Constant& other) { + + static int type_to_size_in_bytes(BasicType t) { + switch (t) { ++ case T_INT: return sizeof(jint ); + case T_LONG: return sizeof(jlong ); + case T_FLOAT: return sizeof(jfloat ); + case T_DOUBLE: return sizeof(jdouble); +@@ -3821,6 +3823,7 @@ void Compile::ConstantTable::emit(CodeBuffer& cb) { + Constant con = _constants.at(i); + address constant_addr = NULL; + switch (con.type()) { ++ case T_INT: constant_addr = _masm.int_constant( con.get_jint() ); break; + case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; + case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; + case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; +diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp +index e4985acc7..60da8587b 100644 +--- a/hotspot/src/share/vm/opto/compile.hpp ++++ b/hotspot/src/share/vm/opto/compile.hpp +@@ -203,6 +203,7 @@ class Compile : public Phase { + + BasicType type() const { return _type; } + ++ jint get_jint() const { return _v._value.i; } + jlong get_jlong() const { return _v._value.j; } + jfloat get_jfloat() const { return _v._value.f; } + jdouble get_jdouble() const { return _v._value.d; } +@@ -259,6 +260,14 @@ class Compile : public Phase { + Constant add(MachConstantNode* n, BasicType type, jvalue value); + Constant add(Metadata* metadata); + Constant add(MachConstantNode* n, MachOper* oper); ++ Constant add(MachConstantNode* n, jint i) { ++ jvalue value; value.i = i; ++ return add(n, T_INT, value); ++ } ++ Constant add(MachConstantNode* n, jlong j) { ++ jvalue value; value.j = j; ++ return add(n, T_LONG, value); ++ } + Constant add(MachConstantNode* n, jfloat f) { + jvalue value; value.f = f; + return add(n, T_FLOAT, value); +diff --git a/hotspot/test/compiler/vectorization/TestNaNVector.java b/hotspot/test/compiler/vectorization/TestNaNVector.java +new file mode 100644 +index 000000000..302657951 +--- /dev/null ++++ b/hotspot/test/compiler/vectorization/TestNaNVector.java +@@ -0,0 +1,84 @@ ++/* ++ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/** ++ * @test ++ * @bug 8160425 ++ * @summary Test vectorization with a signalling NaN. ++ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-OptimizeFill TestNaNVector ++ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-OptimizeFill -XX:MaxVectorSize=4 TestNaNVector ++ */ ++public class TestNaNVector { ++ private char[] array; ++ private static final int LEN = 1024; ++ ++ public static void main(String args[]) { ++ TestNaNVector test = new TestNaNVector(); ++ // Check double precision NaN ++ for (int i = 0; i < 10_000; ++i) { ++ test.vectorizeNaNDP(); ++ } ++ System.out.println("Checking double precision Nan"); ++ test.checkResult(0xfff7); ++ ++ // Check single precision NaN ++ for (int i = 0; i < 10_000; ++i) { ++ test.vectorizeNaNSP(); ++ } ++ System.out.println("Checking single precision Nan"); ++ test.checkResult(0xff80); ++ } ++ ++ public TestNaNVector() { ++ array = new char[LEN]; ++ } ++ ++ public void vectorizeNaNDP() { ++ // This loop will be vectorized and the array store will be replaced by ++ // a 64-bit vector store to four subsequent array elements. The vector ++ // should look like this '0xfff7fff7fff7fff7' and is read from the constant ++ // table. However, in floating point arithmetic this is a signalling NaN ++ // which may be converted to a quiet NaN when processed by the x87 FPU. ++ // If the signalling bit is set, the vector ends up in the constant table ++ // as '0xfffffff7fff7fff7' which leads to an incorrect result. ++ for (int i = 0; i < LEN; ++i) { ++ array[i] = 0xfff7; ++ } ++ } ++ ++ public void vectorizeNaNSP() { ++ // Same as above but with single precision ++ for (int i = 0; i < LEN; ++i) { ++ array[i] = 0xff80; ++ } ++ } ++ ++ public void checkResult(int expected) { ++ for (int i = 0; i < LEN; ++i) { ++ if (array[i] != expected) { ++ throw new RuntimeException("Invalid result: array[" + i + "] = " + (int)array[i] + " != " + expected); ++ } ++ } ++ } ++} ++ +-- +2.12.3 + diff --git a/8161072.patch b/8161072.patch deleted file mode 100644 index 3393688571db7079930bbabf705de7a169c01738..0000000000000000000000000000000000000000 --- a/8161072.patch +++ /dev/null @@ -1,57 +0,0 @@ -From e42367ab7ce5d66823ef32ea00dbc5e44e3b20d1 Mon Sep 17 00:00:00 2001 -Date: Tue, 28 May 2019 21:38:21 +0000 -Subject: [PATCH] 8161072: AArch64: jtreg compiler/uncommontrap/TestDeoptOOM failure - -Summary: -Bug url: https://bugs.openjdk.java.net/browse/JDK-8161072 - ---- - .../cpu/aarch64/vm/templateInterpreter_aarch64.cpp | 25 +++++++++++----------- - 1 file changed, 12 insertions(+), 13 deletions(-) - -diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp -index 8dede4b74..566ddd173 100644 ---- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp -+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp -@@ -223,19 +223,6 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, - __ restore_locals(); - __ restore_constant_pool_cache(); - __ get_method(rmethod); -- -- // handle exceptions -- { -- Label L; -- __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); -- __ cbz(rscratch1, L); -- __ call_VM(noreg, -- CAST_FROM_FN_PTR(address, -- InterpreterRuntime::throw_pending_exception)); -- __ should_not_reach_here(); -- __ bind(L); -- } -- - __ get_dispatch(); - - // Calculate stack limit -@@ -253,6 +240,18 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, - // NULL last_sp until next java call - __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize)); - -+ // handle exceptions -+ { -+ Label L; -+ __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); -+ __ cbz(rscratch1, L); -+ __ call_VM(noreg, -+ CAST_FROM_FN_PTR(address, -+ InterpreterRuntime::throw_pending_exception)); -+ __ should_not_reach_here(); -+ __ bind(L); -+ } -+ - __ dispatch_next(state, step); - return entry; - } --- -2.12.3 - diff --git a/8171537.patch b/8171537.patch deleted file mode 100644 index 5e2d6c59384bb6a42484be29f52a7214416bf8a1..0000000000000000000000000000000000000000 --- a/8171537.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 26c54187c40901643d0cf65a985c98ddcee40bf0 Mon Sep 17 00:00:00 2001 -Date: Fri, 19 Apr 2019 17:42:56 +0000 -Subject: [PATCH] 8171537: aarch64: compiler/c1/Test6849574.java generates guarantee failure in C1 - -Bug url: https://bugs.openjdk.java.net/browse/JDK-8171537 - ---- - hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp -index 6e225870e..e536ce649 100644 ---- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp -+++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp -@@ -3199,7 +3199,7 @@ void LIR_Assembler::peephole(LIR_List *lir) { - } - - void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp_op) { -- Address addr = as_Address(src->as_address_ptr(), noreg); -+ Address addr = as_Address(src->as_address_ptr(), as_reg(tmp_op)); - BasicType type = src->type(); - bool is_oop = type == T_OBJECT || type == T_ARRAY; - --- -2.19.0 - diff --git a/8181503-Can-t-compile-hotspot-with-c-11.patch b/8181503-Can-t-compile-hotspot-with-c-11.patch new file mode 100644 index 0000000000000000000000000000000000000000..74b48a7ea95db64cd0ecbabf5830b742325bb76e --- /dev/null +++ b/8181503-Can-t-compile-hotspot-with-c-11.patch @@ -0,0 +1,69 @@ +From c36e8cdc5f1175a3f2a771194434d76324d8cdbb Mon Sep 17 00:00:00 2001 +Date: Fri, 17 Apr 2020 17:42:09 +0000 +Subject: [PATCH] 8181503: Can't compile hotspot with c++11 + +Summary: : fix c++11 compiler issues +LLT: N/A +Bug url: https://bugs.openjdk.java.net/browse/JDK-8181503 +--- + hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp | 6 +++--- + hotspot/src/share/vm/code/compiledIC.cpp | 2 +- + hotspot/src/share/vm/utilities/vmError.cpp | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +index 018feea1..935a16b5 100644 +--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp ++++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +@@ -281,11 +281,11 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + address os::current_stack_pointer() { + #if defined(__clang__) || defined(__llvm__) + register void *esp; +- __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp)); ++ __asm__("mov %%" SPELL_REG_SP ", %0":"=r"(esp)); + return (address) esp; + #elif defined(SPARC_WORKS) + register void *esp; +- __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp)); ++ __asm__("mov %%" SPELL_REG_SP ", %0":"=r"(esp)); + return (address) ((char*)esp + sizeof(long)*2); + #else + register void *esp __asm__ (SPELL_REG_SP); +@@ -368,7 +368,7 @@ frame os::get_sender_for_C_frame(frame* fr) { + intptr_t* _get_previous_fp() { + #if defined(SPARC_WORKS) || defined(__clang__) || defined(__llvm__) + register intptr_t **ebp; +- __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp)); ++ __asm__("mov %%" SPELL_REG_FP ", %0":"=r"(ebp)); + #else + register intptr_t **ebp __asm__ (SPELL_REG_FP); + #endif +diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp +index 63821c06..06794215 100644 +--- a/hotspot/src/share/vm/code/compiledIC.cpp ++++ b/hotspot/src/share/vm/code/compiledIC.cpp +@@ -222,7 +222,7 @@ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod + assert(bytecode == Bytecodes::_invokeinterface, ""); + int itable_index = call_info->itable_index(); + entry = VtableStubs::find_itable_stub(itable_index); +- if (entry == false) { ++ if (entry == NULL) { + return false; + } + #ifdef ASSERT +diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp +index e5aad6ff..23d495d9 100644 +--- a/hotspot/src/share/vm/utilities/vmError.cpp ++++ b/hotspot/src/share/vm/utilities/vmError.cpp +@@ -399,7 +399,7 @@ void VMError::report(outputStream* st) { + + STEP(15, "(printing type of error)") + +- switch(_id) { ++ switch(static_cast(_id)) { + case OOM_MALLOC_ERROR: + case OOM_MMAP_ERROR: + if (_size) { +-- +2.19.0 + diff --git a/8203481-Incorrect-constraint-for-unextended_sp-in-frame-safe_for_sender.patch b/8203481-Incorrect-constraint-for-unextended_sp-in-frame-safe_for_sender.patch deleted file mode 100644 index 2c65f8243d8406b2c03da315d0ba72189bd4aa9e..0000000000000000000000000000000000000000 --- a/8203481-Incorrect-constraint-for-unextended_sp-in-frame-safe_for_sender.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp -index 65a441240..1e534d3da 100644 ---- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp -+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp -@@ -71,10 +71,20 @@ bool frame::safe_for_sender(JavaThread *thread) { - return false; - } - -- // unextended sp must be within the stack and above or equal sp -- bool unextended_sp_safe = (unextended_sp < thread->stack_base()) && -- (unextended_sp >= sp); -+ // When we are running interpreted code the machine stack pointer, SP, is -+ // set low enough so that the Java expression stack can grow and shrink -+ // without ever exceeding the machine stack bounds. So, ESP >= SP. - -+ // When we call out of an interpreted method, SP is incremented so that -+ // the space between SP and ESP is removed. The SP saved in the callee's -+ // frame is the SP *before* this increment. So, when we walk a stack of -+ // interpreter frames the sender's SP saved in a frame might be less than -+ // the SP at the point of call. -+ -+ // So unextended sp must be within the stack but we need not to check -+ // that unextended sp >= sp -+ -+ bool unextended_sp_safe = (unextended_sp < thread->stack_base()); - if (!unextended_sp_safe) { - return false; - } diff --git a/8203699-java-lang-invoke-SpecialInte.patch b/8203699-java-lang-invoke-SpecialInte.patch deleted file mode 100644 index 35439d663323adfdc6c38172e79fd62aac44d81e..0000000000000000000000000000000000000000 --- a/8203699-java-lang-invoke-SpecialInte.patch +++ /dev/null @@ -1,40 +0,0 @@ -From f9f94ca5422ae79bf4ed90f41b7698febc6bed24 Mon Sep 17 00:00:00 2001 -Date: Fri, 12 Jul 2019 15:26:27 +0000 -Subject: [PATCH] Backport of JDK-8203699: java/lang/invoke/SpecialInterfaceCall fails with SIGILL on aarch64 - -summary: Get super_klass value into r0 to make check in VerifyMethodHandles success -LLT: jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java -Bug url: https://bugs.openjdk.java.net/browse/JDK-8203699 - ---- - .../src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 6 +- - 1 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp -index 42b732f37a..4659d628db 100644 ---- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp -+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp -@@ -1208,7 +1208,6 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, - assert(sub_klass != r0, "killed reg"); // killed by mov(r0, super) - assert(sub_klass != r2, "killed reg"); // killed by lea(r2, &pst_counter) - -- // Get super_klass value into r0 (even if it was in r5 or r2). - RegSet pushed_registers; - if (!IS_A_TEMP(r2)) pushed_registers += r2; - if (!IS_A_TEMP(r5)) pushed_registers += r5; -@@ -1219,6 +1218,11 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, - - push(pushed_registers, sp); - -+ // Get super_klass value into r0 (even if it was in r5 or r2) -+ if (super_klass != r0) { -+ mov(r0, super_klass); -+ } -+ - #ifndef PRODUCT - mov(rscratch2, (address)&SharedRuntime::_partial_subtype_ctr); - Address pst_counter_addr(rscratch2); -diff --git a/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java --- -2.12.3 - diff --git a/8205921-Optimizing-best-of-2-work-stealing-queue-selection.patch b/8205921-Optimizing-best-of-2-work-stealing-queue-selection.patch index 0e6ceb821059dd3915f578b48190e6060f2f87c4..597588bbb75d0e44af853884ba37a691c5f290d8 100644 --- a/8205921-Optimizing-best-of-2-work-stealing-queue-selection.patch +++ b/8205921-Optimizing-best-of-2-work-stealing-queue-selection.patch @@ -174,9 +174,9 @@ index 28dd5aad..271b33a5 100644 if (_cm->verbose_medium()) { gclog_or_tty->print_cr("[%u] stolen " PTR_FORMAT " successfully", _worker_id, p2i((void*) obj)); -@@ -4605,7 +4605,7 @@ CMTask::CMTask(uint worker_id, - : _g1h(G1CollectedHeap::heap()), +@@ -4612,7 +4614,7 @@ CMTask::CMTask(uint worker_id, _worker_id(worker_id), _cm(cm), + _objArray_processor(this), _claimed(false), - _nextMarkBitMap(NULL), _hash_seed(17), + _nextMarkBitMap(NULL), 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/8231631-sun-net-ftp-FtpURLConnectionLeak.java-fails-.patch b/8231631-sun-net-ftp-FtpURLConnectionLeak.java-fails-.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6ab18eba802e9684c74556590107401c641ae6b --- /dev/null +++ b/8231631-sun-net-ftp-FtpURLConnectionLeak.java-fails-.patch @@ -0,0 +1,30 @@ +From 0a3958872fd70590976b185e086eec3f461b27c4 Mon Sep 17 00:00:00 2001 +Date: Fri, 28 Aug 2020 09:28:23 +0800 +Subject: [PATCH] 8231631: sun/net/ftp/FtpURLConnectionLeak.java fails + intermittently with NPE + +Summary: : sun/net/www/ftptest/FtpCommandHandler.java is modified to handle EOF properly +LLT: jdk8u/jdk/test/sun/net/ftp/FtpURLConnectionLeak.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8231631 #2468 +--- + jdk/test/sun/net/www/ftptest/FtpCommandHandler.java | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java b/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java +index 151b3df8e..f6c87d5a4 100644 +--- a/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java ++++ b/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java +@@ -458,6 +458,10 @@ public class FtpCommandHandler extends Thread { + try { + str = in.readLine(); + System.out.println("line: " + str); ++ if (str == null) { ++ System.out.println("EOF read from input"); ++ break; ++ } + buf = new StringBuffer(str); + res = parseCmd(buf); + switch (res) { +-- +2.12.3 + diff --git a/8243670-Unexpected-test-result-caused-by-C2-MergeMem.patch b/8243670-Unexpected-test-result-caused-by-C2-MergeMem.patch new file mode 100644 index 0000000000000000000000000000000000000000..6139bd60194e1bac4434d465bb20505e839eebe9 --- /dev/null +++ b/8243670-Unexpected-test-result-caused-by-C2-MergeMem.patch @@ -0,0 +1,193 @@ +From 3276b4d8d066703d3abc81e3a7815d1c03474af2 Mon Sep 17 00:00:00 2001 +Date: Wed, 19 Aug 2020 17:43:46 +0000 +Subject: [PATCH] 8243670:Unexpected test result caused by C2 + MergeMemNode::Ideal + +Summary: : +LLT: hotspot/test/compiler/c2/TestReplaceEquivPhis.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8243670 +--- + hotspot/src/share/vm/opto/cfgnode.cpp | 24 +++++++ + hotspot/src/share/vm/opto/memnode.cpp | 20 +----- + hotspot/src/share/vm/opto/type.hpp | 7 ++ + hotspot/test/compiler/c2/TestReplaceEquivPhis.java | 77 ++++++++++++++++++++++ + 4 files changed, 109 insertions(+), 19 deletions(-) + create mode 100644 hotspot/test/compiler/c2/TestReplaceEquivPhis.java + +diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp +index dd5a5ec41..f3d223fbd 100644 +--- a/hotspot/src/share/vm/opto/cfgnode.cpp ++++ b/hotspot/src/share/vm/opto/cfgnode.cpp +@@ -1156,6 +1156,30 @@ Node *PhiNode::Identity( PhaseTransform *phase ) { + if (id != NULL) return id; + } + ++ // Looking for phis with identical inputs. If we find one that has ++ // type TypePtr::BOTTOM, replace the current phi with the bottom phi. ++ if (phase->is_IterGVN() && type() == Type::MEMORY && adr_type() != ++ TypePtr::BOTTOM && !adr_type()->is_known_instance()) { ++ uint phi_len = req(); ++ Node* phi_reg = region(); ++ for (DUIterator_Fast imax, i = phi_reg->fast_outs(imax); i < imax; i++) { ++ Node* u = phi_reg->fast_out(i); ++ if (u->is_Phi() && u->as_Phi()->type() == Type::MEMORY && ++ u->adr_type() == TypePtr::BOTTOM && u->in(0) == phi_reg && ++ u->req() == phi_len) { ++ for (uint j = 1; j < phi_len; j++) { ++ if (in(j) != u->in(j)) { ++ u = NULL; ++ break; ++ } ++ } ++ if (u != NULL) { ++ return u; ++ } ++ } ++ } ++ } ++ + return this; // No identity + } + +diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp +index 68a13dbd8..f2a2ee6a2 100644 +--- a/hotspot/src/share/vm/opto/memnode.cpp ++++ b/hotspot/src/share/vm/opto/memnode.cpp +@@ -4418,25 +4418,7 @@ Node *MergeMemNode::Ideal(PhaseGVN *phase, bool can_reshape) { + new_mem = old_mmem->memory_at(i); + } + // else preceding memory was not a MergeMem +- +- // replace equivalent phis (unfortunately, they do not GVN together) +- if (new_mem != NULL && new_mem != new_base && +- new_mem->req() == phi_len && new_mem->in(0) == phi_reg) { +- if (new_mem->is_Phi()) { +- PhiNode* phi_mem = new_mem->as_Phi(); +- for (uint i = 1; i < phi_len; i++) { +- if (phi_base->in(i) != phi_mem->in(i)) { +- phi_mem = NULL; +- break; +- } +- } +- if (phi_mem != NULL) { +- // equivalent phi nodes; revert to the def +- new_mem = new_base; +- } +- } +- } +- ++ + // maybe store down a new value + Node* new_in = new_mem; + if (new_in == new_base) new_in = empty_mem; +diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp +index a9352345e..321d79914 100644 +--- a/hotspot/src/share/vm/opto/type.hpp ++++ b/hotspot/src/share/vm/opto/type.hpp +@@ -431,6 +431,8 @@ public: + return exact_kls != NULL; + } + ++ virtual bool is_known_instance() const { return false; } ++ + private: + // support arrays + static const Type* _zero_type[T_CONFLICT+1]; +@@ -1332,6 +1334,11 @@ public: + return _ptrtype; + } + ++ bool is_known_instance() const { ++ return _ptrtype->is_known_instance(); ++ } ++ ++ + #ifndef PRODUCT + virtual void dump2( Dict &d, uint depth, outputStream *st ) const; + #endif +diff --git a/hotspot/test/compiler/c2/TestReplaceEquivPhis.java b/hotspot/test/compiler/c2/TestReplaceEquivPhis.java +new file mode 100644 +index 000000000..d4c93b390 +--- /dev/null ++++ b/hotspot/test/compiler/c2/TestReplaceEquivPhis.java +@@ -0,0 +1,77 @@ ++/* ++ * Copyright (c) 2020, Huawei Technologies Co. Ltd. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/** ++ * @test ++ * @bug 8243670 ++ * @summary Unexpected test result caused by C2 MergeMemNode::Ideal ++ * ++ * @run main/othervm -Xcomp -XX:-SplitIfBlocks ++ * -XX:CompileOnly=compiler.c2.TestReplaceEquivPhis::test ++ * -XX:-BackgroundCompilation compiler.c2.TestReplaceEquivPhis ++ */ ++ ++package compiler.c2; ++ ++public class TestReplaceEquivPhis { ++ ++ public static final int N = 400; ++ public static volatile int instanceCount = 0; ++ public int iFld = 0; ++ public static int iArrFld[] = new int[N]; ++ ++ public int test() { ++ int v = 0; ++ boolean bArr[] = new boolean[N]; ++ ++ for (int i = 1; i < 344; i++) { ++ iFld = i; ++ for (int j = 2; j <177 ; j++) { ++ v = iFld; ++ iFld = TestReplaceEquivPhis.instanceCount; ++ TestReplaceEquivPhis.iArrFld[i] = 0; ++ iFld += TestReplaceEquivPhis.instanceCount; ++ TestReplaceEquivPhis.iArrFld[i] = 0; ++ bArr[j] = false; ++ TestReplaceEquivPhis.instanceCount = 1; ++ ++ for (int k = 1; k < 3; k++) { ++ // do nothing ++ } ++ } ++ } ++ return v; ++ } ++ ++ public static void main(String[] args) { ++ TestReplaceEquivPhis obj = new TestReplaceEquivPhis(); ++ for (int i = 0; i < 5; i++) { ++ int result = obj.test(); ++ if (result != 2) { ++ throw new RuntimeException("Test failed."); ++ } ++ } ++ System.out.println("Test passed."); ++ } ++ ++} +-- +2.12.3 + diff --git a/Extend-CDS-to-support-app-class-metadata-sharing.patch b/Extend-CDS-to-support-app-class-metadata-sharing.patch new file mode 100644 index 0000000000000000000000000000000000000000..9c5484f76a8b2dd1ceedbfd0744a7a9644080672 --- /dev/null +++ b/Extend-CDS-to-support-app-class-metadata-sharing.patch @@ -0,0 +1,747 @@ +diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp +index 6d62380..58d9116 100644 +--- a/hotspot/src/share/vm/classfile/classFileParser.cpp ++++ b/hotspot/src/share/vm/classfile/classFileParser.cpp +@@ -3939,7 +3939,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, + #if INCLUDE_CDS + if (DumpLoadedClassList != NULL && cfs->source() != NULL && classlist_file->is_open()) { + // Only dump the classes that can be stored into CDS archive +- if (SystemDictionaryShared::is_sharing_possible(loader_data)) { ++ // unless AppCDS is enabled ++ if (_host_klass == NULL && SystemDictionaryShared::is_sharing_possible(loader_data)) { + if (name != NULL) { + ResourceMark rm(THREAD); + classlist_file->print_cr("%s", name->as_C_string()); +diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp +index b9f46df..c7c0f53 100644 +--- a/hotspot/src/share/vm/classfile/classLoader.cpp ++++ b/hotspot/src/share/vm/classfile/classLoader.cpp +@@ -1203,8 +1203,8 @@ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) { + + h = context.record_result(classpath_index, e, result, THREAD); + } else { +- if (DumpSharedSpaces) { +- tty->print_cr("Preload Warning: Cannot find %s", class_name); ++ if (!UseAppCDS && DumpSharedSpaces) { ++ tty->print_cr("Preload Warning: Cannot find %s", class_name); // No need for AppCDS + } + } + +diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp +index 5c6b094..61140d3 100644 +--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp ++++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp +@@ -175,6 +175,16 @@ bool SystemDictionary::is_ext_class_loader(Handle class_loader) { + return (class_loader->klass()->name() == vmSymbols::sun_misc_Launcher_ExtClassLoader()); + } + ++/** ++ * Returns true if the passed class loader is the application class loader. ++ */ ++bool SystemDictionary::is_app_class_loader(Handle class_loader) { ++ if (class_loader.is_null()) { ++ return false; ++ } ++ return (class_loader->klass()->name() == vmSymbols::sun_misc_Launcher_AppClassLoader()); ++} ++ + // ---------------------------------------------------------------------------- + // Resolving of classes + +@@ -336,7 +346,8 @@ Klass* SystemDictionary::resolve_super_or_fail(Symbol* child_name, + // Bugs 4643874, 4715493 + // compute_hash can have a safepoint + +- ClassLoaderData* loader_data = class_loader_data(class_loader); ++ // class loader may be not registered yet, so use register_loader, which will return a valid classloaderData anyway. ++ ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL); + unsigned int d_hash = dictionary()->compute_hash(child_name, loader_data); + int d_index = dictionary()->hash_to_index(d_hash); + unsigned int p_hash = placeholders()->compute_hash(child_name, loader_data); +@@ -526,7 +537,8 @@ instanceKlassHandle SystemDictionary::handle_parallel_super_load( + Handle protection_domain, Handle lockObject, TRAPS) { + + instanceKlassHandle nh = instanceKlassHandle(); // null Handle +- ClassLoaderData* loader_data = class_loader_data(class_loader); ++ // class loader may be not registered yet, so use register_loader, which will return a valid classloaderData anyway. ++ ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL); + unsigned int d_hash = dictionary()->compute_hash(name, loader_data); + int d_index = dictionary()->hash_to_index(d_hash); + unsigned int p_hash = placeholders()->compute_hash(name, loader_data); +@@ -1074,6 +1086,19 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name, + return k(); + } + ++static char* convert_into_package_name(char* name) { ++ char* index = strrchr(name, '/'); ++ if (index == NULL) { ++ return NULL; ++ } else { ++ *index = '\0'; // chop to just the package name ++ while ((index = strchr(name, '/')) != NULL) { ++ *index = '.'; // replace '/' with '.' in package name ++ } ++ return name; ++ } ++} ++ + static bool is_prohibited_package_slow(Symbol* class_name) { + // Caller has ResourceMark + int length; +@@ -1147,12 +1172,9 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name, + // It is illegal to define classes in the "java." package from + // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader + char* name = parsed_name->as_C_string(); +- char* index = strrchr(name, '/'); +- assert(index != NULL, "must be"); +- *index = '\0'; // chop to just the package name +- while ((index = strchr(name, '/')) != NULL) { +- *index = '.'; // replace '/' with '.' in package name +- } ++ name = convert_into_package_name(name); ++ assert(name != NULL, "must be"); ++ + const char* fmt = "Prohibited package name: %s"; + size_t len = strlen(fmt) + strlen(name); + char* message = NEW_RESOURCE_ARRAY(char, len); +@@ -1217,12 +1240,62 @@ Klass* SystemDictionary::find_shared_class(Symbol* class_name) { + + instanceKlassHandle SystemDictionary::load_shared_class( + Symbol* class_name, Handle class_loader, TRAPS) { +- instanceKlassHandle ik (THREAD, find_shared_class(class_name)); +- // Make sure we only return the boot class for the NULL classloader. +- if (ik.not_null() && +- SharedClassUtil::is_shared_boot_class(ik()) && class_loader.is_null()) { +- Handle protection_domain; +- return load_shared_class(ik, class_loader, protection_domain, THREAD); ++ if (!(class_loader.is_null() || SystemDictionary::is_app_class_loader(class_loader) || ++ SystemDictionary::is_ext_class_loader(class_loader))) { ++ return instanceKlassHandle(); ++ } ++ ++ instanceKlassHandle ik (THREAD, find_shared_class(class_name)); // InstanceKlass is find with null class loader. ++ if (ik.not_null()) { ++ if (!UseAppCDS) { ++ // CDS logic ++ if (SharedClassUtil::is_shared_boot_class(ik()) && class_loader.is_null()) { ++ // CDS record boot class load index. ++ Handle protection_domain; ++ return load_shared_class(ik, class_loader, protection_domain, THREAD); ++ } ++ } else { ++ // AppCDS logic. Only use null loader only to load classes that ++ // have been dumped by null loader. For non-null class loaders, ++ // either the class loader data is not initialized (but also not ++ // null) or the same class loader is used to load previously ++ // defined class ++ bool bFound = false; ++ if (class_loader.is_null()) { ++ // condition1: Bootstrap class loader loaded ++ bFound = (ik()->class_loader_data() == NULL || ik()->class_loader_data()->is_the_null_class_loader_data()); ++ } else if (ik()->class_loader_data() != NULL) { ++ // condition2: App Class Loader ++ // condition3: ExtClass Loader ++ // Condition4: not fake class Loader, real one ++ bFound = ((ik->has_fake_loader_data_App() && SystemDictionary::is_app_class_loader(class_loader)) || ++ (ik->has_fake_loader_data_Ext() && SystemDictionary::is_ext_class_loader(class_loader)) || ++ (!ik->has_fake_loader_data() && ik()->class_loader() == class_loader())); ++ } ++ if (!bFound) { ++ return instanceKlassHandle(); ++ } ++ ++ // get protection domain for this class if not loaded by null class loader ++ if (class_loader.not_null()) { ++ ResourceMark rm(THREAD); ++ char* name = ik->name()->as_C_string(); ++ Handle klass_name = java_lang_String::create_from_str(name, CHECK_0); ++ JavaValue result(T_OBJECT); ++ ++ // ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader()); ++ JavaCalls::call_virtual(&result, ++ class_loader, ++ KlassHandle(THREAD, SystemDictionary::URLClassLoader_klass()), ++ vmSymbols::getProtectionDomainInternal_name(), ++ vmSymbols::getProtectionDomainInternal_signature(), ++ klass_name, ++ THREAD); ++ return load_shared_class(ik, class_loader, Handle(THREAD, (oop) result.get_jobject()), THREAD); ++ } else { ++ return load_shared_class(ik, class_loader, Handle(), THREAD); ++ } ++ } + } + return instanceKlassHandle(); + } +@@ -1298,6 +1371,7 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik, + + if (DumpLoadedClassList != NULL && classlist_file->is_open()) { + // Only dump the classes that can be stored into CDS archive ++ // unless AppCDS is enabled + if (SystemDictionaryShared::is_sharing_possible(loader_data)) { + ResourceMark rm(THREAD); + classlist_file->print_cr("%s", ik->name()->as_C_string()); +@@ -1308,6 +1382,32 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik, + // notify a class loaded from shared object + ClassLoadingService::notify_class_loaded(InstanceKlass::cast(ik()), + true /* shared class */); ++ ++ // register package for this class, if necessary ++ if (UseAppCDS && class_loader.not_null()) { ++ ++ ResourceMark rm(THREAD); ++ char* name = ik->name()->as_C_string(); ++ name = convert_into_package_name(name); ++ if (name != NULL) { ++ // not a default package ++ Handle package_name = java_lang_String::create_from_str(name, CHECK_0); ++ // The digital 4 is used only once, indicating the parameter number of ++ // the method invoked in JavaCalls::call_virtual ++ JavaCallArguments args(4); ++ args.push_oop(class_loader); ++ args.push_oop(package_name); ++ args.push_oop(Handle()); ++ args.push_oop(Handle()); ++ JavaValue result(T_VOID); ++ JavaCalls::call_virtual(&result, ++ KlassHandle(THREAD, SystemDictionary::URLClassLoader_klass()), ++ vmSymbols::definePackageInternal_name(), ++ vmSymbols::definePackageInternal_signature(), ++ &args, ++ CHECK_0); ++ } ++ } + } + return ik; + } +@@ -2167,7 +2267,6 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash, + // yet and these will be ignored. + Klass* SystemDictionary::find_constrained_instance_or_array_klass( + Symbol* class_name, Handle class_loader, TRAPS) { +- + // First see if it has been loaded directly. + // Force the protection domain to be null. (This removes protection checks.) + Handle no_protection_domain; +diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp +index 6f0b38a..cab7381 100644 +--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp ++++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp +@@ -649,6 +649,7 @@ public: + Handle class_loader, + TRAPS); + static bool is_ext_class_loader(Handle class_loader); ++ static bool is_app_class_loader(Handle class_loader); + + protected: + static Klass* find_shared_class(Symbol* class_name); +diff --git a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp +index e1adf8b..a8dbda2 100644 +--- a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp ++++ b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp +@@ -35,13 +35,25 @@ public: + static instanceKlassHandle find_or_load_shared_class(Symbol* class_name, + Handle class_loader, + TRAPS) { ++ if (UseAppCDS) { ++ instanceKlassHandle ik = load_shared_class(class_name, class_loader, CHECK_NULL); ++ if (!ik.is_null()) { ++ instanceKlassHandle nh = instanceKlassHandle(); // null Handle ++ ik = find_or_define_instance_class(class_name, class_loader, ik, CHECK_(nh)); ++ } ++ return ik; ++ } + return instanceKlassHandle(); + } + static void roots_oops_do(OopClosure* blk) {} + static void oops_do(OopClosure* f) {} ++ + static bool is_sharing_possible(ClassLoaderData* loader_data) { + oop class_loader = loader_data->class_loader(); +- return (class_loader == NULL); ++ return (class_loader == NULL || ++ (UseAppCDS && (SystemDictionary::is_app_class_loader(class_loader) || ++ SystemDictionary::is_ext_class_loader(class_loader))) ++ ); + } + + static size_t dictionary_entry_size() { +diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp +index f72a948..6bd8dbe 100644 +--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp ++++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp +@@ -418,8 +418,8 @@ + template(getFileURL_signature, "(Ljava/io/File;)Ljava/net/URL;") \ + template(definePackageInternal_name, "definePackageInternal") \ + template(definePackageInternal_signature, "(Ljava/lang/String;Ljava/util/jar/Manifest;Ljava/net/URL;)V") \ +- template(getProtectionDomain_name, "getProtectionDomain") \ +- template(getProtectionDomain_signature, "(Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;") \ ++ template(getProtectionDomainInternal_name, "getProtectionDomainInternal") \ ++ template(getProtectionDomainInternal_signature, "(Ljava/lang/String;)Ljava/security/ProtectionDomain;") \ + template(url_code_signer_array_void_signature, "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \ + template(resolved_references_name, "") \ + template(referencequeue_null_name, "NULL") \ +diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp +index 644e3b1..0f3c076 100644 +--- a/hotspot/src/share/vm/memory/filemap.cpp ++++ b/hotspot/src/share/vm/memory/filemap.cpp +@@ -344,12 +344,12 @@ bool FileMapInfo::init_from_file(int fd) { + + // Read the FileMapInfo information from the file. + bool FileMapInfo::open_for_read() { +- _full_path = Arguments::GetSharedArchivePath(); ++ _full_path = make_log_name(Arguments::GetSharedArchivePath(), NULL); + int fd = open(_full_path, O_RDONLY | O_BINARY, 0); + if (fd < 0) { + if (errno == ENOENT) { + // Not locating the shared archive is ok. +- fail_continue("Specified shared archive not found."); ++ fail_continue("Specified shared archive not found. archive file path:%s", _full_path); + } else { + fail_continue("Failed to open shared archive file (%s).", + strerror(errno)); +@@ -366,7 +366,7 @@ bool FileMapInfo::open_for_read() { + // Write the FileMapInfo information to the file. + + void FileMapInfo::open_for_write() { +- _full_path = Arguments::GetSharedArchivePath(); ++ _full_path = make_log_name(Arguments::GetSharedArchivePath(), NULL); + if (PrintSharedSpaces) { + tty->print_cr("Dumping shared data to file: "); + tty->print_cr(" %s", _full_path); +diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp +index d5826d6..f3c3c51 100644 +--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp ++++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp +@@ -677,14 +677,9 @@ void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) { + SystemDictionary::classes_do(check_one_shared_class); + } while (_check_classes_made_progress); + +- if (IgnoreUnverifiableClassesDuringDump) { +- // This is useful when running JCK or SQE tests. You should not +- // enable this when running real apps. +- SystemDictionary::remove_classes_in_error_state(); +- } else { +- tty->print_cr("Please remove the unverifiable classes from your class list and try again"); +- exit(1); +- } ++ // record error message, remove error state, and continue to dump jsa file ++ tty->print_cr("Please remove the unverifiable classes from your class list and try again"); ++ SystemDictionary::remove_classes_in_error_state(); + } + + // Copy the dependencies from C_HEAP-alloced GrowableArrays to RO-alloced +@@ -803,8 +798,12 @@ int MetaspaceShared::preload_and_dump(const char * class_list_path, + // Got a class name - load it. + TempNewSymbol class_name_symbol = SymbolTable::new_permanent_symbol(class_name, THREAD); + guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol."); ++ ++ Handle loader = UseAppCDS ? SystemDictionary::java_system_loader() : Handle(); + Klass* klass = SystemDictionary::resolve_or_null(class_name_symbol, +- THREAD); ++ loader, ++ Handle(), ++ THREAD); + CLEAR_PENDING_EXCEPTION; + if (klass != NULL) { + if (PrintSharedSpaces && Verbose && WizardMode) { +@@ -824,8 +823,8 @@ int MetaspaceShared::preload_and_dump(const char * class_list_path, + guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class"); + + class_count++; +- } else { +- //tty->print_cr("Preload failed: %s", class_name); ++ } else if (UseAppCDS) { ++ tty->print_cr("Preload failed: %s", class_name); + } + } + fclose(file); +diff --git a/hotspot/src/share/vm/oops/arrayKlass.cpp b/hotspot/src/share/vm/oops/arrayKlass.cpp +index 2d2e44b..129bce6 100644 +--- a/hotspot/src/share/vm/oops/arrayKlass.cpp ++++ b/hotspot/src/share/vm/oops/arrayKlass.cpp +@@ -195,6 +195,12 @@ void ArrayKlass::remove_unshareable_info() { + Klass::remove_unshareable_info(); + // Clear the java mirror + set_component_mirror(NULL); ++ ++ if (_higher_dimension != NULL) { ++ ArrayKlass *ak = ArrayKlass::cast(higher_dimension()); ++ ak->remove_unshareable_info(); ++ } ++ _higher_dimension = NULL; + } + + void ArrayKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { +diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp +index 98a11fe..4502a01 100644 +--- a/hotspot/src/share/vm/oops/constantPool.cpp ++++ b/hotspot/src/share/vm/oops/constantPool.cpp +@@ -180,6 +180,20 @@ void ConstantPool::restore_unshareable_info(TRAPS) { + } + + void ConstantPool::remove_unshareable_info() { ++ if (UseAppCDS) { ++ if (cache() != NULL) { ++ cache()->reset(); ++ } ++ for (int i = 0; i < _length; i++) { ++ if (tag_at(i).is_klass()) { ++ Klass* resolvedKlass = resolved_klass_at(i); ++ ResourceMark rm; ++ char* name = resolvedKlass->name()->as_C_string(); ++ int len = strlen(name); ++ unresolved_klass_at_put(i, resolvedKlass->name()); ++ } ++ } ++ } + // Resolved references are not in the shared archive. + // Save the length for restoration. It is not necessarily the same length + // as reference_map.length() if invokedynamic is saved. +diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp +index cda9a4e..ebcf3d6 100644 +--- a/hotspot/src/share/vm/oops/cpCache.cpp ++++ b/hotspot/src/share/vm/oops/cpCache.cpp +@@ -673,3 +673,16 @@ void ConstantPoolCache::verify_on(outputStream* st) { + // print constant pool cache entries + for (int i = 0; i < length(); i++) entry_at(i)->verify(st); + } ++ ++void ConstantPoolCache::reset() { ++ for (int i = 0; i < length(); i++) { ++ ConstantPoolCacheEntry* entry = entry_at(i); ++ int cp_index = entry->constant_pool_index(); ++ if (!entry->is_initial_resolved_ref_index()) { ++ // constant pool cache after initialization contains ++ // placeholders fr handling invokedynamic and invokehandle - ++ // these need to be preserved and all other entries reset ++ entry->initialize_entry(cp_index); ++ } ++ } ++} +diff --git a/hotspot/src/share/vm/oops/cpCache.hpp b/hotspot/src/share/vm/oops/cpCache.hpp +index a4a6c3f..48f9bbd 100644 +--- a/hotspot/src/share/vm/oops/cpCache.hpp ++++ b/hotspot/src/share/vm/oops/cpCache.hpp +@@ -360,7 +360,14 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC { + bool is_double() const { return flag_state() == dtos; } + TosState flag_state() const { assert((uint)number_of_states <= (uint)tos_state_mask+1, ""); + return (TosState)((_flags >> tos_state_shift) & tos_state_mask); } +- ++ bool is_initial_resolved_ref_index() const { ++ if (_flags == 0 && _f1 == NULL && bytecode_1() == Bytecodes::_nop && bytecode_2() == Bytecodes::_nop) { ++ return true; ++ } else { ++ return false; ++ } ++ } ++ + // Code generation support + static WordSize size() { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); } + static ByteSize size_in_bytes() { return in_ByteSize(sizeof(ConstantPoolCacheEntry)); } +@@ -480,6 +487,8 @@ class ConstantPoolCache: public MetaspaceObj { + void dump_cache(); + #endif // INCLUDE_JVMTI + ++ void reset(); ++ + // Deallocate - no fields to deallocate + DEBUG_ONLY(bool on_stack() { return false; }) + void deallocate_contents(ClassLoaderData* data) {} +diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp +index 6f881ac..6d67113 100644 +--- a/hotspot/src/share/vm/oops/instanceKlass.cpp ++++ b/hotspot/src/share/vm/oops/instanceKlass.cpp +@@ -2452,6 +2452,22 @@ void InstanceKlass::remove_unshareable_info() { + m->remove_unshareable_info(); + } + ++ if (UseAppCDS) { ++ if (_oop_map_cache != NULL) { ++ delete _oop_map_cache; ++ _oop_map_cache = NULL; ++ } ++ ++ JNIid::deallocate(jni_ids()); ++ set_jni_ids(NULL); ++ ++ jmethodID* jmeths = methods_jmethod_ids_acquire(); ++ if (jmeths != (jmethodID*)NULL) { ++ release_set_methods_jmethod_ids(NULL); ++ FreeHeap(jmeths); ++ } ++ } ++ + // do array classes also. + array_klasses_do(remove_unshareable_in_class); + } +diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp +index ba20471..399290f 100644 +--- a/hotspot/src/share/vm/oops/klass.cpp ++++ b/hotspot/src/share/vm/oops/klass.cpp +@@ -63,6 +63,9 @@ void Klass::set_is_cloneable() { + } + } + ++ClassLoaderData *Klass::_fake_loader_data_App = reinterpret_cast(0xFDFDFDFA); ++ClassLoaderData *Klass::_fake_loader_data_Ext = reinterpret_cast(0xFDFDFDFB); ++ + void Klass::set_name(Symbol* n) { + _name = n; + if (_name != NULL) _name->increment_refcount(); +@@ -536,8 +539,21 @@ void Klass::remove_unshareable_info() { + set_java_mirror(NULL); + set_next_link(NULL); + +- // Null out class_loader_data because we don't share that yet. +- set_class_loader_data(NULL); ++ if (!UseAppCDS) { ++ // CDS logic ++ set_class_loader_data(NULL); ++ } else if (class_loader_data() != NULL) { ++ // AppCDS logic ++ if (class_loader() == NULL) { ++ // Null out class loader data for classes loaded by bootstrap (null) loader ++ set_class_loader_data(NULL); ++ } else if(SystemDictionary::is_ext_class_loader(class_loader())) { ++ // Mark class loaded by system class loader ++ set_class_loader_data(_fake_loader_data_Ext); ++ } else { ++ set_class_loader_data(_fake_loader_data_App); ++ } ++ } + } + + void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { +@@ -545,7 +561,10 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec + // If an exception happened during CDS restore, some of these fields may already be + // set. We leave the class on the CLD list, even if incomplete so that we don't + // modify the CLD list outside a safepoint. +- if (class_loader_data() == NULL) { ++ if (class_loader_data() == NULL || has_fake_loader_data()) { ++ // CDS should not set fake loader data ++ assert(!has_fake_loader_data() || (has_fake_loader_data() && UseAppCDS), ++ "setting fake loader data possible only with AppCDS enabled"); + // Restore class_loader_data + set_class_loader_data(loader_data); + +diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp +index 428df42..cb7640c 100644 +--- a/hotspot/src/share/vm/oops/klass.hpp ++++ b/hotspot/src/share/vm/oops/klass.hpp +@@ -188,6 +188,10 @@ private: + // -1. + jshort _shared_class_path_index; + ++ // This is used only during AppCDS to mark classes that have non-null class loader ++ static ClassLoaderData* _fake_loader_data_App; ++ static ClassLoaderData* _fake_loader_data_Ext; ++ + friend class SharedClassUtil; + protected: + +@@ -202,6 +206,10 @@ protected: + enum StaticLookupMode { find_static, skip_static }; + enum PrivateLookupMode { find_private, skip_private }; + ++ bool has_fake_loader_data_App() { return class_loader_data() == _fake_loader_data_App; } ++ bool has_fake_loader_data_Ext() { return class_loader_data() == _fake_loader_data_Ext; } ++ bool has_fake_loader_data() { return (has_fake_loader_data_App() || has_fake_loader_data_Ext()); } ++ + bool is_klass() const volatile { return true; } + + // super +diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp +index f9b6bd3..a04dcac 100644 +--- a/hotspot/src/share/vm/runtime/arguments.cpp ++++ b/hotspot/src/share/vm/runtime/arguments.cpp +@@ -3020,6 +3020,23 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, + // Remaining part of option string + const char* tail; + ++ // Special handling for UseAppCDS flag - it has to enable ++ // SharedArviveFile flag no matter where it's located in the ++ // argument list (and in order to enable UseAppCDS) ++ for (int index = 0; index < args->nOptions; index++) { ++ const JavaVMOption* option = args->options + index; ++ if (match_option(option, "-XX:+UseAppCDS", &tail)) { ++ if (!process_argument("+UseAppCDS", args->ignoreUnrecognized, origin)) { ++ return JNI_EINVAL; ++ } else { ++ const char* n = "SharedArchiveFile"; ++ Flag* shared_archive_flag = Flag::find_flag(n, strlen(n), true, true); ++ shared_archive_flag->unlock_diagnostic(); ++ FLAG_SET_CMDLINE(bool, UseAppCDS, true); ++ } ++ } ++ } ++ + // iterate over arguments + for (int index = 0; index < args->nOptions; index++) { + bool is_absolute_path = false; // for -agentpath vs -agentlib +diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp +index 46bbfb4..520cc31 100644 +--- a/hotspot/src/share/vm/runtime/globals.hpp ++++ b/hotspot/src/share/vm/runtime/globals.hpp +@@ -4010,6 +4010,9 @@ class CommandLineFlags { + product(ccstr, ExtraSharedClassListFile, NULL, \ + "Extra classlist for building the CDS archive file") \ + \ ++ product(bool, UseAppCDS, false, \ ++ "Enable Application Class Data Sharing (AppCDS)") \ ++ \ + experimental(uintx, ArrayAllocatorMallocLimit, \ + SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx), \ + "Allocation less than this value will be allocated " \ +diff --git a/hotspot/src/share/vm/runtime/javaCalls.cpp b/hotspot/src/share/vm/runtime/javaCalls.cpp +index 12925a9..217b8ff 100644 +--- a/hotspot/src/share/vm/runtime/javaCalls.cpp ++++ b/hotspot/src/share/vm/runtime/javaCalls.cpp +@@ -310,7 +310,7 @@ void JavaCalls::call(JavaValue* result, methodHandle method, JavaCallArguments* + void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) { + // During dumping, Java execution environment is not fully initialized. Also, Java execution + // may cause undesirable side-effects in the class metadata. +- assert(!DumpSharedSpaces, "must not execute Java bytecodes when dumping"); ++ assert(!DumpSharedSpaces || UseAppCDS, "must not execute Java bytecodes when dumping"); + + methodHandle method = *m; + JavaThread* thread = (JavaThread*)THREAD; +diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp +index 03b6aaf..03c1098 100644 +--- a/hotspot/src/share/vm/runtime/thread.cpp ++++ b/hotspot/src/share/vm/runtime/thread.cpp +@@ -3428,6 +3428,14 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { + os::pause(); + } + ++ if (DumpSharedSpaces) { ++ // when dumping shared spaces for AppCDS we must disable bytecode ++ // rewriting as it initializes internal (cached) meta-data that ++ // would be stored in the archive but cannot be carried over to ++ // the next execution ++ RewriteBytecodes = false; ++ } ++ + #ifndef USDT2 + HS_DTRACE_PROBE(hotspot, vm__init__begin); + #else /* USDT2 */ +@@ -3554,8 +3562,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { + + // At this point, the Universe is initialized, but we have not executed + // any byte code. Now is a good time (the only time) to dump out the +- // internal state of the JVM for sharing. +- if (DumpSharedSpaces) { ++ // internal state of the JVM for sharing, unless AppCDS is enabled. ++ if (!UseAppCDS && DumpSharedSpaces) { + MetaspaceShared::preload_and_dump(CHECK_0); + ShouldNotReachHere(); + } +@@ -3682,6 +3690,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { + vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION)); + } + ++ if (UseAppCDS && DumpSharedSpaces) { ++ MetaspaceShared::preload_and_dump(CHECK_0); ++ ShouldNotReachHere(); ++ } ++ + #if INCLUDE_ALL_GCS + // Support for ConcurrentMarkSweep. This should be cleaned up + // and better encapsulated. The ugly nested if test would go away +diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp +index fc17aeb..2b458fe 100644 +--- a/hotspot/src/share/vm/utilities/ostream.cpp ++++ b/hotspot/src/share/vm/utilities/ostream.cpp +@@ -495,7 +495,7 @@ static const char* make_log_name_internal(const char* log_name, const char* forc + // -XX:DumpLoadedClassList= + // in log_name, %p => pid1234 and + // %t => YYYY-MM-DD_HH-MM-SS +-static const char* make_log_name(const char* log_name, const char* force_directory) { ++const char* make_log_name(const char* log_name, const char* force_directory) { + char timestr[32]; + get_datetime_string(timestr, sizeof(timestr)); + return make_log_name_internal(log_name, force_directory, os::current_process_id(), +diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp +index fbcb299..530c523 100644 +--- a/hotspot/src/share/vm/utilities/ostream.hpp ++++ b/hotspot/src/share/vm/utilities/ostream.hpp +@@ -332,4 +332,6 @@ class networkStream : public bufferedStream { + + #endif + ++const char* make_log_name(const char* log_name, const char* force_directory); ++ + #endif // SHARE_VM_UTILITIES_OSTREAM_HPP +diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java +index 2e98092..f305c1e 100644 +--- a/jdk/src/share/classes/java/lang/ClassLoader.java ++++ b/jdk/src/share/classes/java/lang/ClassLoader.java +@@ -2182,6 +2182,10 @@ public abstract class ClassLoader { + + // Retrieves the assertion directives from the VM. + private static native AssertionStatusDirectives retrieveDirectives(); ++ ++ protected ProtectionDomain getProtectionDomainInternal(String name) { ++ return null; ++ } + } + + +diff --git a/jdk/src/share/classes/java/net/URLClassLoader.java b/jdk/src/share/classes/java/net/URLClassLoader.java +index 416941c..e82cb6d 100644 +--- a/jdk/src/share/classes/java/net/URLClassLoader.java ++++ b/jdk/src/share/classes/java/net/URLClassLoader.java +@@ -38,6 +38,7 @@ import java.security.Permission; + import java.security.PermissionCollection; + import java.security.PrivilegedAction; + import java.security.PrivilegedExceptionAction; ++import java.security.ProtectionDomain; + import java.security.SecureClassLoader; + import java.util.Enumeration; + import java.util.List; +@@ -343,6 +344,25 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { + return ucp.getURLs(); + } + ++ /* ++ * Retrieve protection domain using the specified class name. ++ * Called from the VM to support AppCDS ++ */ ++ protected ProtectionDomain getProtectionDomainInternal(String name) { ++ String path = name.replace('.', '/').concat(".class"); ++ Resource res = ucp.getResource(path, false); ++ ++ if(res == null) ++ { ++ // Should never happen ++ throw new AssertionError("Cannot find resource fpr path " + path); ++ } ++ URL url = res.getCodeSourceURL(); ++ CodeSigner[] signers = res.getCodeSigners(); ++ CodeSource cs = new CodeSource(url, signers); ++ return getProtectionDomain(cs); ++ } ++ + /** + * Finds and loads the class with the specified name from the URL search + * path. Any URLs referring to JAR files are loaded and opened as needed +diff --git a/jdk/src/share/classes/java/security/SecureClassLoader.java b/jdk/src/share/classes/java/security/SecureClassLoader.java +index 145f4fc..cb5f017 100644 +--- a/jdk/src/share/classes/java/security/SecureClassLoader.java ++++ b/jdk/src/share/classes/java/security/SecureClassLoader.java +@@ -195,7 +195,7 @@ public class SecureClassLoader extends ClassLoader { + /* + * Returned cached ProtectionDomain for the specified CodeSource. + */ +- private ProtectionDomain getProtectionDomain(CodeSource cs) { ++ protected ProtectionDomain getProtectionDomain(CodeSource cs) { + if (cs == null) + return null; + +@@ -215,6 +215,7 @@ public class SecureClassLoader extends ClassLoader { + return pd; + } + ++ + /* + * Check to make sure the class loader has been initialized. + */ diff --git a/Fix-LineBuffer-vappend-when-buffer-too-small.patch b/Fix-LineBuffer-vappend-when-buffer-too-small.patch new file mode 100644 index 0000000000000000000000000000000000000000..9c5b18555869c7f898487f93b7748e52c7b02b31 --- /dev/null +++ b/Fix-LineBuffer-vappend-when-buffer-too-small.patch @@ -0,0 +1,27 @@ +From a409bdd4982a6a463b65b529ed3aedb0c3e29144 Mon Sep 17 00:00:00 2001 +Date: Mon, 17 Aug 2020 19:32:33 +0000 +Subject: [PATCH] Fix LineBuffer::vappend when buffer too small + +Summary: : fix LineBuffer::vappend when buffer too small +LLT: NA +Bug url: NA +--- + hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp +index 75a9a5f95..185b7d67e 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp +@@ -42,7 +42,7 @@ private: + + void vappend(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0) { + int res = os::vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap); +- if (res > BUFFER_LEN) { ++ if (_cur + res > BUFFER_LEN) { + DEBUG_ONLY(warning("buffer too small in LineBuffer");) + _buffer[BUFFER_LEN -1] = 0; + _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again +-- +2.12.3 + diff --git a/Remove-unused-GenericTaskQueueSet-T-F-tasks.patch b/Remove-unused-GenericTaskQueueSet-T-F-tasks.patch new file mode 100644 index 0000000000000000000000000000000000000000..b242ff22646cdf9cff85794ad9804b442dfe2610 --- /dev/null +++ b/Remove-unused-GenericTaskQueueSet-T-F-tasks.patch @@ -0,0 +1,51 @@ +From bd4fd0ac21f668f9f91e802e73cad0c120ba9df6 Mon Sep 17 00:00:00 2001 +Date: Thu, 4 Jun 2020 15:45:47 +0800 +Subject: [PATCH] Remove unused GenericTaskQueueSet::tasks() + +Summary: : remove unused GenericTaskQueueSet::tasks() +LLT: NA +Bug url: NA +--- + hotspot/src/share/vm/utilities/taskqueue.hpp | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp +index 5b03ccfa..9a2e2ee2 100644 +--- a/hotspot/src/share/vm/utilities/taskqueue.hpp ++++ b/hotspot/src/share/vm/utilities/taskqueue.hpp +@@ -541,8 +541,6 @@ class TaskQueueSetSuper { + public: + // Returns "true" if some TaskQueue in the set contains a task. + virtual bool peek() = 0; +- // Tasks in queue +- virtual uint tasks() const = 0; + virtual size_t tasks() = 0; + }; + +@@ -576,7 +574,6 @@ public: + // Returns if stealing succeeds, and sets "t" to the stolen task. + bool steal(uint queue_num, E& t); + bool peek(); +- uint tasks() const; + size_t tasks(); + + uint size() const { return _n; } +@@ -675,15 +672,6 @@ size_t GenericTaskQueueSet::tasks() { + return n; + } + +-template +-uint GenericTaskQueueSet::tasks() const { +- uint n = 0; +- for (uint j = 0; j < _n; j++) { +- n += _queues[j]->size(); +- } +- return n; +-} +- + // When to terminate from the termination protocol. + class TerminatorTerminator: public CHeapObj { + public: +-- +2.19.0 + diff --git a/Support-Git-commit-ID-in-the-SOURCE-field-of-the-release.patch b/Support-Git-commit-ID-in-the-SOURCE-field-of-the-release.patch new file mode 100644 index 0000000000000000000000000000000000000000..de06f705906f991543f9c64263157591ed857cae --- /dev/null +++ b/Support-Git-commit-ID-in-the-SOURCE-field-of-the-release.patch @@ -0,0 +1,68 @@ +From 9945034658585ea943e6326340c06b5932af8d67 Mon Sep 17 00:00:00 2001 +Date: Thu, 5 Dec 2019 10:29:18 +0000 +Subject: [PATCH] Support 'Git commit ID' in the SOURCE field of the release + file. + +Summary: :Support 'Git commit ID' in the SOURCE field of the release file. +LLT: NA +Bug url: NA +--- + common/autoconf/spec.gmk.in | 1 + + make/common/MakeBase.gmk | 29 +++++++++++++++++------------ + 2 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in +index 88f9f539..506cf617 100644 +--- a/common/autoconf/spec.gmk.in ++++ b/common/autoconf/spec.gmk.in +@@ -578,6 +578,7 @@ READELF:=@READELF@ + EXPR:=@EXPR@ + FILE:=@FILE@ + HG:=@HG@ ++GIT:=@GIT@ + OBJCOPY:=@OBJCOPY@ + SETFILE:=@SETFILE@ + XATTR:=@XATTR@ +diff --git a/make/common/MakeBase.gmk b/make/common/MakeBase.gmk +index 9e5e704b..9b7ad702 100644 +--- a/make/common/MakeBase.gmk ++++ b/make/common/MakeBase.gmk +@@ -308,18 +308,23 @@ REPO_LIST = $(patsubst ./%,%,$(patsubst %/,%,$(sort $(dir \ + + # Emit the repo:id pairs to $@ + define GetSourceTips +- $(CD) $(SRC_ROOT) ; \ +- for i in $(REPO_LIST) IGNORE ; do \ +- if [ "$${i}" = "IGNORE" ] ; then \ +- continue; \ +- elif [ -d $${i}/$(HG_DIRECTORY) -a "$(HG_VERSION)" != "" ] ; then \ +- $(PRINTF) " %s:%s" \ +- "$${i}" `$(HG) id -i --repository $${i}` ; \ +- elif [ -f $${i}/$(HGTIP_FILENAME) ] ; then \ +- $(PRINTF) " %s:%s" \ +- "$${i}" `$(CAT) $${i}/$(HGTIP_FILENAME)` ; \ +- fi; \ +- done >> $@ ++ $(if $(and $(HG), $(wildcard $(TOPDIR)/.hg)), \ ++ $$($(CD) $(SRC_ROOT) ; \ ++ for i in $(REPO_LIST) IGNORE ; do \ ++ if [ "$${i}" = "IGNORE" ] ; then \ ++ continue; \ ++ elif [ -d $${i}/$(HG_DIRECTORY) -a "$(HG_VERSION)" != "" ] ; then \ ++ $(PRINTF) " %s:%s" \ ++ "$${i}" `$(HG) id -i --repository $${i}` ; \ ++ elif [ -f $${i}/$(HGTIP_FILENAME) ] ; then \ ++ $(PRINTF) " %s:%s" \ ++ "$${i}" `$(CAT) $${i}/$(HGTIP_FILENAME)` ; \ ++ fi; \ ++ done >> $@), \ ++ $(if $(and $(GIT), $(wildcard $(TOPDIR)/.git)), \ ++ $(PRINTF) ".:git:%s%s\n" \ ++ "$$(git log -n1 --format=%H | cut -c1-12)" \ ++ "$$(if test -n "$$(git status --porcelain)"; then printf '+'; fi)" >> $@, )) + $(PRINTF) "\n" >> $@ + endef + +-- +2.19.0 + diff --git a/Test8167409.sh-fails-to-run-with-32bit-jdk-on-64bit-.patch b/Test8167409.sh-fails-to-run-with-32bit-jdk-on-64bit-.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8d58f5bd312a45efc235332e4aacf5bf300c4f7 --- /dev/null +++ b/Test8167409.sh-fails-to-run-with-32bit-jdk-on-64bit-.patch @@ -0,0 +1,37 @@ +From 0cf95d445b1f6854249987ec55591e26cc21c6a1 Mon Sep 17 00:00:00 2001 +Date: Thu, 14 May 2020 09:59:34 +0800 +Subject: [PATCH] Test8167409.sh fails to run with 32bit jdk on 64bit system + +Summary: : Test8167409.sh fails to run with 32bit jdk on 64bit system +LLT: jdk8u/hotspot/test/compiler/criticalnatives/argumentcorruption/Test8167409.sh +Bug url: +--- + .../criticalnatives/argumentcorruption/Test8167409.sh | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/hotspot/test/compiler/criticalnatives/argumentcorruption/Test8167409.sh b/hotspot/test/compiler/criticalnatives/argumentcorruption/Test8167409.sh +index 81695e75..1108aaf9 100644 +--- a/hotspot/test/compiler/criticalnatives/argumentcorruption/Test8167409.sh ++++ b/hotspot/test/compiler/criticalnatives/argumentcorruption/Test8167409.sh +@@ -61,13 +61,17 @@ case "$OS" in + exit 0; + ;; + esac ++${TESTJAVA}${FS}bin${FS}java -XshowSettings 2>&1 | grep sun.arch.data.model | grep 32 ++if [ 0 -eq $? ] ; then ++ M32="-m32" ++fi + + THIS_DIR=. + + cp ${TESTSRC}${FS}*.java ${THIS_DIR} + ${TESTJAVA}${FS}bin${FS}javac *.java + +-$cc_cmd -fPIC -shared -o libCNCheckLongArgs.so \ ++$cc_cmd ${M32} -fPIC -shared -o libCNCheckLongArgs.so \ + -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \ + ${TESTSRC}${FS}libCNCheckLongArgs.c + +-- +2.19.0 + diff --git a/The-runok-method-retrying-another-port-does-not-take.patch b/The-runok-method-retrying-another-port-does-not-take.patch new file mode 100644 index 0000000000000000000000000000000000000000..bb602ac2fdc4fd1094df8dde0ec9bdc360544c35 --- /dev/null +++ b/The-runok-method-retrying-another-port-does-not-take.patch @@ -0,0 +1,27 @@ +From 952b5418911a0cbe864d83998b1c99904830d463 Mon Sep 17 00:00:00 2001 +Date: Fri, 28 Aug 2020 09:21:14 +0800 +Subject: [PATCH] The runok method retrying another port does not take effect + +Summary: : The runok method retrying another port does not take effect +LLT: jdk8u/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh +Bug url: +--- + jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java +index d9c20c678..60219e68a 100644 +--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java ++++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java +@@ -824,7 +824,7 @@ public class RmiBootstrapTest { + + String errStr = null; + for (int i=0;i : add DumpSharedSpace guarantee when create anonymous classes + LLT: NA + Bug url: NA + +diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp +index f20bf3d2b..3ab82c5c4 100644 +--- a/hotspot/src/share/vm/prims/unsafe.cpp ++++ b/hotspot/src/share/vm/prims/unsafe.cpp +@@ -1058,6 +1058,11 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env, + HeapWord* *temp_alloc, + TRAPS) { + ++ if (DumpSharedSpaces) { ++ tty->print_cr("failed: must not create anonymous classes when dumping."); ++ JVM_Exit(0); ++ } ++ + if (UsePerfData) { + ClassLoader::unsafe_defineClassCallCounter()->inc(); + } 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..4e2bf8aa3489b1a320714cbc00edb862082cdae6 --- /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 +@@ -52,6 +52,7 @@ import sun.misc.JavaOISAccess; + import sun.util.logging.PlatformLogger; + import sun.security.action.GetBooleanAction; + import sun.security.action.GetIntegerAction; ++import sun.misc.Unsafe; + + /** + * An ObjectInputStream deserializes primitive data and objects previously +@@ -284,6 +285,22 @@ public class ObjectInputStream + traceLogger = (filterLog != null && + filterLog.isLoggable(PlatformLogger.Level.FINER)) ? filterLog : null; + } ++ ++ /* ++ * Logger for FastSerializer. ++ * Setup the FastSerializer logger if it is set to FINE ++ * (Assuming it will not change). ++ */ ++ private static final PlatformLogger fastSerLogger; ++ static { ++ if (printFastSerializer) { ++ PlatformLogger fastSerLog = PlatformLogger.getLogger("fastSerializer"); ++ fastSerLogger = (fastSerLog != null && ++ fastSerLog.isLoggable(PlatformLogger.Level.FINE)) ? fastSerLog : null; ++ } else { ++ fastSerLogger = null; ++ } ++ } + } + + /** filter stream for handling block data conversion */ +@@ -312,6 +329,9 @@ public class ObjectInputStream + /** if true, invoke resolveObject() */ + private boolean enableResolve; + ++ /** Used to get the commandline option: useFastSerializer */ ++ private static final Unsafe UNSAFE = Unsafe.getUnsafe(); ++ + /** + * Context during upcalls to class-defined readObject methods; holds + * object currently being deserialized and descriptor for current class. +@@ -325,6 +345,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/fix-crash-in-JVMTI-debug.patch b/fix-crash-in-JVMTI-debug.patch new file mode 100644 index 0000000000000000000000000000000000000000..34c3a71ebf0812f68e7468e2aaf46ac8664da701 --- /dev/null +++ b/fix-crash-in-JVMTI-debug.patch @@ -0,0 +1,24 @@ +From 82250c7c4978bf7591299e8635fb183f36d3546f Mon Sep 17 00:00:00 2001 +Date: Fri, 19 Apr 2019 16:30:04 +0000 +Subject: [PATCH] fix crash in JVMTI debug + +--- + hotspot/src/share/vm/prims/jvmtiEnvBase.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp +index fe2a3811..5db41567 100644 +--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp ++++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp +@@ -1092,7 +1092,7 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec + // If the monitor has no owner, then a non-suspended contending + // thread could potentially change the state of the monitor by + // entering it. The JVM/TI spec doesn't allow this. +- if (owning_thread == NULL && !at_safepoint & ++ if (owning_thread == NULL && !at_safepoint && + !JvmtiEnv::is_thread_fully_suspended(pending_thread, true, &debug_bits)) { + if (ret.owner != NULL) { + destroy_jni_reference(calling_thread, ret.owner); +-- +2.19.0 + diff --git a/fix-incorrect-offset-for-oop-field-with-weak-memory-.patch b/fix-incorrect-offset-for-oop-field-with-weak-memory-.patch new file mode 100644 index 0000000000000000000000000000000000000000..31c4001badc9caa75a577ac436b592309a42f284 --- /dev/null +++ b/fix-incorrect-offset-for-oop-field-with-weak-memory-.patch @@ -0,0 +1,37 @@ +From 7c73365615f00951272310db44dec2939b91b48e Mon Sep 17 00:00:00 2001 +Date: Wed, 19 Feb 2020 19:09:39 +0000 +Subject: [PATCH] fix incorrect offset for oop field with weak memory model + +Summary: : add loadload membar in fast_storefield and fast_accessfield to avoid loading a incorrect offset +LLT: N/A +Bug url: N/A +--- + hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp +index 5a619566..aa9545ee 100644 +--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp +@@ -2922,6 +2922,8 @@ void TemplateTable::fast_storefield(TosState state) + // access constant pool cache + __ get_cache_and_index_at_bcp(r2, r1, 1); + ++ __ membar(MacroAssembler::LoadLoad); ++ + // test for volatile with r3 + __ ldrw(r3, Address(r2, in_bytes(base + + ConstantPoolCacheEntry::flags_offset()))); +@@ -3013,6 +3015,9 @@ void TemplateTable::fast_accessfield(TosState state) + + // access constant pool cache + __ get_cache_and_index_at_bcp(r2, r1, 1); ++ ++ __ membar(MacroAssembler::LoadLoad); ++ + __ ldr(r1, Address(r2, in_bytes(ConstantPoolCache::base_offset() + + ConstantPoolCacheEntry::f2_offset()))); + __ ldrw(r3, Address(r2, in_bytes(ConstantPoolCache::base_offset() + +-- +2.19.0 + diff --git a/generate_source_tarball.sh b/generate_source_tarball.sh index cf0e622446e51251e5a799806c141faa9269e20a..a4f8c2c904279cdc2fa2aac8f7101011218fc7cc 100755 --- a/generate_source_tarball.sh +++ b/generate_source_tarball.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Generates the 'source tarball' for JDK 8 projects. +# Generates the 'source tarball' for jdk8u projects. # # Example: # When used from local repo set REPO_ROOT pointing to file:// with your repo @@ -111,31 +111,31 @@ do hg clone ${REPO_ROOT}/${subrepo} -r ${VERSION} done -if [ -d jdk ]; then -echo "Removing EC source code we don't build" -rm -vf jdk/src/share/native/sun/security/ec/impl/ec2.h -rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_163.c -rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_193.c -rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_233.c -rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_aff.c -rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_mont.c -rm -vf jdk/src/share/native/sun/security/ec/impl/ecp_192.c -rm -vf jdk/src/share/native/sun/security/ec/impl/ecp_224.c - -echo "Syncing EC list with NSS" - -if [ "x$PR3756" = "x" ] ; then -# get pr3756.patch (from http://icedtea.classpath.org/hg/icedtea8) from most correct tag -# Do not push it or publish it (see http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=3756) - wget http://icedtea.classpath.org/hg/icedtea8/raw-file/tip/patches/pr3756.patch - patch -Np1 < pr3756.patch - rm pr3756.patch -else - echo "Applying ${PR3756}" - patch -Np1 < $PR3756 -fi; -fi -find . -name '*.orig' -exec rm -vf '{}' ';' +#if [ -d jdk ]; then +#echo "Removing EC source code we don't build" +#rm -vf jdk/src/share/native/sun/security/ec/impl/ec2.h +#rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_163.c +#rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_193.c +#rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_233.c +#rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_aff.c +#rm -vf jdk/src/share/native/sun/security/ec/impl/ec2_mont.c +#rm -vf jdk/src/share/native/sun/security/ec/impl/ecp_192.c +#rm -vf jdk/src/share/native/sun/security/ec/impl/ecp_224.c +# +#echo "Syncing EC list with NSS" +# +#if [ "x$PR3756" = "x" ] ; then +## get pr3756.patch (from http://icedtea.classpath.org/hg/icedtea8) from most correct tag +## Do not push it or publish it (see http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=3756) +# wget http://icedtea.classpath.org/hg/icedtea8/raw-file/tip/patches/pr3756.patch +# patch -Np1 < pr3756.patch +# rm pr3756.patch +#else +# echo "Applying ${PR3756}" +# patch -Np1 < $PR3756 +#fi; +#fi +#find . -name '*.orig' -exec rm -vf '{}' ';' popd echo "Compressing remaining forest" @@ -150,5 +150,3 @@ mv ${TARBALL_NAME} .. popd echo "Done. You may want to remove the uncompressed version." - - diff --git a/java-1.8.0-openjdk.spec b/java-1.8.0-openjdk.spec index d466692ed6b4e03e9c5f334be1e459410f7842ca..3d48765548c9828904a3f6a4f607b2815f42f304 100644 --- a/java-1.8.0-openjdk.spec +++ b/java-1.8.0-openjdk.spec @@ -77,7 +77,7 @@ %global bootstrap_build 0 %endif -%global release_targets images zip-docs +%global release_targets images docs-zip # No docs nor bootcycle for debug builds %global debug_targets images @@ -148,7 +148,7 @@ # Define old aarch64/jdk8u tree variables for compatibility %global project aarch64-port %global repo jdk8u-shenandoah -%global revision aarch64-shenandoah-jdk8u265-b01 +%global revision aarch64-shenandoah-jdk8u272-b10 %global full_revision %{project}-%{repo}-%{revision} # Define IcedTea version used for SystemTap tapsets and desktop files %global icedteaver 3.15.0 @@ -915,7 +915,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 2 +Release: 0 # 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 @@ -973,12 +973,9 @@ Patch1: 8160300.patch Patch8: replace-vector-to-improve-performance-of-xml.validat.patch Patch9: AARCH64-fix-itable-stub-code-size-limit.patch Patch10: 8221658.patch -Patch11: 8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch Patch12: add-debuginfo-for-libsaproc-on-aarch64.patch -Patch13: 8171537.patch Patch18: fix-vendor-info.patch Patch21: 8202952-C2-Unexpected-dead-nodes-after-matching.patch -Patch22: 8161072.patch Patch24: 8134883.patch Patch25: FromCardCache-default-card-index-can-cause.patch Patch26: disable-UseLSE-on-ARMv8.1-by-default.patch @@ -987,7 +984,6 @@ Patch28: 8194246.patch Patch29: 8214345.patch Patch30: 8191483.patch Patch31: 8141356.patch -Patch32: 8151788.patch Patch33: 8166253.patch Patch34: 8191955.patch Patch35: 8186042-OopmapCache-implementation.patch @@ -995,13 +991,10 @@ Patch36: 8060463.patch Patch37: 8131600.patch Patch38: 8138971.patch Patch40: 8129626.patch -Patch41: 8203699-java-lang-invoke-SpecialInte.patch Patch45: 8191129.patch Patch46: 8182036.patch Patch47: 8166197.patch -Patch48: 8158946-JDK-8165808-JDK-8166583-JDK-.patch Patch51: add-with-company-name-option.patch -Patch56: 8160369.patch Patch57: 8031085.patch Patch58: Reduce-the-probability-of-the-crash-related-to-ciObj.patch Patch62: 8165857-CMS-_overflow_list-is-missing-volatile-speci.patch @@ -1012,7 +1005,6 @@ Patch70: 8164948.patch Patch72: inline-optimize-for-aarch64.patch # 8u242 -Patch73: PS-GC-adding-acquire_size-method-for-PSParallelCompa.patch Patch74: 8191915-java.lang.Math.multiplyExact-not-throw-an-ex.patch Patch75: Add-ability-to-configure-third-port-for-remote-JMX.patch Patch76: 8203196-C1-emits-incorrect-code-due-to-integer-overf.patch @@ -1037,12 +1029,28 @@ Patch95: 8205921-Optimizing-best-of-2-work-stealing-queue-selection.patch # 8u265 Patch96: fix-Long-cache-range-and-remove-VM-option-java.lang.IntegerCache.high-by-default.patch Patch97: leaf-optimize-in-ParallelScanvageGC.patch -Patch98: 8046294-Generate-the-4-byte-timestamp-randomly.patch -Patch100: 8203481-Incorrect-constraint-for-unextended_sp-in-frame-safe_for_sender.patch Patch102: fix-LongCache-s-range-when-BoxTypeCachedMax-number-is-bigger-than-Integer.MAX_VALUE.patch 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 +Patch107: 6896810-Pin.java-fails-with-OOME-during-System.out.p.patch +Patch108: 8231631-sun-net-ftp-FtpURLConnectionLeak.java-fails-.patch +Patch109: Test8167409.sh-fails-to-run-with-32bit-jdk-on-64bit-.patch +Patch111: The-runok-method-retrying-another-port-does-not-take.patch +Patch112: 8048210-8056152-fix-assert-fail-for-an-InnocuousThre.patch +Patch113: 8160425-Vectorization-with-signalling-NaN-returns-wr.patch +Patch114: 8181503-Can-t-compile-hotspot-with-c-11.patch +Patch115: 8243670-Unexpected-test-result-caused-by-C2-MergeMem.patch +Patch116: fix-crash-in-JVMTI-debug.patch +Patch118: Fix-LineBuffer-vappend-when-buffer-too-small.patch +Patch121: Remove-unused-GenericTaskQueueSet-T-F-tasks.patch +Patch122: optimize-jmap-F-dump-xxx.patch +Patch123: recreate-.java_pid-file-when-deleted-for-attach-mechanism.patch +Patch124: Support-Git-commit-ID-in-the-SOURCE-field-of-the-release.patch +Patch125: Extend-CDS-to-support-app-class-metadata-sharing.patch +Patch126: zlib-optimization.patch +Patch127: add-DumpSharedSpace-guarantee-when-create-anonymous-classes.patch ############################################# # @@ -1066,7 +1074,6 @@ Patch539: pr2888-openjdk_should_check_for_system_cacerts_database_eg_etc_pki_jav # to OpenJDK 8u. ############################################# # S8154313: Generated javadoc scattered all over the place -Patch578: jdk8154313-generated_javadoc_scattered_all_over_the_place.patch # 8035341: Allow using a system installed libpng # Patch202: jdk8035341-allow_using_system_installed_libpng.patch # 8042159: Allow using a system-installed lcms2 @@ -1382,12 +1389,9 @@ pushd %{top_level_dir_name} %patch8 -p1 %patch9 -p1 %patch10 -p1 -%patch11 -p1 %patch12 -p1 -%patch13 -p1 %patch18 -p1 %patch21 -p1 -%patch22 -p1 %patch24 -p1 %patch25 -p1 %patch26 -p1 @@ -1396,7 +1400,6 @@ pushd %{top_level_dir_name} %patch29 -p1 %patch30 -p1 %patch31 -p1 -%patch32 -p1 %patch33 -p1 %patch34 -p1 %patch35 -p1 @@ -1404,13 +1407,10 @@ pushd %{top_level_dir_name} %patch37 -p1 %patch38 -p1 %patch40 -p1 -%patch41 -p1 %patch45 -p1 %patch46 -p1 %patch47 -p1 -%patch48 -p1 %patch51 -p1 -%patch56 -p1 %patch57 -p1 %patch58 -p1 %patch62 -p1 @@ -1419,7 +1419,6 @@ pushd %{top_level_dir_name} %patch68 -p1 %patch70 -p1 %patch72 -p1 -%patch73 -p1 %patch74 -p1 %patch75 -p1 %patch76 -p1 @@ -1438,13 +1437,28 @@ pushd %{top_level_dir_name} %patch95 -p1 %patch96 -p1 %patch97 -p1 -%patch98 -p1 -%patch100 -p1 %patch102 -p1 %patch103 -p1 %patch104 -p1 %patch105 -p1 - +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch111 -p1 +%patch112 -p1 +%patch113 -p1 +%patch114 -p1 +%patch115 -p1 +%patch116 -p1 +%patch118 -p1 +%patch121 -p1 +%patch122 -p1 +%patch123 -p1 +%patch124 -p1 +%patch125 -p1 +%patch126 -p1 +%patch127 -p1 popd @@ -1453,9 +1467,6 @@ popd # %patch202 # %patch203 -# Upstreamable fixes -%patch578 - # RPM-only fixes %patch1000 @@ -2064,6 +2075,52 @@ require "copy_jdk_configs.lua" %endif %changelog +* Fri Oct 23 2020 - 1:1.8.0.272-b10.0 +- updated to aarch64-shenandoah-jdk8u272-b10 (from aarch64-port/jdk8u-shenandoah) +- deleted: 8046294-Generate-the-4-byte-timestamp-randomly.patch +- deleted: 8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch +- deleted: 8151788.patch +- deleted: 8161072.patch +- deleted: 8171537.patch +- deleted: 8203481-Incorrect-constraint-for-unextended_sp-in-frame-safe_for_sender.patch +- deleted: 8203699-java-lang-invoke-SpecialInte.patch +- modified: Extend-CDS-to-support-app-class-metadata-sharing.patch +- deleted: Test-SSLSocketSSLEngineTemplate.java-intermittent-fa.patch +- modified: fast-serializer-jdk8.patch +- deleted: fix-CompactibleFreeListSpace-block_size-crash.patch +- deleted: fix-incorrect-klass-field-in-oop-with-weak-memory-model.patch + +* Mon Sep 21 2020 noah -:1.8.0.265-b10.6 +- add add-DumpSharedSpace-guarantee-when-create-anonymous-classes.patch + +* Fri Sep 11 2020 noah -:1.8.0.265-b10.5 +- add 6896810-Pin.java-fails-with-OOME-during-System.out.p.patch +- add 8231631-sun-net-ftp-FtpURLConnectionLeak.java-fails-.patch +- add Test8167409.sh-fails-to-run-with-32bit-jdk-on-64bit-.patch +- add Test-SSLSocketSSLEngineTemplate.java-intermittent-fa.patch +- add The-runok-method-retrying-another-port-does-not-take.patch +- add 8048210-8056152-fix-assert-fail-for-an-InnocuousThre.patch +- add 8160425-Vectorization-with-signalling-NaN-returns-wr.patch +- add 8181503-Can-t-compile-hotspot-with-c-11.patch +- add 8243670-Unexpected-test-result-caused-by-C2-MergeMem.patch +- add fix-crash-in-JVMTI-debug.patch +- add fix-incorrect-klass-field-in-oop-with-weak-memory-model.patch +- add Fix-LineBuffer-vappend-when-buffer-too-small.patch +- add make-disable-precompiled-headers-work.patch +- add fix-CompactibleFreeListSpace-block_size-crash.patch +- add Remove-unused-GenericTaskQueueSet-T-F-tasks.patch +- add optimize-jmap-F-dump-xxx.patch +- add recreate-.java_pid-file-when-deleted-for-attach-mechanism.patch +- add Support-Git-commit-ID-in-the-SOURCE-field-of-the-release.patch +- add Extend-CDS-to-support-app-class-metadata-sharing.patch +- add zlib-optimization.patch + +* 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 diff --git a/jdk8154313-generated_javadoc_scattered_all_over_the_place.patch b/jdk8154313-generated_javadoc_scattered_all_over_the_place.patch deleted file mode 100644 index 3a43c5f03dc6b073e1fe79d7772dc944e72d152b..0000000000000000000000000000000000000000 --- a/jdk8154313-generated_javadoc_scattered_all_over_the_place.patch +++ /dev/null @@ -1,68 +0,0 @@ ---- jdk8/make/Javadoc.gmk 2016-04-01 16:53:41.069477682 +0200 -+++ jdk8/make/Javadoc.gmk 2016-04-01 16:53:41.014477059 +0200 -@@ -220,6 +220,12 @@ - JRE_API_DOCSDIR = $(DOCSDIR)/jre/api - PLATFORM_DOCSDIR = $(DOCSDIR)/platform - -+ -+JAVADOC_ARCHIVE_NAME := jdk-$(FULL_VERSION)-docs.zip -+JAVADOC_ARCHIVE_ASSEMBLY_DIR := $(DOCSTMPDIR)/zip-docs -+JAVADOC_ARCHIVE_DIR := $(OUTPUT_ROOT)/bundles -+JAVADOC_ARCHIVE := $(JAVADOC_ARCHIVE_DIR)/$(JAVADOC_ARCHIVE_NAME) -+ - # The non-core api javadocs need to be able to access the root of the core - # api directory, so for jdk/api or jre/api to get to the core api/ - # directory we would use this: -@@ -319,6 +325,37 @@ - all: docs - docs: coredocs otherdocs - -+# -+# Optional target which bundles all generated javadocs into a zip -+# archive. The dependency on docs is handled in Main.gmk. Incremental -+# building of docs is currently broken so if you invoke zip-docs after -+# docs, the docs are always rebuilt. -+# -+ -+zip-docs: $(JAVADOC_ARCHIVE) -+ -+# -+# Add the core docs as prerequisite to the archive to trigger a rebuild -+# if the core docs were rebuilt. Ideally any doc rebuild should trigger -+# this, but the way prerequisites are currently setup in this file, that -+# is hard to achieve. -+# -+ -+$(JAVADOC_ARCHIVE): $(COREAPI_INDEX_FILE) -+ @$(ECHO) "Compressing javadoc to single $(JAVADOC_ARCHIVE_NAME)" ; -+ $(MKDIR) -p $(JAVADOC_ARCHIVE_DIR) ; -+ $(RM) -r $(JAVADOC_ARCHIVE_ASSEMBLY_DIR) ; -+ $(MKDIR) -p $(JAVADOC_ARCHIVE_ASSEMBLY_DIR); -+ all_roots=`$(FIND) $(DOCSDIR) | $(GREP) index.html `; \ -+ pushd $(JAVADOC_ARCHIVE_ASSEMBLY_DIR); \ -+ for index_file in $${all_roots} ; do \ -+ target_dir=`dirname $${index_file}`; \ -+ name=`$(ECHO) $${target_dir} | $(SED) "s;/spec;;" | $(SED) "s;.*/;;"`; \ -+ $(LN) -s $${target_dir} $${name}; \ -+ done; \ -+ $(ZIP) -q -r $(JAVADOC_ARCHIVE) * ; \ -+ popd ; -+ - ################################################################# - # Production Targets -- USE THESE TARGETS WHEN: - # a) You're generating docs outside of release engineering's ---- jdk8/make/Main.gmk 2016-04-01 16:53:41.311480424 +0200 -+++ jdk8/make/Main.gmk 2016-04-01 16:53:41.266479914 +0200 -@@ -165,6 +165,12 @@ - @($(CD) $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs) - @$(call TargetExit) - -+zip-docs: docs zip-docs-only -+zip-docs-only: start-make -+ @$(call TargetEnter) -+ @($(CD) $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk zip-docs) -+ @$(call TargetExit) -+ - sign-jars: jdk sign-jars-only - sign-jars-only: start-make - @$(call TargetEnter) diff --git a/make-disable-precompiled-headers-work.patch b/make-disable-precompiled-headers-work.patch new file mode 100644 index 0000000000000000000000000000000000000000..6a1c9f54ded6ba5972ed84ba1d9b42144566bdcb --- /dev/null +++ b/make-disable-precompiled-headers-work.patch @@ -0,0 +1,41 @@ +From 16d2fb7faaaad6ae1d3f508af0c654c5c83bf484 Mon Sep 17 00:00:00 2001 +Date: Tue, 8 Sep 2020 09:13:31 +0800 +Subject: [PATCH] make disable precompiled headers work + +Summary: :make disable precompiled headers work +LLT: N/A +Bug url: +--- + hotspot/src/share/vm/oops/oop.hpp | 2 +- + hotspot/src/share/vm/oops/oop.inline.hpp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp +index 41a7bce4d..8a33412ec 100644 +--- a/hotspot/src/share/vm/oops/oop.hpp ++++ b/hotspot/src/share/vm/oops/oop.hpp +@@ -91,7 +91,7 @@ class oopDesc { + narrowKlass* compressed_klass_addr(); + + void set_klass(Klass* k); +- inline void release_set_klass(Klass* k); ++ void release_set_klass(Klass* k); + + // For klass field compression + int klass_gap() const; +diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp +index c3abdb128..3e3883cb6 100644 +--- a/hotspot/src/share/vm/oops/oop.inline.hpp ++++ b/hotspot/src/share/vm/oops/oop.inline.hpp +@@ -141,7 +141,7 @@ inline void oopDesc::set_klass(Klass* k) { + } + } + +-void oopDesc::release_set_klass(Klass* k) { ++inline void oopDesc::release_set_klass(Klass* k) { + CHECK_SET_KLASS(k); + if (UseCompressedClassPointers) { + OrderAccess::release_store(compressed_klass_addr(), +-- +2.12.3 + diff --git a/optimize-jmap-F-dump-xxx.patch b/optimize-jmap-F-dump-xxx.patch new file mode 100644 index 0000000000000000000000000000000000000000..79aef4109ddddfd329089b9215f13bee2d42e673 --- /dev/null +++ b/optimize-jmap-F-dump-xxx.patch @@ -0,0 +1,42 @@ +From 12ec07c99ff937953c3adafc12818136d9fb1d2b Mon Sep 17 00:00:00 2001 +Date: Thu, 9 Apr 2020 09:18:13 +0000 +Subject: [PATCH] optimize jmap -F -dump:xxx + +Summary: optimize jmap -F -dump:xxx to speed up the dump process +LLT: N/A +Bug url: N/A +--- + .../share/classes/sun/jvm/hotspot/oops/Metadata.java | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Metadata.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Metadata.java +index 4fc2ed8c..2e56d270 100644 +--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Metadata.java ++++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Metadata.java +@@ -45,6 +45,7 @@ abstract public class Metadata extends VMObject { + } + + private static VirtualBaseConstructor metadataConstructor; ++ private static Map map = new HashMap(); + + private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { + metadataConstructor = new VirtualBaseConstructor(db, db.lookupType("Metadata"), null, null); +@@ -65,7 +66,14 @@ abstract public class Metadata extends VMObject { + } + + public static Metadata instantiateWrapperFor(Address addr) { +- return metadataConstructor.instantiateWrapperFor(addr); ++ Metadata metadata; ++ if (!map.containsKey(addr)) { ++ metadata = metadataConstructor.instantiateWrapperFor(addr); ++ map.put(addr, metadata); ++ } else { ++ metadata = (Metadata)map.get(addr); ++ } ++ return metadata; + } + + public void iterate(MetadataVisitor visitor) { +-- +2.19.0 + diff --git a/recreate-.java_pid-file-when-deleted-for-attach-mechanism.patch b/recreate-.java_pid-file-when-deleted-for-attach-mechanism.patch new file mode 100644 index 0000000000000000000000000000000000000000..534254a66ddcaeb27cd74c5917457f8f17f663ab --- /dev/null +++ b/recreate-.java_pid-file-when-deleted-for-attach-mechanism.patch @@ -0,0 +1,75 @@ +From 9f8ee6d44e254da38605d3ceb527d412a208c862 Mon Sep 17 00:00:00 2001 +Date: Wed, 12 Aug 2020 12:09:15 +0000 +Subject: [PATCH] recreate .java_pid file when deleted for attach mechanism + +Summary: : +LLT: +Bug url: +--- + hotspot/src/os/linux/vm/attachListener_linux.cpp | 20 ++++++++++++++++---- + hotspot/src/share/vm/services/attachListener.cpp | 1 + + hotspot/src/share/vm/services/attachListener.hpp | 2 +- + 3 files changed, 18 insertions(+), 5 deletions(-) + +diff --git a/hotspot/src/os/linux/vm/attachListener_linux.cpp b/hotspot/src/os/linux/vm/attachListener_linux.cpp +index 700a09ff0..1ca089740 100644 +--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp ++++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp +@@ -485,13 +485,25 @@ bool AttachListener::init_at_startup() { + // If the file .attach_pid exists in the working directory + // or /tmp then this is the trigger to start the attach mechanism + bool AttachListener::is_init_trigger() { +- if (init_at_startup() || is_initialized()) { +- return false; // initialized at startup or already initialized ++ if (init_at_startup()) { ++ return false; // initialized at startup + } +- char fn[PATH_MAX+1]; +- sprintf(fn, ".attach_pid%d", os::current_process_id()); ++ ++ char fn[PATH_MAX + 1]; + int ret; + struct stat64 st; ++ ++ // check initialized ++ if (is_initialized()) { ++ // check .java_pid file exists ++ RESTARTABLE(::stat64(LinuxAttachListener::path(), &st), ret); ++ if (ret == -1) { ++ ::shutdown(LinuxAttachListener::listener(), SHUT_RDWR); ++ } ++ return false; ++ } ++ ++ sprintf(fn, ".attach_pid%d", os::current_process_id()); + RESTARTABLE(::stat64(fn, &st), ret); + if (ret == -1) { + snprintf(fn, sizeof(fn), "%s/.attach_pid%d", +diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp +index 59b2f5483..0f51378dd 100644 +--- a/hotspot/src/share/vm/services/attachListener.cpp ++++ b/hotspot/src/share/vm/services/attachListener.cpp +@@ -425,6 +425,7 @@ static void attach_listener_thread_entry(JavaThread* thread, TRAPS) { + for (;;) { + AttachOperation* op = AttachListener::dequeue(); + if (op == NULL) { ++ AttachListener::set_initialized(false); + return; // dequeue failed or shutdown + } + +diff --git a/hotspot/src/share/vm/services/attachListener.hpp b/hotspot/src/share/vm/services/attachListener.hpp +index 5204c4c62..11ec525c6 100644 +--- a/hotspot/src/share/vm/services/attachListener.hpp ++++ b/hotspot/src/share/vm/services/attachListener.hpp +@@ -71,7 +71,7 @@ class AttachListener: AllStatic { + + public: + static bool is_initialized() { return _initialized; } +- static void set_initialized() { _initialized = true; } ++ static void set_initialized(bool init = true) { _initialized = init; } + + // indicates if this VM supports attach-on-demand + static bool is_attach_supported() { return !DisableAttachMechanism; } +-- +2.12.3 + diff --git a/sources b/sources index e88b018a3f7e585e8560c5f770db945b730028fe..09a2aaaf6d0ecd1bc532e35f875871b2160fcd04 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (tapsets-icedtea-3.15.0.tar.xz) = c752a197cb3d812d50c35e11e4722772be40096c81d2a57933e0d9b8a3c708b9c157b8108a4e33a06ca7bb81648170994408c75d6f69d5ff12785d0c31009671 -SHA512 (aarch64-port-jdk8u-shenandoah-aarch64-shenandoah-jdk8u262-b10.tar.xz) = ed4e67d3b6254113cbe93f47feae2dbbc205995b7a0ec613c87d1c9fc037c9275f332bcdb9c4b7a158e27dfbecb4772671b64084e47f5d1b25ba4677b27c7096 +SHA512 (tapsets-icedtea-3.15.0.tar.xz) = 36eed87c370306c715d7a9d0906a7d719d6d956d38d03fb8f2d528d22e0067cabb3a7df10e8a7c5b65b70f2c12b9a8e7078a78a3cac478b6031d42f36415b05f +SHA512 (aarch64-port-jdk8u-shenandoah-aarch64-shenandoah-jdk8u272-b10.tar.xz) = b9c84cf37cf5cadfaa0283de37a468bd87c633a91159ed67317b2ee04b125baad0b62d9354e01c9c972e4364934e12aea061757df36313114582c54d29377150 diff --git a/update_main_sources.sh b/update_main_sources.sh index 08f735a7cf2e36df83d234cac68b57cef0d465e7..21368baa21086ca5a640f02e99fabe2843305cfb 100755 --- a/update_main_sources.sh +++ b/update_main_sources.sh @@ -31,11 +31,10 @@ if [ "x$REPO_NAME" = "x" ] ; then REPO_NAME="jdk8u-shenandoah" fi if [ "x$VERSION" = "x" ] ; then - VERSION="aarch64-shenandoah-jdk8u262-b10" + VERSION="aarch64-shenandoah-jdk8u272-b10" fi if [ "x$COMPRESSION" = "x" ] ; then -# rhel 5 needs tar.gz COMPRESSION=xz fi if [ "x$FILE_NAME_ROOT" = "x" ] ; then @@ -82,7 +81,7 @@ spec_date=`date +"%a %b %d %Y"` revision_helper=`echo ${MAIN_VERSION%-*}` updatever=`echo ${revision_helper##*u}` buildver=`echo ${MAIN_VERSION##*-}` -echo "* $spec_date $user_full_name <$user_name@redhat.com> - 1:1.8.0.$updatever-$RELEASE.$buildver" +echo "* $spec_date $user_full_name <$user_name@huawei.com> - 1:1.8.0.$updatever-$RELEASE.$buildver" echo "- updated to $MAIN_VERSION (from $PROJECT_NAME/$MAIN_REPO_NAME)" echo "- updated to $VERSION (from $PROJECT_NAME/$REPO_NAME) of hotspot" echo "- used $FILENAME as new sources" diff --git a/zlib-optimization.patch b/zlib-optimization.patch new file mode 100644 index 0000000000000000000000000000000000000000..866a553e5d3f44b511e49d503010421f7ef4ba41 --- /dev/null +++ b/zlib-optimization.patch @@ -0,0 +1,882 @@ +diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk +index c8e4815..c36ac39 100644 +--- a/jdk/make/lib/CoreLibraries.gmk ++++ b/jdk/make/lib/CoreLibraries.gmk +@@ -257,6 +257,9 @@ ifeq ($(USE_EXTERNAL_LIBZ), true) + LIBZIP_EXCLUDES += zlib + else + ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib ++ ifeq ($(OPENJDK_TARGET_CPU), aarch64) ++ ZLIB_CPPFLAGS += -DCRC32_ARMV8_CRC32 -DHASH_ARMV8_CRC32 -march=armv8-a+crc -DUNALIGNED_OK -DADLER32_SIMD_NEON -DSLIDE_HASH_NEON -DINFLATE_CHUNK_SIMD_NEON -O3 ++ endif + endif + + BUILD_LIBZIP_REORDER := +@@ -274,7 +277,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \ + LIBRARY := zip, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + LANG := C, \ +- OPTIMIZATION := LOW, \ ++ OPTIMIZATION := HIGHEST, \ + SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip, \ + EXCLUDES := $(LIBZIP_EXCLUDES), \ + CFLAGS := $(CFLAGS_JDKLIB) \ +diff --git a/jdk/src/share/native/java/util/zip/zlib/deflate.c b/jdk/src/share/native/java/util/zip/zlib/deflate.c +index f30f71b..c018064 100644 +--- a/jdk/src/share/native/java/util/zip/zlib/deflate.c ++++ b/jdk/src/share/native/java/util/zip/zlib/deflate.c +@@ -184,8 +184,16 @@ local const config configuration_table[10] = { + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. + */ +-#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) ++#if defined(HASH_ARMV8_CRC32) ++#include ++#define UPDATE_HASH_CRC_INTERNAL(s, h, c) \ ++ (h = __crc32w(0, (c) & 0xFFFFFF) & ((deflate_state *)s)->hash_mask) + ++#define UPDATE_HASH(s, h, c) \ ++ UPDATE_HASH_CRC_INTERNAL(s, h, *(unsigned *)((uintptr_t)(&c) - (MIN_MATCH-1))) ++#else ++#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) ++#endif + + /* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head +@@ -222,6 +230,46 @@ local const config configuration_table[10] = { + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ ++ ++#if defined(SLIDE_HASH_NEON) ++#include ++static inline void slide_hash_chain(Pos *table, unsigned int entries, uint16_t window_size) { ++ register uint16x8_t v, *p; ++ register size_t n; ++ ++ size_t size = entries * sizeof(table[0]); /* the size of hash table */ ++ Assert((size % (sizeof(uint16x8_t) * 8) == 0), "hash table size err"); /* if it's not 0, size err occurs */ ++ ++ Assert(sizeof(Pos) == 2, "Wrong Pos size"); /* if size of Pos is not 2, release wrong size error */ ++ v = vdupq_n_u16(window_size); ++ ++ p = (uint16x8_t *)table; ++ n = size / (sizeof(uint16x8_t) * 8); ++ do { ++ p[0] = vqsubq_u16(p[0], v); ++ p[1] = vqsubq_u16(p[1], v); ++ p[2] = vqsubq_u16(p[2], v); ++ p[3] = vqsubq_u16(p[3], v); ++ p[4] = vqsubq_u16(p[4], v); ++ p[5] = vqsubq_u16(p[5], v); ++ p[6] = vqsubq_u16(p[6], v); ++ p[7] = vqsubq_u16(p[7], v); ++ p += 8; ++ } while (--n); ++} ++ ++local void slide_hash(s) ++ deflate_state *s; ++{ ++ const size_t size = s->hash_size * sizeof(s->head[0]); ++ Assert(sizeof(Pos) == 2, "Wrong Pos size."); /* if size of Pos is not 2, release wrong size error */ ++ Assert((size % (sizeof(uint16x8_t)*2)) == 0, "Hash table size error."); /* if it's not 0, size err occurs */ ++ slide_hash_chain(s->head, s->hash_size, s->w_size); ++#ifndef FASTEST ++ slide_hash_chain(s->prev, s->w_size, s->w_size); ++#endif ++} ++#else + local void slide_hash(s) + deflate_state *s; + { +@@ -247,6 +295,7 @@ local void slide_hash(s) + } while (--n); + #endif + } ++#endif + + /* ========================================================================= */ + int ZEXPORT deflateInit_(strm, level, version, stream_size) +@@ -1198,14 +1247,15 @@ local unsigned read_buf(strm, buf, size) + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); +- if (strm->state->wrap == 1) { +- strm->adler = adler32(strm->adler, buf, len); +- } + #ifdef GZIP +- else if (strm->state->wrap == 2) { ++ if (strm->state->wrap == 2) { /* use crc32 algo */ + strm->adler = crc32(strm->adler, buf, len); +- } ++ } else + #endif ++ if (strm->state->wrap == 1) { ++ strm->adler = adler32(strm->adler, buf, len); ++ } ++ + strm->next_in += len; + strm->total_in += len; + +diff --git a/jdk/src/share/native/java/util/zip/zlib/inffast.c b/jdk/src/share/native/java/util/zip/zlib/inffast.c +index 4bfc995..2084739 100644 +--- a/jdk/src/share/native/java/util/zip/zlib/inffast.c ++++ b/jdk/src/share/native/java/util/zip/zlib/inffast.c +@@ -81,6 +81,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ ++#if defined(INFLATE_CHUNK_SIMD_NEON) ++ unsigned char FAR *limit; /* safety limit for chunky copies */ ++#endif + #ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ + #endif +@@ -113,7 +116,12 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ + #endif + wsize = state->wsize; + whave = state->whave; ++#if defined(INFLATE_CHUNK_SIMD_NEON) ++ limit = out + strm->avail_out; ++ wnext = (state->wnext == 0 && whave >= wsize) ? wsize : state->wnext; ++#else + wnext = state->wnext; ++#endif + window = state->window; + hold = state->hold; + bits = state->bits; +@@ -221,6 +229,45 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ + #endif + } + from = window; ++#if defined(INFLATE_CHUNK_SIMD_NEON) ++ if (wnext >= op) { /* contiguous in window */ ++ from += wnext - op; ++ } ++ else { /* wrap around window */ ++ op -= wnext; ++ from += wsize - op; ++ if (op < len) { /* some from end of window */ ++ len -= op; ++ out = chunkcopy_safe(out, from, op, limit); ++ from = window; /* more from start of window */ ++ op = wnext; ++ /* This (rare) case can create a situation where ++ the first chunkcopy below must be checked. ++ */ ++ } ++ } ++ if (op < len) { /* still need some from output */ ++ out = chunkcopy_safe(out, from, op, limit); ++ len -= op; ++ /* When dist is small the amount of data that can be ++ copied from the window is also small, and progress ++ towards the dangerous end of the output buffer is ++ also small. This means that for trivial memsets and ++ for chunkunroll_relaxed() a safety check is ++ unnecessary. However, these conditions may not be ++ entered at all, and in that case it's possible that ++ the main copy is near the end. ++ */ ++ out = chunkunroll_relaxed(out, &dist, &len); ++ out = chunkcopy_safe(out, out - dist, len, limit); ++ } ++ else { ++ /* from points to window, so there is no risk of ++ overlapping pointers requiring memset-like behaviour ++ */ ++ out = chunkcopy_safe(out, from, len, limit); ++ } ++#else + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ +@@ -271,8 +318,18 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ + if (len > 1) + *out++ = *from++; + } ++#endif + } +- else { ++ else { ++#if defined(INFLATE_CHUNK_SIMD_NEON) ++ /* Whole reference is in range of current output. No ++ range checks are necessary because we start with room ++ for at least 258 bytes of output, so unroll and roundoff ++ operations can write beyond `out+len` so long as they ++ stay within 258 bytes of `out`. ++ */ ++ out = chunkcopy_lapped_relaxed(out, dist, len); ++#else + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + *out++ = *from++; +@@ -284,7 +341,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ + *out++ = *from++; + if (len > 1) + *out++ = *from++; +- } ++ } ++#endif + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ +diff --git a/jdk/src/share/native/java/util/zip/zlib/inffast.h b/jdk/src/share/native/java/util/zip/zlib/inffast.h +index b8da8bb..0def2e3 100644 +--- a/jdk/src/share/native/java/util/zip/zlib/inffast.h ++++ b/jdk/src/share/native/java/util/zip/zlib/inffast.h +@@ -32,4 +32,374 @@ + subject to change. Applications should only use zlib.h. + */ + ++/* ++ * The chunk-copy code below deals with writing the decoded DEFLATE data to ++ * the output with SIMD methods to increase decode speed. Reading the input ++ * to the DEFLATE decoder with a wide, SIMD method can also increase decode ++ * speed. This option is supported on little endian machines, and reads the ++ * input data in 64-bit (8 byte) chunks. ++ */ ++ + void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); ++ ++#if defined(INFLATE_CHUNK_SIMD_NEON) ++ ++#include ++#include "zutil.h" ++#include ++ ++typedef uint8x16_t z_vec128i_t; ++ ++#define Z_STATIC_ASSERT(name, assert) typedef char name[(assert) ? 1 : -1] ++ ++#if __STDC_VERSION__ >= 199901L ++#define Z_RESTRICT restrict ++#else ++#define Z_RESTRICT ++#endif ++ ++#if defined(__clang__) || defined(__GNUC__) || defined(__llvm__) ++#define Z_BUILTIN_MEMCPY __builtin_memcpy ++#else ++#define Z_BUILTIN_MEMCPY zmemcpy ++#endif ++ ++/* ++ * chunk copy type: the z_vec128i_t type size should be exactly 128-bits ++ * and equal to CHUNKCOPY_CHUNK_SIZE. ++ */ ++#define CHUNKCOPY_CHUNK_SIZE sizeof(z_vec128i_t) ++ ++Z_STATIC_ASSERT(vector_128_bits_wide, ++ CHUNKCOPY_CHUNK_SIZE == sizeof(int8_t) * 16); ++ ++/* ++ * Ask the compiler to perform a wide, unaligned load with a machinevst1q_u8 ++ * instruction appropriate for the z_vec128i_t type. ++ */ ++static inline z_vec128i_t loadchunk( ++ const unsigned char FAR* s) ++{ ++ z_vec128i_t v; ++ Z_BUILTIN_MEMCPY(&v, s, sizeof(v)); ++ return v; ++} ++ ++/* ++ * Ask the compiler to perform a wide, unaligned store with a machine ++ * instruction appropriate for the z_vec128i_t type. ++ */ ++static inline void storechunk( ++ unsigned char FAR* d, ++ const z_vec128i_t v) ++{ ++ Z_BUILTIN_MEMCPY(d, &v, sizeof(v)); ++} ++ ++/* ++ * Perform a memcpy-like operation, assuming that length is non-zero and that ++ * it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if ++ * the length is shorter than this. ++ * ++ * It also guarantees that it will properly unroll the data if the distance ++ * between `out` and `from` is at least CHUNKCOPY_CHUNK_SIZE, which we rely on ++ * in chunkcopy_relaxed(). ++ * ++ * Aside from better memory bus utilisation, this means that short copies ++ * (CHUNKCOPY_CHUNK_SIZE bytes or fewer) will fall straight through the loop ++ * without iteration, which will hopefully make the branch prediction more ++ * reliable. ++ */ ++static inline unsigned char FAR* chunkcopy_core( ++ unsigned char FAR* out, ++ const unsigned char FAR* from, ++ unsigned len) ++{ ++ const int bump = (--len % CHUNKCOPY_CHUNK_SIZE) + 1; ++ storechunk(out, loadchunk(from)); ++ out += bump; ++ from += bump; ++ len /= CHUNKCOPY_CHUNK_SIZE; ++ while (len-- > 0) { ++ storechunk(out, loadchunk(from)); ++ out += CHUNKCOPY_CHUNK_SIZE; ++ from += CHUNKCOPY_CHUNK_SIZE; ++ } ++ return out; ++} ++ ++/* ++ * Like chunkcopy_core(), but avoid writing beyond of legal output. ++ * ++ * Accepts an additional pointer to the end of safe output. A generic safe ++ * copy would use (out + len), but it's normally the case that the end of the ++ * output buffer is beyond the end of the current copy, and this can still be ++ * exploited. ++ */ ++static inline unsigned char FAR* chunkcopy_core_safe( ++ unsigned char FAR* out, ++ const unsigned char FAR* from, ++ unsigned len, ++ unsigned char FAR* limit) ++{ ++ Assert(out + len <= limit, "chunk copy exceeds safety limit"); ++ if ((limit - out) < (ptrdiff_t) CHUNKCOPY_CHUNK_SIZE) { ++ const unsigned char FAR* Z_RESTRICT rfrom = from; ++ if (len & 8) { ++ Z_BUILTIN_MEMCPY(out, rfrom, 8); ++ out += 8; ++ rfrom += 8; ++ } ++ if (len & 4) { ++ Z_BUILTIN_MEMCPY(out, rfrom, 4); ++ out += 4; ++ rfrom += 4; ++ } ++ if (len & 2) { ++ Z_BUILTIN_MEMCPY(out, rfrom, 2); ++ out += 2; ++ rfrom += 2; ++ } ++ if (len & 1) { ++ *out++ = *rfrom++; ++ } ++ return out; ++ } ++ return chunkcopy_core(out, from, len); ++} ++ ++/* ++ * Perform short copies until distance can be rewritten as being at least ++ * CHUNKCOPY_CHUNK_SIZE. ++ * ++ * Assumes it's OK to overwrite at least the first 2*CHUNKCOPY_CHUNK_SIZE ++ * bytes of output even if the copy is shorter than this. This assumption ++ * holds within zlib inflate_fast(), which starts every iteration with at ++ * least 258 bytes of output space available (258 being the maximum length ++ * output from a single token; see inffast.c). ++ */ ++static inline unsigned char FAR* chunkunroll_relaxed( ++ unsigned char FAR* out, ++ unsigned FAR* dist, ++ unsigned FAR* len) ++{ ++ const unsigned char FAR* from = out - *dist; ++ while (*dist < *len && *dist < CHUNKCOPY_CHUNK_SIZE) { ++ storechunk(out, loadchunk(from)); ++ out += *dist; ++ *len -= *dist; ++ *dist += *dist; ++ } ++ return out; ++} ++ ++/* ++ * v_load64_dup(): load *src as an unaligned 64-bit int and duplicate it in ++ * every 64-bit component of the 128-bit result (64-bit int splat). ++ */ ++static inline z_vec128i_t v_load64_dup(const void* src) ++{ ++ return vcombine_u8(vld1_u8(src), vld1_u8(src)); ++} ++ ++/* ++ * v_load32_dup(): load *src as an unaligned 32-bit int and duplicate it in ++ * every 32-bit component of the 128-bit result (32-bit int splat). ++ */ ++static inline z_vec128i_t v_load32_dup(const void* src) ++{ ++ int32_t i32; ++ Z_BUILTIN_MEMCPY(&i32, src, sizeof(i32)); ++ return vreinterpretq_u8_s32(vdupq_n_s32(i32)); ++} ++ ++/* ++ * v_load16_dup(): load *src as an unaligned 16-bit int and duplicate it in ++ * every 16-bit component of the 128-bit result (16-bit int splat). ++ */ ++static inline z_vec128i_t v_load16_dup(const void* src) ++{ ++ int16_t i16; ++ Z_BUILTIN_MEMCPY(&i16, src, sizeof(i16)); ++ return vreinterpretq_u8_s16(vdupq_n_s16(i16)); ++} ++ ++/* ++ * v_load8_dup(): load the 8-bit int *src and duplicate it in every 8-bit ++ * component of the 128-bit result (8-bit int splat). ++ */ ++static inline z_vec128i_t v_load8_dup(const void* src) ++{ ++ return vld1q_dup_u8((const uint8_t*) src); ++} ++ ++/* ++ * v_store_128(): store the 128-bit vec in a memory destination (that might ++ * not be 16-byte aligned) void* out. ++ */ ++static inline void v_store_128(unsigned char* out, const z_vec128i_t vec) ++{ ++ vst1q_u8(out, vec); ++} ++ ++/* ++ * Perform an overlapping copy which behaves as a memset() operation, but ++ * supporting periods other than one, and assume that length is non-zero and ++ * that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE*3 bytes of output ++ * even if the length is shorter than this. ++ */ ++static inline unsigned char FAR* chunkset_store_result( ++ unsigned len, ++ unsigned char FAR* out, ++ z_vec128i_t v) ++{ ++ do { ++ v_store_128(out, v); ++ out += sizeof(v); ++ len -= sizeof(v); ++ } while (len > 0); ++ return out; ++} ++ ++static inline unsigned char FAR* chunkset_core(unsigned char FAR* out, unsigned period, unsigned len) ++{ ++ z_vec128i_t v; ++ const int bump = ((len - 1) % sizeof(v)) + 1; ++ switch (period) { ++ case 1: ++ v = v_load8_dup(out - 1); ++ v_store_128(out, v); ++ out += bump; ++ len -= bump; ++ while (len > 0) { ++ v_store_128(out, v); ++ out += sizeof(v); ++ len -= sizeof(v); ++ } ++ return out; ++ case 2: ++ v = v_load16_dup(out - 2); ++ v_store_128(out, v); ++ out += bump; ++ len -= bump; ++ if (len > 0) { ++ v = v_load16_dup(out - 2); ++ out = chunkset_store_result(len, out, v); ++ } ++ return out; ++ case 4: ++ v = v_load32_dup(out - 4); ++ v_store_128(out, v); ++ out += bump; ++ len -= bump; ++ if (len > 0) { ++ v = v_load32_dup(out - 4); ++ out = chunkset_store_result(len, out, v); ++ } ++ return out; ++ case 8: ++ v = v_load64_dup(out - 8); ++ v_store_128(out, v); ++ out += bump; ++ len -= bump; ++ if (len > 0) { ++ v = v_load64_dup(out - 8); ++ out = chunkset_store_result(len, out, v); ++ } ++ return out; ++ } ++ out = chunkunroll_relaxed(out, &period, &len); ++ return chunkcopy_core(out, out - period, len); ++} ++ ++/* ++ * Perform a memcpy-like operation, but assume that length is non-zero and that ++ * it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if ++ * the length is shorter than this. ++ * ++ * Unlike chunkcopy_core() above, no guarantee is made regarding the behaviour ++ * of overlapping buffers, regardless of the distance between the pointers. ++ * This is reflected in the `restrict`-qualified pointers, allowing the ++ * compiler to re-order loads and stores. ++ */ ++static inline unsigned char FAR* chunkcopy_relaxed( ++ unsigned char FAR* Z_RESTRICT out, ++ const unsigned char FAR* Z_RESTRICT from, ++ unsigned len) ++{ ++ return chunkcopy_core(out, from, len); ++} ++ ++/* ++ * Like chunkcopy_relaxed(), but avoid writing beyond of legal output. ++ * ++ * Unlike chunkcopy_core_safe() above, no guarantee is made regarding the ++ * behaviour of overlapping buffers, regardless of the distance between the ++ * pointers. This is reflected in the `restrict`-qualified pointers, allowing ++ * the compiler to re-order loads and stores. ++ * ++ * Accepts an additional pointer to the end of safe output. A generic safe ++ * copy would use (out + len), but it's normally the case that the end of the ++ * output buffer is beyond the end of the current copy, and this can still be ++ * exploited. ++ */ ++static inline unsigned char FAR* chunkcopy_safe( ++ unsigned char FAR* out, ++ const unsigned char FAR* Z_RESTRICT from, ++ unsigned len, ++ unsigned char FAR* limit) ++{ ++ Assert(out + len <= limit, "chunk copy exceeds safety limit"); ++ return chunkcopy_core_safe(out, from, len, limit); ++} ++ ++/* ++ * Perform chunky copy within the same buffer, where the source and destination ++ * may potentially overlap. ++ * ++ * Assumes that len > 0 on entry, and that it's safe to write at least ++ * CHUNKCOPY_CHUNK_SIZE*3 bytes to the output. ++ */ ++static inline unsigned char FAR* chunkcopy_lapped_relaxed( ++ unsigned char FAR* out, ++ unsigned dist, ++ unsigned len) ++{ ++ if (dist < len && dist < CHUNKCOPY_CHUNK_SIZE) { ++ return chunkset_core(out, dist, len); ++ } ++ return chunkcopy_core(out, out - dist, len); ++} ++ ++/* ++ * Behave like chunkcopy_lapped_relaxed(), but avoid writing beyond of legal ++ * output. ++ * ++ * Accepts an additional pointer to the end of safe output. A generic safe ++ * copy would use (out + len), but it's normally the case that the end of the ++ * output buffer is beyond the end of the current copy, and this can still be ++ * exploited. ++ */ ++static inline unsigned char FAR* chunkcopy_lapped_safe( ++ unsigned char FAR* out, ++ unsigned dist, ++ unsigned len, ++ unsigned char FAR* limit) ++{ ++ Assert(out + len <= limit, "chunk copy exceeds safety limit"); ++ if ((limit - out) < (ptrdiff_t) (3 * CHUNKCOPY_CHUNK_SIZE)) { ++ while (len-- > 0) { ++ *out = *(out - dist); ++ out++; ++ } ++ return out; ++ } ++ return chunkcopy_lapped_relaxed(out, dist, len); ++} ++ ++ ++#undef Z_STATIC_ASSERT ++#undef Z_RESTRICT ++#undef Z_BUILTIN_MEMCPY ++ ++#endif //defined(INFLATE_CHUNK_SIMD_NEON) +diff --git a/jdk/src/share/native/java/util/zip/zlib/inflate.c b/jdk/src/share/native/java/util/zip/zlib/inflate.c +index ca904e7..c78e05b 100644 +--- a/jdk/src/share/native/java/util/zip/zlib/inflate.c ++++ b/jdk/src/share/native/java/util/zip/zlib/inflate.c +@@ -429,9 +429,16 @@ unsigned copy; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { ++#if defined(INFLATE_CHUNK_SIMD_NEON) ++ unsigned wsize = 1U << state->wbits; ++ state->window = (unsigned char FAR *) ++ ZALLOC(strm, CHUNKCOPY_CHUNK_SIZE + wsize, ++ sizeof(unsigned char)); ++#else + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); ++#endif + if (state->window == Z_NULL) return 1; + } + +diff --git a/jdk/src/share/native/java/util/zip/zlib/zadler32.c b/jdk/src/share/native/java/util/zip/zlib/zadler32.c +index e148022..e024a15 100644 +--- a/jdk/src/share/native/java/util/zip/zlib/zadler32.c ++++ b/jdk/src/share/native/java/util/zip/zlib/zadler32.c +@@ -83,7 +83,169 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + # define MOD63(a) a %= BASE + #endif + +-/* ========================================================================= */ ++#if defined(ADLER32_SIMD_NEON) ++#include ++/* ++ * Multiply-add bytes by [ 32, 31, 30, ... ] for s2. ++ */ ++uint32x4_t ZLIB_INTERNAL mul_add_bytes( ++ uint32x4_t v_s2, ++ uint16x8_t v_column_sum_1, ++ uint16x8_t v_column_sum_2, ++ uint16x8_t v_column_sum_3, ++ uint16x8_t v_column_sum_4) ++{ ++ v_s2 = vshlq_n_u32(v_s2, 5); ++ ++ v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_1), ++ (uint16x4_t) { 32, 31, 30, 29 }); ++ v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_1), ++ (uint16x4_t) { 28, 27, 26, 25 }); ++ v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_2), ++ (uint16x4_t) { 24, 23, 22, 21 }); ++ v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_2), ++ (uint16x4_t) { 20, 19, 18, 17 }); ++ v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_3), ++ (uint16x4_t) { 16, 15, 14, 13 }); ++ v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_3), ++ (uint16x4_t) { 12, 11, 10, 9 }); ++ v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_4), ++ (uint16x4_t) { 8, 7, 6, 5 }); ++ v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_4), ++ (uint16x4_t) { 4, 3, 2, 1 }); ++ return v_s2; ++} ++ ++/* ++ * Handle leftover data. ++ */ ++uLong ZLIB_INTERNAL leftover_handler(uint32_t s1, uint32_t s2, const Bytef *buf, z_size_t len) ++{ ++ if (len) { ++ if (len >= 16) { ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ s2 += (s1 += *buf++); ++ ++ len -= 16; ++ } ++ ++ while (len--) { ++ s2 += (s1 += *buf++); ++ } ++ ++ if (s1 >= BASE) ++ s1 -= BASE; ++ s2 %= BASE; ++ } ++ ++ /* ++ * Return the recombined sums. ++ */ ++ return s1 | (s2 << 16); ++} ++ ++uLong ZLIB_INTERNAL adler32_simd_(uLong adler, const Bytef *buf, z_size_t len) ++{ ++ /* ++ * Split Adler-32 into component sums. ++ */ ++ uint32_t s1 = adler & 0xffff; ++ uint32_t s2 = adler >> 16; ++ /* ++ * Serially compute s1 & s2, until the data is 16-byte aligned. ++ */ ++ if ((uintptr_t)buf & 0xf) { ++ while ((uintptr_t)buf & 0xf) { ++ s2 += (s1 += *buf++); ++ --len; ++ } ++ if (s1 >= BASE) ++ s1 -= BASE; ++ s2 %= BASE; ++ } ++ /* ++ * Process the data in blocks. ++ */ ++ const unsigned BLOCK_SIZE = 1 << 5; ++ z_size_t blocks = len / BLOCK_SIZE; ++ len -= blocks * BLOCK_SIZE; ++ while (blocks) { ++ unsigned n = NMAX / BLOCK_SIZE; /* The NMAX constraint. */ ++ if (n > blocks) ++ n = (unsigned) blocks; ++ blocks -= n; ++ /* ++ * Process n blocks of data. At most NMAX data bytes can be ++ * processed before s2 must be reduced modulo BASE. ++ */ ++ uint32x4_t v_s2 = (uint32x4_t) { 0, 0, 0, s1 * n }; ++ uint32x4_t v_s1 = (uint32x4_t) { 0, 0, 0, 0 }; ++ ++ uint16x8_t v_column_sum_1 = vdupq_n_u16(0); ++ uint16x8_t v_column_sum_2 = vdupq_n_u16(0); ++ uint16x8_t v_column_sum_3 = vdupq_n_u16(0); ++ uint16x8_t v_column_sum_4 = vdupq_n_u16(0); ++ do { ++ /* ++ * Load 32 input bytes. ++ */ ++ const uint8x16_t bytes1 = vld1q_u8((uint8_t*)(buf)); ++ const uint8x16_t bytes2 = vld1q_u8((uint8_t*)(buf + 16)); ++ /* ++ * Add previous block byte sum to v_s2. ++ */ ++ v_s2 = vaddq_u32(v_s2, v_s1); ++ /* ++ * Horizontally add the bytes for s1. ++ */ ++ v_s1 = vpadalq_u16(v_s1, vpadalq_u8(vpaddlq_u8(bytes1), bytes2)); ++ /* ++ * Vertically add the bytes for s2. ++ */ ++ v_column_sum_1 = vaddw_u8(v_column_sum_1, vget_low_u8 (bytes1)); ++ v_column_sum_2 = vaddw_u8(v_column_sum_2, vget_high_u8(bytes1)); ++ v_column_sum_3 = vaddw_u8(v_column_sum_3, vget_low_u8 (bytes2)); ++ v_column_sum_4 = vaddw_u8(v_column_sum_4, vget_high_u8(bytes2)); ++ buf += BLOCK_SIZE; ++ } while (--n); ++ v_s2 = mul_add_bytes(v_s2, v_column_sum_1, v_column_sum_2, v_column_sum_3, v_column_sum_4); ++ /* ++ * Sum epi32 ints v_s1(s2) and accumulate in s1(s2). ++ */ ++ uint32x2_t sum1 = vpadd_u32(vget_low_u32(v_s1), vget_high_u32(v_s1)); ++ uint32x2_t sum2 = vpadd_u32(vget_low_u32(v_s2), vget_high_u32(v_s2)); ++ uint32x2_t s1s2 = vpadd_u32(sum1, sum2); ++ ++ s1 += vget_lane_u32(s1s2, 0); ++ s2 += vget_lane_u32(s1s2, 1); ++ /* ++ * Reduce. ++ */ ++ s1 %= BASE; ++ s2 %= BASE; ++ } ++ return leftover_handler(s1, s2, buf, len); ++ ++} ++#endif ++ + uLong ZEXPORT adler32_z(adler, buf, len) + uLong adler; + const Bytef *buf; +@@ -92,6 +254,11 @@ uLong ZEXPORT adler32_z(adler, buf, len) + unsigned long sum2; + unsigned n; + ++#if defined(ADLER32_SIMD_NEON) ++ if (buf && len >= 64) ++ return adler32_simd_(adler, buf, len); ++#endif ++ + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; +diff --git a/jdk/src/share/native/java/util/zip/zlib/zcrc32.c b/jdk/src/share/native/java/util/zip/zlib/zcrc32.c +index c1965fd..ee4e440 100644 +--- a/jdk/src/share/native/java/util/zip/zlib/zcrc32.c ++++ b/jdk/src/share/native/java/util/zip/zlib/zcrc32.c +@@ -257,7 +257,56 @@ uLong ZEXPORT crc32_z(crc, buf, len) + return crc ^ 0xffffffffUL; + } + +-/* ========================================================================= */ ++ ++#ifdef CRC32_ARMV8_CRC32 ++#include ++ ++uLong ZEXPORT crc32(crc, buf, len) ++ uLong crc; ++ const unsigned char FAR *buf; ++ uInt len; ++{ ++ ++ uint32_t c = (uint32_t) ~crc; ++ ++ if (buf == Z_NULL) return 0UL; ++ ++ while (len && ((uintptr_t)buf & 7)) { ++ c = __crc32b(c, *buf++); ++ --len; ++ } ++ ++ const uint64_t *buf8 = (const uint64_t *)buf; ++ ++ while (len >= 64) { ++ c = __crc32d(c, *buf8++); ++ c = __crc32d(c, *buf8++); ++ c = __crc32d(c, *buf8++); ++ c = __crc32d(c, *buf8++); ++ ++ c = __crc32d(c, *buf8++); ++ c = __crc32d(c, *buf8++); ++ c = __crc32d(c, *buf8++); ++ c = __crc32d(c, *buf8++); ++ len -= 64; ++ } ++ ++ while (len >= 8) { ++ c = __crc32d(c, *buf8++); ++ len -= 8; ++ } ++ ++ buf = (const unsigned char *)buf8; ++ ++ while (len--) { ++ c = __crc32b(c, *buf++); ++ } ++ ++ return ~c; ++} ++ ++#else ++ + uLong ZEXPORT crc32(crc, buf, len) + uLong crc; + const unsigned char FAR *buf; +@@ -266,6 +315,8 @@ uLong ZEXPORT crc32(crc, buf, len) + return crc32_z(crc, buf, len); + } + ++#endif ++ + #ifdef BYFOUR + + /*