Compare commits

...

14 Commits

Author SHA1 Message Date
openeuler-ci-bot
53cace2b5e
!146 sync master to openEuler-24.03-LTS
From: @Autistic_boyya 
Reviewed-by: @kuenking111 
Signed-off-by: @kuenking111
2025-02-26 09:15:39 +00:00
佛系少年中二
7e283f1796 sync master to openEuler-24.03-LTS 2025-02-25 16:45:21 +08:00
openeuler-ci-bot
aa0a32da92
!139 [sync] PR-116: Fix build error for riscv64
From: @openeuler-sync-bot 
Reviewed-by: @jiangfeilong1003 
Signed-off-by: @jiangfeilong1003
2025-01-24 07:48:50 +00:00
Dingli Zhang
5437ac2c6c Fix build error for riscv64
(cherry picked from commit 89dfdc3119707448a1eec768f2aecf86464b04a6)
2024-12-30 15:54:22 +08:00
openeuler-ci-bot
c95057c154
!121 sync master to openEuler-24.03-LTS
From: @neu-mobi 
Reviewed-by: @kuenking111 
Signed-off-by: @kuenking111
2024-11-18 11:56:18 +00:00
佛系少年中二
8acecd1fe4 sync master to openEuler-24.03-LTS 2024-11-18 16:55:21 +08:00
openeuler-ci-bot
193da075e3
!95 Merge master(update to 17.0.12)
From: @DXwangg 
Reviewed-by: @kuenking111 
Signed-off-by: @kuenking111
2024-08-06 03:46:56 +00:00
DXwangg
ace712a1d3 Merge master(update to 17.0.12) 2024-07-29 15:31:08 +08:00
openeuler-ci-bot
419d05f85e
!90 update to 17.0.12
From: @DXwangg 
Reviewed-by: @kuenking111 
Signed-off-by: @kuenking111
2024-07-23 11:53:23 +00:00
DXwangg
cf054c4cb3 IADXQP:update to 17.0.12 2024-07-23 17:28:33 +08:00
openeuler-ci-bot
b00a299285
!84 Update LoongArch src
From: @panxuefeng-loongson 
Reviewed-by: @kuenking111 
Signed-off-by: @kuenking111
2024-06-11 08:08:28 +00:00
panxuefeng
fe0e1ef945 Update LoongArch64-support.patch 2024-06-06 10:00:05 +08:00
openeuler-ci-bot
16701ba501
!73 upgrade to jdk17.0.11-ga
From: @kuenking111 
Reviewed-by: @alexanderbill 
Signed-off-by: @alexanderbill
2024-04-30 06:10:52 +00:00
18855466553
8ea9d78b85 upgrade to jdk17.0.11-ga 2024-04-30 10:06:09 +08:00
47 changed files with 544463 additions and 1093 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -208,9 +208,9 @@ deleted file mode 100644
index f47331a6d..000000000
--- a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java
+++ /dev/null
@@ -1,137 +0,0 @@
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2022, BELLSOFT. All rights reserved.
- * Copyright (c) 2024, BELLSOFT. 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
@ -300,13 +300,12 @@ index f47331a6d..000000000
- "-Xbatch",
- "-XX:+TieredCompilation",
- "-XX:+SegmentedCodeCache",
- "-XX:CompileOnly=" + className + "::main",
- "-XX:ReservedCodeCacheSize=" + (bigCodeHeap ? "256M" : "200M"),
- "-XX:+UnlockDiagnosticVMOptions",
- "-XX:+PrintAssembly",
- "-XX:CompileCommand=option," + className + "::main,bool,PrintAssembly,true",
- className};
-
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(procArgs);
- ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(procArgs);
- OutputAnalyzer output = new OutputAnalyzer(pb.start());
- List<String> lines = output.asLines();
-

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

View File

@ -0,0 +1,24 @@
From 4c0d9de31c79d6e8e71fda0d8bc67c7352451dc0 Mon Sep 17 00:00:00 2001
Date: Fri, 29 Nov 2024 16:48:18 +0800
Subject: 8323066 TestSkipRebuildRemsetPhase.java fails with Skipping Remembered Set Rebuild
---
test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
index 860d3ce48..1a4c13132 100644
--- a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
+++ b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
@@ -45,7 +45,7 @@ public class TestSkipRebuildRemsetPhase {
"-XX:+UnlockExperimentalVMOptions",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
- "-XX:G1MixedGCLiveThresholdPercent=20",
+ "-XX:G1MixedGCLiveThresholdPercent=0",
"-Xlog:gc+marking=debug,gc+phases=debug,gc+remset+tracking=trace",
"-Xms10M",
"-Xmx10M",
--
2.22.0

View File

@ -0,0 +1,22 @@
Subject: 8335610: DiagnosticFramework: CmdLine::is_executable() correction
---
src/hotspot/share/services/diagnosticFramework.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/services/diagnosticFramework.hpp b/src/hotspot/share/services/diagnosticFramework.hpp
index e182e5440..166384193 100644
--- a/src/hotspot/share/services/diagnosticFramework.hpp
+++ b/src/hotspot/share/services/diagnosticFramework.hpp
@@ -67,7 +67,7 @@ public:
const char* cmd_addr() const { return _cmd; }
size_t cmd_len() const { return _cmd_len; }
bool is_empty() const { return _cmd_len == 0; }
- bool is_executable() const { return is_empty() || _cmd[0] != '#'; }
+ bool is_executable() const { return !is_empty() && _cmd[0] != '#'; }
bool is_stop() const { return !is_empty() && strncmp("stop", _cmd, _cmd_len) == 0; }
};
--
2.33.0

View File

