Add several patches

This commit is contained in:
noah 2020-09-11 18:42:18 +08:00
parent c4644a81bd
commit 9f4cfa396a
22 changed files with 2823 additions and 2 deletions

View File

@ -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: <java.lang>: 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

View File

@ -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: <java.lang>: 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

View File

@ -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: <hotspot>: 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

View File

@ -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: <compile>: 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<unsigned int>(_id)) {
case OOM_MALLOC_ERROR:
case OOM_MMAP_ERROR:
if (_size) {
--
2.19.0

View File

@ -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>: 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

View File

@ -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: <c2>: <Unexpected test result caused by C2 MergeMemNode>
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

View File

@ -0,0 +1,748 @@
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);
@@ -1072,6 +1084,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;
+ }
+}
+
// Add a klass to the system from a stream (called by jni_DefineClass and
// JVM_DefineClass).
// Note: class_name can be NULL. In that case we do not know the name of
@@ -1125,12 +1150,10 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
// JVM_DefineClass or jni_DefineClass unless you're the bootclassloader
ResourceMark rm(THREAD);
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, "<resolved_references>") \
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<ClassLoaderData *>(0xFDFDFDFA);
+ClassLoaderData *Klass::_fake_loader_data_Ext = reinterpret_cast<ClassLoaderData *>(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=<file_name>
// 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.
*/

View File

@ -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: <runtime>: 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

View File

@ -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<T, F>::tasks()
Summary: <gc>: remove unused GenericTaskQueueSet<T, F>::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<T, F>::tasks() {
return n;
}
-template<class T, MEMFLAGS F>
-uint GenericTaskQueueSet<T, F>::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<mtInternal> {
public:
--
2.19.0

View File

@ -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: <make>: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

View File

@ -0,0 +1,42 @@
From 82b702f9680471ba548866aa17756f76d980ee0a Mon Sep 17 00:00:00 2001
Date: Fri, 28 Aug 2020 09:13:33 +0800
Subject: [PATCH] Test SSLSocketSSLEngineTemplate.java intermittent failed with
"Data length error"
Summary: <java.rmi>: Test SSLSocketSSLEngineTemplate.java intermittent failed with "Data length error"
LLT: jdk8u/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
Bug url:
---
.../security/ssl/templates/SSLSocketSSLEngineTemplate.java | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java b/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
index 661941677..181bbc8fd 100644
--- a/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
+++ b/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
@@ -154,6 +154,8 @@ public class SSLSocketSSLEngineTemplate {
SSLSocketSSLEngineTemplate test =
new SSLSocketSSLEngineTemplate(protocol);
test.runTest(true);
+ // invalid session
+ test.invalidSession();
test.runTest(false);
}
@@ -488,4 +490,13 @@ public class SSLSocketSSLEngineTemplate {
System.out.println(str);
}
}
+
+ /*
+ * invalid session
+ */
+ private void invalidSession() {
+ if (sslSocket != null && sslSocket.getSession() != null) {
+ sslSocket.getSession().invalidate();
+ }
+ }
}
--
2.12.3

View File

@ -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: <test case>: 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

View File

@ -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: <java.rmi>: 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<conf.length;i++) {
- for (int j = 0; j < PORT_TEST_LEN; i++) {
+ for (int j = 0; j < PORT_TEST_LEN; j++) {
try {
errStr = testConfiguration(conf[i],port+testPort++);
break;
--
2.12.3

View File

@ -0,0 +1,13 @@
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
index 1a915aa..e5a5501 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
@@ -998,7 +998,7 @@ size_t CompactibleFreeListSpace::block_size(const HeapWord* p) const {
// Ensure klass read before size.
Klass* k = oop(p)->klass_or_null_acquire();
- if (k != NULL) {
+ if (k != NULL && Metaspace::contains(k)) {
assert(k->is_klass(), "Should really be klass oop.");
oop o = (oop)p;
assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");

View File

@ -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

View File

@ -0,0 +1,32 @@
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
index b7b3da6..1a915aa 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
@@ -994,6 +994,8 @@ size_t CompactibleFreeListSpace::block_size(const HeapWord* p) const {
return res;
}
} else {
+ OrderAccess::acquire();
+
// Ensure klass read before size.
Klass* k = oop(p)->klass_or_null_acquire();
if (k != NULL) {
@@ -1044,6 +1046,8 @@ const {
return res;
}
} else {
+ OrderAccess::acquire();
+
// Ensure klass read before size.
Klass* k = oop(p)->klass_or_null_acquire();
if (k != NULL) {
@@ -1098,6 +1102,9 @@ bool CompactibleFreeListSpace::block_is_obj(const HeapWord* p) const {
// assert(CollectedHeap::use_parallel_gc_threads() || _bt.block_start(p) == p,
// "Should be a block boundary");
if (FreeChunk::indicatesFreeChunk(p)) return false;
+
+ OrderAccess::acquire();
+
Klass* k = oop(p)->klass_or_null_acquire();
if (k != NULL) {
// Ignore mark word because it may have been used to

View File

@ -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: <interpreter>: 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

View File

@ -915,7 +915,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r
Name: java-%{javaver}-%{origin}
Version: %{javaver}.%{updatever}.%{buildver}
Release: 4
Release: 5
# 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
@ -1044,6 +1044,26 @@ 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
Patch110: Test-SSLSocketSSLEngineTemplate.java-intermittent-fa.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
Patch117: fix-incorrect-klass-field-in-oop-with-weak-memory-model.patch
Patch118: Fix-LineBuffer-vappend-when-buffer-too-small.patch
Patch119: make-disable-precompiled-headers-work.patch
Patch120: fix-CompactibleFreeListSpace-block_size-crash.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
#############################################
#
@ -1446,7 +1466,26 @@ pushd %{top_level_dir_name}
%patch104 -p1
%patch105 -p1
%patch106 -p1
%patch107 -p1
%patch108 -p1
%patch109 -p1
%patch110 -p1
%patch111 -p1
%patch112 -p1
%patch113 -p1
%patch114 -p1
%patch115 -p1
%patch116 -p1
%patch117 -p1
%patch118 -p1
%patch119 -p1
%patch120 -p1
%patch121 -p1
%patch122 -p1
%patch123 -p1
%patch124 -p1
%patch125 -p1
%patch126 -p1
popd
@ -2066,6 +2105,28 @@ require "copy_jdk_configs.lua"
%endif
%changelog
* Fri Sep 11 2020 noah <hedongbo@huawei.com> -: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 <hedongbo@huawei.com> - 1:1.8.0.265-b10.4
- add fast-serializer-jdk8.patch

View File

@ -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: <runtime>: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

View File

@ -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<Metadata> metadataConstructor;
+ private static Map map = new HashMap();
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
metadataConstructor = new VirtualBaseConstructor<Metadata>(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

View File

@ -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: <hotspot>: <enable attach mechanism when .java_pid is lost>
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<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

882
zlib-optimization.patch Normal file
View File

@ -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)<<s->hash_shift) ^ (c)) & s->hash_mask)
+#if defined(HASH_ARMV8_CRC32)
+#include <arm_acle.h>
+#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)<<s->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 <arm_neon.h>
+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 <stdint.h>
+#include "zutil.h"
+#include <arm_neon.h>
+
+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 <arm_neon.h>
+/*
+ * 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 <arm_acle.h>
+
+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
/*