!103 sync master to openEuler-24.03-LTS-Next

From: @neu-mobi 
Reviewed-by: @kuenking111 
Signed-off-by: @kuenking111
This commit is contained in:
openeuler-ci-bot 2024-09-05 09:32:50 +00:00 committed by Gitee
commit 4938d64272
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
20 changed files with 527725 additions and 1988 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,175 +0,0 @@
Date: Sat, 27 May 2023 17:40:53 +0800
Subject: add
8302595-use-after-free-related-to-GraphKit-clone_map.patch
---
src/hotspot/share/opto/compile.hpp | 3 ++-
src/hotspot/share/opto/graphKit.cpp | 23 +++++++++++++++++++++
src/hotspot/share/opto/graphKit.hpp | 7 ++++++-
src/hotspot/share/opto/library_call.cpp | 6 +++---
src/hotspot/share/opto/node.hpp | 5 +++++
src/hotspot/share/opto/phaseX.hpp | 5 +++++
src/hotspot/share/opto/vectorIntrinsics.cpp | 4 ++--
7 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp
index 6e5f2ed23..b7c18b337 100644
--- a/src/hotspot/share/opto/compile.hpp
+++ b/src/hotspot/share/opto/compile.hpp
@@ -921,7 +921,8 @@ class Compile : public Phase {
// Parsing, optimization
PhaseGVN* initial_gvn() { return _initial_gvn; }
Unique_Node_List* for_igvn() { return _for_igvn; }
- inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List.
+ inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp.
+ inline void remove_for_igvn(Node* n); // Body is after class Unique_Node_List in node.hpp.
void set_initial_gvn(PhaseGVN *gvn) { _initial_gvn = gvn; }
void set_for_igvn(Unique_Node_List *for_igvn) { _for_igvn = for_igvn; }
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index a3df43c23..07d1999b2 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -738,6 +738,29 @@ SafePointNode* GraphKit::clone_map() {
return clonemap;
}
+// -----------------------------destruct_map_clone------------------------------
+// Order of destruct is important to increase the likelyhood that memory can be re-used. We need
+// to destruct/free/delete in the exact opposite order as clone_map().
+void GraphKit::destruct_map_clone(SafePointNode* sfp) {
+ if (sfp == nullptr) return;
+
+ Node* mem = sfp->memory();
+ JVMState* jvms = sfp->jvms();
+
+ if (jvms != nullptr) {
+ delete jvms;
+ }
+
+ remove_for_igvn(sfp);
+ gvn().clear_type(sfp);
+ sfp->destruct(&_gvn);
+
+ if (mem != nullptr) {
+ gvn().clear_type(mem);
+ mem->destruct(&_gvn);
+ }
+}
+
//-----------------------------set_map_clone-----------------------------------
void GraphKit::set_map_clone(SafePointNode* m) {
diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp
index d815e2195..22f868442 100644
--- a/src/hotspot/share/opto/graphKit.hpp
+++ b/src/hotspot/share/opto/graphKit.hpp
@@ -94,7 +94,7 @@ class GraphKit : public Phase {
void* barrier_set_state() const { return C->barrier_set_state(); }
void record_for_igvn(Node* n) const { C->record_for_igvn(n); } // delegate to Compile
-
+ void remove_for_igvn(Node* n) const { C->remove_for_igvn(n); }
// Handy well-known nodes:
Node* null() const { return zerocon(T_OBJECT); }
Node* top() const { return C->top(); }
@@ -170,6 +170,11 @@ class GraphKit : public Phase {
// Clone the existing map state. (Implements PreserveJVMState.)
SafePointNode* clone_map();
+ // Reverses the work done by clone_map(). Should only be used when the node returned by
+ // clone_map() is ultimately not used. Calling Node::destruct directly in the previously
+ // mentioned circumstance instead of this method may result in use-after-free.
+ void destruct_map_clone(SafePointNode* sfp);
+
// Set the map to a clone of the given one.
void set_map_clone(SafePointNode* m);
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
index b5970545c..2dd246093 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -1563,7 +1563,7 @@ bool LibraryCallKit::inline_string_char_access(bool is_store) {
set_sp(old_sp);
return false;
}
- old_map->destruct(&_gvn);
+ destruct_map_clone(old_map);
if (is_store) {
access_store_at(value, adr, TypeAryPtr::BYTES, ch, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED);
} else {
@@ -2346,7 +2346,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
mismatched = true; // conservatively mark all "wide" on-heap accesses as mismatched
}
- old_map->destruct(&_gvn);
+ destruct_map_clone(old_map);
assert(!mismatched || alias_type->adr_type()->is_oopptr(), "off-heap access can't be mismatched");
if (mismatched) {
@@ -2597,7 +2597,7 @@ bool LibraryCallKit::inline_unsafe_load_store(const BasicType type, const LoadSt
return false;
}
- old_map->destruct(&_gvn);
+ destruct_map_clone(old_map);
// For CAS, unlike inline_unsafe_access, there seems no point in
// trying to refine types. Just use the coarse types here.
diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp
index 2a78e259d..b79e7673f 100644
--- a/src/hotspot/share/opto/node.hpp
+++ b/src/hotspot/share/opto/node.hpp
@@ -1647,6 +1647,11 @@ inline void Compile::record_for_igvn(Node* n) {
_for_igvn->push(n);
}
+// Inline definition of Compile::remove_for_igvn must be deferred to this point.
+inline void Compile::remove_for_igvn(Node* n) {
+ _for_igvn->remove(n);
+}
+
//------------------------------Node_Stack-------------------------------------
class Node_Stack {
friend class VMStructs;
diff --git a/src/hotspot/share/opto/phaseX.hpp b/src/hotspot/share/opto/phaseX.hpp
index 6d0d8ca46..252761161 100644
--- a/src/hotspot/share/opto/phaseX.hpp
+++ b/src/hotspot/share/opto/phaseX.hpp
@@ -238,6 +238,11 @@ public:
assert(t != NULL, "type must not be null");
_types.map(n->_idx, t);
}
+ void clear_type(const Node* n) {
+ if (n->_idx < _types.Size()) {
+ _types.map(n->_idx, NULL);
+ }
+ }
// Record an initial type for a node, the node's bottom type.
void set_type_bottom(const Node* n) {
// Use this for initialization when bottom_type() (or better) is not handy.
diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp
index 06f491419..92f292438 100644
--- a/src/hotspot/share/opto/vectorIntrinsics.cpp
+++ b/src/hotspot/share/opto/vectorIntrinsics.cpp
@@ -868,7 +868,7 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
set_result(box);
}
- old_map->destruct(&_gvn);
+ destruct_map_clone(old_map);
if (can_access_non_heap) {
insert_mem_bar(Op_MemBarCPUOrder);
@@ -1006,7 +1006,7 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
set_result(box);
}
- old_map->destruct(&_gvn);
+ destruct_map_clone(old_map);
C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
return true;
--
2.22.0

View File

@ -1,24 +0,0 @@
Date: Sat, 27 May 2023 17:39:02 +0800
Subject: add
8303069-Memory-leak-in-CompilerOracle-parse_from_lin.patch
---
src/hotspot/share/compiler/compilerOracle.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp
index 69a327873..5149121c5 100644
--- a/src/hotspot/share/compiler/compilerOracle.cpp
+++ b/src/hotspot/share/compiler/compilerOracle.cpp
@@ -308,6 +308,8 @@ static void register_command(TypedMethodOptionMatcher* matcher,
if (option == CompileCommand::Blackhole && !UnlockExperimentalVMOptions) {
warning("Blackhole compile option is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions");
+ // Delete matcher as we don't keep it
+ delete matcher;
return;
}
--
2.22.0

View File

@ -1,29 +0,0 @@
Date: Sat, 27 May 2023 17:40:24 +0800
Subject: add
8304683-Memory-leak-in-WB_IsMethodCompatible.patch
---
src/hotspot/share/prims/whitebox.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
index 296bfe9e4..f6c947f13 100644
--- a/src/hotspot/share/prims/whitebox.cpp
+++ b/src/hotspot/share/prims/whitebox.cpp
@@ -821,10 +821,9 @@ static bool is_excluded_for_compiler(AbstractCompiler* comp, methodHandle& mh) {
return true;
}
DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp);
- if (directive->ExcludeOption) {
- return true;
- }
- return false;
+ bool exclude = directive->ExcludeOption;
+ DirectivesStack::release(directive);
+ return exclude;
}
static bool can_be_compiled_at_level(methodHandle& mh, jboolean is_osr, int level) {
--
2.22.0

View File

@ -1,260 +0,0 @@
Date: Sat, 27 May 2023 17:38:35 +0800
Subject: add
8305541-C2-Div-Mod-nodes-without-zero-check-could-be.patch
---
src/hotspot/share/opto/loopnode.hpp | 3 +
src/hotspot/share/opto/loopopts.cpp | 42 ++++-
.../c2/TestSplitDivisionThroughPhi.java | 161 ++++++++++++++++++
3 files changed, 205 insertions(+), 1 deletion(-)
create mode 100644 test/hotspot/jtreg/compiler/c2/TestSplitDivisionThroughPhi.java
diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp
index ebc3bd1db..0db6d0881 100644
--- a/src/hotspot/share/opto/loopnode.hpp
+++ b/src/hotspot/share/opto/loopnode.hpp
@@ -1506,6 +1506,9 @@ private:
void try_move_store_after_loop(Node* n);
bool identical_backtoback_ifs(Node *n);
bool can_split_if(Node *n_ctrl);
+ bool cannot_split_division(const Node* n, const Node* region) const;
+ static bool is_divisor_counted_loop_phi(const Node* divisor, const Node* loop);
+ bool loop_phi_backedge_type_contains_zero(const Node* phi_divisor, const Type* zero) const;
// Determine if a method is too big for a/another round of split-if, based on
// a magic (approximate) ratio derived from the equally magic constant 35000,
diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp
index c0804ed67..9e0f1b2d2 100644
--- a/src/hotspot/share/opto/loopopts.cpp
+++ b/src/hotspot/share/opto/loopopts.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2023, 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
@@ -61,6 +61,10 @@ Node* PhaseIdealLoop::split_thru_phi(Node* n, Node* region, int policy) {
return NULL;
}
+ if (cannot_split_division(n, region)) {
+ return NULL;
+ }
+
// Bail out if 'n' is a Div or Mod node whose zero check was removed earlier (i.e. control is NULL) and its divisor is an induction variable
// phi p of a trip-counted (integer) loop whose inputs could be zero (include zero in their type range). p could have a more precise type
// range that does not necessarily include all values of its inputs. Since each of these inputs will be a divisor of the newly cloned nodes
@@ -225,6 +229,42 @@ Node* PhaseIdealLoop::split_thru_phi(Node* n, Node* region, int policy) {
return phi;
}
+// Return true if 'n' is a Div or Mod node (without zero check If node which was removed earlier) with a loop phi divisor
+// of a trip-counted (integer or long) loop with a backedge input that could be zero (include zero in its type range). In
+// this case, we cannot split the division to the backedge as it could freely float above the loop exit check resulting in
+// a division by zero. This situation is possible because the type of an increment node of an iv phi (trip-counter) could
+// include zero while the iv phi does not (see PhiNode::Value() for trip-counted loops where we improve types of iv phis).
+// We also need to check other loop phis as they could have been created in the same split-if pass when applying
+// PhaseIdealLoop::split_thru_phi() to split nodes through an iv phi.
+bool PhaseIdealLoop::cannot_split_division(const Node* n, const Node* region) const {
+ const Type* zero;
+ switch (n->Opcode()) {
+ case Op_DivI:
+ case Op_ModI:
+ zero = TypeInt::ZERO;
+ break;
+ case Op_DivL:
+ case Op_ModL:
+ zero = TypeLong::ZERO;
+ break;
+ default:
+ return false;
+ }
+
+ assert(n->in(0) == NULL, "divisions with zero check should already have bailed out earlier in split-if");
+ Node* divisor = n->in(2);
+ return is_divisor_counted_loop_phi(divisor, region) &&
+ loop_phi_backedge_type_contains_zero(divisor, zero);
+}
+
+bool PhaseIdealLoop::is_divisor_counted_loop_phi(const Node* divisor, const Node* loop) {
+ return loop->is_BaseCountedLoop() && divisor->is_Phi() && divisor->in(0) == loop;
+}
+
+bool PhaseIdealLoop::loop_phi_backedge_type_contains_zero(const Node* phi_divisor, const Type* zero) const {
+ return _igvn.type(phi_divisor->in(LoopNode::LoopBackControl))->filter_speculative(zero) != Type::TOP;
+}
+
//------------------------------dominated_by------------------------------------
// Replace the dominated test with an obvious true or false. Place it on the
// IGVN worklist for later cleanup. Move control-dependent data Nodes on the
diff --git a/test/hotspot/jtreg/compiler/c2/TestSplitDivisionThroughPhi.java b/test/hotspot/jtreg/compiler/c2/TestSplitDivisionThroughPhi.java
new file mode 100644
index 000000000..5a42e7d36
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c2/TestSplitDivisionThroughPhi.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 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
+* @key stress randomness
+* @bug 8299259
+* @requires vm.compiler2.enabled
+* @summary Test various cases of divisions/modulo which should not be split through iv phis.
+* @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:LoopUnrollLimit=0 -XX:+StressGCM -XX:StressSeed=884154126
+* -XX:CompileCommand=compileonly,compiler.splitif.TestSplitDivisionThroughPhi::*
+* compiler.splitif.TestSplitDivisionThroughPhi
+*/
+
+/**
+* @test
+* @key stress randomness
+* @bug 8299259
+* @requires vm.compiler2.enabled
+* @summary Test various cases of divisions/modulo which should not be split through iv phis.
+* @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:LoopUnrollLimit=0 -XX:+StressGCM
+* -XX:CompileCommand=compileonly,compiler.splitif.TestSplitDivisionThroughPhi::*
+* compiler.splitif.TestSplitDivisionThroughPhi
+*/
+
+package compiler.splitif;
+
+public class TestSplitDivisionThroughPhi {
+ static int iFld;
+ static long lFld;
+ static boolean flag;
+
+
+ public static void main(String[] strArr) {
+ for (int i = 0; i < 5000; i++) {
+ testPushDivIThruPhi();
+ testPushDivIThruPhiInChain();
+ testPushModIThruPhi();
+ testPushModIThruPhiInChain();
+ testPushDivLThruPhi();
+ testPushDivLThruPhiInChain();
+ testPushModLThruPhi();
+ testPushModLThruPhiInChain();
+ }
+ }
+
+ // Already fixed by JDK-8248552.
+ static void testPushDivIThruPhi() {
+ for (int i = 10; i > 1; i -= 2) {
+ // The Div node is only split in later loop opts phase because the zero divisor check is only removed
+ // in IGVN after the first loop opts phase.
+ //
+ // iv phi i type: [2..10]
+ // When splitting the DivI through the iv phi, it ends up on the back edge with the trip count decrement
+ // as input which has type [0..8]. We end up executing a division by zero on the last iteration because
+ // the DivI it is not pinned to the loop exit test and can freely float above the loop exit check.
+ iFld = 10 / i;
+ }
+ }
+
+ // Same as above but with an additional Mul node between the iv phi and the Div node. Both nodes are split through
+ // the iv phi in one pass of Split If.
+ static void testPushDivIThruPhiInChain() {
+ for (int i = 10; i > 1; i -= 2) {
+ // Empty one iteration loop which is only removed after split if in first loop opts phase. This prevents
+ // that the Mul node is already split through the iv phi while the Div node cannot be split yet due to
+ // the zero divisor check which can only be removed in the IGVN after the first loop opts pass.
+ for (int j = 0; j < 1; j++) {
+ }
+ iFld = 10 / (i * 100);
+ }
+ }
+
+ // Already fixed by JDK-8248552.
+ static void testPushModIThruPhi() {
+ for (int i = 10; i > 1; i -= 2) {
+ iFld = 10 / i;
+ }
+ }
+
+ // Same as above but with ModI.
+ static void testPushModIThruPhiInChain() {
+ for (int i = 10; i > 1; i -= 2) {
+ for (int j = 0; j < 1; j++) {
+ }
+ iFld = 10 / (i * 100);
+ }
+ }
+
+ // Long cases only trigger since JDK-8256655.
+
+ // Same as above but with DivL.
+ static void testPushDivLThruPhi() {
+ for (long i = 10; i > 1; i -= 2) {
+ lFld = 10L / i;
+
+ // Loop that is not removed such that we do not transform the outer LongCountedLoop (only done if innermost)
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+
+ // Same as above but with DivL.
+ static void testPushDivLThruPhiInChain() {
+ for (long i = 10; i > 1; i -= 2) {
+ for (int j = 0; j < 1; j++) {
+ }
+ lFld = 10L / (i * 100L);
+
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+
+ // Same as above but with ModL
+ static void testPushModLThruPhi() {
+ for (long i = 10; i > 1; i -= 2) {
+ lFld = 10L % i;
+
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+
+ // Same as above but with ModL
+ static void testPushModLThruPhiInChain() {
+ for (long i = 10; i > 1; i -= 2) {
+ for (int j = 0; j < 1; j++) {
+ }
+ lFld = 10L % (i * 100L);
+
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+}
--
2.22.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,884 @@
---
make/data/hotspot-symbols/symbols-unix | 1 +
.../classfile/systemDictionaryShared.cpp | 4 ++-
src/hotspot/share/include/jvm.h | 6 ++++
.../jbooster/client/clientDataManager.cpp | 7 ++++
.../share/jbooster/jBoosterManager.cpp | 27 ++++++++++++++
.../share/jbooster/jBoosterManager.hpp | 4 +++
.../share/jbooster/jBoosterSymbols.hpp | 1 +
.../share/jbooster/jbooster_globals.hpp | 26 +++++++-------
src/hotspot/share/jbooster/lazyAot.cpp | 14 +++++---
.../jbooster/server/serverDataManager.cpp | 17 ++++++++-
.../jbooster/server/serverMessageHandler.cpp | 10 +++---
src/hotspot/share/oops/methodData.cpp | 9 ++---
src/hotspot/share/oops/methodData.hpp | 2 +-
src/hotspot/share/prims/jvm.cpp | 21 +++++++++++
src/hotspot/share/runtime/arguments.cpp | 1 +
.../src/jdk/tools/jaotc/Main.java | 14 ++++++--
.../ci/hotspot/HotSpotResolvedObjectType.java | 2 ++
.../HotSpotResolvedObjectTypeImpl.java | 36 +++++++++++++++++++
.../jbooster/JBoosterCompilationContext.java | 12 +++++++
.../management/HotSpotGraalManagement.java | 21 +++++++++++
.../core/test/StableArrayReadFoldingTest.java | 6 ++--
.../compiler/hotspot/HotSpotGraalRuntime.java | 11 ++++++
.../graalvm/compiler/hotspot/stubs/Stub.java | 8 +++++
.../common/inlining/walker/InliningData.java | 8 +++++
.../JBoosterCompilationContextImpl.java | 20 +++++++++++
.../share/native/libjbooster/JBooster.c | 6 ++++
test/hotspot/jtreg/ProblemList-graal.txt | 4 +++
test/jdk/tools/jbooster/JBoosterCmdTest.java | 12 +++----
test/jdk/tools/launcher/HelpFlagsTest.java | 2 +-
29 files changed, 272 insertions(+), 40 deletions(-)
diff --git a/make/data/hotspot-symbols/symbols-unix b/make/data/hotspot-symbols/symbols-unix
index ac8434902..33ce73012 100644
--- a/make/data/hotspot-symbols/symbols-unix
+++ b/make/data/hotspot-symbols/symbols-unix
@@ -212,5 +212,6 @@ JVM_JBoosterInitVM
JVM_JBoosterHandleConnection
JVM_JBoosterPrintStoredClientData
JVM_JBoosterGetMetaspaceMethodData
+JVM_JBoosterFreeUnusedCodeBlobs
JVM_JBoosterStartupNativeCallback
JVM_DefineTrustedSharedClass
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp
index ee4bd6f24..163b581fb 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp
@@ -445,6 +445,7 @@ public:
}
InstanceKlass* caller_ik() const { return _caller_ik; }
+ Method* member_method() const { return _member_method; }
};
@@ -1798,7 +1799,8 @@ public:
bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
assert_lock_strong(DumpTimeTable_lock);
- if (key.caller_ik()->is_loader_alive()) {
+ // ignore obsolete lambda
+ if (key.caller_ik()->is_loader_alive() && !key.member_method()->is_obsolete()) {
info.metaspace_pointers_do(_it);
key.metaspace_pointers_do(_it);
}
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h
index 4cdc9cfb6..488ad25ce 100644
--- a/src/hotspot/share/include/jvm.h
+++ b/src/hotspot/share/include/jvm.h
@@ -1125,6 +1125,12 @@ JVM_JBoosterPrintStoredClientData(JNIEnv *env, jboolean print_all);
JNIEXPORT long JNICALL
JVM_JBoosterGetMetaspaceMethodData(JNIEnv *env, jint session_id, jlong metaspace_method);
+/**
+ * Free unused codeBlobs.
+ */
+JNIEXPORT void JNICALL
+JVM_JBoosterFreeUnusedCodeBlobs(JNIEnv *env, jobject blobs);
+
/**
* Callback of startup signal.
*/
diff --git a/src/hotspot/share/jbooster/client/clientDataManager.cpp b/src/hotspot/share/jbooster/client/clientDataManager.cpp
index 93fa45d7c..0504dc656 100644
--- a/src/hotspot/share/jbooster/client/clientDataManager.cpp
+++ b/src/hotspot/share/jbooster/client/clientDataManager.cpp
@@ -21,6 +21,8 @@
* questions.
*/
+#include "classfile/systemDictionary.hpp"
+#include "classfile/vmSymbols.hpp"
#include "jbooster/client/clientDaemonThread.hpp"
#include "jbooster/client/clientDataManager.hpp"
#include "jbooster/client/clientStartupSignal.hpp"
@@ -325,6 +327,11 @@ void ClientDataManager::init_phase2(TRAPS) {
ClientStartupSignal::init_phase2();
}
ClientDaemonThread::start_thread(CHECK);
+
+ if (_singleton->is_clr_allowed()) {
+ Klass* klass = SystemDictionary::resolve_or_fail(vmSymbols::java_net_ClassLoaderResourceCache(), true, CHECK);
+ InstanceKlass::cast(klass)->initialize(CHECK);
+ }
}
jint ClientDataManager::escape() {
diff --git a/src/hotspot/share/jbooster/jBoosterManager.cpp b/src/hotspot/share/jbooster/jBoosterManager.cpp
index 9a8959589..64af5e894 100644
--- a/src/hotspot/share/jbooster/jBoosterManager.cpp
+++ b/src/hotspot/share/jbooster/jBoosterManager.cpp
@@ -152,3 +152,30 @@ void JBoosterManager::init_phase2(TRAPS) {
ServerDataManager::init_phase2(CHECK);
}
}
+
+void JBoosterManager::check_argument(JVMFlagsEnum flag) {
+ if (JVMFlag::is_cmdline(flag)) {
+ vm_exit_during_initialization(err_msg("Do not set VM option "
+ "%s without UseJBooster enabled.", JVMFlag::flag_from_enum(flag)->name()));
+ }
+}
+
+void JBoosterManager::check_arguments() {
+ if (UseJBooster) return;
+
+ check_argument(FLAG_MEMBER_ENUM(JBoosterAddress));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterPort));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterTimeout));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterExitIfUnsupported));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterCrashIfNoServer));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterProgramName));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterCachePath));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterLocalMode));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterStartupSignal));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterStartupMaxTime));
+ check_argument(FLAG_MEMBER_ENUM(BoostStopAtLevel));
+ check_argument(FLAG_MEMBER_ENUM(UseBoostPackages));
+ check_argument(FLAG_MEMBER_ENUM(JBoosterClientStrictMatch));
+ check_argument(FLAG_MEMBER_ENUM(PrintAllClassInfo));
+ check_argument(FLAG_MEMBER_ENUM(CheckClassFileTimeStamp));
+}
\ No newline at end of file
diff --git a/src/hotspot/share/jbooster/jBoosterManager.hpp b/src/hotspot/share/jbooster/jBoosterManager.hpp
index eb42f869a..a1bc4d445 100644
--- a/src/hotspot/share/jbooster/jBoosterManager.hpp
+++ b/src/hotspot/share/jbooster/jBoosterManager.hpp
@@ -27,6 +27,7 @@
#include "jbooster/jbooster_globals.hpp"
#include "memory/allocation.hpp"
#include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
#include "utilities/exceptions.hpp"
/**
@@ -46,6 +47,9 @@ public:
static jint init_phase1();
static void init_phase2(TRAPS);
+ static void check_arguments();
+ static void check_argument(JVMFlagsEnum flag);
+
static void client_only() NOT_DEBUG_RETURN;
static void server_only() NOT_DEBUG_RETURN;
diff --git a/src/hotspot/share/jbooster/jBoosterSymbols.hpp b/src/hotspot/share/jbooster/jBoosterSymbols.hpp
index 720e17d58..e45bf85aa 100644
--- a/src/hotspot/share/jbooster/jBoosterSymbols.hpp
+++ b/src/hotspot/share/jbooster/jBoosterSymbols.hpp
@@ -29,5 +29,6 @@
template(codesource_signature, "Ljava/security/CodeSource;") \
template(getProtectionDomainByURLString_name, "getProtectionDomainByURLString") \
template(getProtectionDomainByURLString_signature, "(Ljava/lang/String;)Ljava/security/ProtectionDomain;") \
+ template(java_net_ClassLoaderResourceCache, "java/net/ClassLoaderResourceCache") \
#endif // SHARE_JBOOSTER_JBOOSTERSYMBOLS_HPP
diff --git a/src/hotspot/share/jbooster/jbooster_globals.hpp b/src/hotspot/share/jbooster/jbooster_globals.hpp
index e9ba39e2d..3eb74abf8 100644
--- a/src/hotspot/share/jbooster/jbooster_globals.hpp
+++ b/src/hotspot/share/jbooster/jbooster_globals.hpp
@@ -41,43 +41,43 @@
"Play the role of the JBooster server. " \
"This flag is automatically set in VM.") \
\
- product(ccstr, JBoosterAddress, "127.0.0.1", \
+ product(ccstr, JBoosterAddress, "127.0.0.1", EXPERIMENTAL, \
"Address of the JBooster server. Default: '127.0.0.1'.") \
\
- product(ccstr, JBoosterPort, NULL, \
+ product(ccstr, JBoosterPort, NULL, EXPERIMENTAL, \
"Port of the JBooster server.") \
\
- product(uint, JBoosterTimeout, 4'000, \
+ product(uint, JBoosterTimeout, 4'000, EXPERIMENTAL, \
"Timeout of the JBooster connection. Default: 4,000 ms.") \
\
- product(bool, JBoosterExitIfUnsupported, true, \
+ product(bool, JBoosterExitIfUnsupported, true, EXPERIMENTAL, \
"Exit the VM if the client uses features " \
"that are not supported by the server.") \
\
product(bool, JBoosterCrashIfNoServer, false, DIAGNOSTIC, \
"Exit the VM if the server is not available.") \
\
- product(ccstr, JBoosterProgramName, NULL, \
+ product(ccstr, JBoosterProgramName, NULL, EXPERIMENTAL, \
"Unique name of current app.") \
\
- product(ccstr, JBoosterCachePath, NULL, \
+ product(ccstr, JBoosterCachePath, NULL, EXPERIMENTAL, \
"The directory path for JBooster caches " \
"(default: $HOME/.jbooster/client).") \
\
- product(bool, JBoosterLocalMode, false, \
+ product(bool, JBoosterLocalMode, false, EXPERIMENTAL, \
"No connection to the server and uses only the local cache.") \
\
- product(ccstr, JBoosterStartupSignal, NULL, \
+ product(ccstr, JBoosterStartupSignal, NULL, EXPERIMENTAL, \
"The first invocation of the signal method means the end of " \
"the client start-up phase. " \
"The relevant logic is executed at exit if it's not set.") \
\
- product(int, JBoosterStartupMaxTime, 600, \
+ product(int, JBoosterStartupMaxTime, 600, EXPERIMENTAL, \
"Max seconds required for the start-up phase (0 means off). " \
"A plan B when JBoosterStartupSignal fails.") \
range(0, max_jint) \
\
- product(int, BoostStopAtLevel, 3, \
+ product(int, BoostStopAtLevel, 3, EXPERIMENTAL, \
"0 for no optimization; 1 with class loader resource cache; " \
"2 with aggressive CDS; 3 with lazy AOT; 4 with PGO.") \
range(0, 4) \
@@ -104,13 +104,13 @@
"Cache and share the name-url pairs in " \
"java.net.URLClassLoader#findResource.") \
\
- product(ccstr, DumpClassLoaderResourceCacheFile, NULL, \
+ product(ccstr, DumpClassLoaderResourceCacheFile, NULL, EXPERIMENTAL, \
"The file path to dump class loader resource cache.") \
\
- product(ccstr, LoadClassLoaderResourceCacheFile, NULL, \
+ product(ccstr, LoadClassLoaderResourceCacheFile, NULL, EXPERIMENTAL, \
"The file path to laod class loader resource cache.") \
\
- product(uint, ClassLoaderResourceCacheSizeEachLoader, 2000, \
+ product(uint, ClassLoaderResourceCacheSizeEachLoader, 2000, EXPERIMENTAL, \
"Max number of entries that can be cached in each " \
"class loader (delete old values based on LRU).") \
\
diff --git a/src/hotspot/share/jbooster/lazyAot.cpp b/src/hotspot/share/jbooster/lazyAot.cpp
index 91c570328..d36bfe671 100644
--- a/src/hotspot/share/jbooster/lazyAot.cpp
+++ b/src/hotspot/share/jbooster/lazyAot.cpp
@@ -321,19 +321,23 @@ class KlassGetAllInstanceKlassesClosure: public KlassClosure {
GrowableArray<InstanceKlass*>* _klasses;
GrowableArray<Method*>* _methods_to_compile;
GrowableArray<Method*>* _methods_not_compile;
+ ScalarHashSet<Symbol*>* _visited;
public:
KlassGetAllInstanceKlassesClosure(GrowableArray<InstanceKlass*>* klasses,
GrowableArray<Method*>* methods_to_compile,
- GrowableArray<Method*>* methods_not_compile):
+ GrowableArray<Method*>* methods_not_compile,
+ ScalarHashSet<Symbol*>* visited):
_klasses(klasses),
_methods_to_compile(methods_to_compile),
- _methods_not_compile(methods_not_compile) {}
+ _methods_not_compile(methods_not_compile),
+ _visited(visited) {}
void do_klass(Klass* k) override {
if (!k->is_instance_klass()) return;
InstanceKlass* ik = InstanceKlass::cast(k);
if (!ik->is_loaded()) return;
+ if (!_visited->add(ik->name())) return; // skip dup klass
if (PrintAllClassInfo) {
ResourceMark rm;
@@ -375,6 +379,7 @@ class CLDGetAllInstanceKlassesClosure: public CLDClosure {
GrowableArray<InstanceKlass*>* _klasses;
GrowableArray<Method*>* _methods_to_compile;
GrowableArray<Method*>* _methods_not_compile;
+ ScalarHashSet<Symbol*> _visited;
private:
void for_each(ClassLoaderData* cld) {
@@ -394,7 +399,7 @@ private:
}
if (!cld->has_class_mirror_holder() && LazyAOT::can_be_compiled(cld)) {
if (_loaders != nullptr) _loaders->append(cld);
- KlassGetAllInstanceKlassesClosure cl(_klasses, _methods_to_compile, _methods_not_compile);
+ KlassGetAllInstanceKlassesClosure cl(_klasses, _methods_to_compile, _methods_not_compile, &_visited);
cld->classes_do(&cl);
}
}
@@ -408,7 +413,8 @@ public:
_loaders(all_loaders),
_klasses(klasses_to_compile),
_methods_to_compile(methods_to_compile),
- _methods_not_compile(methods_not_compile) {}
+ _methods_not_compile(methods_not_compile),
+ _visited() {}
void do_cld(ClassLoaderData* cld) override { for_each(cld); }
};
diff --git a/src/hotspot/share/jbooster/server/serverDataManager.cpp b/src/hotspot/share/jbooster/server/serverDataManager.cpp
index 33d6faf4c..8753102a4 100644
--- a/src/hotspot/share/jbooster/server/serverDataManager.cpp
+++ b/src/hotspot/share/jbooster/server/serverDataManager.cpp
@@ -33,6 +33,7 @@
#include "jbooster/utilities/concurrentHashMap.inline.hpp"
#include "jbooster/utilities/fileUtils.hpp"
#include "logging/log.hpp"
+#include "memory/metadataFactory.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/symbol.hpp"
@@ -363,12 +364,26 @@ JClientSessionData::JClientSessionData(uint32_t session_id,
_cl_s2c(),
_cl_c2s(),
_k_c2s(),
- _m2md(),
+ _m2md(Mutex::nonleaf),
_ref_cnt(1) {}
JClientSessionData::~JClientSessionData() {
guarantee(ref_cnt().get() == 0, "sanity");
_program_data->ref_cnt().dec_and_update_time();
+ if (_m2md.size() > 0) {
+ JavaThread* THREAD = JavaThread::current();
+ auto clear_func = [] (JClientSessionData::AddressMap::KVNode* kv_node) -> bool {
+ assert(kv_node->key() != nullptr && kv_node->value() != nullptr, "sanity");
+ Method* m = (Method*)kv_node->key();
+ MethodData* md = (MethodData*)kv_node->value();
+ assert(*md->get_failed_speculations_address() == NULL, "must be");
+ md->~MethodData();
+ ClassLoaderData* loader_data = m->method_holder()->class_loader_data();
+ MetadataFactory::free_metadata(loader_data, md);
+ return true;
+ };
+ _m2md.for_each(clear_func, THREAD);
+ }
}
address JClientSessionData::get_address(AddressMap& table, address key, Thread* thread) {
diff --git a/src/hotspot/share/jbooster/server/serverMessageHandler.cpp b/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
index a92d1c6a4..962e93cc7 100644
--- a/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
+++ b/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
@@ -348,11 +348,10 @@ int ServerMessageHandler::handle_lazy_aot_compilation_task(TRAPS) {
log_info(jbooster, compilation)("Skippd as this program has been compiled. session_id=%u.",
ss().session_id());
} else {
- log_error(jbooster, compilation)("Unknown compile state. session_id=%u.",
- ss().session_id());
+ log_info(jbooster, compilation)("Aot cache no generated. session_id=%u.",
+ ss().session_id());
}
}
- guarantee(!(compile_in_current_thread && aot_cache_state.is_being_generated()), "some logic missing?");
return 0;
}
@@ -364,9 +363,10 @@ int ServerMessageHandler::try_to_compile_lazy_aot(GrowableArray<InstanceKlass*>*
JClientProgramData* pd = ss().session_data()->program_data();
JClientCacheState& aot_cache_state = pd->aot_cache_state();
if (klasses_to_compile->is_empty()) {
+ // the expected path without plugin
aot_cache_state.set_not_generated();
- log_error(jbooster, compilation)("Failed to compile as the compilation list is empty. session_id=%u.",
- ss().session_id());
+ log_info(jbooster, compilation)("Stop compilation as the compilation list is empty. session_id=%u.",
+ ss().session_id());
return 0;
}
diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp
index 58432f1eb..12a0f3cf0 100644
--- a/src/hotspot/share/oops/methodData.cpp
+++ b/src/hotspot/share/oops/methodData.cpp
@@ -1963,9 +1963,10 @@ MethodData::MethodData(const methodHandle& method, const bool* ignored)
_data[0] = 0;
}
-MethodData* MethodData::create_instance_for_jbooster(Method* method, int size, char* mem, TRAPS) {
+MethodData* MethodData::create_instance_for_jbooster(Method* method, int byte_size, char* mem, TRAPS) {
+ int word_size = align_metadata_size(align_up(byte_size, BytesPerWord)/BytesPerWord);
ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
- MethodData* res = new (loader_data, size, MetaspaceObj::MethodDataType, THREAD)
+ MethodData* res = new (loader_data, word_size, MetaspaceObj::MethodDataType, THREAD)
MethodData(methodHandle(THREAD, method), (const bool*) nullptr);
// backup
@@ -1975,12 +1976,12 @@ MethodData* MethodData::create_instance_for_jbooster(Method* method, int size, c
// memcpy
int start = in_bytes(byte_offset_of(MethodData, _method)) + sizeof(res->_method);
- memcpy((void*) (((char*) res) + start), mem + start, size - start);
+ memcpy((void*) (((char*) res) + start), mem + start, byte_size - start);
// restore
memcpy((void*) &res->_extra_data_lock, lock_bak, sizeof(res->_extra_data_lock));
res->_failed_speculations = fs_bak;
- res->set_size(size);
+ res->set_size(byte_size);
return res;
}
diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp
index a83b373a8..9a7dfd50e 100644
--- a/src/hotspot/share/oops/methodData.hpp
+++ b/src/hotspot/share/oops/methodData.hpp
@@ -2549,7 +2549,7 @@ public:
private:
MethodData(const methodHandle& method, const bool* ignored);
public:
- static MethodData* create_instance_for_jbooster(Method* method, int size, char* mem, TRAPS);
+ static MethodData* create_instance_for_jbooster(Method* method, int byte_size, char* mem, TRAPS);
#endif // INCLUDE_JBOOSTER
};
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index bafbfe08d..90b0866e9 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -109,6 +109,7 @@
#include "jbooster/client/clientMessageHandler.hpp"
#include "jbooster/net/serverListeningThread.hpp"
#include "jbooster/server/serverDataManager.hpp"
+#include "services/memoryService.hpp"
#endif // INCLUDE_JBOOSTER
#include <errno.h>
@@ -3891,6 +3892,26 @@ JVM_ENTRY(jlong, JVM_JBoosterGetMetaspaceMethodData(JNIEnv *env, jint session_id
#endif // INCLUDE_JBOOSTER
JVM_END
+JVM_ENTRY(void, JVM_JBoosterFreeUnusedCodeBlobs(JNIEnv *env, jobject blobs))
+#if INCLUDE_JBOOSTER
+ typeArrayOop address_array = typeArrayOop(JNIHandles::resolve(blobs));
+ int length = address_array->length();
+ {
+ MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ for (int index = 0; index < length; index++) {
+ jlong adr = address_array->long_at(index);
+ RuntimeBlob* rb = (RuntimeBlob*)(address)adr;
+ assert(rb != nullptr && rb->is_runtime_stub(), "sanity");
+ rb->flush();
+ log_trace(codecache, jbooster)("free %s", rb->name());
+ CodeCache::free(rb);
+ }
+ }
+ // Track memory usage statistic after releasing CodeCache_lock
+ MemoryService::track_code_cache_memory_usage();
+#endif // INCLUDE_JBOOSTER
+JVM_END
+
JVM_ENTRY(void, JVM_JBoosterStartupNativeCallback(JNIEnv *env))
#if INCLUDE_JBOOSTER
if (!UseJBooster) return;
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 2921f3f38..bc56a1322 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -4025,6 +4025,7 @@ jint Arguments::apply_ergo() {
// So the time for sending client VM flags to the server should be later
// than most VM flags are initialized, but earlier than the time for CDS
// initialization.
+ JBoosterManager::check_arguments();
if (UseJBooster || AsJBooster) {
result = JBoosterManager::init_phase1();
if (result != JNI_OK) return result;
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
index 7e44c0cdb..5091b95a7 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
@@ -165,6 +165,7 @@ public final class Main {
e.printStackTrace();
} finally {
log.flush();
+ jboosterContext.clear();
JBoosterCompilationContext.set(null);
// Make sure the static fields are not used.
@@ -239,6 +240,7 @@ public final class Main {
@SuppressWarnings("try")
private boolean run() throws Exception {
LogPrinter.openLog();
+ HotSpotGraalRuntime runtime = null;
try {
@@ -249,7 +251,12 @@ public final class Main {
try (Timer t = new Timer(this, "")) {
classesToCompile = collector.collectClassesToCompile();
- printer.printInfo(classesToCompile.size() + " classes found");
+ if (classesToCompile == null) {
+ printer.printInfo("no class found, stop compilation");
+ return false;
+ } else {
+ printer.printInfo(classesToCompile.size() + " classes found");
+ }
}
OptionValues graalOptions = HotSpotGraalOptionValues.defaultOptions();
@@ -259,7 +266,7 @@ public final class Main {
}
graalOptions = new OptionValues(graalOptions, GeneratePIC, true, ImmutableCode, true);
GraalJVMCICompiler graalCompiler = HotSpotGraalCompilerFactory.createCompiler("JAOTC", JVMCI.getRuntime(), graalOptions, CompilerConfigurationFactory.selectFactory(null, graalOptions));
- HotSpotGraalRuntime runtime = (HotSpotGraalRuntime) graalCompiler.getGraalRuntime();
+ runtime = (HotSpotGraalRuntime) graalCompiler.getGraalRuntime();
GraalHotSpotVMConfig graalHotSpotVMConfig = runtime.getVMConfig();
if (graalHotSpotVMConfig.verifyOops) {
@@ -387,6 +394,9 @@ public final class Main {
printer.printlnVerbose("");
} finally {
+ if (runtime != null && options.isAsJBooster()) {
+ runtime.kill();
+ }
LogPrinter.closeLog();
}
return true;
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java
index f1c741c59..24d9f6b99 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java
@@ -115,4 +115,6 @@ public interface HotSpotResolvedObjectType extends ResolvedJavaType {
* does not support fingerprints)
*/
long getFingerprint();
+
+ boolean canClassInitBarrierWorkIn(HotSpotResolvedObjectType otherType);
}
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
index 19f7cc0b0..b21015aff 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
@@ -1066,4 +1066,40 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
return UNSAFE.getInt(getMetaspaceKlass() + config().instanceKlassMiscFlagsOffset);
}
+ private boolean isAncestor(ClassLoader target, ClassLoader context) {
+ ClassLoader acl = context;
+ do {
+ acl = acl.getParent();
+ if (target == acl) {
+ return true;
+ }
+ } while (acl != null);
+ return false;
+ }
+
+ public boolean canClassInitBarrierWorkIn(HotSpotResolvedObjectType otherType) {
+ if (!(this.mirror instanceof DirectHotSpotObjectConstantImpl)) return false;
+ DirectHotSpotObjectConstantImpl targetObj = (DirectHotSpotObjectConstantImpl) this.mirror;
+ if (!(targetObj.object instanceof Class)) return false;
+ ClassLoader targetClassLoader = ((Class) targetObj.object).getClassLoader();
+ if (targetClassLoader == null) {
+ // Class will be loaded by bootclassloader, no need to care classloader
+ return true;
+ }
+
+ if (!(otherType instanceof HotSpotResolvedObjectTypeImpl)) return false;
+ if (!(((HotSpotResolvedObjectTypeImpl)otherType).mirror instanceof DirectHotSpotObjectConstantImpl)) return false;
+ DirectHotSpotObjectConstantImpl contextObj = (DirectHotSpotObjectConstantImpl) ((HotSpotResolvedObjectTypeImpl)otherType).mirror;
+ if (!(contextObj.object instanceof Class)) return false;
+ ClassLoader contextClassLoader = ((Class) contextObj.object).getClassLoader();
+
+ if (targetClassLoader == contextClassLoader) {
+ return true;
+ }
+
+ if (contextClassLoader == null) {
+ return false;
+ }
+ return isAncestor(targetClassLoader, contextClassLoader);
+ }
}
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/jbooster/JBoosterCompilationContext.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/jbooster/JBoosterCompilationContext.java
index aa18682e9..b26786a52 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/jbooster/JBoosterCompilationContext.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/jbooster/JBoosterCompilationContext.java
@@ -166,6 +166,18 @@ public interface JBoosterCompilationContext {
*/
AtomicInteger getCompileQueueFailedMethodCount();
+ /**
+ * Record JBooster Installed CodeBlobs, only save address.
+ * (To support multiple compilations in single process with graal compiler)
+ */
+ void recordJBoosterInstalledCodeBlobs(long address);
+
+ /**
+ * Do some cleanup after the current compilation is complete.
+ * (To support multiple compilations in single process with graal compiler)
+ */
+ void clear();
+
/**
* Should the method be excluded for inline.
* (To support PGO)
diff --git a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java
index c1c33c775..ca9a340a8 100644
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java
@@ -127,6 +127,26 @@ public final class HotSpotGraalManagement implements HotSpotGraalManagementRegis
deferred = null;
}
+ /**
+ * check and clear dead beans.
+ */
+ private void checkAlive() {
+ // last alive bean
+ HotSpotGraalManagement before = null;
+ for (HotSpotGraalManagement m = deferred; m != null; m = m.nextDeferred) {
+ HotSpotGraalRuntime runtime = m.bean.getRuntime();
+ if (!runtime.isAlive()) {
+ if (before == null) {
+ deferred = m.nextDeferred;
+ } else {
+ before.nextDeferred = m.nextDeferred;
+ }
+ } else {
+ before = m;
+ }
+ }
+ }
+
@Override
public void run() {
while (true) {
@@ -150,6 +170,7 @@ public final class HotSpotGraalManagement implements HotSpotGraalManagementRegis
* Checks for active MBean server and if available, processes deferred registrations.
*/
synchronized void poll() {
+ checkAlive();
if (platformMBeanServer == null) {
try {
ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StableArrayReadFoldingTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StableArrayReadFoldingTest.java
index dde111f58..15989778f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StableArrayReadFoldingTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StableArrayReadFoldingTest.java
@@ -99,7 +99,8 @@ public class StableArrayReadFoldingTest extends GraalCompilerTest {
return beforeKill == afterKill;
}
- @Test
+ // obsoleted in JDK17: unaligned access is illegal in CompilerToVM.readFieldValue
+ // @Test
public void testKillWithSameTypeUnaligned() {
Assume.assumeTrue("Only test unaligned access on AMD64", getTarget().arch instanceof AMD64);
ResolvedJavaMethod method = getResolvedJavaMethod("killWithSameTypeUnaligned");
@@ -115,7 +116,8 @@ public class StableArrayReadFoldingTest extends GraalCompilerTest {
return beforeKill == afterKill;
}
- @Test
+ // obsoleted in JDK17: unaligned access is illegal in CompilerToVM.readFieldValue
+ // @Test
public void testKillWithDifferentTypeUnaligned() {
Assume.assumeTrue("Only test unaligned access on AMD64", getTarget().arch instanceof AMD64);
ResolvedJavaMethod method = getResolvedJavaMethod("killWithDifferentTypeUnaligned");
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
index 41dcd67e8..aa3e57de2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
@@ -571,6 +571,17 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
return compilationProblemsPerAction;
}
+ // support server mode
+ private boolean alive = true;
+
+ public boolean isAlive() {
+ return alive;
+ }
+
+ public void kill() {
+ alive = false;
+ }
+
// ------- Management interface ---------
private HotSpotGraalManagementRegistration management;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java
index 5e3013055..a9fdfe2c2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/Stub.java
@@ -68,6 +68,7 @@ import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Infopoint;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
+import jdk.vm.ci.jbooster.JBoosterCompilationContext;
import jdk.vm.ci.meta.DefaultProfilingInfo;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.TriState;
@@ -202,6 +203,13 @@ public abstract class Stub {
// code if we don't have a corresponding VM global symbol.
HotSpotCompiledCode compiledCode = HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, null, null, compResult, options);
code = codeCache.installCode(null, compiledCode, null, null, false);
+
+ JBoosterCompilationContext ctx = JBoosterCompilationContext.get();
+ if (ctx != null) {
+ // record installedcode for jbooster.
+ // clean it later in JBoosterCompilationContext.clear().
+ ctx.recordJBoosterInstalledCodeBlobs(code.getAddress());
+ }
} catch (Throwable e) {
throw debug.handle(e);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java
index d2f7b99cc..4126db192 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java
@@ -70,6 +70,7 @@ import org.graalvm.compiler.phases.common.inlining.policy.InliningPolicy;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import jdk.vm.ci.code.BailoutException;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.jbooster.JBoosterCompilationContext;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
import jdk.vm.ci.meta.JavaTypeProfile;
@@ -319,6 +320,13 @@ public class InliningData {
ArrayList<ResolvedJavaMethod> concreteMethods = new ArrayList<>();
ArrayList<Double> concreteMethodsProbabilities = new ArrayList<>();
for (int i = 0; i < ptypes.length; i++) {
+ if (ctx != null && ctx.usePGO() && (contextType instanceof HotSpotResolvedObjectType) && (ptypes[i].getType() instanceof HotSpotResolvedObjectType)) {
+ HotSpotResolvedObjectType target = (HotSpotResolvedObjectType) (ptypes[i].getType());
+ if (!target.canClassInitBarrierWorkIn((HotSpotResolvedObjectType) contextType)) {
+ // conflict with classInitBarrier, ignore it
+ continue;
+ }
+ }
ResolvedJavaMethod concrete = ptypes[i].getType().resolveConcreteMethod(targetMethod, contextType);
if (concrete == null) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "could not resolve method");
diff --git a/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java b/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java
index 65f28e141..4918f8552 100644
--- a/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java
+++ b/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java
@@ -23,7 +23,9 @@
package jdk.jbooster;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
@@ -51,6 +53,7 @@ public class JBoosterCompilationContextImpl implements JBoosterCompilationContex
private final AtomicInteger elfSectionShStrTabNrOfBytes = new AtomicInteger(0);
private final AtomicInteger compileQueueSuccessfulMethodCount = new AtomicInteger(0);
private final AtomicInteger compileQueueFailedMethodCount = new AtomicInteger(0);
+ private final Set<Long> installedCodeBlobs = Collections.synchronizedSet(new HashSet<>());;
private CountDownLatch aotCompilerRemainingTaskCount = null;
@@ -164,5 +167,22 @@ public class JBoosterCompilationContextImpl implements JBoosterCompilationContex
return getMetaspaceMethodData(sessionId, metaspaceMethod);
}
+ @Override
+ public void recordJBoosterInstalledCodeBlobs(long address) {
+ installedCodeBlobs.add(address);
+ }
+
+ @Override
+ public void clear() {
+ long[] blobs = new long[installedCodeBlobs.size()];
+ int index = 0;
+ for (long blob : installedCodeBlobs) {
+ blobs[index++] = blob;
+ }
+ freeUnusedCodeBlobs(blobs);
+ }
+
private static native long getMetaspaceMethodData(int sessionId, long metaspaceMethod);
+
+ private static native long freeUnusedCodeBlobs(long[] blobs);
}
diff --git a/src/jdk.jbooster/share/native/libjbooster/JBooster.c b/src/jdk.jbooster/share/native/libjbooster/JBooster.c
index 664c761ff..0c25710ae 100644
--- a/src/jdk.jbooster/share/native/libjbooster/JBooster.c
+++ b/src/jdk.jbooster/share/native/libjbooster/JBooster.c
@@ -49,3 +49,9 @@ Java_jdk_jbooster_JBoosterCompilationContextImpl_getMetaspaceMethodData(JNIEnv *
{
return JVM_JBoosterGetMetaspaceMethodData(env, session_id, metaspace_method);
}
+
+JNIEXPORT void JNICALL
+Java_jdk_jbooster_JBoosterCompilationContextImpl_freeUnusedCodeBlobs(JNIEnv * env, jclass unused, jobject blobs)
+{
+ return JVM_JBoosterFreeUnusedCodeBlobs(env, blobs);
+}
\ No newline at end of file
diff --git a/test/hotspot/jtreg/ProblemList-graal.txt b/test/hotspot/jtreg/ProblemList-graal.txt
index f7e6f56a4..a66973d90 100644
--- a/test/hotspot/jtreg/ProblemList-graal.txt
+++ b/test/hotspot/jtreg/ProblemList-graal.txt
@@ -242,3 +242,7 @@ org.graalvm.compiler.core.test.deopt.CompiledMethodTest 8202955
org.graalvm.compiler.hotspot.test.ReservedStackAccessTest 8213567 windows-all
+# Obsoleted in JDK17
+compiler/graalunit/CoreJdk9Test.java 8218074
+compiler/graalunit/HotspotJdk9Test.java 8218074
+compiler/graalunit/Replacements9Test.java 8218074
diff --git a/test/jdk/tools/jbooster/JBoosterCmdTest.java b/test/jdk/tools/jbooster/JBoosterCmdTest.java
index 4a0fe7e7b..98439e699 100644
--- a/test/jdk/tools/jbooster/JBoosterCmdTest.java
+++ b/test/jdk/tools/jbooster/JBoosterCmdTest.java
@@ -42,7 +42,7 @@ public class JBoosterCmdTest extends JBoosterTestBase {
private static void testServerPort1(TestContext ctx) throws Exception {
Process p = jbooster(ctx, List.of(), List.of());
p.waitFor(WAIT_SHORT_TIME, TimeUnit.SECONDS);
- assertEquals(p.exitValue(), 1, "port not set");
+ assertEquals(p.exitValue(), 0, "port not set");
}
private static void testServerPort2(TestContext ctx) throws Exception {
@@ -56,19 +56,19 @@ public class JBoosterCmdTest extends JBoosterTestBase {
private static void testServerPort3(TestContext ctx) throws Exception {
Process p = jbooster(ctx, List.of(), List.of("-p", "1"));
p.waitFor(WAIT_SHORT_TIME, TimeUnit.SECONDS);
- assertEquals(p.exitValue(), 1, "port < 1024");
+ assertEquals(p.exitValue(), 0, "port < 1024");
}
private static void testServerPort4(TestContext ctx) throws Exception {
Process p = jbooster(ctx, List.of(), List.of("-p", "456716"));
p.waitFor(WAIT_SHORT_TIME, TimeUnit.SECONDS);
- assertEquals(p.exitValue(), 1, "port > 65535");
+ assertEquals(p.exitValue(), 0, "port > 65535");
}
private static void testServerArgFormat1(TestContext ctx) throws Exception {
Process p = jbooster(ctx, List.of(), List.of("-p", SERVER_PORT_STR, "-t"));
p.waitFor(WAIT_SHORT_TIME, TimeUnit.SECONDS);
- assertEquals(p.exitValue(), 1, "no arg for -t");
+ assertEquals(p.exitValue(), 0, "no arg for -t");
}
private static void testServerArgFormat2(TestContext ctx) throws Exception {
@@ -98,13 +98,13 @@ public class JBoosterCmdTest extends JBoosterTestBase {
private static void testServerArgFormat6(TestContext ctx) throws Exception {
Process p = jbooster(ctx, List.of(), List.of("-p", "-t", "12345"));
p.waitFor(WAIT_SHORT_TIME, TimeUnit.SECONDS);
- assertEquals(p.exitValue(), 1, "no arg for -p");
+ assertEquals(p.exitValue(), 0, "no arg for -p");
}
private static void testServerArgFormat7(TestContext ctx) throws Exception {
Process p = jbooster(ctx, List.of(), List.of("--help=123"));
p.waitFor(WAIT_SHORT_TIME, TimeUnit.SECONDS);
- assertEquals(p.exitValue(), 1, "--help do not need arg");
+ assertEquals(p.exitValue(), 0, "--help do not need arg");
}
private static void testClientArg1(TestContext ctx) throws Exception {
diff --git a/test/jdk/tools/launcher/HelpFlagsTest.java b/test/jdk/tools/launcher/HelpFlagsTest.java
index 7e7cf47f9..29d5515ba 100644
--- a/test/jdk/tools/launcher/HelpFlagsTest.java
+++ b/test/jdk/tools/launcher/HelpFlagsTest.java
@@ -130,7 +130,7 @@ public class HelpFlagsTest extends TestHelper {
new ToolHelpSpec("javadoc", 1, 1, 1, 0, 1, 1, 1), // -?, -h, --help -help, Documents -help
new ToolHelpSpec("javap", 1, 1, 1, 0, 1, 1, 2), // -?, -h, --help -help, Documents -help
new ToolHelpSpec("javaw", 1, 1, 1, 0, 1, 1, 1), // -?, -h, --help -help, Documents -help, win only
- new ToolHelpSpec("jbooster", 1, 1, 1, 0, 1, 1, 1), // -?, -h, --help -help, Documents -help
+ new ToolHelpSpec("jbooster", 1, 1, 1, 0, 1, 1, 0), // -?, -h, --help -help, Documents -help
new ToolHelpSpec("jcmd", 1, 1, 1, 0, 1, 0, 1), // -?, -h, --help, -help accepted but not documented.
new ToolHelpSpec("jdb", 1, 1, 1, 0, 1, 1, 0), // -?, -h, --help -help, Documents -help
new ToolHelpSpec("jdeprscan", 1, 1, 1, 0, 0, 0, 1), // -?, -h, --help
--
2.19.1

View File

@ -0,0 +1,147 @@
From d99167036135396d6bdd798027c4d669e5765e7f Mon Sep 17 00:00:00 2001
Subject: 7036144:GZIPInputStream readTrailer uses faulty available() test for end-of-stream
---
.../java/util/zip/GZIPInputStream.java | 24 ++---
.../zip/GZIP/GZIPInputStreamAvailable.java | 93 +++++++++++++++++++
2 files changed, 102 insertions(+), 15 deletions(-)
create mode 100644 test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java
diff --git a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java
index 613a02bba..4f3f9eae4 100644
--- a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java
+++ b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java
@@ -224,23 +224,17 @@ public class GZIPInputStream extends InflaterInputStream {
(readUInt(in) != (inf.getBytesWritten() & 0xffffffffL)))
throw new ZipException("Corrupt GZIP trailer");
- // If there are more bytes available in "in" or
- // the leftover in the "inf" is > 26 bytes:
- // this.trailer(8) + next.header.min(10) + next.trailer(8)
// try concatenated case
- if (this.in.available() > 0 || n > 26) {
- int m = 8; // this.trailer
- try {
- m += readHeader(in); // next.header
- } catch (IOException ze) {
- return true; // ignore any malformed, do nothing
- }
- inf.reset();
- if (n > m)
- inf.setInput(buf, len - n + m, n - m);
- return false;
+ int m = 8; // this.trailer
+ try {
+ m += readHeader(in); // next.header
+ } catch (IOException ze) {
+ return true; // ignore any malformed, do nothing
}
- return true;
+ inf.reset();
+ if (n > m)
+ inf.setInput(buf, len - n + m, n - m);
+ return false;
}
/*
diff --git a/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java b/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java
new file mode 100644
index 000000000..1468c104f
--- /dev/null
+++ b/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2023, 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 7036144
+ * @summary Test concatenated gz streams when available() returns zero
+ * @run junit GZIPInputStreamAvailable
+ */
+
+import org.junit.jupiter.api.Test;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+public class GZIPInputStreamAvailable {
+
+ public static final int NUM_COPIES = 100;
+
+ @Test
+ public void testZeroAvailable() throws IOException {
+
+ // Create some uncompressed data and then repeat it NUM_COPIES times
+ byte[] uncompressed1 = "this is a test".getBytes("ASCII");
+ byte[] uncompressedN = repeat(uncompressed1, NUM_COPIES);
+
+ // Compress the original data and then repeat that NUM_COPIES times
+ byte[] compressed1 = deflate(uncompressed1);
+ byte[] compressedN = repeat(compressed1, NUM_COPIES);
+
+ // (a) Read back inflated data from a stream where available() is accurate and verify
+ byte[] readback1 = inflate(new ByteArrayInputStream(compressedN));
+ assertArrayEquals(uncompressedN, readback1);
+
+ // (b) Read back inflated data from a stream where available() always returns zero and verify
+ byte[] readback2 = inflate(new ZeroAvailableStream(new ByteArrayInputStream(compressedN)));
+ assertArrayEquals(uncompressedN, readback2);
+ }
+
+ public static byte[] repeat(byte[] data, int count) {
+ byte[] repeat = new byte[data.length * count];
+ int off = 0;
+ for (int i = 0; i < count; i++) {
+ System.arraycopy(data, 0, repeat, off, data.length);
+ off += data.length;
+ }
+ return repeat;
+ }
+
+ public static byte[] deflate(byte[] data) throws IOException {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ try (GZIPOutputStream out = new GZIPOutputStream(buf)) {
+ out.write(data);
+ }
+ return buf.toByteArray();
+ }
+
+ public static byte[] inflate(InputStream in) throws IOException {
+ return new GZIPInputStream(in).readAllBytes();
+ }
+
+ public static class ZeroAvailableStream extends FilterInputStream {
+ public ZeroAvailableStream(InputStream in) {
+ super(in);
+ }
+ @Override
+ public int available() {
+ return 0;
+ }
+ }
+}
--
2.23.0

File diff suppressed because it is too large Load Diff

View File

@ -1,180 +0,0 @@
From 6ae9bfbc94701aa91941169aff53863fe004db49 Mon Sep 17 00:00:00 2001
Date: Mon, 24 Apr 2023 19:10:50 +0800
Subject: [PATCH] Delete expired certificate
---
make/data/cacerts/geotrustglobalca | 27 ------------
make/data/cacerts/luxtrustglobalrootca | 28 -------------
make/data/cacerts/quovadisrootca | 41 -------------------
.../security/lib/cacerts/VerifyCACerts.java | 16 +-------
4 files changed, 2 insertions(+), 110 deletions(-)
delete mode 100644 make/data/cacerts/geotrustglobalca
delete mode 100644 make/data/cacerts/luxtrustglobalrootca
delete mode 100644 make/data/cacerts/quovadisrootca
diff --git a/make/data/cacerts/geotrustglobalca b/make/data/cacerts/geotrustglobalca
deleted file mode 100644
index 7f8bf9a66..000000000
--- a/make/data/cacerts/geotrustglobalca
+++ /dev/null
@@ -1,27 +0,0 @@
-Owner: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
-Issuer: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
-Serial number: 23456
-Valid from: Tue May 21 04:00:00 GMT 2002 until: Sat May 21 04:00:00 GMT 2022
-Signature algorithm name: SHA1withRSA
-Subject Public Key Algorithm: 2048-bit RSA key
-Version: 3
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
-R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
-9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
-fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
-iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
-1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
-bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
-MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
-ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
-uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
-Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
-tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
-hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
-5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
------END CERTIFICATE-----
diff --git a/make/data/cacerts/luxtrustglobalrootca b/make/data/cacerts/luxtrustglobalrootca
deleted file mode 100644
index 7fb3d818f..000000000
--- a/make/data/cacerts/luxtrustglobalrootca
+++ /dev/null
@@ -1,28 +0,0 @@
-Owner: CN=LuxTrust Global Root, O=LuxTrust s.a., C=LU
-Issuer: CN=LuxTrust Global Root, O=LuxTrust s.a., C=LU
-Serial number: bb8
-Valid from: Thu Mar 17 09:51:37 GMT 2011 until: Wed Mar 17 09:51:37 GMT 2021
-Signature algorithm name: SHA256withRSA
-Subject Public Key Algorithm: 2048-bit RSA key
-Version: 3
------BEGIN CERTIFICATE-----
-MIIDZDCCAkygAwIBAgICC7gwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCTFUx
-FjAUBgNVBAoTDUx1eFRydXN0IHMuYS4xHTAbBgNVBAMTFEx1eFRydXN0IEdsb2Jh
-bCBSb290MB4XDTExMDMxNzA5NTEzN1oXDTIxMDMxNzA5NTEzN1owRDELMAkGA1UE
-BhMCTFUxFjAUBgNVBAoTDUx1eFRydXN0IHMuYS4xHTAbBgNVBAMTFEx1eFRydXN0
-IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsn+n
-QPAiygz267Hxyw6VV0B1r6A/Ps7sqjJX5hmxZ0OYWmt8s7j6eJyqpoSyYBuAQc5j
-zR8XCJmk9e8+EsdMsFeaXHhAePxFjdqRZ9w6Ubltc+a3OY52OrQfBfVpVfmTz3iI
-Sr6qm9d7R1tGBEyCFqY19vx039a0r9jitScRdFmiwmYsaArhmIiIPIoFdRTjuK7z
-CISbasE/MRivJ6VLm6T9eTHemD0OYcqHmMH4ijCc+j4z1aXEAwfh95Z0GAAnOCfR
-K6qq4UFFi2/xJcLcopeVx0IUM115hCNq52XAV6DYXaljAeew5Ivo+MVjuOVsdJA9
-x3f8K7p56aTGEnin/wIDAQABo2AwXjAMBgNVHRMEBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAfBgNVHSMEGDAWgBQXFYWJCS8kh28/HRvk8pZ5g0gTzjAdBgNVHQ4EFgQU
-FxWFiQkvJIdvPx0b5PKWeYNIE84wDQYJKoZIhvcNAQELBQADggEBAFrwHNDUUM9B
-fua4nX3DcNBeNv9ujnov3kgR1TQuPLdFwlQlp+HBHjeDtpSutkVIA+qVvuucarQ3
-XB8u02uCgUNbCj8RVWOs+nwIAjegPDkEM/6XMshS5dklTbDG7mgfcKpzzlcD3H0K
-DTPy0lrfCmw7zBFRlxqkIaKFNQLXgCLShLL4wKpov9XrqsMLq6F8K/f1O4fhVFfs
-BSTveUJO84ton+Ruy4KZycwq3FPCH3CDqyEPVrRI/98HIrOM+R2mBN8tAza53W/+
-MYhm/2xtRDSvCHc+JtJy9LtHVpM8mGPhM7uZI5K1g3noHZ9nrWLWidb2/CfeMifL
-hNp3hSGhEiE=
------END CERTIFICATE-----
diff --git a/make/data/cacerts/quovadisrootca b/make/data/cacerts/quovadisrootca
deleted file mode 100644
index 0c195ff51..000000000
--- a/make/data/cacerts/quovadisrootca
+++ /dev/null
@@ -1,41 +0,0 @@
-Owner: CN=QuoVadis Root Certification Authority, OU=Root Certification Authority, O=QuoVadis Limited, C=BM
-Issuer: CN=QuoVadis Root Certification Authority, OU=Root Certification Authority, O=QuoVadis Limited, C=BM
-Serial number: 3ab6508b
-Valid from: Mon Mar 19 18:33:33 GMT 2001 until: Wed Mar 17 18:33:33 GMT 2021
-Signature algorithm name: SHA1withRSA
-Subject Public Key Algorithm: 2048-bit RSA key
-Version: 3
------BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
-MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
-IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
-dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
-li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
-rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
-WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
-F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
-xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
-Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
-dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
-ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
-IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
-c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
-ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
-Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
-KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
-KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
-y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
-dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
-VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
-fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
-7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
-cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
-mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
-xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
-SnQ2+Q==
------END CERTIFICATE-----
diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
index c67aa91dd..9079299fb 100644
--- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
+++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
@@ -54,12 +54,12 @@ public class VerifyCACerts {
+ File.separator + "security" + File.separator + "cacerts";
// The numbers of certs now.
- private static final int COUNT = 90;
+ private static final int COUNT = 87;
// SHA-256 of cacerts, can be generated with
// shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
private static final String CHECKSUM
- = "21:8C:35:29:4C:E2:49:D2:83:30:DF:8B:5E:39:F8:8C:D6:C5:2B:59:05:32:74:E5:79:A5:91:9F:3C:57:B9:E3";
+ = "D5:5B:7A:BD:8F:4A:DA:19:75:90:28:61:E7:40:6D:A2:54:F5:64:C0:F0:30:29:16:FB:46:9B:57:D5:F7:04:D7";
// Hex formatter to upper case with ":" delimiter
private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase();
@@ -120,8 +120,6 @@ public class VerifyCACerts {
"7E:37:CB:8B:4C:47:09:0C:AB:36:55:1B:A6:F4:5D:B8:40:68:0F:BA:16:6A:95:2D:B1:00:71:7F:43:05:3F:C2");
put("digicerthighassuranceevrootca [jdk]",
"74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF");
- put("geotrustglobalca [jdk]",
- "FF:85:6A:2D:25:1D:CD:88:D3:66:56:F4:50:12:67:98:CF:AB:AA:DE:40:79:9C:72:2D:E4:D2:B5:DB:36:A7:3A");
put("geotrustprimaryca [jdk]",
"37:D5:10:06:C5:12:EA:AB:62:64:21:F1:EC:8C:92:01:3F:C5:F8:2A:E9:8E:E5:33:EB:46:19:B8:DE:B4:D0:6C");
put("geotrustprimarycag2 [jdk]",
@@ -154,10 +152,6 @@ public class VerifyCACerts {
"5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE");
put("letsencryptisrgx1 [jdk]",
"96:BC:EC:06:26:49:76:F3:74:60:77:9A:CF:28:C5:A7:CF:E8:A3:C0:AA:E1:1A:8F:FC:EE:05:C0:BD:DF:08:C6");
- put("luxtrustglobalrootca [jdk]",
- "A1:B2:DB:EB:64:E7:06:C6:16:9E:3C:41:18:B2:3B:AA:09:01:8A:84:27:66:6D:8B:F0:E2:88:91:EC:05:19:50");
- put("quovadisrootca [jdk]",
- "A4:5E:DE:3B:BB:F0:9C:8A:E1:5C:72:EF:C0:72:68:D6:93:A2:1C:99:6F:D5:1E:67:CA:07:94:60:FD:6D:88:73");
put("quovadisrootca1g3 [jdk]",
"8A:86:6F:D1:B2:76:B5:7E:57:8E:92:1C:65:82:8A:2B:ED:58:E9:F2:F2:88:05:41:34:B7:F1:F4:BF:C9:CC:74");
put("quovadisrootca2 [jdk]",
@@ -262,12 +256,6 @@ public class VerifyCACerts {
add("addtrustexternalca [jdk]");
// Valid until: Sat May 30 10:44:50 GMT 2020
add("addtrustqualifiedca [jdk]");
- // Valid until: Wed Mar 17 02:51:37 PDT 2021
- add("luxtrustglobalrootca [jdk]");
- // Valid until: Wed Mar 17 11:33:33 PDT 2021
- add("quovadisrootca [jdk]");
- // Valid until: Sat May 21 04:00:00 GMT 2022
- add("geotrustglobalca [jdk]");
}
};

View File

@ -0,0 +1,137 @@
From 0a09586f510fb92a4e9eec3aa87fd9673b7b68a7 Mon Sep 17 00:00:00 2001
Subject: Extending the IV Length Supported by KAEProvider AES/Gcm
---
.../security/openssl/kae_symmetric_cipher.c | 23 ++++++--
.../security/openssl/KAEGcmIvLenTest.java | 53 +++++++++++++++++++
2 files changed, 73 insertions(+), 3 deletions(-)
create mode 100644 test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java
diff --git a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c
index 67151f53a..220964d5f 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c
@@ -146,6 +146,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
const EVP_CIPHER* cipher = NULL;
ENGINE* kaeEngine = NULL;
int keyLength = (*env)->GetArrayLength(env, key);
+ int ivLength = 0;
const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0);
if (StartsWith("aes", algo)) {
@@ -158,7 +159,6 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
KAE_TRACE("KAESymmetricCipherBase_nativeInit: kaeEngine => %p", kaeEngine);
- (*env)->ReleaseStringUTFChars(env, cipherType, algo);
if (cipher == NULL) {
KAE_ThrowOOMException(env, "create EVP_CIPHER fail");
goto cleanup;
@@ -170,19 +170,35 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
if (iv != NULL) {
ivBytes = (*env)->GetByteArrayElements(env, iv, NULL);
+ ivLength = (*env)->GetArrayLength(env, iv);
}
if (key != NULL) {
keyBytes = (*env)->GetByteArrayElements(env, key, NULL);
}
- if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, (const unsigned char*)keyBytes,
- (const unsigned char*)ivBytes, encrypt ? 1 : 0)) {
+ if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, NULL,
+ NULL, encrypt ? 1 : 0)) {
KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex failed", KAE_ThrowRuntimeException);
goto cleanup;
}
+ if (strcasecmp(algo + 8, "gcm") == 0) {
+ /* Set IV length if default 12 bytes (96 bits) is not appropriate */
+ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivLength, NULL)) {
+ KAE_ThrowFromOpenssl(env, "EVP_CIPHER_CTX_ctrl failed", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+ }
+
+ if (!EVP_CipherInit_ex(ctx, NULL, kaeEngine, (const unsigned char*)keyBytes,
+ (const unsigned char*)ivBytes, encrypt ? 1 : 0)) {
+ KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex int key & iv failed", KAE_ThrowRuntimeException);
+ goto cleanup;
+ }
+
EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0);
+ (*env)->ReleaseStringUTFChars(env, cipherType, algo);
FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength);
return (jlong)ctx;
@@ -190,6 +206,7 @@ cleanup:
if (ctx != NULL) {
EVP_CIPHER_CTX_free(ctx);
}
+ (*env)->ReleaseStringUTFChars(env, cipherType, algo);
FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength);
return 0;
}
diff --git a/test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java b/test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java
new file mode 100644
index 000000000..444e47264
--- /dev/null
+++ b/test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java
@@ -0,0 +1,53 @@
+import org.openeuler.security.openssl.KAEProvider;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.Security;
+import java.util.Arrays;
+
+/**
+ * @test
+ * @summary Basic test for AES/GCM Iv
+ * @modules jdk.crypto.kaeprovider/org.openeuler.security.openssl
+ * @requires os.arch=="aarch64"
+ * @run main KAEGcmIvLenTest
+ */
+public class KAEGcmIvLenTest {
+ private static String plainText = "helloworldhellow"; // 16bytes for NoPadding
+ private static String shortPlainText = "helloworld"; // 5 bytes for padding
+ private static SecretKeySpec ks = new SecretKeySpec("AESEncryptionKey".getBytes(StandardCharsets.UTF_8), "AES"); // key has 16 bytes
+ private static int[] ivLens = {12, 16};
+ public static void main(String[] args) throws Exception {
+ Security.addProvider(new KAEProvider());
+ for (int ivLen : ivLens) {
+ testGcm(plainText,"AES/GCM/NoPadding", "KAEProvider", "SunJCE", ivLen);
+ testGcm(plainText,"AES/GCM/NoPadding", "SunJCE", "KAEProvider", ivLen);
+ testGcm(shortPlainText,"AES/GCM/NoPadding", "KAEProvider", "SunJCE", ivLen);
+ testGcm(shortPlainText,"AES/GCM/NoPadding", "SunJCE", "KAEProvider", ivLen);
+ }
+
+ }
+
+ private static void testGcm(String plainText, String algo, String encryptProvider, String decryptProvider, int ivLen) throws Exception {
+ Cipher enCipher = Cipher.getInstance(algo, encryptProvider);
+ enCipher.init(Cipher.ENCRYPT_MODE, ks, getIv(ivLen));
+ byte[] cipherText = enCipher.doFinal(plainText.getBytes());
+
+ Cipher deCipher = Cipher.getInstance(algo, decryptProvider);
+ deCipher.init(Cipher.DECRYPT_MODE, ks, getIv(ivLen));
+ byte[] origin = deCipher.doFinal(cipherText);
+
+ if (!Arrays.equals(plainText.getBytes(), origin)) {
+ throw new RuntimeException("gcm decryption failed, algo = " + algo);
+ }
+ }
+
+ private static GCMParameterSpec getIv(int ivLen) {
+ if (ivLen == 16) {
+ return new GCMParameterSpec(128, "abcdefghabcdefgh".getBytes(StandardCharsets.UTF_8));
+ }
+ return new GCMParameterSpec(96, "abcdefghabcd".getBytes(StandardCharsets.UTF_8));
+ }
+}
--
2.19.1

566
KAE-zip-Features.patch Normal file
View File

@ -0,0 +1,566 @@
---
make/autoconf/libraries.m4 | 4 ++
make/autoconf/spec.gmk.in | 1 +
make/modules/java.base/lib/CoreLibraries.gmk | 39 ++++++++++--
src/hotspot/share/runtime/arguments.cpp | 9 +++
.../share/classes/java/util/zip/Deflater.java | 27 ++++++++
.../java/util/zip/GZIPInputStream.java | 62 ++++++++++++++++++-
.../java/util/zip/GZIPOutputStream.java | 35 ++++++++++-
.../share/classes/java/util/zip/Inflater.java | 23 +++++++
.../java/util/zip/InflaterInputStream.java | 21 +++++++
src/java.base/share/conf/security/java.policy | 4 ++
src/java.base/share/native/libzip/Deflater.c | 38 ++++++++++++
src/java.base/share/native/libzip/Inflater.c | 37 ++++++++++-
.../zip/GZIP/GZIPOutputStreamHeaderTest.java | 4 ++
13 files changed, 296 insertions(+), 8 deletions(-)
diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4
index 264a83189..b6a261eef 100644
--- a/make/autoconf/libraries.m4
+++ b/make/autoconf/libraries.m4
@@ -198,4 +198,8 @@ AC_DEFUN_ONCE([LIB_SETUP_MISC_LIBS],
# Control if libzip can use mmap. Available for purposes of overriding.
LIBZIP_CAN_USE_MMAP=true
AC_SUBST(LIBZIP_CAN_USE_MMAP)
+
+ # Control if libz can use mmap. Available for purposes of overriding.
+ LIBZ_CAN_USE_MMAP=true
+ AC_SUBST(LIBZ_CAN_USE_MMAP)
])
diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in
index e3f43ebf0..769c3ae3c 100644
--- a/make/autoconf/spec.gmk.in
+++ b/make/autoconf/spec.gmk.in
@@ -787,6 +787,7 @@ USE_EXTERNAL_LIBZ:=@USE_EXTERNAL_LIBZ@
LIBZ_CFLAGS:=@LIBZ_CFLAGS@
LIBZ_LIBS:=@LIBZ_LIBS@
LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@
+LIBZ_CAN_USE_MMAP:=@LIBZ_CAN_USE_MMAP@
MSVCR_DLL:=@MSVCR_DLL@
VCRUNTIME_1_DLL:=@VCRUNTIME_1_DLL@
MSVCP_DLL:=@MSVCP_DLL@
diff --git a/make/modules/java.base/lib/CoreLibraries.gmk b/make/modules/java.base/lib/CoreLibraries.gmk
index bb09d8cf8..8b03ea56e 100644
--- a/make/modules/java.base/lib/CoreLibraries.gmk
+++ b/make/modules/java.base/lib/CoreLibraries.gmk
@@ -119,9 +119,39 @@ $(BUILD_LIBJAVA): $(BUILD_LIBFDLIBM)
##########################################################################################
-BUILD_LIBZIP_EXCLUDES :=
-ifeq ($(USE_EXTERNAL_LIBZ), true)
- LIBZIP_EXCLUDES += zlib
+ifeq ($(USE_EXTERNAL_LIBZ), false)
+ ifeq ($(OPENJDK_TARGET_OS), linux)
+ ifeq ($(LIBZ_CAN_USE_MMAP), true)
+ BUILD_LIBZ_MMAP := -DUSE_MMAP
+ endif
+
+ $(eval $(call SetupJdkLibrary, BUILD_LIBZ, \
+ NAME := z, \
+ SRC := $(TOPDIR)/src/java.base/share/native/libzip/zlib, \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(filter-out -fvisibility=hidden,$(CFLAGS_JDKLIB) $(LIBZ_CFLAGS)), \
+ CFLAGS_unix := $(BUILD_LIBZ_MMAP) -UDEBUG, \
+ DISABLED_WARNINGS_gcc := unused-function implicit-fallthrough, \
+ DISABLED_WARNINGS_gcc_gzlib.c := implicit-function-declaration, \
+ DISABLED_WARNINGS_gcc_gzwrite.c := implicit-function-declaration, \
+ DISABLED_WARNINGS_gcc_gzread.c := implicit-function-declaration, \
+ DISABLED_WARNINGS_clang := format-nonliteral, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS_unix := , \
+ LIBS_windows := jvm.lib $(WIN_JAVA_LIB), \
+ ))
+
+ $(BUILD_LIBZ): $(BUILD_LIBJAVA)
+
+ TARGETS += $(BUILD_LIBZ)
+ endif
+endif
+
+##########################################################################################
+
+ifeq ($(OPENJDK_TARGET_OS), linux)
+ LIBZIP_EXCLUDES := zlib
endif
ifeq ($(LIBZIP_CAN_USE_MMAP), true)
@@ -139,10 +169,11 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBZIP, \
DISABLED_WARNINGS_clang := format-nonliteral, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS_unix := -ljvm -ljava $(LIBZ_LIBS), \
+ LIBS_unix := -ljvm -ljava -lz, \
LIBS_windows := jvm.lib $(WIN_JAVA_LIB), \
))
+$(BUILD_LIBZIP): $(BUILD_LIBZ)
$(BUILD_LIBZIP): $(BUILD_LIBJAVA)
TARGETS += $(BUILD_LIBZIP)
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index bc56a1322..9ef0a0db2 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -2617,6 +2617,15 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
// -D
} else if (match_option(option, "-D", &tail)) {
const char* value;
+#ifndef AARCH64
+ if (match_option(option, "-DGZIP_USE_KAE=", &value)) {
+ if (strcmp(value, "true") == 0) {
+ jio_fprintf(defaultStream::output_stream(),
+ "-DGZIP_USE_KAE is not supported. This system propertiy is valid only on aarch64 architecture machines.\n"
+ "The compression action is performed using the native compression capability of the JDK.\n");
+ }
+ }
+#endif
if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
*value!= '\0' && strcmp(value, "\"\"") != 0) {
// abort if -Djava.endorsed.dirs is set
diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java
index 88da99ba6..02852ab64 100644
--- a/src/java.base/share/classes/java/util/zip/Deflater.java
+++ b/src/java.base/share/classes/java/util/zip/Deflater.java
@@ -201,6 +201,20 @@ public class Deflater {
init(level, DEFAULT_STRATEGY, nowrap));
}
+ /**
+ * Creates a new compressor using the specified compression level
+ * and windowBits.
+ * This method is mainly used to support the KAE-zip feature.
+ * @param level the compression level (0-9)
+ * @param windowBits compression format (-15~31)
+ */
+ public Deflater(int level, int windowBits) {
+ this.level = level;
+ this.strategy = DEFAULT_STRATEGY;
+ this.zsRef = new DeflaterZStreamRef(this,
+ initKAE(level, DEFAULT_STRATEGY, windowBits));
+ }
+
/**
* Creates a new compressor using the specified compression level.
* Compressed data will be generated in ZLIB format.
@@ -878,6 +892,18 @@ public class Deflater {
}
}
+ /**
+ * Resets deflater so that a new set of input data can be processed.
+ * Java fields are not initialized.
+ * This method is mainly used to support the KAE-zip feature.
+ */
+ public void resetKAE() {
+ synchronized (zsRef) {
+ ensureOpen();
+ reset(zsRef.address());
+ }
+ }
+
/**
* Closes the compressor and discards any unprocessed input.
*
@@ -909,6 +935,7 @@ public class Deflater {
}
private static native long init(int level, int strategy, boolean nowrap);
+ private static native long initKAE(int level, int strategy, int windowBits);
private static native void setDictionary(long addr, byte[] b, int off,
int len);
private static native void setDictionaryBuffer(long addr, long bufAddress, int len);
diff --git a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java
index 4f3f9eae4..1d8afae1c 100644
--- a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java
+++ b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java
@@ -54,6 +54,23 @@ public class GZIPInputStream extends InflaterInputStream {
private boolean closed = false;
+ /**
+ * The field is mainly used to support the KAE-zip feature.
+ */
+ private static boolean GZIP_USE_KAE = false;
+
+ private static int WINDOWBITS = 31;
+
+ private static int FLUSHKAE = 2;
+
+ static {
+ if ("aarch64".equals(System.getProperty("os.arch"))) {
+ GZIP_USE_KAE = Boolean.parseBoolean(System.getProperty("GZIP_USE_KAE", "false"));
+ WINDOWBITS = Integer.parseInt(System.getProperty("WINDOWBITS", "31"));
+ FLUSHKAE = Integer.parseInt(System.getProperty("FLUSHKAE", "2"));
+ }
+ }
+
/**
* Check to make sure that this stream has not been closed
*/
@@ -74,8 +91,13 @@ public class GZIPInputStream extends InflaterInputStream {
* @throws IllegalArgumentException if {@code size <= 0}
*/
public GZIPInputStream(InputStream in, int size) throws IOException {
- super(in, in != null ? new Inflater(true) : null, size);
+ super(in, in != null ? (GZIP_USE_KAE ? new Inflater(WINDOWBITS, FLUSHKAE) : new Inflater(true)) : null, size);
usesDefaultInflater = true;
+
+ // When GZIP_USE_KAE is true, the header of the file is readed
+ // through the native zlib library, not in java code.
+ if (GZIP_USE_KAE) return;
+
readHeader(in);
}
@@ -116,13 +138,16 @@ public class GZIPInputStream extends InflaterInputStream {
}
int n = super.read(buf, off, len);
if (n == -1) {
- if (readTrailer())
+ if (GZIP_USE_KAE ? readTrailerKAE() : readTrailer())
eos = true;
else
return this.read(buf, off, len);
} else {
crc.update(buf, off, n);
}
+ if (GZIP_USE_KAE && inf.finished()) {
+ if (readTrailerKAE()) eos = true;
+ }
return n;
}
@@ -237,6 +262,39 @@ public class GZIPInputStream extends InflaterInputStream {
return false;
}
+ /*
+ * Reads GZIP member trailer and returns true if the eos
+ * reached, false if there are more (concatenated gzip
+ * data set)
+ *
+ * This method is mainly used to support the KAE-zip feature.
+ */
+ private boolean readTrailerKAE() throws IOException {
+ InputStream in = this.in;
+ int n = inf.getRemaining();
+ if (n > 0) {
+ in = new SequenceInputStream(
+ new ByteArrayInputStream(buf, len - n, n),
+ new FilterInputStream(in) {
+ public void close() throws IOException {}
+ });
+ }
+ // If there are more bytes available in "in" or the leftover in the "inf" is > 18 bytes:
+ // next.header.min(10) + next.trailer(8), try concatenated case
+
+ if (n > 18) {
+ inf.reset();
+ inf.setInput(buf, len - n, n);
+ } else {
+ try {
+ fillKAE(n);
+ } catch (IOException e) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/*
* Reads unsigned integer in Intel byte order.
*/
diff --git a/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java b/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
index cdfac329c..f9570265e 100644
--- a/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
+++ b/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
@@ -55,6 +55,20 @@ public class GZIPOutputStream extends DeflaterOutputStream {
// Represents the default "unknown" value for OS header, per RFC-1952
private static final byte OS_UNKNOWN = (byte) 255;
+ /**
+ * The field is mainly used to support the KAE-zip feature.
+ */
+ private static boolean GZIP_USE_KAE = false;
+
+ private static int WINDOWBITS = 31;
+
+ static {
+ if ("aarch64".equals(System.getProperty("os.arch"))) {
+ GZIP_USE_KAE = Boolean.parseBoolean(System.getProperty("GZIP_USE_KAE", "false"));
+ WINDOWBITS = Integer.parseInt(System.getProperty("WINDOWBITS", "31"));
+ }
+ }
+
/**
* Creates a new output stream with the specified buffer size.
*
@@ -90,10 +104,16 @@ public class GZIPOutputStream extends DeflaterOutputStream {
public GZIPOutputStream(OutputStream out, int size, boolean syncFlush)
throws IOException
{
- super(out, out != null ? new Deflater(Deflater.DEFAULT_COMPRESSION, true) : null,
+ super(out, out != null ?
+ (GZIP_USE_KAE ? new Deflater(Deflater.DEFAULT_COMPRESSION, WINDOWBITS) :
+ new Deflater(Deflater.DEFAULT_COMPRESSION, true)) : null,
size,
syncFlush);
usesDefaultDeflater = true;
+
+ // When GZIP_USE_KAE is true, the header of the file is written
+ // through the native zlib library, not in java code.
+ if (GZIP_USE_KAE) return;
writeHeader();
crc.reset();
}
@@ -163,6 +183,13 @@ public class GZIPOutputStream extends DeflaterOutputStream {
int len = def.deflate(buf, 0, buf.length);
if (def.finished() && len <= buf.length - TRAILER_SIZE) {
// last deflater buffer. Fit trailer at the end
+ // When GZIP_USE_KAE is true, the trailer of the file is written
+ // through the native zlib library, not in java code.
+ if (GZIP_USE_KAE) {
+ out.write(buf, 0, len);
+ def.resetKAE();
+ return;
+ }
writeTrailer(buf, len);
len = len + TRAILER_SIZE;
out.write(buf, 0, len);
@@ -173,6 +200,12 @@ public class GZIPOutputStream extends DeflaterOutputStream {
}
// if we can't fit the trailer at the end of the last
// deflater buffer, we write it separately
+ // When GZIP_USE_KAE is true, the trailer of the file is written
+ // through the native zlib library, not in java code.
+ if (GZIP_USE_KAE) {
+ def.resetKAE();
+ return;
+ }
byte[] trailer = new byte[TRAILER_SIZE];
writeTrailer(trailer, 0);
out.write(trailer);
diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java
index b6fe36010..77e4dd07f 100644
--- a/src/java.base/share/classes/java/util/zip/Inflater.java
+++ b/src/java.base/share/classes/java/util/zip/Inflater.java
@@ -131,6 +131,17 @@ public class Inflater {
this.zsRef = new InflaterZStreamRef(this, init(nowrap));
}
+ /**
+ * Creates a new decompressor.
+ * This method is mainly used to support the KAE-zip feature.
+ *
+ * @param windowBits compression format (-15~31)
+ * @param flushKAE inflate flush type (0~6)
+ */
+ public Inflater(int windowBits, int flushKAE) {
+ this.zsRef = new InflaterZStreamRef(this, initKAE(windowBits, flushKAE));
+ }
+
/**
* Creates a new decompressor.
*/
@@ -692,6 +703,17 @@ public class Inflater {
}
}
+ /**
+ * Resets inflater so that a new set of input data can be processed.
+ * This method is mainly used to support the KAE-zip feature.
+ */
+ public void resetKAE() {
+ synchronized (zsRef) {
+ ensureOpen();
+ reset(zsRef.address());
+ }
+ }
+
/**
* Closes the decompressor and discards any unprocessed input.
*
@@ -716,6 +738,7 @@ public class Inflater {
private static native void initIDs();
private static native long init(boolean nowrap);
+ private static native long initKAE(int windowBits, int flushKAE);
private static native void setDictionary(long addr, byte[] b, int off,
int len);
private static native void setDictionaryBuffer(long addr, long bufAddress, int len);
diff --git a/src/java.base/share/classes/java/util/zip/InflaterInputStream.java b/src/java.base/share/classes/java/util/zip/InflaterInputStream.java
index 534241d3d..88f8c5f1b 100644
--- a/src/java.base/share/classes/java/util/zip/InflaterInputStream.java
+++ b/src/java.base/share/classes/java/util/zip/InflaterInputStream.java
@@ -246,6 +246,27 @@ public class InflaterInputStream extends FilterInputStream {
inf.setInput(buf, 0, len);
}
+ /**
+ * Fills input buffer with more data to decompress.
+ * This method is mainly used to support the KAE-zip feature.
+ * @param n Maximum Read Bytes
+ * @throws IOException if an I/O error has occurred
+ */
+ protected void fillKAE(int n) throws IOException {
+ ensureOpen();
+ byte[] buftmp = new byte[buf.length];
+ if (n != 0) {
+ System.arraycopy(buf, buf.length - n, buftmp, 0, n);
+ }
+ int kaelen = in.read(buftmp, n, buf.length - n);
+ if (kaelen == -1) {
+ throw new EOFException("Unexpected end of ZLIB input stream");
+ }
+ System.arraycopy(buftmp, 0, buf, buf.length - n - kaelen, n + kaelen);
+ inf.reset();
+ inf.setInput(buf, buf.length - n - kaelen, n + kaelen);
+ }
+
/**
* Tests if this input stream supports the {@code mark} and
* {@code reset} methods. The {@code markSupported}
diff --git a/src/java.base/share/conf/security/java.policy b/src/java.base/share/conf/security/java.policy
index 1554541d1..4eda61464 100644
--- a/src/java.base/share/conf/security/java.policy
+++ b/src/java.base/share/conf/security/java.policy
@@ -41,4 +41,8 @@ grant {
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
+
+ permission java.util.PropertyPermission "GZIP_USE_KAE", "read";
+ permission java.util.PropertyPermission "WINDOWBITS", "read";
+ permission java.util.PropertyPermission "FLUSHKAE", "read";
};
diff --git a/src/java.base/share/native/libzip/Deflater.c b/src/java.base/share/native/libzip/Deflater.c
index 1ed1994d4..c04d5c42a 100644
--- a/src/java.base/share/native/libzip/Deflater.c
+++ b/src/java.base/share/native/libzip/Deflater.c
@@ -76,6 +76,44 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level,
}
}
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Deflater_initKAE(JNIEnv *env, jclass cls, jint level,
+ jint strategy, jint windowBits)
+{
+ z_stream *strm = calloc(1, sizeof(z_stream));
+
+ if (strm == 0) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ } else {
+ const char *msg;
+ int ret = deflateInit2(strm, level, Z_DEFLATED,
+ windowBits,
+ DEF_MEM_LEVEL, strategy);
+ switch (ret) {
+ case Z_OK:
+ return ptr_to_jlong(strm);
+ case Z_MEM_ERROR:
+ free(strm);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ case Z_STREAM_ERROR:
+ free(strm);
+ JNU_ThrowIllegalArgumentException(env, 0);
+ return jlong_zero;
+ default:
+ msg = ((strm->msg != NULL) ? strm->msg :
+ (ret == Z_VERSION_ERROR) ?
+ "zlib returned Z_VERSION_ERROR: "
+ "compile time and runtime zlib implementations differ" :
+ "unknown error initializing zlib library");
+ free(strm);
+ JNU_ThrowInternalError(env, msg);
+ return jlong_zero;
+ }
+ }
+}
+
static void throwInternalErrorHelper(JNIEnv *env, z_stream *strm, const char *fixmsg) {
const char *msg = NULL;
msg = (strm->msg != NULL) ? strm->msg : fixmsg;
diff --git a/src/java.base/share/native/libzip/Inflater.c b/src/java.base/share/native/libzip/Inflater.c
index a41e9775b..4835bfac2 100644
--- a/src/java.base/share/native/libzip/Inflater.c
+++ b/src/java.base/share/native/libzip/Inflater.c
@@ -44,6 +44,7 @@
static jfieldID inputConsumedID;
static jfieldID outputConsumedID;
+static jint inflaterFlushType = Z_PARTIAL_FLUSH;
JNIEXPORT void JNICALL
Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls)
@@ -87,6 +88,40 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap)
}
}
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Inflater_initKAE(JNIEnv *env, jclass cls, jint windowBits, jint flushKAE)
+{
+ z_stream *strm = calloc(1, sizeof(z_stream));
+ inflaterFlushType = flushKAE;
+
+ if (strm == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ } else {
+ const char *msg;
+ int ret = inflateInit2(strm, windowBits);
+ switch (ret) {
+ case Z_OK:
+ return ptr_to_jlong(strm);
+ case Z_MEM_ERROR:
+ free(strm);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ default:
+ msg = ((strm->msg != NULL) ? strm->msg :
+ (ret == Z_VERSION_ERROR) ?
+ "zlib returned Z_VERSION_ERROR: "
+ "compile time and runtime zlib implementations differ" :
+ (ret == Z_STREAM_ERROR) ?
+ "inflateInit2 returned Z_STREAM_ERROR" :
+ "unknown error initializing zlib library");
+ free(strm);
+ JNU_ThrowInternalError(env, msg);
+ return jlong_zero;
+ }
+ }
+}
+
static void checkSetDictionaryResult(JNIEnv *env, jlong addr, int res)
{
switch (res) {
@@ -137,7 +172,7 @@ static jint doInflate(jlong addr,
strm->avail_in = inputLen;
strm->avail_out = outputLen;
- ret = inflate(strm, Z_PARTIAL_FLUSH);
+ ret = inflate(strm, inflaterFlushType);
return ret;
}
diff --git a/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java b/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java
index 93c2e91fe..4038ad9a7 100644
--- a/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java
+++ b/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java
@@ -35,6 +35,10 @@ import java.util.zip.GZIPOutputStream;
* @bug 8244706
* @summary Verify that the OS header flag in the stream written out by java.util.zip.GZIPOutputStream
* has the correct expected value
+ * @comment This test case is not suitable for GZIP-zip feature testing, the ninth byte in the header
+ * of the gzip file identifies the operating system that generated the file. By default, the byte of
+ * the compressed package generated by JDK is 0xff (OS_UNKNOWN). KAE-zip relies on the underlying
+ * zlib library to write header files, this field is set to 0x03 (OS_UNIX). Therefore, this case will fail
* @run testng GZIPOutputStreamHeaderTest
*/
public class GZIPOutputStreamHeaderTest {
--
2.19.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -903,7 +903,7 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release}
Name: java-%{javaver}-%{origin}
Version: %{newjavaver}.%{buildver}
Release: 0
Release: 3
# 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
@ -932,7 +932,7 @@ Summary: %{origin_nice} Runtime Environment %{majorver}
# The test code includes copies of NSS under the Mozilla Public License v2.0
# The PCSClite headers are under a BSD with advertising license
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA-MD
URL: http://openjdk.java.net/
@ -1013,6 +1013,20 @@ Patch43: puyuan-jdk17.0.9-patch.patch
#17.0.11
Patch44: jdk17-Add-KAE-provider.patch
#17.0.12
Patch45: Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch
Patch46: Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch
Patch47: Add-JBooster-RPC-module-and-basic-framework.patch
Patch48: 8264806-Backport-Graal-Compiler.patch
Patch49: 8264805-Backport-Ahead-of-Time-Compiler.patch
Patch50: Add-JBooster-Lazy-AOT-module.patch
Patch51: Add-Aggressive-CDS-module.patch
Patch52: Add-Class-Loader-Resource-Cache-module.patch
Patch53: Add-JBooster-options-check.patch
Patch54: KAE-zip-Features.patch
Patch55: heap-dump-redact-support.patch
Patch56: Backport-Important-Fixed-Issues.patch
############################################
#
# LoongArch64 specific patches
@ -1270,6 +1284,18 @@ pushd %{top_level_dir_name}
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
popd # openjdk
%endif
@ -1397,7 +1423,7 @@ bash ../configure \
--enable-kae=yes \
%endif
--with-version-build=%{buildver} \
--with-version-pre=\"${EA_DESIGNATOR}\" \
--with-version-pre="${EA_DESIGNATOR}" \
--with-version-opt=%{lts_designator} \
%if "%toolchain" == "clang"
--with-toolchain-type=clang \
@ -1837,6 +1863,17 @@ cjc.mainProgram(args) -- the returns from copy_jdk_configs.lua should not affect
%changelog
* Fri Aug 30 2024 neu-mob <liuyulong35@huawei.com> - 1:17.0.12.7-3
- Add some features: JBooster/KAE zip
* Sat Aug 3 2024 kuenking111 <wangkun49@huawei.com> - 1:17.0.12.7-2
- add Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch
- add Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch
* Thu Jul 25 2024 songliyang <songliyang@kylinos.cn> - 1:17.0.12.7-1
- update Loongarch support patch to fix the error while applying in prep stage
- delete redundant symbols while viewing spec file with vim that make it strange on highlight
* Thu Jul 18 2024 DXwangg <wangjiawei80@huawei.com> - 1:17.0.12.7-0
- modify 8280872-Reorder-code-cache-segments-to-improv.patch
- update to 17.0.12+7(ga)