@ -0,0 +1,40 @@
Subject: 8337274: Remove repeated 'the' in StyleSheet.create{Small,Large}AttributeSet
---
.../share/classes/javax/swing/text/html/StyleSheet.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java
index 958b3a899..25490291a 100644
--- a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java
+++ b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java
@@ -691,7 +691,7 @@ public class StyleSheet extends StyleContext {
* to return an AttributeSet that provides some sort of
* attribute conversion.
*
- * @param a The set of attributes to be represented in the
+ * @param a The set of attributes to be represented in
* the compact form.
*/
protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) {
@@ -707,7 +707,7 @@ public class StyleSheet extends StyleContext {
* to return a MutableAttributeSet that provides some sort of
* attribute conversion.
*
- * @param a The set of attributes to be represented in the
+ * @param a The set of attributes to be represented in
* the larger form.
*/
protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) {
@@ -2140,7 +2140,7 @@ public class StyleSheet extends StyleContext {
/**
* Returns a string that represents the value
* of the HTML.Attribute.TYPE attribute.
- * If this attributes is not defined, then
+ * If this attributes is not defined,
* then the type defaults to "disc" unless
* the tag is on Ordered list. In the case
* of the latter, the default type is "decimal".
--
2.33.0

View File

@ -0,0 +1,21 @@
Subject: 8337982: Remove dead undef assrt0n
---
src/hotspot/share/memory/metaspace/blockTree.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/hotspot/share/memory/metaspace/blockTree.cpp b/src/hotspot/share/memory/metaspace/blockTree.cpp
index ed2964534..9c78eef84 100644
--- a/src/hotspot/share/memory/metaspace/blockTree.cpp
+++ b/src/hotspot/share/memory/metaspace/blockTree.cpp
@@ -180,7 +180,6 @@ void BlockTree::verify() const {
// as many nodes as are in this tree)
_counter.check(counter);
- #undef assrt0n
}
void BlockTree::zap_range(MetaWord* p, size_t word_size) {
--
2.33.0

View File

@ -0,0 +1,22 @@
Subject: 8338785: The java.awt.datatransfer.SystemFlavorMap#FLAVOR_MAP_KEY field is not used
---
.../share/classes/java/awt/datatransfer/SystemFlavorMap.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java b/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java
index d48146513..4bde236fc 100644
--- a/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java
+++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java
@@ -61,8 +61,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
*/
private static String JavaMIME = "JAVA_DATAFLAVOR:";
- private static final Object FLAVOR_MAP_KEY = new Object();
-
/**
* The list of valid, decoded text flavor representation classes, in order
* from best to worst.
--
2.33.0

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,24 @@
From 530c07c5f332d2bce540acb181652f64457ec6c6 Mon Sep 17 00:00:00 2001
Date: Fri, 29 Nov 2024 16:00:40 +0800
Subject: Add Fix clear mark for NativeGotJump
---
src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
index fe7461964..f9438c235 100644
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
@@ -131,7 +131,7 @@ void NativePltCall::set_stub_to_clean() {
NativeLoadGot* method_loader = nativeLoadGot_at(plt_c2i_stub());
NativeGotJump* jump = nativeGotJump_at(method_loader->next_instruction_address());
method_loader->set_data(0);
- jump->set_jump_destination((address)-1);
+ jump->set_jump_destination((address)Universe::non_oop_word());
}
void NativePltCall::verify() const {
--
2.22.0

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,121 @@
From e2fd78d2cb7771f7cbc884e8c36d9a91fa0f8696 Mon Sep 17 00:00:00 2001
Date: Fri, 29 Nov 2024 15:40:37 +0800
Subject: Add KAE-zip GzipKAEBenchmark Benchmark
---
test/jdk/java/util/zip/GzipKAEBenchmark.java | 102 +++++++++++++++++++
1 file changed, 102 insertions(+)
create mode 100644 test/jdk/java/util/zip/GzipKAEBenchmark.java
diff --git a/test/jdk/java/util/zip/GzipKAEBenchmark.java b/test/jdk/java/util/zip/GzipKAEBenchmark.java
new file mode 100644
index 000000000..6d753e14e
--- /dev/null
+++ b/test/jdk/java/util/zip/GzipKAEBenchmark.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2024, 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.
+ */
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import java.util.concurrent.TimeUnit;
+import java.util.Random;
+
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Warmup(iterations = 5, time = 5, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.MILLISECONDS)
+@Fork(jvmArgsPrepend = {"-Xms1G", "-Xmx1G", "-XX:+AlwaysPreTouch"}, value = 1)
+@Threads(1)
+@State(Scope.Benchmark)
+public class GzipKAEBenchmark {
+
+ private byte[] srcBytes;
+ private byte[] dstBytes;
+
+ Random rnd = new Random(8192);
+ ByteArrayOutputStream srcBAOS = new ByteArrayOutputStream();
+ ByteArrayOutputStream dstBAOS = new ByteArrayOutputStream();
+
+ @Setup
+ public void setup() throws IOException {
+ Random rnd = new Random(8192);
+ ByteArrayOutputStream srcBAOS = new ByteArrayOutputStream();
+ ByteArrayOutputStream dstBAOS = new ByteArrayOutputStream();
+ for (int j = 0; j < 8192; j++) {
+ byte[] src = new byte[rnd.nextInt(8192) + 1];
+ rnd.nextBytes(src);
+ srcBAOS.write(src);
+ }
+ srcBytes = srcBAOS.toByteArray();
+ try (GZIPOutputStream gzos = new GZIPOutputStream(dstBAOS)) {
+ gzos.write(srcBytes);
+ }
+ dstBytes = dstBAOS.toByteArray();
+ }
+
+ @Param({"512", "2048", "10240", "51200", "204800"})
+ private int BuffSize;
+
+ @Benchmark
+ public void GzipDeflateTest() throws IOException{
+ ByteArrayOutputStream byteArrayInputStream = new ByteArrayOutputStream();
+ try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayInputStream, BuffSize)) {
+ gzipOutputStream.write(srcBytes);
+ }
+ }
+
+ @Benchmark
+ public void GzipInflateTest() {
+ ByteArrayInputStream bais = new ByteArrayInputStream(dstBytes);
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ try (GZIPInputStream gzipInputStream = new GZIPInputStream(bais, BuffSize)) {
+ byte[] buffer = new byte[1024*1024];
+ int len;
+ while ((len = gzipInputStream.read(buffer)) > 0) {
+ byteArrayOutputStream.write(buffer, 0, len);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
--
2.22.0

5263
Add-jbolt-feature.patch Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1584,7 +1584,7 @@ index f8900a13b..356c6ca8b 100644
+#endif
while (len > 0) {
const unsigned int nBytes = len > INT_MAX ? INT_MAX : (unsigned int)len;
const ssize_t num_written = (ssize_t)os::write(_fd, buf, nBytes);
const bool successful_write = os::write(_fd, buf, nBytes);
diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp
index cd0115248..41e946563 100644
--- a/src/hotspot/share/prims/jni.cpp

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

@ -0,0 +1,29 @@
Subject: Backport of 8330191: Fix typo in precompiled.hpp
---
src/hotspot/share/precompiled/precompiled.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/precompiled/precompiled.hpp b/src/hotspot/share/precompiled/precompiled.hpp
index d34304741..54d03ed71 100644
--- a/src/hotspot/share/precompiled/precompiled.hpp
+++ b/src/hotspot/share/precompiled/precompiled.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2024, 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
@@ -29,7 +29,7 @@
// These header files are included in at least 130 C++ files, as of
// measurements made in November 2018. This list excludes files named
-// *.include.hpp, since including them decreased build performance.
+// *.inline.hpp, since including them decreased build performance.
#include "classfile/classLoaderData.hpp"
#include "classfile/javaClasses.hpp"
--
2.33.0

View File

@ -0,0 +1,22 @@
Subject: Backport of 8333088: ubsan: shenandoahAdaptiveHeuristics.cpp: runtime error: division by zero
---
.../gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp
index 819f1e8d7..371e4c90c 100644
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp
@@ -243,7 +243,7 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() {
double avg_cycle_time = _gc_time_history->davg() + (_margin_of_error_sd * _gc_time_history->dsd());
double avg_alloc_rate = _allocation_rate.upper_bound(_margin_of_error_sd);
- if (avg_cycle_time > allocation_headroom / avg_alloc_rate) {
+ if (avg_cycle_time * avg_alloc_rate > allocation_headroom) {
log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for average allocation rate (%.0f %sB/s) to deplete free headroom (" SIZE_FORMAT "%s) (margin of error = %.2f)",
avg_cycle_time * 1000,
byte_size_in_proper_unit(avg_alloc_rate), proper_unit_for_byte_size(avg_alloc_rate),
--
2.33.0

View File

@ -0,0 +1,29 @@
Subject: Backport of 8337712: Wrong javadoc in java.util.Date#toString(): 61 and right parenthesis
---
src/java.base/share/classes/java/util/Date.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java.base/share/classes/java/util/Date.java b/src/java.base/share/classes/java/util/Date.java
index d0b31a402..9a0552dd3 100644
--- a/src/java.base/share/classes/java/util/Date.java
+++ b/src/java.base/share/classes/java/util/Date.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2024, 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
@@ -1014,7 +1014,7 @@ public class Date
* <li>{@code mm} is the minute within the hour ({@code 00} through
* {@code 59}), as two decimal digits.
* <li>{@code ss} is the second within the minute ({@code 00} through
- * {@code 61}, as two decimal digits.
+ * {@code 61}), as two decimal digits.
* <li>{@code zzz} is the time zone (and may reflect daylight saving
* time). Standard time zone abbreviations include those
* recognized by the method {@code parse}. If time zone
--
2.33.0

View File

@ -0,0 +1,21 @@
Subject: Backport of 8339351: Remove duplicate line in FileMapHeader::print
---
src/hotspot/share/cds/filemap.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp
index fa981d38c..106c14bfc 100644
--- a/src/hotspot/share/cds/filemap.cpp
+++ b/src/hotspot/share/cds/filemap.cpp
@@ -287,7 +287,6 @@ void FileMapHeader::print(outputStream* st) {
st->print_cr("- core_region_alignment: " SIZE_FORMAT, _core_region_alignment);
st->print_cr("- obj_alignment: %d", _obj_alignment);
st->print_cr("- narrow_oop_base: " INTPTR_FORMAT, p2i(_narrow_oop_base));
- st->print_cr("- narrow_oop_base: " INTPTR_FORMAT, p2i(_narrow_oop_base));
st->print_cr("- narrow_oop_shift %d", _narrow_oop_shift);
st->print_cr("- compact_strings: %d", _compact_strings);
st->print_cr("- max_heap_size: " UINTX_FORMAT, _max_heap_size);
--
2.33.0

View File

@ -0,0 +1,30 @@
Subject: Backport of JDK-8305680
---
src/hotspot/share/services/diagnosticCommand.cpp | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp
index 51f47421c..1400e4a3f 100644
--- a/src/hotspot/share/services/diagnosticCommand.cpp
+++ b/src/hotspot/share/services/diagnosticCommand.cpp
@@ -191,16 +191,6 @@ void HelpDCmd::execute(DCmdSource source, TRAPS) {
factory->is_enabled() ? "" : " [disabled]");
output()->print_cr("%s", factory->description());
output()->print_cr("\nImpact: %s", factory->impact());
- JavaPermission p = factory->permission();
- if(p._class != NULL) {
- if(p._action != NULL) {
- output()->print_cr("\nPermission: %s(%s, %s)",
- p._class, p._name == NULL ? "null" : p._name, p._action);
- } else {
- output()->print_cr("\nPermission: %s(%s)",
- p._class, p._name == NULL ? "null" : p._name);
- }
- }
output()->cr();
cmd = factory->create_resource_instance(output());
if (cmd != NULL) {
--
2.33.0

View File

@ -0,0 +1,23 @@
Subject: Backport of JDK-8305937
Signed-off-by: Qeryu <u201911667@hust.edu.cn>
---
test/jdk/com/sun/jdi/TestScaffold.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/jdk/com/sun/jdi/TestScaffold.java b/test/jdk/com/sun/jdi/TestScaffold.java
index 2d4885c90..e46a44eda 100644
--- a/test/jdk/com/sun/jdi/TestScaffold.java
+++ b/test/jdk/com/sun/jdi/TestScaffold.java
@@ -513,7 +513,7 @@ abstract public class TestScaffold extends TargetAdapter {
public void connect(String args[]) {
ArgInfo argInfo = parseArgs(args);
- argInfo.targetVMArgs += VMConnection.getDebuggeeVMOptions();
+ argInfo.targetVMArgs = VMConnection.getDebuggeeVMOptions() + " " + argInfo.targetVMArgs;
connection = new VMConnection(argInfo.connectorSpec,
argInfo.traceFlags);
--
2.33.0

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]");
}
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,363 @@
From b084e0e23535cb7e46802c3bf471ee8cafbe8a74 Mon Sep 17 00:00:00 2001
Subject: Fix a concurrent issue of program data ref cnt
---
.../share/jbooster/jClientArguments.hpp | 4 +
.../jbooster/server/serverDataManager.hpp | 4 +
.../utilities/concurrentHashMap.inline.hpp | 20 +---
test/hotspot/gtest/jbooster/test_net.cpp | 1 +
test/hotspot/gtest/jbooster/test_server.cpp | 107 ++++++++++++++++++
test/hotspot/gtest/jbooster/test_util.cpp | 3 +-
.../jbooster/JBoosterConcurrentTest.java | 106 +++++++++++++++++
test/jdk/tools/jbooster/TEST.properties | 1 +
8 files changed, 231 insertions(+), 15 deletions(-)
create mode 100644 test/hotspot/gtest/jbooster/test_server.cpp
create mode 100644 test/jdk/tools/jbooster/JBoosterConcurrentTest.java
create mode 100644 test/jdk/tools/jbooster/TEST.properties
diff --git a/src/hotspot/share/jbooster/jClientArguments.hpp b/src/hotspot/share/jbooster/jClientArguments.hpp
index 491ac3159..dd56ddc36 100644
--- a/src/hotspot/share/jbooster/jClientArguments.hpp
+++ b/src/hotspot/share/jbooster/jClientArguments.hpp
@@ -60,6 +60,9 @@ DECLARE_SERIALIZER_INTRUSIVE(JClientBoostLevel);
* Arguments that identify a program.
*/
class JClientArguments final: public CHeapObj<mtJBooster> {
+ // @see test/hotspot/gtest/jbooster/test_server.cpp
+ friend class Gtest_JBoosterServer;
+
enum InitState {
NOT_INITIALIZED_FOR_SEREVR,
INITIALIZED_FOR_SEREVR,
@@ -103,6 +106,7 @@ private:
public:
JClientArguments(bool is_client);
+ JClientArguments(DebugUtils* ignored) {} // for GTEST only
~JClientArguments();
int serialize(MessageBuffer& buf) const;
diff --git a/src/hotspot/share/jbooster/server/serverDataManager.hpp b/src/hotspot/share/jbooster/server/serverDataManager.hpp
index c6ef4c99a..a53af341c 100644
--- a/src/hotspot/share/jbooster/server/serverDataManager.hpp
+++ b/src/hotspot/share/jbooster/server/serverDataManager.hpp
@@ -173,6 +173,9 @@ public:
* The data of the program (usually a .class or .jar file) executed by the client.
*/
class JClientProgramData final: public CHeapObj<mtJBooster> {
+ // @see test/hotspot/gtest/jbooster/test_server.cpp
+ friend class Gtest_JBoosterServer;
+
public:
using ClassLoaderTable = ConcurrentHashMap<ClassLoaderKey, ClassLoaderData*, mtJBooster>;
@@ -195,6 +198,7 @@ private:
public:
JClientProgramData(uint32_t program_id, JClientArguments* program_args);
+ JClientProgramData(DebugUtils* ignored) {} // for GTEST only
~JClientProgramData();
uint32_t program_id() const { return _program_id; }
diff --git a/src/hotspot/share/jbooster/utilities/concurrentHashMap.inline.hpp b/src/hotspot/share/jbooster/utilities/concurrentHashMap.inline.hpp
index e69da290f..8abb853b7 100644
--- a/src/hotspot/share/jbooster/utilities/concurrentHashMap.inline.hpp
+++ b/src/hotspot/share/jbooster/utilities/concurrentHashMap.inline.hpp
@@ -168,8 +168,8 @@ inline V* ConcurrentHashMap<K, V, F, Events>::get(const K& key, Thread* thread)
V* res = nullptr;
if (_table.get(thread, lookup, get, &grow_hint)) {
- KVNode& kv_node = *get.res();
- res = &kv_node.value();
+ assert(get.res() != nullptr, "sanity");
+ res = &(get.res()->value());
}
return res;
@@ -184,18 +184,10 @@ inline V* ConcurrentHashMap<K, V, F, Events>::put_if_absent(const K& key, V& val
V* res = nullptr;
- do {
- if (_table.insert(thread, lookup, KVNode(key, value), &grow_hint, &clean_hint)) {
- res = &value;
- break;
- }
-
- if (_table.get(thread, lookup, get, &grow_hint)) {
- KVNode& kv_node = *get.res();
- res = &kv_node.value();
- break;
- }
- } while (true);
+ KVNode kv_node(key, value);
+ bool success = _table.insert_get(thread, lookup, kv_node, get, &grow_hint, &clean_hint);
+ assert(get.res() != nullptr, "sanity");
+ res = &(get.res()->value());
if (grow_hint) {
grow_if_needed(thread);
diff --git a/test/hotspot/gtest/jbooster/test_net.cpp b/test/hotspot/gtest/jbooster/test_net.cpp
index dd45dd65a..336418cf4 100644
--- a/test/hotspot/gtest/jbooster/test_net.cpp
+++ b/test/hotspot/gtest/jbooster/test_net.cpp
@@ -37,6 +37,7 @@
#include "runtime/os.inline.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
+
#include "unittest.hpp"
static int try_catch_func(int i) {
diff --git a/test/hotspot/gtest/jbooster/test_server.cpp b/test/hotspot/gtest/jbooster/test_server.cpp
new file mode 100644
index 000000000..322b947fd
--- /dev/null
+++ b/test/hotspot/gtest/jbooster/test_server.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2020, 2024, 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.
+ */
+
+#include "precompiled.hpp"
+#include "utilities/macros.hpp"
+
+#if INCLUDE_JBOOSTER
+
+#include "common.hpp"
+
+#include "jbooster/jClientArguments.hpp"
+#include "jbooster/server/serverDataManager.hpp"
+#include "jbooster/utilities/concurrentHashMap.inline.hpp"
+#include "jbooster/utilities/debugUtils.inline.hpp"
+#include "utilities/stringUtils.hpp"
+
+#include "unittest.hpp"
+
+struct Gtest_JBoosterServer {
+ static JClientArguments* create_mock_JClientArguments(uint32_t id) {
+ JClientArguments* mock = new JClientArguments((DebugUtils*) nullptr);
+
+ // [FOR EACH ARG]
+ mock->_cpu_arch = JClientArguments::CpuArch::CPU_UNKOWN;
+ mock->_jvm_version = id;
+ mock->_internal_jvm_info = StringUtils::copy_to_heap("internaljvminfo", mtJBooster);
+ mock->_program_name = StringUtils::copy_to_heap("programname", mtJBooster);
+ mock->_program_entry = StringUtils::copy_to_heap("programentry", mtJBooster);
+ mock->_is_jar = true;
+ mock->_classpath_name_hash = 1u;
+ mock->_classpath_timestamp_hash = 2u;
+ mock->_agent_name_hash = 3u;
+ mock->_cds_file_size = 456;
+ mock->_java_commands = StringUtils::copy_to_heap("javacommands", mtJBooster);
+ mock->_related_flags = new JClientVMFlags(true);
+
+ mock->_hash = mock->calc_hash();
+ mock->_state = JClientArguments::INITIALIZED_FOR_SEREVR;
+
+ return mock;
+ }
+
+ static JClientProgramData* create_mock_JClientProgramData(uint32_t program_id, JClientArguments* program_args) {
+ JClientProgramData* mock = new JClientProgramData((DebugUtils*) nullptr);
+
+ mock->_program_id = program_id;
+ mock->_program_args = program_args->move();
+ mock->_ref_cnt.inc();
+ mock->_program_str_id = StringUtils::copy_to_heap("programstrid", mtJBooster);
+ mock->clr_cache_state().init(StringUtils::copy_to_heap("gtestclr", mtJBooster));
+ mock->dy_cds_cache_state().init(StringUtils::copy_to_heap("gtestdycds", mtJBooster));
+ mock->agg_cds_cache_state().init(StringUtils::copy_to_heap("gtestaggcds", mtJBooster));
+ mock->aot_static_cache_state().init(StringUtils::copy_to_heap("gtestaotstatic", mtJBooster));
+ mock->aot_pgo_cache_state().init(StringUtils::copy_to_heap("gtestaotpgo", mtJBooster));
+
+ return mock;
+ }
+};
+
+TEST_VM(JBoosterServer, program_data_ref_cnt) {
+ JavaThread* THREAD = JavaThread::current();
+ ServerDataManager::JClientProgramDataMap programs;
+ JClientArguments* program_args1 = Gtest_JBoosterServer::create_mock_JClientArguments(11);
+ JClientProgramData* new_pd1 = Gtest_JBoosterServer::create_mock_JClientProgramData(1u, program_args1);
+ delete program_args1;
+ JClientProgramData** res1 = programs.put_if_absent(new_pd1->program_args(), new_pd1, THREAD);
+ EXPECT_NE(res1, (JClientProgramData**) nullptr);
+ EXPECT_EQ(*res1, new_pd1);
+ EXPECT_EQ(new_pd1->ref_cnt().get(), 1);
+
+ JClientArguments* program_args2 = Gtest_JBoosterServer::create_mock_JClientArguments(11);
+ JClientProgramData* new_pd2 = Gtest_JBoosterServer::create_mock_JClientProgramData(2u, program_args2);
+ delete program_args2;
+ JClientProgramData** res2 = programs.put_if_absent(new_pd2->program_args(), new_pd2, THREAD);
+ EXPECT_NE(res2, (JClientProgramData**) nullptr);
+ EXPECT_EQ(*res2, new_pd1);
+ EXPECT_EQ(new_pd1->ref_cnt().get(), 2);
+ EXPECT_EQ(new_pd2->ref_cnt().get(), 1);
+
+ new_pd2->ref_cnt().dec_and_update_time();
+ delete new_pd2;
+
+ new_pd1->ref_cnt().dec_and_update_time();
+ new_pd1->ref_cnt().dec_and_update_time();
+}
+
+#endif // INCLUDE_JBOOSTER
diff --git a/test/hotspot/gtest/jbooster/test_util.cpp b/test/hotspot/gtest/jbooster/test_util.cpp
index 461e3faa7..178998189 100644
--- a/test/hotspot/gtest/jbooster/test_util.cpp
+++ b/test/hotspot/gtest/jbooster/test_util.cpp
@@ -35,10 +35,11 @@
#include "jbooster/utilities/scalarHashMap.inline.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/thread.hpp"
-#include "unittest.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/stringUtils.hpp"
+#include "unittest.hpp"
+
class ATestClass {};
template <typename T>
diff --git a/test/jdk/tools/jbooster/JBoosterConcurrentTest.java b/test/jdk/tools/jbooster/JBoosterConcurrentTest.java
new file mode 100644
index 000000000..56423ba82
--- /dev/null
+++ b/test/jdk/tools/jbooster/JBoosterConcurrentTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2020, 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.
+ */
+
+import java.net.ServerSocket;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+import static jdk.test.lib.Asserts.*;
+
+/*
+ * jbooster testing.
+ * @test
+ * @summary Test jbooster server
+ * @library ../lib
+ * /test/lib
+ * @modules jdk.jbooster
+ * @build SimpleClient
+ * @run main/othervm/timeout=5000 JBoosterConcurrentTest
+ */
+public class JBoosterConcurrentTest extends JBoosterTestBase {
+ public static final List<String> SERVER_FAST_CLEANUP_ARGS = Stream.concat(SERVER_STANDARD_ARGS.stream(), Stream.of(
+ "--unused-cleanup-timeout=1"
+ )).collect(Collectors.toList());
+
+ private static void testProgramDataCleanup(TestContext ctx) throws Exception {
+ Process server = jbooster(ctx, List.of(), SERVER_FAST_CLEANUP_ARGS);
+ OutputAnalyzer out = new OutputAnalyzer(server);
+ server.waitFor(WAIT_START_TIME, TimeUnit.SECONDS);
+
+ List<Process> apps = new ArrayList<>();
+ final int rounds = 100;
+ final int concurrent = 5;
+ for (int r = 0; r < rounds; ++r) {
+ if (r % 10 == 0) {
+ System.out.println("Try " + (r + 1) + "round:");
+ }
+
+ ArrayList<String> clientArgs = new ArrayList<>(CLIENT_STANDARD_ARGS);
+ clientArgs.add(clientArgs.size() - 1, "-XX:JBoosterProgramName=simple-" + r);
+
+ for (int j = 0; j < concurrent; ++j) {
+ Process p = java(ctx, clientArgs);
+ apps.add(p);
+ }
+
+ if (r % 10 == 0) {
+ for (Process p : apps) {
+ p.waitFor(WAIT_EXIT_TIME, TimeUnit.SECONDS);
+ assertEquals(p.exitValue(), 0, "good");
+ }
+ apps.clear();
+ }
+ }
+
+ System.out.println("Get data 1:");
+ writeToStdin(server, "d\n");
+
+ for (Process p : apps) {
+ p.waitFor(WAIT_EXIT_TIME, TimeUnit.SECONDS);
+ assertEquals(p.exitValue(), 0, "good");
+ }
+ apps.clear();
+
+ System.out.println("Get data 2:");
+ writeToStdin(server, "d\n");
+
+ Thread.sleep(5 * 60 * 1000);
+
+ System.out.println("Get data 3:");
+ writeToStdin(server, "d\n");
+ writeToStdin(server, "d\n");
+ writeToStdin(server, "d\n");
+ exitNormallyByCommandQ(server);
+ out.shouldContain("JClientProgramData:\n -");
+ out.shouldContain("JClientSessionData:\n\nJClientProgramData:\n\n".repeat(4));
+ }
+
+ public static void main(String[] args) throws Exception {
+ testCases(JBoosterConcurrentTest.class);
+ }
+}
diff --git a/test/jdk/tools/jbooster/TEST.properties b/test/jdk/tools/jbooster/TEST.properties
new file mode 100644
index 000000000..e11b8706b
--- /dev/null
+++ b/test/jdk/tools/jbooster/TEST.properties
@@ -0,0 +1 @@
+maxOutputSize = 2500000
--
2.22.0

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

View File

@ -0,0 +1,84 @@
From bc5f9fe895849d80d69ef273703e17d2e3ffc968 Mon Sep 17 00:00:00 2001
Subject: Fix JBooster file issue caused by os::write change
---
.../share/jbooster/net/serializationWrappers.cpp | 15 +++++++++------
.../share/jbooster/net/serializationWrappers.hpp | 2 +-
test/hotspot/gtest/jbooster/test_net.cpp | 6 +-----
test/hotspot/gtest/jbooster/test_util.cpp | 4 ++--
4 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/src/hotspot/share/jbooster/net/serializationWrappers.cpp b/src/hotspot/share/jbooster/net/serializationWrappers.cpp
index 13db948f6..58310e976 100644
--- a/src/hotspot/share/jbooster/net/serializationWrappers.cpp
+++ b/src/hotspot/share/jbooster/net/serializationWrappers.cpp
@@ -385,12 +385,15 @@ int FileWrapper::deserialize(MessageBuffer& buf) {
JB_RETURN(buf.deserialize_ref_no_meta(size_to_recv));
// content (use low-level APIs to save a memcpy)
- uint32_t left = size_to_recv;
- do {
- uint32_t write_size = (uint32_t) os::write(_fd, buf.cur_buf_ptr(), left);
- buf.skip_cur_offset(write_size);
- left -= write_size;
- } while (left > 0);
+ if (!os::write(_fd, buf.cur_buf_ptr(), size_to_recv)) {
+ int e = errno;
+ errno = 0;
+ guarantee(e != 0, "sanity");
+ log_warning(jbooster, serialization)("Fail to write file \"%s\": errno=%s(\"%s\") .",
+ _file_path, os::errno_name(e), os::strerror(e));
+ JB_RETURN(e);
+ }
+ buf.skip_cur_offset(size_to_recv);
// update status
_handled_file_size += size_to_recv;
diff --git a/src/hotspot/share/jbooster/net/serializationWrappers.hpp b/src/hotspot/share/jbooster/net/serializationWrappers.hpp
index cc7f96c15..02816fcc5 100644
--- a/src/hotspot/share/jbooster/net/serializationWrappers.hpp
+++ b/src/hotspot/share/jbooster/net/serializationWrappers.hpp
@@ -253,7 +253,7 @@ public:
bool is_null() const { return _file_size == MessageConst::NULL_PTR; }
bool is_file_all_handled() const {
- assert(_file_size >= _handled_file_size, "sanity");
+ guarantee(_file_size >= _handled_file_size, "sanity");
return _handled_once && _file_size == _handled_file_size;
}
diff --git a/test/hotspot/gtest/jbooster/test_net.cpp b/test/hotspot/gtest/jbooster/test_net.cpp
index a2c45be5e..9eb29fc3a 100644
--- a/test/hotspot/gtest/jbooster/test_net.cpp
+++ b/test/hotspot/gtest/jbooster/test_net.cpp
@@ -348,11 +348,7 @@ static void create_test_file_for_file_wrapper(const char* file_name) {
int fd = os::open(file_name, O_BINARY | O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0666);
ASSERT_TRUE(fd >= 0);
ASSERT_EQ(errno, 0);
- uint32_t left = mem_size;
- do {
- uint32_t write_size = (uint32_t) os::write(fd, mem + mem_size - left, left);
- left -= write_size;
- } while (left > 0);
+ ASSERT_TRUE(os::write(fd, mem, mem_size));
os::close(fd);
FREE_C_HEAP_ARRAY(char, mem);
}
diff --git a/test/hotspot/gtest/jbooster/test_util.cpp b/test/hotspot/gtest/jbooster/test_util.cpp
index ab7fd9b39..cd65804be 100644
--- a/test/hotspot/gtest/jbooster/test_util.cpp
+++ b/test/hotspot/gtest/jbooster/test_util.cpp
@@ -46,8 +46,8 @@ static const char* get_type_name(T t) {
}
static void write_file(const char* file_path, const char* content) {
- int fd = os::open(file_path, O_BINARY | O_WRONLY | O_CREAT, 0666);;
- os::write(fd, content, strlen(content) + 1);
+ int fd = os::open(file_path, O_BINARY | O_WRONLY | O_CREAT, 0666);
+ ASSERT_TRUE(os::write(fd, content, strlen(content) + 1));
os::close(fd);
}
--
2.23.0

View File

@ -0,0 +1,699 @@
From bcc1964f3ac7ffe6995f6734bc14cbbe07a09363 Mon Sep 17 00:00:00 2001
Date: Fri, 29 Nov 2024 15:38:42 +0800
Subject: Implement JBooster RPC byte alignment
---
.../share/jbooster/jClientArguments.cpp | 21 +++
.../share/jbooster/jClientArguments.hpp | 5 +
.../share/jbooster/net/messageBuffer.cpp | 34 ++++-
.../share/jbooster/net/messageBuffer.hpp | 19 ++-
.../jbooster/net/messageBuffer.inline.hpp | 44 +++++-
.../share/jbooster/net/rpcCompatibility.cpp | 43 ++++--
.../share/jbooster/net/serialization.hpp | 13 +-
.../jbooster/server/serverDataManager.cpp | 22 +--
.../jbooster/server/serverDataManager.hpp | 4 +-
.../jbooster/server/serverMessageHandler.cpp | 6 +-
test/hotspot/gtest/jbooster/test_net.cpp | 129 ++++++++++++++----
11 files changed, 272 insertions(+), 68 deletions(-)
diff --git a/src/hotspot/share/jbooster/jClientArguments.cpp b/src/hotspot/share/jbooster/jClientArguments.cpp
index 37093d031..b215913ea 100644
--- a/src/hotspot/share/jbooster/jClientArguments.cpp
+++ b/src/hotspot/share/jbooster/jClientArguments.cpp
@@ -34,6 +34,27 @@
#include "runtime/arguments.hpp"
#include "utilities/stringUtils.hpp"
+int JClientBoostLevel::serialize(MessageBuffer& buf) const {
+ uint8_t v = (_allow_clr ? (1 << 0) : 0)
+ | (_allow_cds ? (1 << 1) : 0)
+ | (_allow_aot ? (1 << 2) : 0)
+ | (_enable_aot_pgo ? (1 << 3) : 0)
+ | (_enable_cds_agg ? (1 << 4) : 0);
+ return buf.serialize_no_meta(v);
+}
+
+int JClientBoostLevel::deserialize(MessageBuffer& buf) {
+ uint8_t v = 0b10000000;
+ JB_RETURN(buf.deserialize_ref_no_meta(v));
+ assert((v & 0b10000000) == 0, "sanity");
+ _allow_clr = (v & (1 << 0));
+ _allow_cds = (v & (1 << 1));
+ _allow_aot = (v & (1 << 2));
+ _enable_aot_pgo = (v & (1 << 3));
+ _enable_cds_agg = (v & (1 << 4));
+ return 0;
+}
+
static JClientArguments::CpuArch calc_cpu() {
#ifdef X86
return JClientArguments::CpuArch::CPU_X86;
diff --git a/src/hotspot/share/jbooster/jClientArguments.hpp b/src/hotspot/share/jbooster/jClientArguments.hpp
index be057a07d..09c5dfdc0 100644
--- a/src/hotspot/share/jbooster/jClientArguments.hpp
+++ b/src/hotspot/share/jbooster/jClientArguments.hpp
@@ -49,8 +49,13 @@ public:
void set_allow_aot(bool allow_aot) { _allow_aot = allow_aot; }
void set_enable_aot_pgo(bool enable_aot_pgo) { _enable_aot_pgo = enable_aot_pgo; }
void set_enable_cds_agg(bool enable_cds_agg) { _enable_cds_agg = enable_cds_agg; }
+
+ int serialize(MessageBuffer& buf) const;
+ int deserialize(MessageBuffer& buf);
};
+DECLARE_SERIALIZER_INTRUSIVE(JClientBoostLevel);
+
/**
* Arguments that identify a program.
*/
diff --git a/src/hotspot/share/jbooster/net/messageBuffer.cpp b/src/hotspot/share/jbooster/net/messageBuffer.cpp
index 4673bb784..980cfbfed 100644
--- a/src/hotspot/share/jbooster/net/messageBuffer.cpp
+++ b/src/hotspot/share/jbooster/net/messageBuffer.cpp
@@ -23,15 +23,34 @@
#include "jbooster/net/messageBuffer.inline.hpp"
+/**
+ * Allocate an extra eight bytes in case the array object is not 8-byte aligned.
+ */
+char* MessageBuffer::alloc_buf_obj(uint32_t new_buf_size) {
+ return NEW_C_HEAP_ARRAY(char, new_buf_size + sizeof(int64_t), mtJBooster);
+}
+
+void MessageBuffer::del_buf_obj(char* buf_obj) {
+ FREE_C_HEAP_ARRAY(char, buf_obj);
+}
+
+/**
+ * Make the beginning of buf be 8-byte aligned.
+ */
+char* MessageBuffer::calc_buf_start(char* buf_obj) {
+ return buf_obj + calc_padding<int64_t>((uint32_t) reinterpret_cast<uintptr_t>(buf_obj));
+}
+
MessageBuffer::MessageBuffer(SerializationMode smode, CommunicationStream* stream):
_smode(smode),
_buf_size(_default_buf_size),
- _buf(NEW_C_HEAP_ARRAY(char, _buf_size, mtJBooster)),
+ _buf_obj(alloc_buf_obj(_buf_size)),
+ _buf(calc_buf_start(_buf_obj)),
_cur_offset(0),
_stream(stream) {}
MessageBuffer::~MessageBuffer() {
- FREE_C_HEAP_ARRAY(char, _buf);
+ del_buf_obj(_buf_obj);
}
/**
@@ -50,12 +69,19 @@ uint32_t MessageBuffer::calc_new_buf_size(uint32_t required_size) {
}
void MessageBuffer::expand_buf(uint32_t required_size, uint32_t copy_size) {
+ char* old_buf_obj = _buf_obj;
char* old_buf = _buf;
+
uint32_t new_buf_size = calc_new_buf_size(required_size);
- char* new_buf = NEW_C_HEAP_ARRAY(char, new_buf_size, mtJBooster);
+ char* new_buf_obj = alloc_buf_obj(new_buf_size);
+ char* new_buf = calc_buf_start(new_buf_obj);
+ guarantee((new_buf_obj + new_buf_size + sizeof(int64_t)) >= (new_buf + copy_size), "sanity");
memcpy(new_buf, old_buf, copy_size);
+ _buf_obj = new_buf_obj;
_buf = new_buf;
_buf_size = new_buf_size;
- FREE_C_HEAP_ARRAY(char, old_buf);
+ del_buf_obj(old_buf_obj);
+
+ assert(((int) (reinterpret_cast<uintptr_t>(_buf)) & 7) == 0, "8-byte aligned");
}
diff --git a/src/hotspot/share/jbooster/net/messageBuffer.hpp b/src/hotspot/share/jbooster/net/messageBuffer.hpp
index aaa8e7c3b..04e41e9d6 100644
--- a/src/hotspot/share/jbooster/net/messageBuffer.hpp
+++ b/src/hotspot/share/jbooster/net/messageBuffer.hpp
@@ -56,7 +56,7 @@ public:
void assert_can_deserialize() const NOT_DEBUG_RETURN;
};
-class MessageBuffer final: public StackObj {
+class MessageBuffer: public StackObj {
friend class Message;
private:
@@ -64,14 +64,23 @@ private:
SerializationMode _smode;
uint32_t _buf_size;
- char* _buf;
+ char* _buf_obj; // malloced buf object
+ char* _buf; // 8-byte aligned buf start
uint32_t _cur_offset;
CommunicationStream* const _stream;
private:
- static uint32_t calc_new_buf_size(uint32_t required_size);
+ static char* alloc_buf_obj(uint32_t new_buf_size);
+ static void del_buf_obj(char* buf_obj);
+
void expand_buf(uint32_t required_size, uint32_t copy_size);
+protected: // for gtest
+ template <typename Arg>
+ static uint32_t calc_padding(uint32_t offset);
+ static char* calc_buf_start(char* buf_obj);
+ static uint32_t calc_new_buf_size(uint32_t required_size);
+
public:
MessageBuffer(SerializationMode smode, CommunicationStream* stream = nullptr);
~MessageBuffer();
@@ -95,6 +104,8 @@ public:
}
// serializers
+ template <typename Arg>
+ int serialize_base(Arg v);
int serialize_memcpy(const void* from, uint32_t arg_size);
template <typename Arg>
int serialize_no_meta(const Arg& arg);
@@ -102,6 +113,8 @@ public:
int serialize_with_meta(const Arg* arg_ptr);
// deserializers
+ template <typename Arg>
+ int deserialize_base(Arg& to);
int deserialize_memcpy(void* to, uint32_t arg_size);
template <typename Arg>
int deserialize_ref_no_meta(Arg& arg);
diff --git a/src/hotspot/share/jbooster/net/messageBuffer.inline.hpp b/src/hotspot/share/jbooster/net/messageBuffer.inline.hpp
index c7dc0986f..9500c1aaa 100644
--- a/src/hotspot/share/jbooster/net/messageBuffer.inline.hpp
+++ b/src/hotspot/share/jbooster/net/messageBuffer.inline.hpp
@@ -38,6 +38,26 @@ inline void SerializationMode::assert_can_deserialize() const {
}
#endif
+template <typename Arg>
+inline uint32_t MessageBuffer::calc_padding(uint32_t offset) {
+ static_assert((sizeof(Arg) & (sizeof(Arg) - 1)) == 0, "Should be 1, 2, 4, 8!");
+ static_assert(sizeof(Arg) <= 8, "Should be 1, 2, 4, 8!");
+ return (-offset) & (sizeof(Arg) - 1);
+}
+
+template <typename Arg>
+inline int MessageBuffer::serialize_base(Arg v) {
+ static_assert(std::is_arithmetic<Arg>::value || std::is_enum<Arg>::value, "Base types or enums only!");
+ _smode.assert_can_serialize();
+ uint32_t arg_size = (uint32_t) sizeof(Arg);
+ uint32_t padding = calc_padding<Arg>(_cur_offset);
+ uint32_t nxt_offset = _cur_offset + padding + arg_size;
+ expand_if_needed(nxt_offset, _cur_offset);
+ *((Arg*) (_buf + _cur_offset + padding)) = v;
+ _cur_offset = nxt_offset;
+ return 0;
+}
+
inline int MessageBuffer::serialize_memcpy(const void* from, uint32_t arg_size) {
_smode.assert_can_serialize();
assert(from != nullptr, "sanity");
@@ -56,11 +76,13 @@ inline int MessageBuffer::serialize_no_meta(const Arg& arg) {
template <typename Arg>
inline int MessageBuffer::serialize_with_meta(const Arg* arg_ptr) {
+ static_assert(MessageConst::arg_meta_size == sizeof(uint32_t), "Meta changed?");
_smode.assert_can_serialize();
if (arg_ptr == nullptr) {
return serialize_no_meta(MessageConst::NULL_PTR);
}
const Arg& arg = *arg_ptr;
+ skip_cur_offset(calc_padding<uint32_t >(_cur_offset));
uint32_t meta_offset = _cur_offset;
skip_cur_offset(MessageConst::arg_meta_size);
expand_if_needed(_cur_offset, _cur_offset);
@@ -68,7 +90,25 @@ inline int MessageBuffer::serialize_with_meta(const Arg* arg_ptr) {
// fill arg meta at last
uint32_t arg_size = _cur_offset - meta_offset - MessageConst::arg_meta_size;
- memcpy((void*) (_buf + meta_offset), &arg_size, sizeof(arg_size));
+ *((uint32_t*) (_buf + meta_offset)) = arg_size;
+ return 0;
+}
+
+template <typename Arg>
+inline int MessageBuffer::deserialize_base(Arg& to) {
+ static_assert(std::is_arithmetic<Arg>::value || std::is_enum<Arg>::value, "Base types or enums only!");
+ _smode.assert_can_deserialize();
+ uint32_t arg_size = (uint32_t) sizeof(Arg);
+ uint32_t padding = calc_padding<Arg>(_cur_offset);
+ uint32_t nxt_offset = _cur_offset + padding + arg_size;
+ if (_buf_size < nxt_offset) {
+ log_warning(jbooster, rpc)("The size to parse is longer than the msg size: "
+ "arg_size=%u, cur_offset=%u, nxt_offset=%u, buf_size=%u",
+ arg_size, _cur_offset, nxt_offset, _buf_size);
+ return JBErr::BAD_MSG_DATA;
+ }
+ to = *((Arg*) (_buf + _cur_offset + padding));
+ _cur_offset = nxt_offset;
return 0;
}
@@ -125,7 +165,7 @@ inline int MessageBuffer::deserialize_with_meta(Arg* const& arg_ptr) {
return 0;
}
const char* type_name = DebugUtils::type_name<Arg>();
- log_warning(jbooster, rpc)("The arg size does match the parsed size: "
+ log_warning(jbooster, rpc)("The arg size does not match the parsed size: "
"arg=%s, arg_size=%u, (cur_size - arg_begin)=%u.",
type_name, arg_size, _cur_offset - arg_begin);
FREE_C_HEAP_ARRAY(char, type_name);
diff --git a/src/hotspot/share/jbooster/net/rpcCompatibility.cpp b/src/hotspot/share/jbooster/net/rpcCompatibility.cpp
index 7f849a6fe..a48d1c2d8 100644
--- a/src/hotspot/share/jbooster/net/rpcCompatibility.cpp
+++ b/src/hotspot/share/jbooster/net/rpcCompatibility.cpp
@@ -21,6 +21,7 @@
* questions.
*/
+#include "classfile/vmSymbols.hpp"
#include "jbooster/dataTransmissionUtils.hpp"
#include "jbooster/jBoosterManager.hpp"
#include "jbooster/jClientArguments.hpp"
@@ -33,9 +34,18 @@
#include "jbooster/net/rpcCompatibility.hpp"
#include "jbooster/net/serializationWrappers.hpp"
#include "jbooster/net/serverStream.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/method.hpp"
+#include "oops/methodData.hpp"
-static constexpr uint32_t calc_new_hash(uint32_t old_hash, uint32_t ele_hash) {
- return 31 * old_hash + ele_hash;
+static constexpr uint32_t calc_new_hash(uint32_t old_hash) {
+ return old_hash;
+}
+
+template <typename... Rest>
+static constexpr uint32_t calc_new_hash(uint32_t old_hash, uint32_t ele_hash, Rest... rest_hashes) {
+ uint32_t new_hash = old_hash * 31u + ele_hash;
+ return calc_new_hash(new_hash, rest_hashes...);
}
template <typename T>
@@ -54,20 +64,35 @@ static constexpr uint32_t calc_classes_hash() {
return calc_new_hash(calc_classes_hash<Second, Rest...>(), calc_class_hash<First>());
}
-/**
- * Returns a magic number computed at compile time based on the sizes of some classes.
- * It is just an crude way to check compatibility for now. More policies can be added later.
- */
-static constexpr uint32_t calc_magic_num() {
+static constexpr uint32_t classes_hash() {
return calc_classes_hash<
JBoosterManager, JClientVMFlags, JClientArguments,
JBErr, Message, MessageBuffer,
CommunicationStream, ClientStream, ServerStream,
ArrayWrapper<int>, MemoryWrapper, StringWrapper, FileWrapper,
- ClassLoaderKey, ClassLoaderChain, ClassLoaderLocator, KlassLocator, MethodLocator, ProfileDataCollector
+ ClassLoaderKey, ClassLoaderChain, ClassLoaderLocator, KlassLocator, MethodLocator, ProfileDataCollector,
+ InstanceKlass, Method, MethodData
>();
}
+static constexpr uint32_t little_or_big_endian() {
+ return (uint32_t) LITTLE_ENDIAN_ONLY('L') BIG_ENDIAN_ONLY('B');
+}
+
+/**
+ * Returns a magic number computed at compile time based on the sizes of some classes.
+ * It is just an crude way to check compatibility for now. More policies can be added later.
+ */
+static constexpr uint32_t calc_magic_num() {
+ return calc_new_hash(
+ classes_hash(),
+ little_or_big_endian(),
+ static_cast<uint32_t>(vmSymbolID::SID_LIMIT)
+ );
+}
+
+static constexpr uint32_t _magic_num = calc_magic_num();
+
uint32_t RpcCompatibility::magic_num() {
- return calc_magic_num();
+ return _magic_num;
}
diff --git a/src/hotspot/share/jbooster/net/serialization.hpp b/src/hotspot/share/jbooster/net/serialization.hpp
index f9a2996c5..ed8387eb6 100644
--- a/src/hotspot/share/jbooster/net/serialization.hpp
+++ b/src/hotspot/share/jbooster/net/serialization.hpp
@@ -72,21 +72,20 @@
// ------------------------------ Default Serializer -------------------------------
// The types it support for serialization/deserialization:
// - Base types: bool, int, long long, size_t, uint64_t, and so on.
-// - POD classes without pointers.
//
-// memcpy() is good enough in most cases. Even for base types such as char and size_t,
-// memcpy() has the similar performance as assignment (`=`) according to our tests.
-// It's also a choice to use assignment here. But if a class overloads the operator `=`
-// and allocates something on the heap, it can cause a memory leak.
+// No default serializer for classes! Implement them manually.
+//
+// Use uintptr_t instead of address (aka unsigned char*) if you want to serialize a
+// pointer.
template <typename Arg>
struct SerializationImpl {
static int serialize(MessageBuffer& buf, const Arg& arg) {
- return buf.serialize_memcpy(&arg, sizeof(Arg));
+ return buf.serialize_base(arg);
}
static int deserialize_ref(MessageBuffer& buf, Arg& arg) {
- return buf.deserialize_memcpy(&arg, sizeof(Arg));
+ return buf.deserialize_base(arg);
}
CANNOT_DESERIALIZE_POINTER(Arg);
diff --git a/src/hotspot/share/jbooster/server/serverDataManager.cpp b/src/hotspot/share/jbooster/server/serverDataManager.cpp
index b2f36c4e5..c3d5f290e 100644
--- a/src/hotspot/share/jbooster/server/serverDataManager.cpp
+++ b/src/hotspot/share/jbooster/server/serverDataManager.cpp
@@ -340,18 +340,18 @@ ClassLoaderData* JClientProgramData::add_class_loader_if_absent(const ClassLoade
// ------------------------------ JClientSessionData -------------------------------
class AddressMapKVArray: public StackObj {
- GrowableArray<address>* _key_array;
- GrowableArray<address>* _value_array;
+ GrowableArray<uintptr_t>* _key_array;
+ GrowableArray<uintptr_t>* _value_array;
public:
- AddressMapKVArray(GrowableArray<address>* key_array,
- GrowableArray<address>* value_array) :
+ AddressMapKVArray(GrowableArray<uintptr_t>* key_array,
+ GrowableArray<uintptr_t>* value_array) :
_key_array(key_array),
_value_array(value_array) {}
bool operator () (JClientSessionData::AddressMap::KVNode* kv_node) {
assert(kv_node->key() != nullptr && kv_node->value() != nullptr, "sanity");
- _key_array->append(kv_node->key());
- _value_array->append(kv_node->value());
+ _key_array->append(reinterpret_cast<uintptr_t>(kv_node->key()));
+ _value_array->append(reinterpret_cast<uintptr_t>(kv_node->value()));
return true;
}
};
@@ -422,17 +422,17 @@ void JClientSessionData::add_klass_address(address client_klass_addr,
put_address(_k_c2s, client_klass_addr, server_cld_addr, thread);
}
-void JClientSessionData::klass_array(GrowableArray<address>* key_array,
- GrowableArray<address>* value_array,
+void JClientSessionData::klass_array(GrowableArray<uintptr_t>* key_array,
+ GrowableArray<uintptr_t>* value_array,
Thread* thread) {
AddressMapKVArray array(key_array, value_array);
_k_c2s.for_each(array, thread);
}
-void JClientSessionData::klass_pointer_map_to_server(GrowableArray<address>* klass_array, Thread* thread) {
- for (GrowableArrayIterator<address> iter = klass_array->begin();
+void JClientSessionData::klass_pointer_map_to_server(GrowableArray<uintptr_t>* klass_array, Thread* thread) {
+ for (GrowableArrayIterator<uintptr_t> iter = klass_array->begin();
iter != klass_array->end(); ++iter) {
- InstanceKlass* klass = (InstanceKlass*) (*iter);
+ InstanceKlass* klass = reinterpret_cast<InstanceKlass*>(*iter);
Array<Method*>* methods = klass->methods();
for (int method_index = 0; method_index < methods->length(); method_index++) {
MethodData* method_data = method_data_address((address)(methods->at(method_index)), thread);
diff --git a/src/hotspot/share/jbooster/server/serverDataManager.hpp b/src/hotspot/share/jbooster/server/serverDataManager.hpp
index 2cb7d2de0..c6ef4c99a 100644
--- a/src/hotspot/share/jbooster/server/serverDataManager.hpp
+++ b/src/hotspot/share/jbooster/server/serverDataManager.hpp
@@ -291,9 +291,9 @@ public:
Klass* server_klass_address(address client_klass_addr, Thread* thread);
void add_klass_address(address client_klass_addr, address server_cld_addr, Thread* thread);
- void klass_array(GrowableArray<address>* key_array, GrowableArray<address>* value_array, Thread* thread);
+ void klass_array(GrowableArray<uintptr_t>* key_array, GrowableArray<uintptr_t>* value_array, Thread* thread);
- void klass_pointer_map_to_server(GrowableArray<address>* klass_array, Thread* thread);
+ void klass_pointer_map_to_server(GrowableArray<uintptr_t>* klass_array, Thread* thread);
void add_method_data(address method, address method_data, Thread* thread);
bool remove_method_data(address method, Thread* thread);
diff --git a/src/hotspot/share/jbooster/server/serverMessageHandler.cpp b/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
index 49c25efb1..f46b839bb 100644
--- a/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
+++ b/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
@@ -196,14 +196,14 @@ int ServerMessageHandler::request_missing_klasses(TRAPS) {
int ServerMessageHandler::request_method_data(TRAPS) {
ResourceMark rm(THREAD);
- GrowableArray<address> client_klass_array;
- GrowableArray<address> server_klass_array;
+ GrowableArray<uintptr_t> client_klass_array;
+ GrowableArray<uintptr_t> server_klass_array;
ss().session_data()->klass_array(&client_klass_array,
&server_klass_array,
THREAD);
{
- ArrayWrapper<address> aw(&client_klass_array);
+ ArrayWrapper<uintptr_t> aw(&client_klass_array);
JB_RETURN(ss().send_request(MessageType::Profilinginfo, &aw));
InstanceKlass** klass_array_base = NULL;
if (server_klass_array.length() > 0) {
diff --git a/test/hotspot/gtest/jbooster/test_net.cpp b/test/hotspot/gtest/jbooster/test_net.cpp
index 9eb29fc3a..bf20b0aa3 100644
--- a/test/hotspot/gtest/jbooster/test_net.cpp
+++ b/test/hotspot/gtest/jbooster/test_net.cpp
@@ -26,10 +26,12 @@
#if INCLUDE_JBOOSTER
+#include "jbooster/jClientArguments.hpp"
#include "jbooster/net/message.inline.hpp"
#include "jbooster/net/messageBuffer.inline.hpp"
#include "jbooster/net/serializationWrappers.inline.hpp"
#include "jbooster/utilities/fileUtils.hpp"
+#include "memory/resourceArea.hpp"
#include "runtime/os.inline.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
@@ -105,6 +107,47 @@ static void copy_message_buffer(MessageBuffer& to, MessageBuffer& from) {
memcpy(to.buf(), from.buf(), from.cur_offset());
}
+class MockMessageBuffer: public MessageBuffer {
+public:
+ static bool test() {
+ // calc_padding<char[6]>(0); // should not pass the compilation
+ EXPECT_EQ(calc_padding<char>(123), 0u);
+ EXPECT_EQ(calc_padding<char>(124), 0u);
+ EXPECT_EQ(calc_padding<short>(123), 1u);
+ EXPECT_EQ(calc_padding<short>(120), 0u);
+ EXPECT_EQ(calc_padding<int>(0), 0u);
+ EXPECT_EQ(calc_padding<int>(1), 3u);
+ EXPECT_EQ(calc_padding<int>(2), 2u);
+ EXPECT_EQ(calc_padding<int>(3), 1u);
+ EXPECT_EQ(calc_padding<int>(4), 0u);
+ EXPECT_EQ(calc_padding<int>(400), 0u);
+ EXPECT_EQ(calc_padding<uint64_t>(1), 7u);
+ EXPECT_EQ(calc_padding<uint64_t>(3), 5u);
+ EXPECT_EQ(calc_padding<uint64_t>(12), 4u);
+ EXPECT_EQ(calc_padding<uint64_t>(7), 1u);
+
+ EXPECT_EQ(calc_buf_start(reinterpret_cast<char*>(7)), reinterpret_cast<char*>(8));
+ EXPECT_EQ(calc_buf_start(reinterpret_cast<char*>(9)), reinterpret_cast<char*>(16));
+ EXPECT_EQ(calc_buf_start(reinterpret_cast<char*>(12)), reinterpret_cast<char*>(16));
+ EXPECT_EQ(calc_buf_start(reinterpret_cast<char*>(65535)), reinterpret_cast<char*>(65536));
+ EXPECT_EQ(calc_buf_start(reinterpret_cast<char*>(65536)), reinterpret_cast<char*>(65536));
+
+ EXPECT_EQ(calc_new_buf_size(0), 0u);
+ EXPECT_EQ(calc_new_buf_size(1), 1u);
+ EXPECT_EQ(calc_new_buf_size(2), 2u);
+ EXPECT_EQ(calc_new_buf_size(3), 4u);
+ EXPECT_EQ(calc_new_buf_size(65535), 65536u);
+ EXPECT_EQ(calc_new_buf_size(65536), 65536u);
+ EXPECT_EQ(calc_new_buf_size(65537), 131072u);
+
+ return true;
+ }
+};
+
+TEST(JBoosterNet, padding) {
+ ASSERT_TRUE(MockMessageBuffer::test());
+}
+
TEST(JBoosterNet, try_catch) {
int i;
for (i = 0; i < 9; ++i) {
@@ -145,24 +188,25 @@ TEST(JBoosterNet, serializationn_basics) {
int i1 = 1234;
int64_t l1 = 900000000000000ll;
EXPECT_EQ(buf.serialize_no_meta(c1), 0);
- EXPECT_EQ(buf.cur_offset(), 1u);
+ EXPECT_EQ(buf.cur_offset(), 1u); // 1 (char)
EXPECT_EQ(buf.serialize_no_meta(i1), 0);
- EXPECT_EQ(buf.cur_offset(), 5u);
+ EXPECT_EQ(buf.cur_offset(), 8u); // 1 (last) + 3 (padding) + 4 (int32)
EXPECT_EQ(buf.serialize_no_meta(l1), 0);
- EXPECT_EQ(buf.cur_offset(), 13u);
+ EXPECT_EQ(buf.cur_offset(), 16u); // 8 (last) + 8 (int64)
uint32_t u1 = 2468;
const char* s1 = nullptr;
const char* s2 = "hello";
const char* s3 = "world!";
EXPECT_EQ(buf.serialize_with_meta(&u1), 0);
- EXPECT_EQ(buf.cur_offset(), 21u);
+ EXPECT_EQ(buf.cur_offset(), 24u); // 16 (last) + 4 (int32) + 4 (int32)
EXPECT_EQ(buf.serialize_with_meta(&s1), 0);
- EXPECT_EQ(buf.cur_offset(), 29u);
+ EXPECT_EQ(buf.cur_offset(), 32u); // 24 (last) + 4 (int32) + 4 (int32)
EXPECT_EQ(buf.serialize_with_meta(&s2), 0);
- EXPECT_EQ(buf.cur_offset(), 42u);
+ EXPECT_EQ(buf.cur_offset(), 45u); // 32 (last) + 4 (int32) + 4 (int32) + 5 (strlen)
EXPECT_EQ(buf.serialize_with_meta(&s3), 0);
- EXPECT_EQ(buf.cur_offset(), 56u);
+ EXPECT_EQ(buf.cur_offset(), 62u); // 45 (last) + 3 (padding) + 4 (int32) + 4 (int32) + 6 (strlen)
+ EXPECT_EQ((int) (reinterpret_cast<uintptr_t>(buf.buf())) & 7, 0); // 8-byte aligned
cache_size = buf.cur_offset();
memcpy(cache, buf.buf(), cache_size);
@@ -177,9 +221,9 @@ TEST(JBoosterNet, serializationn_basics) {
EXPECT_EQ(buf.deserialize_ref_no_meta(c1), 0);
EXPECT_EQ(buf.cur_offset(), 1u);
EXPECT_EQ(buf.deserialize_ref_no_meta(i1), 0);
- EXPECT_EQ(buf.cur_offset(), 5u);
+ EXPECT_EQ(buf.cur_offset(), 8u);
EXPECT_EQ(buf.deserialize_ref_no_meta(l1), 0);
- EXPECT_EQ(buf.cur_offset(), 13u);
+ EXPECT_EQ(buf.cur_offset(), 16u);
EXPECT_EQ(c1, '6');
EXPECT_EQ(i1, 1234);
EXPECT_EQ(l1, 900000000000000ll);
@@ -189,13 +233,15 @@ TEST(JBoosterNet, serializationn_basics) {
char s2[6];
StringWrapper s3;
EXPECT_EQ(buf.deserialize_with_meta(&u1), 0);
- EXPECT_EQ(buf.cur_offset(), 21u);
+ EXPECT_EQ(buf.cur_offset(), 24u);
EXPECT_EQ(buf.deserialize_with_meta(&s1), 0);
- EXPECT_EQ(buf.cur_offset(), 29u);
+ EXPECT_EQ(buf.cur_offset(), 32u);
EXPECT_EQ(buf.deserialize_with_meta(&s2), 0);
- EXPECT_EQ(buf.cur_offset(), 42u);
+ EXPECT_EQ(buf.cur_offset(), 45u);
EXPECT_EQ(buf.deserialize_with_meta(&s3), 0);
- EXPECT_EQ(buf.cur_offset(), 56u);
+ EXPECT_EQ(buf.cur_offset(), 62u);
+ EXPECT_EQ(((int) reinterpret_cast<uintptr_t>(buf.buf())) & 7, 0);
+
EXPECT_EQ(u1, 2468u);
EXPECT_STREQ(s1, nullptr);
EXPECT_STREQ(s2, "hello");
@@ -227,18 +273,11 @@ TEST_VM(JBoosterNet, serializationn_string) {
EXPECT_STREQ(ss3, s3);
}
- { MessageBuffer buf(SerializationMode::DESERIALIZE);
- copy_message_buffer(buf, buf0);
- char s1[1];
- ASSERT_DEATH(buf.deserialize_with_meta(&s1), "");
- }
-
{ MessageBuffer buf(SerializationMode::DESERIALIZE);
copy_message_buffer(buf, buf0);
char s1[64];
EXPECT_EQ(buf.deserialize_with_meta(&s1), 0);
EXPECT_STREQ(ss1, s1);
- ASSERT_DEATH(buf.deserialize_with_meta(&s1), "");
}
{ MessageBuffer buf(SerializationMode::DESERIALIZE);
@@ -269,8 +308,20 @@ TEST_VM(JBoosterNet, serializationn_string) {
}
}
-TEST(JBoosterNet, serializationn_crash) {
- int err;
+#ifdef ASSERT
+
+TEST_VM_ASSERT_MSG(JBoosterNet, serializationn_string_crash_null, ".*cannot set array to null") {
+ MessageBuffer buf(SerializationMode::BOTH);
+ const char* s = nullptr;
+ EXPECT_EQ(buf.serialize_with_meta(&s), 0);
+
+ char s1[8];
+ buf.reset_cur_offset();
+ buf.deserialize_with_meta(&s1); // should crash here
+ ASSERT_TRUE(false);
+}
+
+TEST_VM_ASSERT_MSG(JBoosterNet, serializationn_string_crash_arr_too_small, ".*array index out of bounds") {
MessageBuffer buf(SerializationMode::BOTH);
const char* s = "hello";
EXPECT_EQ(buf.serialize_with_meta(&s), 0);
@@ -282,12 +333,12 @@ TEST(JBoosterNet, serializationn_crash) {
char s2[5];
buf.reset_cur_offset();
- bool old = SuppressFatalErrorMessage;
- SuppressFatalErrorMessage = true;
- ASSERT_DEATH(buf.deserialize_with_meta(&s2), "");
- SuppressFatalErrorMessage = old;
+ buf.deserialize_with_meta(&s2); // should crash here
+ ASSERT_TRUE(false);
}
+#endif // ASSERT
+
TEST(JBoosterNet, serializationn_wrappers) {
MessageBuffer buf(SerializationMode::BOTH);
uint32_t mem_size = 16u * 1024;
@@ -303,7 +354,7 @@ TEST(JBoosterNet, serializationn_wrappers) {
ga.append(&s4);
ArrayWrapper<StringWrapper> aw(&ga);
EXPECT_EQ(buf.serialize_with_meta(&aw), 0);
- EXPECT_EQ(buf.cur_offset(), 0u + (4 + 4) + (1 + 2 + 3 + 4 + 4 * (4 + 4)));
+ EXPECT_EQ(buf.cur_offset(), 0u + (4 + 4) + ((1 + 3) + (2 + 2) + (3 + 1) + 4 + 4 * (4 + 4)));
char* mem = NEW_C_HEAP_ARRAY(char, mem_size, mtJBooster);
memset(mem, 0x68, mem_size);
@@ -385,6 +436,30 @@ TEST(JBoosterNet, serializationn_file_wrapper) {
FileUtils::remove(file_name2);
}
+TEST(JBoosterNet, serializationn_others) {
+ MessageBuffer buf(SerializationMode::BOTH);
+
+ {
+ JClientBoostLevel lvl;
+ lvl.set_allow_clr(true);
+ lvl.set_allow_aot(true);
+ lvl.set_enable_cds_agg(true);
+ EXPECT_EQ(buf.serialize_with_meta(&lvl), 0);
+ }
+
+ buf.reset_cur_offset();
+
+ {
+ JClientBoostLevel lvl;
+ EXPECT_EQ(buf.deserialize_with_meta(&lvl), 0);
+ EXPECT_EQ(lvl.is_clr_allowed(), true);
+ EXPECT_EQ(lvl.is_cds_allowed(), false);
+ EXPECT_EQ(lvl.is_aot_allowed(), true);
+ EXPECT_EQ(lvl.is_aot_pgo_enabled(), false);
+ EXPECT_EQ(lvl.is_cds_agg_enabled(), true);
+ }
+}
+
TEST(JBoosterNet, expansion_of_message_buffer) {
MessageBuffer buf(SerializationMode::SERIALIZE);
ASSERT_EQ(buf.buf_size(), 4096u);
--
2.22.0

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 deprecated-non-prototype, \
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

View File

@ -0,0 +1,880 @@
From 3cc21f911715cc0112f9a2e80a199723b29262e1 Mon Sep 17 00:00:00 2001
Date: Fri, 29 Nov 2024 15:39:13 +0800
Subject: Optimize LazyAOT klasses sending strategy
---
.../jbooster/client/clientMessageHandler.cpp | 6 ++
.../jbooster/client/clientMessageHandler.hpp | 1 +
.../share/jbooster/jClientArguments.cpp | 15 +++
.../share/jbooster/jClientArguments.hpp | 1 +
.../share/jbooster/jbooster_globals.hpp | 4 +
src/hotspot/share/jbooster/lazyAot.cpp | 15 ++-
src/hotspot/share/jbooster/lazyAot.hpp | 2 +
.../jbooster/net/communicationStream.cpp | 15 ++-
.../net/communicationStream.inline.hpp | 1 +
src/hotspot/share/jbooster/net/errorCode.hpp | 1 +
src/hotspot/share/jbooster/net/message.hpp | 5 +
.../share/jbooster/net/message.inline.hpp | 2 +
.../share/jbooster/net/messageType.hpp | 1 +
src/hotspot/share/jbooster/net/netCommon.hpp | 8 +-
.../jbooster/server/serverMessageHandler.cpp | 10 +-
.../jbooster/server/serverMessageHandler.hpp | 3 +-
.../share/jbooster/utilities/fileUtils.cpp | 64 ++-----------
.../share/jbooster/utilities/fileUtils.hpp | 3 +-
.../jbooster/JBoosterCompilationContext.java | 5 +
.../graalvm/compiler/java/BytecodeParser.java | 29 ++++++
.../share/classes/jdk/jbooster/JBooster.java | 8 +-
.../JBoosterCompilationContextImpl.java | 10 +-
test/hotspot/gtest/jbooster/common.hpp | 96 +++++++++++++++++++
test/hotspot/gtest/jbooster/test_net.cpp | 4 +-
test/hotspot/gtest/jbooster/test_util.cpp | 12 ++-
test/jdk/tools/jbooster/JBoosterTestBase.java | 6 +-
26 files changed, 244 insertions(+), 83 deletions(-)
create mode 100644 test/hotspot/gtest/jbooster/common.hpp
diff --git a/src/hotspot/share/jbooster/client/clientMessageHandler.cpp b/src/hotspot/share/jbooster/client/clientMessageHandler.cpp
index 9119b897a..b8278d41c 100644
--- a/src/hotspot/share/jbooster/client/clientMessageHandler.cpp
+++ b/src/hotspot/share/jbooster/client/clientMessageHandler.cpp
@@ -289,6 +289,12 @@ int ClientMessageHandler::handle_ArrayKlasses() {
return 0;
}
+int ClientMessageHandler::handle_ResolveExtraKlasses() {
+ ResourceMark rm;
+ bool should_resolve_extra_Klasses = JBoosterResolveExtraKlasses;
+ JB_RETURN(cs().send_response(&should_resolve_extra_Klasses));
+ return 0;
+}
// ---------------------------------- Some Tasks -----------------------------------
int ClientMessageHandler::send_cache_file_sync_task() {
diff --git a/src/hotspot/share/jbooster/client/clientMessageHandler.hpp b/src/hotspot/share/jbooster/client/clientMessageHandler.hpp
index 66844247c..94ff7387d 100644
--- a/src/hotspot/share/jbooster/client/clientMessageHandler.hpp
+++ b/src/hotspot/share/jbooster/client/clientMessageHandler.hpp
@@ -38,6 +38,7 @@
F(MethodLocators ) \
F(Profilinginfo ) \
F(ArrayKlasses ) \
+ F(ResolveExtraKlasses ) \
class ArrayKlass;
class ClassLoaderData;
diff --git a/src/hotspot/share/jbooster/jClientArguments.cpp b/src/hotspot/share/jbooster/jClientArguments.cpp
index b215913ea..42aba4181 100644
--- a/src/hotspot/share/jbooster/jClientArguments.cpp
+++ b/src/hotspot/share/jbooster/jClientArguments.cpp
@@ -171,6 +171,14 @@ const char* calc_java_commands_by_class(const char* full_cmd, int full_cmd_len)
return StringUtils::copy_to_heap(start, mtJBooster);
}
+static int64_t calc_cds_file_size() {
+ char* default_archive_path = Arguments::get_default_shared_archive_path();
+ if (default_archive_path == nullptr) { return -1; }
+ int64_t cds_file_size = FileUtils::file_size(default_archive_path);
+ StringUtils::free_from_heap(default_archive_path);
+ return cds_file_size;
+}
+
JClientArguments::JClientArguments(bool is_client) {
if (is_client) {
init_for_client();
@@ -224,6 +232,7 @@ void JClientArguments::init_for_client() {
_classpath_name_hash = calc_classpath_name_hash(app_cp, app_cp_len);
_classpath_timestamp_hash = calc_classpath_timestamp_hash(app_cp, app_cp_len);
_agent_name_hash = calc_agent_name_hash();
+ _cds_file_size = calc_cds_file_size();
if (JBoosterClientStrictMatch) {
_java_commands = is_jar ? calc_java_commands_by_jar(full_cmd, app_cp_len)
: calc_java_commands_by_class(full_cmd, full_cmd_len);
@@ -248,6 +257,7 @@ uint32_t JClientArguments::calc_hash() {
result = calc_new_hash(result, _classpath_name_hash);
result = calc_new_hash(result, _classpath_timestamp_hash);
result = calc_new_hash(result, _agent_name_hash);
+ result = calc_new_hash(result, _cds_file_size);
result = calc_new_hash(result, StringUtils::hash_code(_java_commands));
result = calc_new_hash(result, _related_flags->hash());
@@ -267,6 +277,7 @@ bool JClientArguments::equals(const JClientArguments* that) const {
if (this->_classpath_name_hash != that->_classpath_name_hash) return false;
if (this->_classpath_timestamp_hash != that->_classpath_timestamp_hash) return false;
if (this->_agent_name_hash != that->_agent_name_hash) return false;
+ if (this->_cds_file_size != that->_cds_file_size) return false;
if (StringUtils::compare(this->_java_commands, that->_java_commands) != 0) return false;
if (!this->_related_flags->equals(that->_related_flags)) return false;
return true;
@@ -284,6 +295,7 @@ void JClientArguments::print_args(outputStream* st) const {
st->print_cr(" classpath_name_hash: %x", _classpath_name_hash);
st->print_cr(" classpath_timestamp_hash: %x", _classpath_timestamp_hash);
st->print_cr(" agent_name_hash: %x", _agent_name_hash);
+ st->print_cr(" cds_file_size: %lu", _cds_file_size);
st->print_cr(" java_commands: \"%s\"", _java_commands);
st->print_cr(" vm_flags:");
st->print_cr(" hash: %u", _related_flags->hash());
@@ -307,6 +319,7 @@ int JClientArguments::serialize(MessageBuffer& buf) const {
JB_RETURN(buf.serialize_no_meta(_classpath_name_hash));
JB_RETURN(buf.serialize_no_meta(_classpath_timestamp_hash));
JB_RETURN(buf.serialize_no_meta(_agent_name_hash));
+ JB_RETURN(buf.serialize_no_meta(_cds_file_size));
JB_RETURN(buf.serialize_with_meta(&_java_commands));
JB_RETURN(buf.serialize_with_meta(_related_flags));
@@ -343,6 +356,8 @@ int JClientArguments::deserialize(MessageBuffer& buf) {
JB_RETURN(buf.deserialize_ref_no_meta(_agent_name_hash));
+ JB_RETURN(buf.deserialize_ref_no_meta(_cds_file_size));
+
StringWrapper sw_java_commands;
JB_RETURN(buf.deserialize_with_meta(&sw_java_commands));
_java_commands = sw_java_commands.export_string();
diff --git a/src/hotspot/share/jbooster/jClientArguments.hpp b/src/hotspot/share/jbooster/jClientArguments.hpp
index 09c5dfdc0..491ac3159 100644
--- a/src/hotspot/share/jbooster/jClientArguments.hpp
+++ b/src/hotspot/share/jbooster/jClientArguments.hpp
@@ -92,6 +92,7 @@ private:
uint32_t _classpath_name_hash;
uint32_t _classpath_timestamp_hash;
uint32_t _agent_name_hash;
+ int64_t _cds_file_size;
const char* _java_commands;
JClientVMFlags* _related_flags;
// ========================= end =========================
diff --git a/src/hotspot/share/jbooster/jbooster_globals.hpp b/src/hotspot/share/jbooster/jbooster_globals.hpp
index 74968af75..c3cdd71f8 100644
--- a/src/hotspot/share/jbooster/jbooster_globals.hpp
+++ b/src/hotspot/share/jbooster/jbooster_globals.hpp
@@ -119,6 +119,10 @@
\
product(ccstr, JBoosterServerSSLRootCerts, NULL, EXPERIMENTAL, \
"The file path to save server SSL root certificate.") \
+ \
+ product(bool, JBoosterResolveExtraKlasses, true, EXPERIMENTAL, \
+ "Whether resolve additional klasses " \
+ "while collecting klasses for AOT.") \
// end of JBOOSTER_FLAGS
diff --git a/src/hotspot/share/jbooster/lazyAot.cpp b/src/hotspot/share/jbooster/lazyAot.cpp
index 410d575e9..462b0c72b 100644
--- a/src/hotspot/share/jbooster/lazyAot.cpp
+++ b/src/hotspot/share/jbooster/lazyAot.cpp
@@ -199,7 +199,11 @@ void LazyAOT::collect_klasses_in_constant_pool(GrowableArray<InstanceKlass*>* ds
int len = dst->length();
for (int i = last_len; i < len; ++i) {
ThreadInVMfromNative tiv(THREAD);
- collect_klasses_in_constant_pool(dst, vis, dst->at(i), ALL_KLASSES, CHECK);
+ if (JBoosterResolveExtraKlasses) {
+ collect_klasses_in_constant_pool(dst, vis, dst->at(i), ALL_KLASSES, CHECK);
+ } else {
+ collect_klasses_in_constant_pool(dst, vis, dst->at(i), RESOLVED_KLASSES, CHECK);
+ }
}
last_len = len;
}
@@ -527,6 +531,7 @@ bool LazyAOT::compile_classes_by_graal(int session_id,
const char* file_path,
GrowableArray<InstanceKlass*>* klasses,
bool use_pgo,
+ bool resolve_no_extra_klasses,
TRAPS) {
DebugUtils::assert_thread_in_vm();
@@ -541,9 +546,11 @@ bool LazyAOT::compile_classes_by_graal(int session_id,
java_args.push_int(session_id);
java_args.push_oop(file_path_h);
java_args.push_oop(hash_set_h);
+ java_args.push_int(use_pgo);
+ java_args.push_int(resolve_no_extra_klasses);
TempNewSymbol compile_classes_name = SymbolTable::new_symbol("compileClasses");
- TempNewSymbol compile_classes_signature = SymbolTable::new_symbol("(ILjava/lang/String;Ljava/util/Set;)Z");
+ TempNewSymbol compile_classes_signature = SymbolTable::new_symbol("(ILjava/lang/String;Ljava/util/Set;ZZ)Z");
JavaCalls::call_static(&result, ServerDataManager::get().main_klass(),
compile_classes_name,
compile_classes_signature,
@@ -557,6 +564,7 @@ bool LazyAOT::compile_methods_by_graal(int session_id,
GrowableArray<Method*>* methods_to_compile,
GrowableArray<Method*>* methods_not_compile,
bool use_pgo,
+ bool resolve_no_extra_klasses,
TRAPS) {
DebugUtils::assert_thread_in_vm();
@@ -580,9 +588,10 @@ bool LazyAOT::compile_methods_by_graal(int session_id,
java_args.push_oop(method_name_set_h);
java_args.push_oop(not_method_name_set_h);
java_args.push_int(use_pgo);
+ java_args.push_int(resolve_no_extra_klasses);
TempNewSymbol compile_methods_name = SymbolTable::new_symbol("compileMethods");
- TempNewSymbol compile_methods_signature = SymbolTable::new_symbol("(ILjava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Z)Z");
+ TempNewSymbol compile_methods_signature = SymbolTable::new_symbol("(ILjava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ZZ)Z");
JavaCalls::call_static(&result, ServerDataManager::get().main_klass(),
compile_methods_name,
compile_methods_signature,
diff --git a/src/hotspot/share/jbooster/lazyAot.hpp b/src/hotspot/share/jbooster/lazyAot.hpp
index 1d2a49351..5b4183118 100644
--- a/src/hotspot/share/jbooster/lazyAot.hpp
+++ b/src/hotspot/share/jbooster/lazyAot.hpp
@@ -112,6 +112,7 @@ public:
const char* file_path,
GrowableArray<InstanceKlass*>* klasses,
bool use_pgo,
+ bool resolve_extra_klasses,
TRAPS);
static bool compile_methods_by_graal(int session_id,
const char* file_path,
@@ -119,6 +120,7 @@ public:
GrowableArray<Method*>* methods_to_compile,
GrowableArray<Method*>* methods_not_compile,
bool use_pgo,
+ bool resolve_extra_klasses,
TRAPS);
};
diff --git a/src/hotspot/share/jbooster/net/communicationStream.cpp b/src/hotspot/share/jbooster/net/communicationStream.cpp
index cdb4b8fa7..37bb45032 100644
--- a/src/hotspot/share/jbooster/net/communicationStream.cpp
+++ b/src/hotspot/share/jbooster/net/communicationStream.cpp
@@ -145,16 +145,18 @@ int CommunicationStream::recv_message() {
Message& msg = _msg_recv;
// read once (or memmove from the overflowed buffer) to get message size
uint32_t read_size, msg_size;
+ uint16_t magic_num;
+ const uint32_t min_read_size = sizeof(msg_size) + sizeof(magic_num);
if (msg.has_overflow()) {
read_size = msg.move_overflow();
- if (read_size < sizeof(msg_size)) {
+ if (read_size < min_read_size) {
read_size += read_once_from_stream(msg.buf_beginning() + read_size, msg.buf_size() - read_size);
}
} else {
read_size = read_once_from_stream(msg.buf_beginning(), msg.buf_size());
}
- if (read_size < sizeof(msg_size)) {
+ if (read_size < min_read_size) {
if (!is_stream_closed()) {
log_warning(jbooster, rpc)("Failed to read the size of the message (read_size=%d). stream_id=%u.",
read_size, stream_id());
@@ -162,7 +164,16 @@ int CommunicationStream::recv_message() {
return return_errno_or_flag(JBErr::BAD_MSG_SIZE);
}
+ magic_num = msg.deserialize_magic_num_only();
+ if (magic_num != MessageConst::RPC_MAGIC) {
+ log_warning(jbooster, rpc)("Message not from JBooster client. stream_id=%u.", stream_id());
+ return return_errno_or_flag(JBErr::BAD_MAGIC_NUM);
+ }
msg_size = msg.deserialize_size_only();
+ if (msg_size > MessageConst::MAX_MSG_SIZE) {
+ log_warning(jbooster, rpc)("Message size should be no more than 2GB. stream_id=%u.", stream_id());
+ return return_errno_or_flag(JBErr::BAD_MSG_SIZE);
+ }
if (read_size > msg_size) { // read too much
msg.set_overflow(msg_size, read_size - msg_size);
} else if (read_size < msg_size) { // read the rest then
diff --git a/src/hotspot/share/jbooster/net/communicationStream.inline.hpp b/src/hotspot/share/jbooster/net/communicationStream.inline.hpp
index 45311c2be..bc5c0565f 100644
--- a/src/hotspot/share/jbooster/net/communicationStream.inline.hpp
+++ b/src/hotspot/share/jbooster/net/communicationStream.inline.hpp
@@ -58,6 +58,7 @@ inline bool CommunicationStream::check_received_message_size() {
template <typename... Args>
inline int CommunicationStream::send_request(MessageType type, const Args* const... args) {
_msg_send.set_msg_type(type);
+ _msg_send.set_magic_num(MessageConst::RPC_MAGIC);
_msg_send.set_cur_buf_offset_after_meta();
JB_RETURN(_msg_send.serialize(args...));
_msg_send.set_msg_size_based_on_cur_buf_offset();
diff --git a/src/hotspot/share/jbooster/net/errorCode.hpp b/src/hotspot/share/jbooster/net/errorCode.hpp
index 625ef6951..cbb4cc54c 100644
--- a/src/hotspot/share/jbooster/net/errorCode.hpp
+++ b/src/hotspot/share/jbooster/net/errorCode.hpp
@@ -30,6 +30,7 @@
f(CONN_CLOSED, "Connection has been closed" ) \
f(CONN_CLOSED_BY_PEER, "Connection is closed by the other end" ) \
f(BAD_SSL, "Unexpected SSL error during initialization" ) \
+ f(BAD_MAGIC_NUM, "Unexpected magic number of the received message" ) \
f(BAD_MSG_SIZE, "Unexpected size of the received message" ) \
f(BAD_MSG_TYPE, "Unexpected message type of the received message" ) \
f(BAD_MSG_DATA, "Unexpected payload data of the received message" ) \
diff --git a/src/hotspot/share/jbooster/net/message.hpp b/src/hotspot/share/jbooster/net/message.hpp
index 47d2634e2..413ff84a5 100644
--- a/src/hotspot/share/jbooster/net/message.hpp
+++ b/src/hotspot/share/jbooster/net/message.hpp
@@ -33,6 +33,7 @@ class Message: public MessageConst {
private:
struct {
uint32_t msg_size;
+ uint16_t magic_num;
MessageType msg_type;
} _meta;
@@ -58,6 +59,7 @@ public:
uint32_t msg_size() const { return _meta.msg_size; }
void set_msg_size(uint32_t size) { _meta.msg_size = size; }
void set_msg_size_based_on_cur_buf_offset() { set_msg_size(cur_buf_offset()); }
+ void set_magic_num(uint16_t magic_num) { _meta.magic_num = magic_num; }
MessageType msg_type() const { return _meta.msg_type; }
void set_msg_type(MessageType type) { _meta.msg_type = type; }
@@ -76,6 +78,9 @@ public:
}
uint32_t deserialize_size_only() { return *((uint32_t*)_buf.buf()); }
+ uint16_t deserialize_magic_num_only() { return *((uint16_t*)(_buf.buf() + sizeof(_meta.msg_size))); }
+
+ bool check_magic_num(uint16_t magic_num) { return magic_num == MessageConst::RPC_MAGIC; }
template <typename... Args>
int serialize(const Args* const... args);
diff --git a/src/hotspot/share/jbooster/net/message.inline.hpp b/src/hotspot/share/jbooster/net/message.inline.hpp
index 5b5add47f..b85362efe 100644
--- a/src/hotspot/share/jbooster/net/message.inline.hpp
+++ b/src/hotspot/share/jbooster/net/message.inline.hpp
@@ -78,6 +78,7 @@ inline int Message::deserialize(Args* const&... args) {
inline void Message::serialize_meta() {
_buf.set_cur_offset(0);
_buf.serialize_no_meta(_meta.msg_size);
+ _buf.serialize_no_meta(_meta.magic_num);
_buf.serialize_no_meta(_meta.msg_type);
assert(cur_buf_offset() == meta_size, "sanity");
}
@@ -85,6 +86,7 @@ inline void Message::serialize_meta() {
inline void Message::deserialize_meta() {
_buf.set_cur_offset(0);
_buf.deserialize_ref_no_meta(_meta.msg_size);
+ _buf.deserialize_ref_no_meta(_meta.magic_num);
_buf.deserialize_ref_no_meta(_meta.msg_type);
assert(cur_buf_offset() == meta_size, "sanity");
}
diff --git a/src/hotspot/share/jbooster/net/messageType.hpp b/src/hotspot/share/jbooster/net/messageType.hpp
index f8cb8f3e6..dbd89c07c 100644
--- a/src/hotspot/share/jbooster/net/messageType.hpp
+++ b/src/hotspot/share/jbooster/net/messageType.hpp
@@ -54,6 +54,7 @@
f(ArrayKlasses, "from server" ) \
f(DataOfKlasses, "from server" ) \
f(MethodLocators, "from server" ) \
+ f(ResolveExtraKlasses, "from server" ) \
\
/* others */ \
f(FileSegment, "from both" ) \
diff --git a/src/hotspot/share/jbooster/net/netCommon.hpp b/src/hotspot/share/jbooster/net/netCommon.hpp
index 8706b7f22..2e30708cc 100644
--- a/src/hotspot/share/jbooster/net/netCommon.hpp
+++ b/src/hotspot/share/jbooster/net/netCommon.hpp
@@ -133,13 +133,15 @@
class MessageConst {
public:
+ static constexpr uint32_t MAX_MSG_SIZE = 0x80000000;
+ static constexpr uint16_t RPC_MAGIC = 0xB05E;
enum: uint32_t {
/**
* The layout of the message in the buffer:
- * | msg_size | msg_type | ... (all of the arguments) ... |
- * | 4 bytes | 2 bytes | msg_size - 4 - 2 bytes |
+ * | msg_size | magic_num | msg_type | ... (all of the arguments) ... |
+ * | 4 bytes | 2 bytes | 2 bytes | msg_size - 4 - 2 bytes |
*/
- meta_size = sizeof(uint32_t) + sizeof(MessageType),
+ meta_size = sizeof(uint32_t) + sizeof(uint16_t) + sizeof(MessageType),
/**
* The layout of each argument in the buffer:
* | arg_size | ... (payload of the argument) ... |
diff --git a/src/hotspot/share/jbooster/server/serverMessageHandler.cpp b/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
index f46b839bb..713ea1374 100644
--- a/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
+++ b/src/hotspot/share/jbooster/server/serverMessageHandler.cpp
@@ -319,11 +319,15 @@ int ServerMessageHandler::handle_lazy_aot_compilation_task(TRAPS) {
GrowableArray<Method*> methods_to_compile;
GrowableArray<Method*> methods_not_compile;
bool compile_in_current_thread = false;
+ bool resolve_extra_klasses = true;
JB_TRY {
compile_in_current_thread = !aot_cache_state.is_cached() && aot_cache_state.set_being_generated();
JB_THROW(ss().send_response(&compile_in_current_thread));
if (compile_in_current_thread) {
+ JB_RETURN(ss().send_request(MessageType::ResolveExtraKlasses));
+ JB_RETURN(ss().recv_response(&resolve_extra_klasses));
+
JB_THROW(request_missing_class_loaders(THREAD));
JB_THROW(request_missing_klasses(THREAD));
JB_THROW(request_methods_to_compile(&klasses_to_compile, &methods_to_compile, THREAD));
@@ -345,6 +349,7 @@ int ServerMessageHandler::handle_lazy_aot_compilation_task(TRAPS) {
&methods_to_compile,
&methods_not_compile,
enabling_aot_pgo,
+ resolve_extra_klasses,
THREAD));
} else { // not compile in current thread
if (aot_cache_state.is_being_generated()) {
@@ -365,6 +370,7 @@ int ServerMessageHandler::try_to_compile_lazy_aot(GrowableArray<InstanceKlass*>*
GrowableArray<Method*>* methods_to_compile,
GrowableArray<Method*>* methods_not_compile,
bool enabling_aot_pgo,
+ bool resolve_extra_klasses,
TRAPS) {
JClientProgramData* pd = ss().session_data()->program_data();
JClientCacheState& aot_cache_state = enabling_aot_pgo ? pd->aot_pgo_cache_state() : pd->aot_static_cache_state();
@@ -382,10 +388,10 @@ int ServerMessageHandler::try_to_compile_lazy_aot(GrowableArray<InstanceKlass*>*
ThreadInVMfromNative tiv(THREAD);
if (methods_to_compile->is_empty()) {
- successful = LazyAOT::compile_classes_by_graal(session_id, file_path, klasses_to_compile, enabling_aot_pgo, THREAD);
+ successful = LazyAOT::compile_classes_by_graal(session_id, file_path, klasses_to_compile, enabling_aot_pgo, resolve_extra_klasses, THREAD);
} else {
successful = LazyAOT::compile_methods_by_graal(session_id, file_path, klasses_to_compile,
- methods_to_compile, methods_not_compile, enabling_aot_pgo, THREAD);
+ methods_to_compile, methods_not_compile, enabling_aot_pgo, resolve_extra_klasses, THREAD);
}
if (successful) {
diff --git a/src/hotspot/share/jbooster/server/serverMessageHandler.hpp b/src/hotspot/share/jbooster/server/serverMessageHandler.hpp
index 26926dd41..c761b9c44 100644
--- a/src/hotspot/share/jbooster/server/serverMessageHandler.hpp
+++ b/src/hotspot/share/jbooster/server/serverMessageHandler.hpp
@@ -59,7 +59,8 @@ private:
int try_to_compile_lazy_aot(GrowableArray<InstanceKlass*>* klasses_to_compile,
GrowableArray<Method*>* methods_to_compile,
GrowableArray<Method*>* methods_not_compile,
- bool use_pgo,
+ bool enabling_aot_pgo,
+ bool resolve_extra_klasses,
TRAPS);
public:
ServerMessageHandler(ServerStream* server_stream);
diff --git a/src/hotspot/share/jbooster/utilities/fileUtils.cpp b/src/hotspot/share/jbooster/utilities/fileUtils.cpp
index f19bf8fb3..598013523 100644
--- a/src/hotspot/share/jbooster/utilities/fileUtils.cpp
+++ b/src/hotspot/share/jbooster/utilities/fileUtils.cpp
@@ -75,6 +75,13 @@ bool FileUtils::is_dir(const char* path) {
return S_ISDIR(st.st_mode);
}
+int64_t FileUtils::file_size(const char* path) {
+ struct stat st = {0};
+ if (os::stat(path, &st) != 0) return -1;
+ // We don't care if it is a regular file.
+ return st.st_size;
+}
+
uint64_t FileUtils::modify_time(const char* path) {
struct stat st = {0};
if (os::stat(path, &st) != 0) return 0;
@@ -119,60 +126,3 @@ bool FileUtils::move(const char* path_from, const char* path_to) {
bool FileUtils::remove(const char* path) {
return ::remove(path) == 0;
}
-
-bool FileUtils::is_same(const char* path1, const char* path2) {
- bool res = false;
- char* buf1 = nullptr;
- char* buf2 = nullptr;
- int fd1 = os::open(path1, O_BINARY | O_RDONLY, 0);
- int fd2 = os::open(path2, O_BINARY | O_RDONLY, 0);
- do {
- if (fd1 < 0 || fd2 < 0) break;
- int64_t size1 = os::lseek(fd1, 0, SEEK_END);
- int64_t size2 = os::lseek(fd2, 0, SEEK_END);
- if (size1 != size2) break;
- int64_t size = size1;
- os::lseek(fd1, 0, SEEK_SET);
- os::lseek(fd2, 0, SEEK_SET);
- // We don't use NEW_RESOURCE_ARRAY here as Thread::current() may
- // not be initialized yet.
- buf1 = NEW_C_HEAP_ARRAY(char, (size_t) size, mtJBooster);
- buf2 = NEW_C_HEAP_ARRAY(char, (size_t) size, mtJBooster);
- size1 = (int64_t) os::read(fd1, buf1, size);
- size2 = (int64_t) os::read(fd2, buf2, size);
- guarantee(size1 == size && size2 == size, "sanity");
- res = memcmp(buf1, buf2, size) == 0;
- } while (false);
- if (fd1 >= 0) os::close(fd1);
- if (fd2 >= 0) os::close(fd2);
- if (buf1 != nullptr) {
- FREE_C_HEAP_ARRAY(char, buf1);
- }
- if (buf2 != nullptr) {
- FREE_C_HEAP_ARRAY(char, buf2);
- }
- return res;
-}
-
-bool FileUtils::is_same(const char* path, const char* content, int64_t size) {
- bool res = false;
- char* buf = nullptr;
- int fd = os::open(path, O_BINARY | O_RDONLY, 0);
- do {
- if (fd < 0) break;
- int64_t fsize = os::lseek(fd, 0, SEEK_END);
- if (fsize != size) break;
- os::lseek(fd, 0, SEEK_SET);
- // We don't use NEW_RESOURCE_ARRAY here as Thread::current() may
- // not be initialized yet.
- buf = NEW_C_HEAP_ARRAY(char, (size_t) size, mtJBooster);
- fsize = (int64_t) os::read(fd, buf, size);
- guarantee(fsize == size, "sanity");
- res = memcmp(content, buf, size) == 0;
- } while (false);
- if (fd >= 0) os::close(fd);
- if (buf != nullptr) {
- FREE_C_HEAP_ARRAY(char, buf);
- }
- return res;
-}
diff --git a/src/hotspot/share/jbooster/utilities/fileUtils.hpp b/src/hotspot/share/jbooster/utilities/fileUtils.hpp
index 2b5734754..ccc677af7 100644
--- a/src/hotspot/share/jbooster/utilities/fileUtils.hpp
+++ b/src/hotspot/share/jbooster/utilities/fileUtils.hpp
@@ -44,14 +44,13 @@ public:
static bool exists(const char* path);
static bool is_file(const char* path);
static bool is_dir(const char* path);
+ static int64_t file_size(const char* path);
static uint64_t modify_time(const char* path);
static bool mkdir(const char* path);
static bool mkdirs(const char* path);
static bool rename(const char* path_from, const char* path_to);
static bool move(const char* path_from, const char* path_to);
static bool remove(const char* path);
- static bool is_same(const char* path1, const char* path2);
- static bool is_same(const char* path, const char* content, int64_t size);
class ListDir: public StackObj {
const char* _path;
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 b26786a52..85c9bf464 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
@@ -94,6 +94,11 @@ public interface JBoosterCompilationContext {
*/
boolean usePGO();
+ /**
+ * return true if compilation uses extra-resolved klasses
+ */
+ boolean resolveExtraKlasses();
+
/**
* Get methodCount of CompiledMethodInfo.
* (To support multi-task concurrent compilation of AOT)
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
index e429e43e8..01ee855d3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
@@ -263,6 +263,7 @@ import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LUDICROU
import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_DURING_PARSING;
import static org.graalvm.compiler.nodes.type.StampTool.isPointerNonNull;
+import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -4386,6 +4387,20 @@ public class BytecodeParser implements GraphBuilderContext {
}
protected void maybeEagerlyResolve(int cpi, int bytecode) {
+ JBoosterCompilationContext ctx = JBoosterCompilationContext.get();
+ if (ctx != null && !ctx.resolveExtraKlasses()) {
+ try{
+ maybeEagerlyResolveBase(cpi, bytecode);
+ } catch (NoClassDefFoundError e) {
+ debug.log("Cannot resolve all elements in constant pool");
+ return;
+ }
+ } else {
+ maybeEagerlyResolveBase(cpi, bytecode);
+ }
+ }
+
+ protected void maybeEagerlyResolveBase(int cpi, int bytecode) {
if (intrinsicContext != null) {
constantPool.loadReferencedType(cpi, bytecode);
} else if (graphBuilderConfig.eagerResolving()) {
@@ -4420,6 +4435,20 @@ public class BytecodeParser implements GraphBuilderContext {
}
protected JavaType maybeEagerlyResolve(JavaType type, ResolvedJavaType accessingClass) {
+ JBoosterCompilationContext ctx = JBoosterCompilationContext.get();
+ if (ctx != null && !ctx.resolveExtraKlasses()) {
+ try{
+ return maybeEagerlyResolveBase(type, accessingClass);
+ } catch (NoClassDefFoundError e) {
+ debug.log("Cannot resolve all elements in constant pool");
+ return type;
+ }
+ } else {
+ return maybeEagerlyResolveBase(type, accessingClass);
+ }
+ }
+
+ protected JavaType maybeEagerlyResolveBase(JavaType type, ResolvedJavaType accessingClass) {
if (graphBuilderConfig.eagerResolving() || parsingIntrinsic()) {
return type.resolve(accessingClass);
}
diff --git a/src/jdk.jbooster/share/classes/jdk/jbooster/JBooster.java b/src/jdk.jbooster/share/classes/jdk/jbooster/JBooster.java
index db5d916ac..76d62e9b2 100644
--- a/src/jdk.jbooster/share/classes/jdk/jbooster/JBooster.java
+++ b/src/jdk.jbooster/share/classes/jdk/jbooster/JBooster.java
@@ -175,15 +175,15 @@ public final class JBooster {
/**
* This method is invoked only in C++.
*/
- private static boolean compileClasses(int sessionId, String filePath, Set<Class<?>> classes, boolean usePGO) {
- return compileMethods(sessionId, filePath, classes, null, null, usePGO);
+ private static boolean compileClasses(int sessionId, String filePath, Set<Class<?>> classes, boolean usePGO, boolean resolveExtraKlasses) {
+ return compileMethods(sessionId, filePath, classes, null, null, usePGO, resolveExtraKlasses);
}
/**
* This method is invoked only in C++.
*/
private static boolean compileMethods(int sessionId, String filePath, Set<Class<?>> classes,
- Set<String> methodsToCompile, Set<String> methodsNotToCompile, boolean usePGO) {
+ Set<String> methodsToCompile, Set<String> methodsNotToCompile, boolean usePGO, boolean resolveExtraKlasses) {
LOGGER.log(INFO, "Compilation task received: classes_to_compile={0}, methods_to_compile={1}, methods_not_compile={2}, session_id={3}.",
classes.size(),
(methodsToCompile == null ? "all" : String.valueOf(methodsToCompile.size())),
@@ -191,7 +191,7 @@ public final class JBooster {
sessionId);
try {
JBoosterCompilationContextImpl ctx = new JBoosterCompilationContextImpl(
- sessionId, filePath, classes, methodsToCompile, methodsNotToCompile, usePGO);
+ sessionId, filePath, classes, methodsToCompile, methodsNotToCompile, usePGO, resolveExtraKlasses);
return new Main(ctx).compileForJBooster();
} catch (Exception e) {
e.printStackTrace();
diff --git a/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java b/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java
index 4918f8552..efdeee9e5 100644
--- a/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java
+++ b/src/jdk.jbooster/share/classes/jdk/jbooster/JBoosterCompilationContextImpl.java
@@ -43,6 +43,7 @@ public class JBoosterCompilationContextImpl implements JBoosterCompilationContex
private final Set<String> methodsToCompile;
private final Set<String> methodsNotToCompile;
private final boolean usePGO;
+ private final boolean resolveExtraKlasses;
// These values are used to replace the static values in AOT classes.
private final AtomicInteger compiledMethodInfoMethodsCount = new AtomicInteger(0);
@@ -63,13 +64,15 @@ public class JBoosterCompilationContextImpl implements JBoosterCompilationContex
Set<Class<?>> classesToCompile,
Set<String> methodsToCompile,
Set<String> methodsNotCompile,
- boolean usePGO) {
+ boolean usePGO,
+ boolean resolveExtraKlasses) {
this.sessionId = sessionId;
this.filePath = filePath;
this.classesToCompile = classesToCompile;
this.methodsToCompile = methodsToCompile;
this.methodsNotToCompile = methodsNotCompile;
this.usePGO = usePGO;
+ this.resolveExtraKlasses = resolveExtraKlasses;
}
@Override
@@ -102,6 +105,11 @@ public class JBoosterCompilationContextImpl implements JBoosterCompilationContex
return usePGO;
}
+ @Override
+ public boolean resolveExtraKlasses() {
+ return resolveExtraKlasses;
+ }
+
@Override
public AtomicInteger getCompiledMethodInfoMethodsCount() {
return compiledMethodInfoMethodsCount;
diff --git a/test/hotspot/gtest/jbooster/common.hpp b/test/hotspot/gtest/jbooster/common.hpp
new file mode 100644
index 000000000..15b773786
--- /dev/null
+++ b/test/hotspot/gtest/jbooster/common.hpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2020, 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.
+ */
+
+#ifndef GTEST_JBOOSTER_COMMON
+#define GTEST_JBOOSTER_COMMON
+
+#if INCLUDE_JBOOSTER
+
+// @see src/hotspot/share/memory/filemap.cpp
+#ifndef O_BINARY // if defined (Win32) use binary files.
+#define O_BINARY 0 // otherwise do nothing.
+#endif
+
+class TestUtils {
+public:
+ static bool is_same(const char* path1, const char* path2) {
+ bool res = false;
+ char* buf1 = nullptr;
+ char* buf2 = nullptr;
+ int fd1 = os::open(path1, O_BINARY | O_RDONLY, 0);
+ int fd2 = os::open(path2, O_BINARY | O_RDONLY, 0);
+ do {
+ if (fd1 < 0 || fd2 < 0) break;
+ int64_t size1 = os::lseek(fd1, 0, SEEK_END);
+ int64_t size2 = os::lseek(fd2, 0, SEEK_END);
+ if (size1 != size2) break;
+ int64_t size = size1;
+ os::lseek(fd1, 0, SEEK_SET);
+ os::lseek(fd2, 0, SEEK_SET);
+ // We don't use NEW_RESOURCE_ARRAY here as Thread::current() may
+ // not be initialized yet.
+ buf1 = NEW_C_HEAP_ARRAY(char, (size_t) size, mtJBooster);
+ buf2 = NEW_C_HEAP_ARRAY(char, (size_t) size, mtJBooster);
+ size1 = (int64_t) os::read(fd1, buf1, size);
+ size2 = (int64_t) os::read(fd2, buf2, size);
+ guarantee(size1 == size && size2 == size, "sanity");
+ res = memcmp(buf1, buf2, size) == 0;
+ } while (false);
+ if (fd1 >= 0) os::close(fd1);
+ if (fd2 >= 0) os::close(fd2);
+ if (buf1 != nullptr) {
+ FREE_C_HEAP_ARRAY(char, buf1);
+ }
+ if (buf2 != nullptr) {
+ FREE_C_HEAP_ARRAY(char, buf2);
+ }
+ return res;
+ }
+
+ static bool is_same(const char* path, const char* content, int64_t size) {
+ bool res = false;
+ char* buf = nullptr;
+ int fd = os::open(path, O_BINARY | O_RDONLY, 0);
+ do {
+ if (fd < 0) break;
+ int64_t fsize = os::lseek(fd, 0, SEEK_END);
+ if (fsize != size) break;
+ os::lseek(fd, 0, SEEK_SET);
+ // We don't use NEW_RESOURCE_ARRAY here as Thread::current() may
+ // not be initialized yet.
+ buf = NEW_C_HEAP_ARRAY(char, (size_t) size, mtJBooster);
+ fsize = (int64_t) os::read(fd, buf, size);
+ guarantee(fsize == size, "sanity");
+ res = memcmp(content, buf, size) == 0;
+ } while (false);
+ if (fd >= 0) os::close(fd);
+ if (buf != nullptr) {
+ FREE_C_HEAP_ARRAY(char, buf);
+ }
+ return res;
+ }
+};
+
+#endif // INCLUDE_JBOOSTER
+
+#endif // GTEST_JBOOSTER_COMMON
\ No newline at end of file
diff --git a/test/hotspot/gtest/jbooster/test_net.cpp b/test/hotspot/gtest/jbooster/test_net.cpp
index bf20b0aa3..dd45dd65a 100644
--- a/test/hotspot/gtest/jbooster/test_net.cpp
+++ b/test/hotspot/gtest/jbooster/test_net.cpp
@@ -26,6 +26,8 @@
#if INCLUDE_JBOOSTER
+#include "common.hpp"
+
#include "jbooster/jClientArguments.hpp"
#include "jbooster/net/message.inline.hpp"
#include "jbooster/net/messageBuffer.inline.hpp"
@@ -431,7 +433,7 @@ TEST(JBoosterNet, serializationn_file_wrapper) {
}
EXPECT_EQ(times, 3);
}
- EXPECT_TRUE(FileUtils::is_same(file_name1, file_name2));
+ EXPECT_TRUE(TestUtils::is_same(file_name1, file_name2));
FileUtils::remove(file_name1);
FileUtils::remove(file_name2);
}
diff --git a/test/hotspot/gtest/jbooster/test_util.cpp b/test/hotspot/gtest/jbooster/test_util.cpp
index cd65804be..461e3faa7 100644
--- a/test/hotspot/gtest/jbooster/test_util.cpp
+++ b/test/hotspot/gtest/jbooster/test_util.cpp
@@ -26,6 +26,8 @@
#if INCLUDE_JBOOSTER
+#include "common.hpp"
+
#include "classfile/symbolTable.hpp"
#include "jbooster/utilities/concurrentHashMap.inline.hpp"
#include "jbooster/utilities/debugUtils.inline.hpp"
@@ -95,13 +97,13 @@ TEST(JBoosterUtil, file) {
write_file("gtest-jbooster-tmp5", "12345");
write_file("gtest-jbooster-tmp6", "12345");
- EXPECT_TRUE(FileUtils::is_same("gtest-jbooster-tmp5", "gtest-jbooster-tmp6"));
+ EXPECT_TRUE(TestUtils::is_same("gtest-jbooster-tmp5", "gtest-jbooster-tmp6"));
write_file("gtest-jbooster-tmp6", "123456");
- EXPECT_FALSE(FileUtils::is_same("gtest-jbooster-tmp5", "gtest-jbooster-tmp6"));
+ EXPECT_FALSE(TestUtils::is_same("gtest-jbooster-tmp5", "gtest-jbooster-tmp6"));
- EXPECT_TRUE(FileUtils::is_same("gtest-jbooster-tmp5", "12345", 6));
- EXPECT_FALSE(FileUtils::is_same("gtest-jbooster-tmp5", "12346", 6));
- EXPECT_FALSE(FileUtils::is_same("gtest-jbooster-tmp5", "123456", 7));
+ EXPECT_TRUE(TestUtils::is_same("gtest-jbooster-tmp5", "12345", 6));
+ EXPECT_FALSE(TestUtils::is_same("gtest-jbooster-tmp5", "12346", 6));
+ EXPECT_FALSE(TestUtils::is_same("gtest-jbooster-tmp5", "123456", 7));
EXPECT_FALSE(FileUtils::is_file("gtest-jbooster-tmp4"));
EXPECT_TRUE(FileUtils::is_dir("gtest-jbooster-tmp4"));
diff --git a/test/jdk/tools/jbooster/JBoosterTestBase.java b/test/jdk/tools/jbooster/JBoosterTestBase.java
index 08792a77b..4c1dcbd4a 100644
--- a/test/jdk/tools/jbooster/JBoosterTestBase.java
+++ b/test/jdk/tools/jbooster/JBoosterTestBase.java
@@ -44,11 +44,12 @@ import jdk.test.lib.Utils;
* @see JcmdBase
*/
public class JBoosterTestBase {
- public static final int WAIT_START_TIME = 2;
+ public static final int WAIT_START_TIME = 128;
public static final int WAIT_SHORT_TIME = 8;
public static final int WAIT_EXIT_TIME = 64;
public static final int SERVER_PORT = 41567;
+ public static final int SERVER_CONNECTION_TIMEOUT = 256 * 1000;
public static final String SERVER_PORT_STR = "41567";
public static final String CLIENT_CACHE_PATH = "jbooster-cache-client";
@@ -80,7 +81,8 @@ public class JBoosterTestBase {
public static final List<String> SERVER_STANDARD_ARGS = List.of(
"--server-port=" + SERVER_PORT_STR,
- "--cache-path=" + SERVER_CACHE_PATH
+ "--cache-path=" + SERVER_CACHE_PATH,
+ "--connection-timeout=" + SERVER_CONNECTION_TIMEOUT
);
private static final ProcessBuilder processBuilder = new ProcessBuilder();
--
2.22.0

View File

@ -0,0 +1,623 @@
From fcf500b87f0ddcd1fff0b9a0040b1be1b8a37321 Mon Sep 17 00:00:00 2001
Date: Fri, 29 Nov 2024 15:36:57 +0800
Subject: SA redact support password
---
src/hotspot/share/runtime/arguments.cpp | 16 ++--
src/hotspot/share/runtime/arguments.hpp | 5 -
src/hotspot/share/runtime/globals.hpp | 2 +-
src/hotspot/share/services/heapRedactor.cpp | 7 +-
src/hotspot/share/services/heapRedactor.hpp | 1 +
.../classes/sun/jvm/hotspot/SALauncher.java | 10 +-
.../classes/sun/jvm/hotspot/tools/JMap.java | 36 +++++++
.../hotspot/utilities/HeapHprofBinWriter.java | 75 ++++++++++++++-
.../jvm/hotspot/utilities/HeapRedactor.java | 30 +++---
.../share/classes/sun/tools/jmap/JMap.java | 96 +++++++++++++++----
10 files changed, 227 insertions(+), 51 deletions(-)
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 42b4f90f1..f24cabb11 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -121,8 +121,6 @@ bool Arguments::_has_jimage = false;
char* Arguments::_ext_dirs = NULL;
-char* Arguments::_heap_dump_redact_auth = NULL;
-
bool PathString::set_value(const char *value) {
if (_value != NULL) {
FreeHeap(_value);
@@ -3743,23 +3741,23 @@ jint Arguments::match_special_option_and_act(const JavaVMInitArgs* args,
warning("Heap dump redacting did not setup properly, using wrong argument?");
vm_exit_during_initialization("Syntax error, expecting -XX:HeapDumpRedact=[off|names|basic|full|diyrules|annotation]",NULL);
}
+ continue;
}
// heapDump redact password
if(match_option(option, "-XX:RedactPassword=", &tail)) {
if(tail == NULL || strlen(tail) == 0) {
VerifyRedactPassword = false;
- jio_fprintf(defaultStream::output_stream(), "redact password is null, disable verify heap dump authority.\n");
} else {
- VerifyRedactPassword = true;
- size_t redact_password_len = strlen(tail);
- _heap_dump_redact_auth = NEW_C_HEAP_ARRAY(char, redact_password_len+1, mtArguments);
- memcpy(_heap_dump_redact_auth, tail, redact_password_len);
- _heap_dump_redact_auth[redact_password_len] = '\0';
- memset((void*)tail, '0', redact_password_len);
+ char* split_char = strstr(const_cast<char*>(tail), ",");
+ VerifyRedactPassword = !(split_char == NULL || strlen(split_char) < SALT_LEN);
+ }
+ if(!VerifyRedactPassword) {
+ jio_fprintf(defaultStream::output_stream(), "redact password is null or with bad format, disable verify heap dump authority.\n");
}
}
+
#ifndef PRODUCT
if (match_option(option, "-XX:+PrintFlagsWithComments")) {
JVMFlag::printFlags(tty, true);
diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp
index 6b9759906..cb2a04a2d 100644
--- a/src/hotspot/share/runtime/arguments.hpp
+++ b/src/hotspot/share/runtime/arguments.hpp
@@ -468,8 +468,6 @@ class Arguments : AllStatic {
char** base_archive_path,
char** top_archive_path) NOT_CDS_RETURN;
- static char* _heap_dump_redact_auth;
-
public:
// Parses the arguments, first phase
static jint parse(const JavaVMInitArgs* args);
@@ -555,9 +553,6 @@ class Arguments : AllStatic {
// Java launcher properties
static void process_sun_java_launcher_properties(JavaVMInitArgs* args);
- // heap dump redact password
- static const char* get_heap_dump_redact_auth() { return _heap_dump_redact_auth; }
-
// System properties
static void init_system_properties();
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index b51e50ddf..680e78c04 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -568,7 +568,7 @@ const intx ObjectAlignmentInBytes = 8;
"verify authority for operating heapDump redact feature") \
\
product(ccstr, RedactPassword, NULL, \
- "authority for operating heapDump redact feature") \
+ "authority for operating heapDump redact feature, format {password,salt}, salt length >= 8") \
\
product(ccstr, NativeMemoryTracking, DEBUG_ONLY("summary") NOT_DEBUG("off"), \
"Native memory tracking options") \
diff --git a/src/hotspot/share/services/heapRedactor.cpp b/src/hotspot/share/services/heapRedactor.cpp
index 0e7b0a97c..cfb5b3f82 100644
--- a/src/hotspot/share/services/heapRedactor.cpp
+++ b/src/hotspot/share/services/heapRedactor.cpp
@@ -170,12 +170,15 @@ void HeapRedactor::init(outputStream* out) {
* if HeapDumpRedact is NULL , jmap operation can not open redact feature without password
* if HeapDumpRedact is not NULL, jmap operation can not change redact level without password
**/
- if(Arguments::get_heap_dump_redact_auth() == NULL) {
+ char* split_char = NULL;
+ if(RedactPassword == NULL || (split_char = strstr(const_cast<char*>(RedactPassword), ",")) == NULL || strlen(split_char) < SALT_LEN) {
VerifyRedactPassword = false;
}
if(VerifyRedactPassword && !_use_sys_params) {
+ size_t auth_len = strlen(RedactPassword);
+ size_t suffix_len = strlen(split_char);
if(_redact_params.redact_password == NULL ||
- strcmp(_redact_params.redact_password, Arguments::get_heap_dump_redact_auth()) ) {
+ strncmp(_redact_params.redact_password, RedactPassword, auth_len-suffix_len) ) {
// no password or wrong password
_use_sys_params = true;
if(out != NULL) {
diff --git a/src/hotspot/share/services/heapRedactor.hpp b/src/hotspot/share/services/heapRedactor.hpp
index 790430507..e5a5bf440 100644
--- a/src/hotspot/share/services/heapRedactor.hpp
+++ b/src/hotspot/share/services/heapRedactor.hpp
@@ -32,6 +32,7 @@
#endif
#define MAX_MAP_FILE_LENGTH 1024
+#define SALT_LEN 9
enum HeapDumpRedactLevel {
REDACT_UNKNOWN,
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java
index 291e483e0..91a432574 100644
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java
@@ -322,7 +322,8 @@ public class SALauncher {
Map.entry("HeapDumpRedact=", "HeapDumpRedact"),
Map.entry("RedactMap=", "RedactMap"),
Map.entry("RedactMapFile=", "RedactMapFile"),
- Map.entry("RedactClassPath=", "RedactClassPath"));
+ Map.entry("RedactClassPath=", "RedactClassPath"),
+ Map.entry("RedactPassword", "RedactPassword"));
}
private static void runJMAP(String[] oldArgs) {
@@ -337,6 +338,7 @@ public class SALauncher {
String redactMap = newArgMap.get("RedactMap");
String redactMapFile = newArgMap.get("RedactMapFile");
String redactClassPath = newArgMap.get("RedactClassPath");
+ boolean hasRedactPassword = newArgMap.containsKey("RedactPassword");
if (!requestHeapdump && (dumpfile != null)) {
throw new IllegalArgumentException("Unexpected argument: dumpfile");
}
@@ -359,6 +361,9 @@ public class SALauncher {
if (redactClassPath != null) {
command += ",RedactClassPath=" + redactClassPath;
}
+ if(hasRedactPassword) {
+ command += ",RedactPassword";
+ }
newArgMap.put(command, null);
}
@@ -369,9 +374,12 @@ public class SALauncher {
newArgMap.remove("RedactMap");
newArgMap.remove("RedactMapFile");
newArgMap.remove("RedactClassPath");
+ newArgMap.remove("RedactPassword");
JMap.main(buildAttachArgs(newArgMap, false));
}
+
+
private static void runJINFO(String[] oldArgs) {
Map<String, String> longOptsMap = Map.of("exe=", "exe",
"core=", "core",
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java
index e52cd1fb1..fbead3ce4 100644
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java
@@ -25,6 +25,9 @@
package sun.jvm.hotspot.tools;
import java.io.*;
+import java.nio.CharBuffer;
+import java.util.regex.Pattern;
+
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.utilities.*;
@@ -189,6 +192,9 @@ public class JMap extends Tool {
redactParams.setRedactMapFile(keyValue[1]);
} else if (keyValue[0].equals("RedactClassPath")) {
redactParams.setRedactClassPath(keyValue[1]);
+ } else if (keyValue[0].equals("RedactPassword")) {
+ redactParams.setRedactPassword(getRedactPassword());
+
} else {
System.err.println("unknown option:" + keyValue[0]);
@@ -226,6 +232,36 @@ public class JMap extends Tool {
jmap.execute(args);
}
+ private static CharBuffer getRedactPassword() {
+ CharBuffer redactPassword = CharBuffer.wrap("");
+ // heap dump may need a password
+ Console console = System.console();
+ char[] passwords = null;
+ if (console == null) {
+ return redactPassword;
+ }
+
+ try {
+ passwords = console.readPassword("redact authority password:");
+ } catch (Exception e) {
+ }
+ if(passwords == null) {
+ return redactPassword;
+ }
+
+ try {
+ CharBuffer cb = CharBuffer.wrap(passwords);
+ String passwordPattern = "^[0-9a-zA-Z!@#$]{1,9}$";
+ if(!Pattern.matches(passwordPattern, cb)) {
+ return redactPassword;
+ }
+ redactPassword = cb;
+ } catch (Exception e) {
+ }
+
+ return redactPassword;
+ }
+
public boolean writeHeapHprofBin(String fileName, int gzLevel) {
try {
HeapHprofBinWriter hgw;
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
index e73b6f9a3..566d88646 100644
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
@@ -28,6 +28,10 @@ import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.*;
+import java.nio.CharBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
import java.util.*;
import java.util.zip.*;
import sun.jvm.hotspot.debugger.*;
@@ -37,6 +41,10 @@ import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.classfile.*;
import sun.jvm.hotspot.gc.z.ZCollectedHeap;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
/*
* This class writes Java heap in hprof binary format. This format is
* used by Heap Analysis Tool (HAT). The class is heavily influenced
@@ -386,6 +394,11 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
private static final long MAX_U4_VALUE = 0xFFFFFFFFL;
int serialNum = 1;
+ // encrypt
+ private static int SALT_MIN_LENGTH = 8;
+ private static int HASH_BIT_SIZE = 256;
+ private static int HASH_ITERATIONS_COUNT = 10000;
+
// Heap Redact
private HeapRedactor heapRedactor;
@@ -404,6 +417,10 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
return heapRedactor.getHeapDumpRedactLevel();
}
+ public Optional<CharBuffer> getHeapDumpRedactPassword() {
+ return heapRedactor == null ? Optional.empty() : Optional.ofNullable(heapRedactor.getRedactPassword());
+ }
+
private Optional<String> lookupRedactName(String name){
return heapRedactor == null ? Optional.empty() : heapRedactor.lookupRedactName(name);
}
@@ -454,10 +471,66 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
this.gzLevel = gzLevel;
}
+ private boolean checkPassword() {
+ Optional<String> redactAuthOption = getVMRedactParameter("RedactPassword");
+ String redactAuth = redactAuthOption.isPresent() ? redactAuthOption.get() : null;
+ boolean redactAuthFlag = true;
+ if(redactAuth != null) {
+ String[] auths = redactAuth.split(",");
+ if(auths.length != 2) {
+ return redactAuthFlag;
+ }
+
+ Optional<CharBuffer> passwordOption = getHeapDumpRedactPassword();
+ CharBuffer password = passwordOption.isPresent() ? passwordOption.get() : CharBuffer.wrap("");
+ char[] passwordChars = null;
+ try {
+ passwordChars = password.array();
+
+ byte[] saltBytes = auths[1].getBytes("UTF-8");
+ if(saltBytes.length < SALT_MIN_LENGTH) {
+ return redactAuthFlag;
+ }
+
+ String digestStr = getEncryptValue(passwordChars, saltBytes);
+ redactAuthFlag = auths[0].equals(digestStr);
+ } catch (Exception e) {
+ // ignore
+ redactAuthFlag = false;
+ } finally {
+ // clear all password
+ if(passwordChars != null) {
+ Arrays.fill(passwordChars, '0');
+ }
+ }
+ }
+
+ return redactAuthFlag;
+ }
+
+ private String getEncryptValue(char[] passwordValue, byte[] saltBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
+ StringBuilder digestStrBuilder = new StringBuilder();
+
+ KeySpec spec = new PBEKeySpec(passwordValue, saltBytes, HASH_ITERATIONS_COUNT, HASH_BIT_SIZE);
+ SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
+ SecretKey secretKey = secretKeyFactory.generateSecret(spec);
+ byte[] digestBytes = secretKey.getEncoded();
+ for (byte b : digestBytes) {
+ String hex = Integer.toHexString(0xff & b);
+ if (hex.length() == 1) {
+ digestStrBuilder.append('0');
+ }
+ digestStrBuilder.append(hex);
+ }
+ String digestStr = digestStrBuilder.toString();
+
+ return digestStr;
+ }
+
public synchronized void write(String fileName) throws IOException {
VM vm = VM.getVM();
- if(getHeapDumpRedactLevel() == HeapRedactor.HeapDumpRedactLevel.REDACT_UNKNOWN) {
+ if(getHeapDumpRedactLevel() == HeapRedactor.HeapDumpRedactLevel.REDACT_UNKNOWN || !checkPassword()) {
resetRedactParams();
}
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapRedactor.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapRedactor.java
index c2a916617..5c442b2bb 100644
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapRedactor.java
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapRedactor.java
@@ -30,6 +30,7 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -51,7 +52,7 @@ public class HeapRedactor {
private HeapDumpRedactLevel redactLevel;
private Map<String, String> redactNameTable;
private Map<String, Map<String, String>> redactClassTable;
- private String redactClassFullName = null;
+ private String redactClassFullName = null;
private Map<Long, String> redactValueTable;
private RedactVectorNode headerNode;
private RedactVectorNode currentNode;
@@ -62,6 +63,7 @@ public class HeapRedactor {
public static final String REDACT_MAP_PREFIX = "RedactMap=";
public static final String REDACT_MAP_FILE_PREFIX = "RedactMapFile=";
public static final String REDACT_CLASS_PATH_PREFIX = "RedactClassPath=";
+ public static final String REDACT_PASSWORD_PREFIX = "RedactPassword=";
public static final String REDACT_UNKNOWN_STR = "UNKNOWN";
public static final String REDACT_OFF_STR = "OFF";
@@ -82,14 +84,6 @@ public class HeapRedactor {
public static final int PATH_MAX = 4096;
public static final int REDACT_VECTOR_SIZE = 1024;
- public HeapRedactor(String options) {
- redactLevel = HeapDumpRedactLevel.REDACT_UNKNOWN;
- redactNameTable = null;
- redactClassTable = null;
- redactValueTable = null;
- init(options);
- }
-
public HeapRedactor(RedactParams redactParams) {
this.redactParams = redactParams;
redactLevel = HeapDumpRedactLevel.REDACT_UNKNOWN;
@@ -167,6 +161,10 @@ public class HeapRedactor {
return redactParams.getRedactClassPath();
}
+ public CharBuffer getRedactPassword(){
+ return redactParams.getRedactPassword();
+ }
+
public Optional<Map<String, String>> getRedactRulesTable(String key) {
return Optional.ofNullable(redactClassTable == null ? null: redactClassTable.get(key));
}
@@ -218,7 +216,7 @@ public class HeapRedactor {
}
private RedactParams parseRedactOptions(String optionStr) {
- RedactParams params = new RedactParams(REDACT_OFF_OPTION, null, null, null);
+ RedactParams params = new RedactParams(REDACT_OFF_OPTION, null, null, null, null);
if (optionStr != null) {
String[] options = optionStr.split(",");
for (String option : options) {
@@ -321,16 +319,18 @@ public class HeapRedactor {
private String redactMap;
private String redactMapFile;
private String redactClassPath;
+ private CharBuffer redactPassword;
private boolean enableRedact = false;
public RedactParams() {
}
- public RedactParams(String heapDumpRedact, String redactMap, String redactMapFile, String redactClassPath) {
+ public RedactParams(String heapDumpRedact, String redactMap, String redactMapFile, String redactClassPath, CharBuffer redactPassword) {
this.heapDumpRedact = heapDumpRedact;
this.redactMap = redactMap;
this.redactMapFile = redactMapFile;
this.redactClassPath = redactClassPath;
+ this.redactPassword = redactPassword;
}
@Override
@@ -395,6 +395,14 @@ public class HeapRedactor {
this.redactClassPath = redactClassPath;
}
+ public CharBuffer getRedactPassword() {
+ return redactPassword;
+ }
+
+ public void setRedactPassword(CharBuffer redactPassword) {
+ this.redactPassword = redactPassword;
+ }
+
public static boolean checkLauncherHeapdumpRedactSupport(String value) {
String[] validValues = {REDACT_BASIC_OPTION, REDACT_NAME_OPTION, REDACT_FULL_OPTION, REDACT_DIYRULES_OPTION, REDACT_ANNOTATION_OPTION, REDACT_OFF_OPTION};
for (String validValue : validValues) {
diff --git a/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java b/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java
index ef4ea7152..6479863a6 100644
--- a/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java
+++ b/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java
@@ -25,14 +25,17 @@
package sun.tools.jmap;
+import java.io.BufferedInputStream;
import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Collection;
import java.util.regex.Pattern;
@@ -43,6 +46,10 @@ import com.sun.tools.attach.AttachNotSupportedException;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.common.ProcessArgumentMatcher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
/*
* This class is the main class for the JMap utility. It parses its arguments
* and decides if the command should be satisfied using the VM attach mechanism
@@ -51,6 +58,10 @@ import sun.tools.common.ProcessArgumentMatcher;
* options are mapped to SA tools.
*/
public class JMap {
+ // encrypt
+ private static int SALT_MIN_LENGTH = 8;
+ private static int HASH_BIT_SIZE = 256;
+ private static int HASH_ITERATIONS_COUNT = 10000;
public static void main(String[] args) throws Exception {
if (args.length == 0) {
@@ -250,7 +261,7 @@ public class JMap {
} else if (subopt.startsWith("RedactClassPath")) {
redactParams.setRedactClassPath(subopt.substring("RedactClassPath=".length()));
} else if (subopt.startsWith("RedactPassword")) {
- redactPassword = getRedactPassword();
+ redactPassword = getRedactPassword(pid);
} else {
System.err.println("Fail: invalid option: '" + subopt + "'");
usage(1);
@@ -282,7 +293,7 @@ public class JMap {
}
}
- private static String getRedactPassword() {
+ private static String getRedactPassword(String pid) {
String redactPassword = ",RedactPassword=";
// heap dump may need a password
Console console = System.console();
@@ -300,42 +311,85 @@ public class JMap {
}
String digestStr = null;
- byte[] passwordBytes = null;
try {
CharBuffer cb = CharBuffer.wrap(passwords);
String passwordPattern = "^[0-9a-zA-Z!@#$]{1,9}$";
if(!Pattern.matches(passwordPattern, cb)) {
return redactPassword;
}
- Charset cs = Charset.forName("UTF-8");
- passwordBytes= cs.encode(cb).array();
-
- StringBuilder digestStrBuilder = new StringBuilder();
- MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
- byte[] digestBytes = messageDigest.digest(passwordBytes);
- for(byte b : digestBytes) {
- String hex = Integer.toHexString(0xff & b);
- if(hex.length() == 1) {
- digestStrBuilder.append('0');
- }
- digestStrBuilder.append(hex);
+
+ String salt = getSalt(pid);
+ if(salt == null) {
+ return redactPassword;
+ }
+ byte[] saltBytes = salt.getBytes("UTF-8");
+ if(saltBytes.length < SALT_MIN_LENGTH) {
+ return redactPassword;
}
- digestStr = digestStrBuilder.toString();
+ digestStr = getEncryptValue(passwords, saltBytes);
} catch (Exception e) {
}finally {
// clear all password
if(passwords != null) {
Arrays.fill(passwords, '0');
}
- if(passwordBytes != null) {
- Arrays.fill(passwordBytes, (byte) 0);
- }
}
redactPassword += (digestStr == null ? "" : digestStr);
return redactPassword;
}
+ private static String getSalt(String pid) throws Exception {
+ String salt = null;
+ StringBuilder redactAuth = new StringBuilder();
+
+ VirtualMachine vm = VirtualMachine.attach(pid);
+ HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) vm;
+ String flag = "RedactPassword";
+ try (InputStream in = hvm.printFlag(flag); BufferedInputStream bis = new BufferedInputStream(in);
+ InputStreamReader isr = new InputStreamReader(bis, "UTF-8")) {
+ char c[] = new char[256];
+ int n;
+ do {
+ n = isr.read(c);
+
+ if (n > 0) {
+ redactAuth.append(n == c.length ? c : Arrays.copyOf(c, n));
+ }
+ } while (n > 0);
+ }
+ vm.detach();
+
+ if(redactAuth.length() > 0) {
+ String[] auths = redactAuth.toString().split(",");
+ if(auths.length != 2) {
+ return salt;
+ }
+ return auths[1].trim();
+ }
+
+ return salt;
+ }
+
+ private static String getEncryptValue(char[] passwordValue, byte[] saltBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
+ StringBuilder digestStrBuilder = new StringBuilder();
+
+ KeySpec spec = new PBEKeySpec(passwordValue, saltBytes, HASH_ITERATIONS_COUNT, HASH_BIT_SIZE);
+ SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
+ SecretKey secretKey = secretKeyFactory.generateSecret(spec);
+ byte[] digestBytes = secretKey.getEncoded();
+ for (byte b : digestBytes) {
+ String hex = Integer.toHexString(0xff & b);
+ if (hex.length() == 1) {
+ digestStrBuilder.append('0');
+ }
+ digestStrBuilder.append(hex);
+ }
+ String digestStr = digestStrBuilder.toString();
+
+ return digestStr;
+ }
+
private static void checkForUnsupportedOptions(String[] args) {
// Check arguments for -F, -m, and non-numeric value
// and warn the user that SA is not supported anymore
--
2.22.0

View File

@ -13,7 +13,7 @@ index 000000000..b717bafbe
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+17.0.10.0.13
+17.0.14.0.13
--
2.19.0

View File

@ -0,0 +1,28 @@
From d01d6f1d2c4baeb238a850ccedc8b2ab1a926eb0 Mon Sep 17 00:00:00 2001
Date: Thu, 31 Oct 2024 17:06:06 +0800
Subject: downgrade fcntl64 to fcntl on linux
---
src/hotspot/os/linux/os_linux.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
index e59af5504..96b92344f 100644
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -122,6 +122,12 @@
#include <sched.h>
#endif
+#if defined(AARCH64)
+ __asm__(".symver fcntl64,fcntl@GLIBC_2.17");
+#elif defined(AMD64)
+ __asm__(".symver fcntl64,fcntl@GLIBC_2.2.5");
+#endif
+
// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
// getrusage() is prepared to handle the associated failure.
#ifndef RUSAGE_THREAD
--
2.22.0

View File

@ -1,20 +1,20 @@
From 2e5e3cc58933e166cba5a3f0e3c59d0ca3849196 Mon Sep 17 00:00:00 2001
Date: Thu, 24 Mar 2022 11:12:46 +0800
Subject: [PATCH] downgrade the glibc symver of memcpy
From 9771982512066b47e42084ac61f714a6d8da5d6d Mon Sep 17 00:00:00 2001
Date: Sat, 30 Nov 2024 17:25:24 +0800
Subject: downgrade the glibc symver of memcpy
---
make/common/NativeCompilation.gmk | 9 +++++++++
make/hotspot/lib/CompileJvm.gmk | 8 ++++++++
src/hotspot/share/runtime/memcpy.cpp | 20 ++++++++++++++++++++
.../linux/native/applauncher/LinuxPackage.c | 3 +++
4 files changed, 40 insertions(+)
make/common/NativeCompilation.gmk | 9 +++++++++
make/hotspot/lib/CompileJvm.gmk | 15 ++++++++++++++
src/hotspot/share/runtime/memcpy.cpp | 20 +++++++++++++++++++
.../linux/native/applauncher/LinuxPackage.c | 3 +++
4 files changed, 47 insertions(+)
create mode 100644 src/hotspot/share/runtime/memcpy.cpp
diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk
index 1e2b170..4f22e2d 100644
index 215d90d17..01c47dbb0 100644
--- a/make/common/NativeCompilation.gmk
+++ b/make/common/NativeCompilation.gmk
@@ -1102,6 +1102,15 @@ define SetupNativeCompilationBody
@@ -1133,6 +1133,15 @@ define SetupNativeCompilationBody
endif
endif
@ -31,10 +31,24 @@ index 1e2b170..4f22e2d 100644
$$($1_LIBS) $$($1_EXTRA_LIBS) $$($1_MT) \
$$($1_CREATE_DEBUGINFO_CMDS) $$($1_MANIFEST_VERSION) \
diff --git a/make/hotspot/lib/CompileJvm.gmk b/make/hotspot/lib/CompileJvm.gmk
index 65edd04..d5b689e 100644
index 230aa54f7..93af36d93 100644
--- a/make/hotspot/lib/CompileJvm.gmk
+++ b/make/hotspot/lib/CompileJvm.gmk
@@ -167,6 +167,14 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJVM, \
@@ -83,6 +83,13 @@ DISABLED_WARNINGS_gcc := parentheses comment unknown-pragmas address \
empty-body strict-overflow sequence-point maybe-uninitialized \
misleading-indentation cast-function-type shift-negative-value
+ifeq ($(DEBUG_LEVEL), fastdebug)
+ ifeq ($(call And, $(call isTargetOs, linux) $(call isTargetCpu, aarch64)), true)
+ # False positive warnings for atomic_linux_aarch64.hpp on GCC >= 12
+ DISABLED_WARNINGS_gcc += stringop-overflow
+ endif
+endif
+
ifeq ($(call check-jvm-feature, zero), true)
DISABLED_WARNINGS_gcc += return-type switch clobbered
endif
@@ -169,6 +176,14 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJVM, \
PRECOMPILED_HEADER_EXCLUDE := $(JVM_PRECOMPILED_HEADER_EXCLUDE), \
))
@ -51,7 +65,7 @@ index 65edd04..d5b689e 100644
# macros.
diff --git a/src/hotspot/share/runtime/memcpy.cpp b/src/hotspot/share/runtime/memcpy.cpp
new file mode 100644
index 0000000..6ab4ddb
index 000000000..6ab4ddb64
--- /dev/null
+++ b/src/hotspot/share/runtime/memcpy.cpp
@@ -0,0 +1,20 @@
@ -76,10 +90,10 @@ index 0000000..6ab4ddb
+#endif
+#endif
diff --git a/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c b/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c
index 5e3ef36..55a7e9c 100644
index 26d65f806..b7b114ac3 100644
--- a/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c
+++ b/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c
@@ -33,6 +33,9 @@
@@ -34,6 +34,9 @@
#include "JvmLauncher.h"
#include "LinuxPackage.h"
@ -90,5 +104,5 @@ index 5e3ef36..55a7e9c 100644
static char* getModulePath(void) {
char modulePath[PATH_MAX] = { 0 };
--
1.8.3.1
2.33.0

File diff suppressed because it is too large Load Diff

View File

@ -10630,7 +10630,7 @@ index 1e16c157f..9ed420d52 100644
import java.util.List;
@@ -53,7 +54,13 @@ public class KeyAgreementTest {
String kpgAlgo = args[1];
String provider = args[2];
String provider = System.getProperty("test.provider.name", args[2]);
System.out.println("Testing " + kaAlgo);
- AlgoSpec aSpec = AlgoSpec.valueOf(AlgoSpec.class, kaAlgo);
+ AlgoSpec aSpec;
@ -10663,16 +10663,18 @@ diff --git a/test/jdk/java/security/Signature/SignatureGetInstance.java b/test/j
index c246773f8..b69258cd9 100644
--- a/test/jdk/java/security/Signature/SignatureGetInstance.java
+++ b/test/jdk/java/security/Signature/SignatureGetInstance.java
@@ -49,8 +49,11 @@ public class SignatureGetInstance {
@@ -54,9 +54,13 @@ public class SignatureGetInstance {
MyPrivKey testPriv = new MyPrivKey();
MyPubKey testPub = new MyPubKey();
+ Provider kaeProvider = Security.getProvider("KAEProvider");
+ String expectedProvName = kaeProvider != null ? "KAEProvider" : "SunRsaSign";
+ String expectedProvName = kaeProvider != null ? "KAEProvider" : "SunRsaSign";
+
+
testDblInit(testPriv, testPub, true, "TestProvider");
- testDblInit(kp.getPrivate(), kp.getPublic(), true, "SunRsaSign");
+ testDblInit(kp.getPrivate(), kp.getPublic(), true, expectedProvName);
testDblInit(kp.getPrivate(), kp.getPublic(), true,
- System.getProperty("test.provider.name", "SunRsaSign"));
+ System.getProperty("test.provider.name", expectedProName));
testDblInit(testPriv, kp.getPublic(), false, null);
testDblInit(kp.getPrivate(), testPub, false, null);
@ -12833,7 +12835,7 @@ index 58bcbe911..bfc38df35 100644
String expected;
String value = args[1];
- expected = "SunJCE";
- expected = System.getProperty("test.provider.name", "SunJCE");
+
+ if (Security.getProperty("security.provider.1").equals("KAEProvider")) {
+ expected = "KAEProvider";
@ -12873,12 +12875,12 @@ diff --git a/test/jdk/sun/security/pkcs11/policy b/test/jdk/sun/security/pkcs11/
index 54281a781..4d887e239 100644
--- a/test/jdk/sun/security/pkcs11/policy
+++ b/test/jdk/sun/security/pkcs11/policy
@@ -1,3 +1,4 @@
@@ -1,4 +1,5 @@
grant {
permission java.lang.RuntimePermission "setSecurityManager";
permission java.util.PropertyPermission "test.provider.name", "read";
+ permission java.util.PropertyPermission "kae.disableKaeDispose", "read";
};
\ No newline at end of file
diff --git a/test/jdk/sun/security/ssl/CipherSuite/DisabledCurve.java b/test/jdk/sun/security/ssl/CipherSuite/DisabledCurve.java
index 26304c5df..ca618ccfe 100644
--- a/test/jdk/sun/security/ssl/CipherSuite/DisabledCurve.java

View File

@ -74,6 +74,7 @@
%global aarch64 aarch64 arm64 armv8
%global jit_arches x86_64 %{aarch64} loongarch64 riscv64
%global aot_arches x86_64 %{aarch64}
%global linux_x64_aarch64 aarch64 x86_64
# Set of architectures for which java has short vector math library (libsvml.so)
%global svml_arches x86_64
@ -161,7 +162,7 @@
# Used via new version scheme. JDK 17 was
# GA'ed in March 2021 => 21.9
%global vendor_version_string 21.9
%global securityver 11
%global securityver 14
# buildjdkver is usually same as %%{majorver},
# but in time of bootstrap of next jdk, it is majorver-1,
# and this it is better to change it here, on single place
@ -187,7 +188,7 @@
%global origin_nice OpenJDK
%global top_level_dir_name %{origin}
%global minorver 0
%global buildver 9
%global buildver 7
# priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit
%if %is_system_jdk
%global priority %( printf '%02d%02d%02d%02d' %{majorver} %{minorver} %{securityver} %{buildver} )
@ -565,6 +566,9 @@ exit 0
%ifarch %{aarch64}
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/libj2kae.so
%endif
%ifarch %{linux_x64_aarch64}
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/libjbooster.so
%endif
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/libsyslookup.so
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/libverify.so
%{_jvmdir}/%{sdkdir -- %{?1}}/lib/libzip.so
@ -645,6 +649,10 @@ exit 0
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jdeps
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jdeprscan
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jimage
%ifarch %{linux_x64_aarch64}
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jaotc
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jbooster
%endif
%ifarch %{jit_arches}
%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jhsdb
%{_mandir}/man1/jhsdb-%{uniquesuffix -- %{?1}}.1.gz
@ -690,6 +698,9 @@ exit 0
%{_mandir}/man1/jmod-%{uniquesuffix -- %{?1}}.1.gz
%{_mandir}/man1/jshell-%{uniquesuffix -- %{?1}}.1.gz
%{_mandir}/man1/jfr-%{uniquesuffix -- %{?1}}.1.gz
%ifarch %{linux_x64_aarch64}
%{_mandir}/man1/jaotc-%{uniquesuffix -- %{?1}}.1.gz
%endif
%if %{with_systemtap}
%dir %{tapsetroot}
@ -903,7 +914,7 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release}
Name: java-%{javaver}-%{origin}
Version: %{newjavaver}.%{buildver}
Release: 4
Release: 2
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
@ -932,7 +943,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 +1024,43 @@ 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
Patch57: Backport-of-JDK-8305680.patch
Patch58: Backport-of-JDK-8305937.patch
Patch59: 8338785-The-java.awt.datatransfer.SystemFlavorMap-FL.patch
Patch60: 8337982-Remove-dead-undef-assrt0n.patch
Patch61: 8337274-Remove-repeated-the-in-StyleSheet.create-Sma.patch
Patch62: 8335610-DiagnosticFramework-CmdLine-is_executable-co.patch
Patch63: Backport-of-8333088-ubsan-shenandoahAdaptiveHeuristi.patch
Patch64: Backport-of-8339351-Remove-duplicate-line-in-FileMap.patch
Patch65: Backport-of-8330191-Fix-typo-in-precompiled.hpp.patch
Patch66: Backport-of-8337712-Wrong-javadoc-in-java.util.Date-.patch
#17.0.13
Patch67: Huawei-Fix-JBooster-file-issue-caused-by-os-write-change.patch
Patch68: downgrade-fcntl64-to-fcntl-on-linux.patch
Patch69: Add-jbolt-feature.patch
Patch70: Enable-TLS-to-communciation-between-JBooster-Server-.patch
Patch71: SA-redact-support-password.patch
Patch72: Add-specialized-hashmap-version-of-the-long-type.patch
Patch73: Implement-JBooster-RPC-byte-alignment.patch
Patch74: Optimize-LazyAOT-klasses-sending-strategy.patch
Patch75: Add-KAE-zip-GzipKAEBenchmark-Benchmark.patch
Patch76: Add-Fix-clear-mark-for-NativeGotJump.patch
Patch77: 8323066-TestSkipRebuildRemsetPhase.java-fails-with-S.patch
Patch78: Fix-a-concurrent-issue-of-program-data-ref-cnt.patch
############################################
#
# LoongArch64 specific patches
@ -1241,42 +1289,117 @@ fi
# OpenJDK patches
%ifnarch loongarch64
%ifnarch loongarch64 riscv64
pushd %{top_level_dir_name}
%patch1 -p1
%patch3 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch16 -p1
%patch18 -p1
%patch19 -p1
%patch22 -p1
%patch23 -p1
%patch26 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch36 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch 1 -p1
%patch 3 -p1
%patch 6 -p1
%patch 7 -p1
%patch 8 -p1
%patch 9 -p1
%patch 10 -p1
%patch 11 -p1
%patch 12 -p1
%patch 13 -p1
%patch 14 -p1
%patch 16 -p1
%patch 18 -p1
%patch 19 -p1
%patch 22 -p1
%patch 23 -p1
%patch 26 -p1
%patch 28 -p1
%patch 29 -p1
%patch 30 -p1
%patch 31 -p1
%patch 32 -p1
%patch 36 -p1
%patch 41 -p1
%patch 42 -p1
%patch 43 -p1
%patch 44 -p1
%patch 45 -p1
%patch 46 -p1
%patch 47 -p1
%patch 48 -p1
%patch 49 -p1
%patch 50 -p1
%patch 51 -p1
%patch 52 -p1
%patch 53 -p1
%patch 54 -p1
%patch 55 -p1
%patch 56 -p1
%patch 57 -p1
%patch 58 -p1
%patch 59 -p1
%patch 60 -p1
%patch 61 -p1
%patch 62 -p1
%patch 63 -p1
%patch 64 -p1
%patch 65 -p1
%patch 66 -p1
%patch 67 -p1
%patch 68 -p1
%patch 69 -p1
%patch 70 -p1
%patch 71 -p1
%patch 72 -p1
%patch 73 -p1
%patch 74 -p1
%patch 75 -p1
%patch 76 -p1
%patch 77 -p1
%patch 78 -p1
popd # openjdk
%endif
%ifarch riscv64
pushd %{top_level_dir_name}
%patch 1 -p1
%patch 3 -p1
%patch 6 -p1
%patch 7 -p1
%patch 8 -p1
%patch 9 -p1
%patch 10 -p1
%patch 11 -p1
%patch 12 -p1
%patch 13 -p1
%patch 14 -p1
%patch 16 -p1
%patch 18 -p1
%patch 19 -p1
%patch 22 -p1
%patch 23 -p1
%patch 26 -p1
%patch 28 -p1
%patch 29 -p1
%patch 30 -p1
%patch 31 -p1
%patch 32 -p1
%patch 36 -p1
%patch 41 -p1
%patch 42 -p1
%patch 43 -p1
%patch 57 -p1
%patch 58 -p1
%patch 59 -p1
%patch 60 -p1
%patch 61 -p1
%patch 62 -p1
%patch 63 -p1
%patch 64 -p1
%patch 65 -p1
%patch 66 -p1
%patch 68 -p1
popd
%endif
%ifarch loongarch64
pushd %{top_level_dir_name}
%patch2000 -p1
%patch 2000 -p1
popd
%endif
@ -1397,7 +1520,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 \
@ -1410,6 +1533,9 @@ bash ../configure \
--with-debug-level=$debugbuild \
--with-native-debug-symbols=internal \
--enable-unlimited-crypto \
%ifarch %{linux_x64_aarch64}
--enable-jvm-feature-jbooster \
%endif
--with-zlib=system \
--with-libjpeg=system \
--with-giflib=system \
@ -1837,6 +1963,98 @@ cjc.mainProgram(args) -- the returns from copy_jdk_configs.lua should not affect
%changelog
* Fri Feb 21 2025 songliyang <songliyang@kylinos.cn> - 1:17.0.14.7-2
- fix LoongArch64 support patch apply error
* Tue Feb 11 2025 Pan Xuefeng <panxuefeng@loongson.cn> - 1:17.0.14.7-1
- upgrade LoongArch64 port to 17.0.14
* Thu Jan 23 2025 Benshuai5D <benshuai5d@huawei> - 1:17.0.14.7-0
- update to 17.0.14
- modify 8264805-Backport-Ahead-of-Time-Compiler.patch
- modify 8280872-Reorder-code-cache-segments-to-improv.patch
- modify 8323066-TestSkipRebuildRemsetPhase.java-fails-with-S.patch
- modify Backport-Important-Fixed-Issues.patch
- modify add-version-txt.patch
- modify jdk17-Add-KAE-provider.patch
* Thu Dec 12 2024 kuenking111 <wangkun49@huawei.com> - 1:17.0.13.11-8
- add Fix-a-concurrent-issue-of-program-data-ref-cnt.patch
* Fri Dec 6 2024 kuenking111 <wangkun49@huawei.com> - 1:17.0.13.11-7
- modify Add-jbolt-feature.patch
- modify Add-specialized-hashmap-version-of-the-long-type.patch
- modify Enable-TLS-to-communciation-between-JBooster-Server-.patch
* Wed Dec 4 2024 Dingli Zhang <dingli@iscas.ac.cn> - 1:17.0.13.11-6
- Split patches for riscv64
- Increase the architecture isolation of jaotc
* Tue Dec 03 2024 shenzhongwei <shenzhongwei@kylinos.cn> - 1:17.0.13.11-5
- fix: %patchN is deprecated (51 usages found), use %patch N (or %patch -P N)
* Fri Nov 29 2024 kuenking111 <wangkun49@huawei.com> - 1:17.0.13.11-4
- add Add-jbolt-feature.patch
- add Enable-TLS-to-communciation-between-JBooster-Server-.patch
- add SA-redact-support-password.patch
- add Add-specialized-hashmap-version-of-the-long-type.patch
- add Implement-JBooster-RPC-byte-alignment.patch
- add Optimize-LazyAOT-klasses-sending-strategy.patch
- add Add-KAE-zip-GzipKAEBenchmark-Benchmark.patch
- add Add-Fix-clear-mark-for-NativeGotJump.patch
- add 8323066-TestSkipRebuildRemsetPhase.java-fails-with-S.patch
- modify downgrade-the-glibc-symver-of-memcpy.patch
* Tue Nov 12 2024 Dingli Zhang <dingli@iscas.ac.cn> - 1:17.0.13.11-3
- Fix build error for riscv64
* Wed Nov 6 2024 Pan Xuefeng <panxuefeng@loongson.cn> - 1:17.0.13.11-2
- upgrade LoongArch64 port to 17.0.13
* Thu Oct 31 2024 neu-mobi <liuyulong35@huawei.com> - 1:17.0.13.11-1
- add downgrade-fcntl64-to-fcntl-on-linux.patch
* Wed Oct 16 2024 Benshuai5D <zhangyunbo7@huawei.com> - 1:17.0.13.11-0
- modify 8264805-Backport-Ahead-of-Time-Compiler.patch
- modify 8264806-Backport-Graal-Compiler.patch
- modify Add-JBooster-Lazy-AOT-module.patch
- modify Apply-TBI-to-ZGC-of-JDK17.patch
- modify Backport-Important-Fixed-Issues.patch
- modify KAE-zip-Features.patch
- modify add-version-txt.patch
- add Huawei-Fix-JBooster-file-issue-caused-by-os-write-change.patch
- update to 17.0.13+11(ga)
* Mon Oct 14 2024 Autistic_boyya <wangzhongyi7@huawei.com> - 1:17.0.12.7-5
- Add Backport-of-JDK-8305680.patch
- Add Backport-of-JDK-8305937.patch
- Add 8338785-The-java.awt.datatransfer.SystemFlavorMap-FL.patch
- Add 8337982-Remove-dead-undef-assrt0n.patch
- Add 8337274-Remove-repeated-the-in-StyleSheet.create-Sma.patch
- Add 8335610-DiagnosticFramework-CmdLine-is_executable-co.patch
- Add Backport-of-8333088-ubsan-shenandoahAdaptiveHeuristi.patch
- Add Backport-of-8339351-Remove-duplicate-line-in-FileMap.patch
- Add Backport-of-8330191-Fix-typo-in-precompiled.hpp.patch
- Add Backport-of-8337712-Wrong-javadoc-in-java.util.Date-.patch
* Mon Sep 23 2024 Dingli Zhang <dingli@iscas.ac.cn> - 1:17.0.12.7-4
- Remove the KAE patch for riscv64 to fix build errors
* 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)
* Tue Jul 16 2024 songliyang <songliyang@kylinos.cn> - 1:17.0.11.9-4
- null the arg to solve openjdk-headless install error
@ -1852,7 +2070,7 @@ cjc.mainProgram(args) -- the returns from copy_jdk_configs.lua should not affect
* Thu Apr 18 2024 Autistic_boyya <wangzhongyi7@huawei.com> - 1:17.0.11.9-0.rolling
- del 8295068-SSLEngine-throws-NPE-parsing-CertificateRequ.patch
- modify puyuan-jdk17.0.9-patch.patch
- modify puyuan-jdk17.0.9-patch.patch
* Mon Feb 26 2024 misaka00251 <liuxin@iscas.ac.cn> - 1:17.0.10.9-2
- Remove riscv64 support patch, already upstreamed