upgrade to aarch64-shenandoah-jdk8u242-b08
This commit is contained in:
parent
f128e41137
commit
dda01ec71b
127
8139041-Redundant-DMB-instructions.patch
Normal file
127
8139041-Redundant-DMB-instructions.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From f88d00280661d697440e40bf1300121bb704bb84 Mon Sep 17 00:00:00 2001
|
||||
From: wuyan <wuyan34@huawei.com>
|
||||
Date: Tue, 19 Nov 2019 11:38:36 +0800
|
||||
Subject: [PATCH] 8139041: Redundant DMB instructions
|
||||
|
||||
Summary: <aarch64>: Redundant DMB instructions
|
||||
LLT: jtreg
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8139041
|
||||
---
|
||||
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 14 ++++++++++++++
|
||||
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp | 7 +++++++
|
||||
hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp | 17 +++++++++++++++++
|
||||
hotspot/src/share/vm/asm/codeBuffer.hpp | 7 +++++++
|
||||
4 files changed, 45 insertions(+)
|
||||
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
|
||||
index 178ec531b4..86abf44446 100644
|
||||
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
|
||||
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
|
||||
@@ -1761,6 +1761,20 @@ int MacroAssembler::corrected_idivq(Register result, Register ra, Register rb,
|
||||
return idivq_offset;
|
||||
}
|
||||
|
||||
+void MacroAssembler::membar(Membar_mask_bits order_constraint) {
|
||||
+ address prev = pc() - NativeMembar::instruction_size;
|
||||
+ if (prev == code()->last_membar()) {
|
||||
+ NativeMembar *bar = NativeMembar_at(prev);
|
||||
+ // We are merging two memory barrier instructions. On AArch64 we
|
||||
+ // can do this simply by ORing them together.
|
||||
+ bar->set_kind(bar->get_kind() | order_constraint);
|
||||
+ BLOCK_COMMENT("merged membar");
|
||||
+ } else {
|
||||
+ code()->set_last_membar(pc());
|
||||
+ dmb(Assembler::barrier(order_constraint));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// MacroAssembler routines found actually to be needed
|
||||
|
||||
void MacroAssembler::push(Register src)
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
|
||||
index 02216f1b10..388177589d 100644
|
||||
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
|
||||
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
|
||||
@@ -153,6 +153,13 @@ class MacroAssembler: public Assembler {
|
||||
strw(scratch, a);
|
||||
}
|
||||
|
||||
+ void bind(Label& L) {
|
||||
+ Assembler::bind(L);
|
||||
+ code()->clear_last_membar();
|
||||
+ }
|
||||
+
|
||||
+ void membar(Membar_mask_bits order_constraint);
|
||||
+
|
||||
// Frame creation and destruction shared between JITs.
|
||||
void build_frame(int framesize);
|
||||
void remove_frame(int framesize);
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp
|
||||
index 20deea54c7..0176e41184 100644
|
||||
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp
|
||||
+++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp
|
||||
@@ -103,6 +103,12 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
|
||||
static bool maybe_cpool_ref(address instr) {
|
||||
return is_adrp_at(instr) || is_ldr_literal_at(instr);
|
||||
}
|
||||
+
|
||||
+ bool is_Membar() {
|
||||
+ unsigned int insn = uint_at(0);
|
||||
+ return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
|
||||
+ Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
|
||||
+ }
|
||||
};
|
||||
|
||||
inline NativeInstruction* nativeInstruction_at(address address) {
|
||||
@@ -488,4 +494,15 @@ inline NativeCallTrampolineStub* nativeCallTrampolineStub_at(address addr) {
|
||||
return (NativeCallTrampolineStub*)addr;
|
||||
}
|
||||
|
||||
+class NativeMembar : public NativeInstruction {
|
||||
+public:
|
||||
+ unsigned int get_kind() { return Instruction_aarch64::extract(uint_at(0), 11, 8); }
|
||||
+ void set_kind(int order_kind) { Instruction_aarch64::patch(addr_at(0), 11, 8, order_kind); }
|
||||
+};
|
||||
+
|
||||
+inline NativeMembar *NativeMembar_at(address addr) {
|
||||
+ assert(nativeInstruction_at(addr)->is_Membar(), "no membar found");
|
||||
+ return (NativeMembar*)addr;
|
||||
+}
|
||||
+
|
||||
#endif // CPU_AARCH64_VM_NATIVEINST_AARCH64_HPP
|
||||
diff --git a/hotspot/src/share/vm/asm/codeBuffer.hpp b/hotspot/src/share/vm/asm/codeBuffer.hpp
|
||||
index 02b619ad77..a89f2c18b3 100644
|
||||
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp
|
||||
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp
|
||||
@@ -368,6 +368,8 @@ class CodeBuffer: public StackObj {
|
||||
OopRecorder _default_oop_recorder; // override with initialize_oop_recorder
|
||||
Arena* _overflow_arena;
|
||||
|
||||
+ address _last_membar; // used to merge consecutive memory barriers
|
||||
+
|
||||
address _decode_begin; // start address for decode
|
||||
address decode_begin();
|
||||
|
||||
@@ -380,6 +382,7 @@ class CodeBuffer: public StackObj {
|
||||
_oop_recorder = NULL;
|
||||
_decode_begin = NULL;
|
||||
_overflow_arena = NULL;
|
||||
+ _last_membar = NULL;
|
||||
}
|
||||
|
||||
void initialize(address code_start, csize_t code_size) {
|
||||
@@ -567,6 +570,10 @@ class CodeBuffer: public StackObj {
|
||||
OopRecorder* oop_recorder() const { return _oop_recorder; }
|
||||
CodeStrings& strings() { return _code_strings; }
|
||||
|
||||
+ address last_membar() const { return _last_membar; }
|
||||
+ void set_last_membar(address a) { _last_membar = a; }
|
||||
+ void clear_last_membar() { set_last_membar(NULL); }
|
||||
+
|
||||
void free_strings() {
|
||||
if (!_code_strings.is_null()) {
|
||||
_code_strings.free(); // sets _strings Null as a side-effect.
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -9,14 +9,14 @@ Bug url: https://bugs.openjdk.java.net/browse/JDK-8148754
|
||||
hotspot/src/share/vm/opto/loopTransform.cpp | 44 ++++++++-------------
|
||||
hotspot/src/share/vm/opto/loopnode.cpp | 36 +++++++++++++++++
|
||||
hotspot/src/share/vm/opto/loopnode.hpp | 3 ++
|
||||
hotspot/src/share/vm/opto/superword.cpp | 18 ++++-----
|
||||
4 files changed, 64 insertions(+), 37 deletions(-)
|
||||
hotspot/src/share/vm/opto/superword.cpp | 18 +++------
|
||||
4 files changed, 61 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp
|
||||
index 2edc6f8e4..3148e5cae 100644
|
||||
index e3637b652..f6783b910 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopTransform.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp
|
||||
@@ -1226,21 +1226,14 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
|
||||
@@ -1222,21 +1222,14 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
|
||||
|
||||
Node *opaq = NULL;
|
||||
if (adjust_min_trip) { // If not maximally unrolling, need adjustment
|
||||
@ -46,7 +46,7 @@ index 2edc6f8e4..3148e5cae 100644
|
||||
// Zero-trip test uses an 'opaque' node which is not shared.
|
||||
assert(opaq->outcnt() == 1 && opaq->in(1) == limit, "");
|
||||
}
|
||||
@@ -1810,7 +1803,6 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
||||
@@ -1806,7 +1799,6 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
||||
#endif
|
||||
assert(RangeCheckElimination, "");
|
||||
CountedLoopNode *cl = loop->_head->as_CountedLoop();
|
||||
@ -54,7 +54,7 @@ index 2edc6f8e4..3148e5cae 100644
|
||||
|
||||
// protect against stride not being a constant
|
||||
if (!cl->stride_is_con())
|
||||
@@ -1822,20 +1814,18 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
||||
@@ -1818,20 +1810,18 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
||||
// to not ever trip end tests
|
||||
Node *main_limit = cl->limit();
|
||||
|
||||
@ -85,10 +85,10 @@ index 2edc6f8e4..3148e5cae 100644
|
||||
|
||||
// Find the pre-loop limit; we will expand it's iterations to
|
||||
diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
index ce0a7393d..ef845ca93 100644
|
||||
index 37c56681d..e2c0645cf 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
@@ -3278,6 +3278,42 @@ Node* PhaseIdealLoop::compute_lca_of_uses(Node* n, Node* early, bool verify) {
|
||||
@@ -3284,6 +3284,42 @@ Node* PhaseIdealLoop::compute_lca_of_uses(Node* n, Node* early, bool verify) {
|
||||
return LCA;
|
||||
}
|
||||
|
||||
@ -132,10 +132,10 @@ index ce0a7393d..ef845ca93 100644
|
||||
// Compute latest legal control.
|
||||
Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
|
||||
diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp
|
||||
index aba285205..24926d047 100644
|
||||
index 150d1be0f..558b10504 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopnode.hpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopnode.hpp
|
||||
@@ -620,6 +620,9 @@ private:
|
||||
@@ -621,6 +621,9 @@ private:
|
||||
bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop);
|
||||
|
||||
public:
|
||||
@ -146,35 +146,36 @@ index aba285205..24926d047 100644
|
||||
guarantee(n != NULL, "No Node.");
|
||||
return _nodes[n->_idx] != NULL;
|
||||
diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp
|
||||
index 543ffc035..53878000f 100644
|
||||
index 0bc171b5c..a14210ee2 100644
|
||||
--- a/hotspot/src/share/vm/opto/superword.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/superword.cpp
|
||||
@@ -2208,15 +2208,18 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) {
|
||||
@@ -2209,21 +2209,13 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) {
|
||||
//----------------------------get_pre_loop_end---------------------------
|
||||
// Find pre loop end from main loop. Returns null if none.
|
||||
CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) {
|
||||
- Node *ctrl = cl->in(LoopNode::EntryControl);
|
||||
CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) {
|
||||
- Node* ctrl = cl->in(LoopNode::EntryControl);
|
||||
- if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL;
|
||||
- Node *iffm = ctrl->in(0);
|
||||
- Node* iffm = ctrl->in(0);
|
||||
- if (!iffm->is_If()) return NULL;
|
||||
- Node *p_f = iffm->in(0);
|
||||
- Node* bolzm = iffm->in(1);
|
||||
- if (!bolzm->is_Bool()) return NULL;
|
||||
- Node* cmpzm = bolzm->in(1);
|
||||
- if (!cmpzm->is_Cmp()) return NULL;
|
||||
- Node* opqzm = cmpzm->in(2);
|
||||
- // Can not optimize a loop if zero-trip Opaque1 node is optimized
|
||||
- // away and then another round of loop opts attempted.
|
||||
- if (opqzm->Opcode() != Op_Opaque1) {
|
||||
+ // The loop cannot be optimized if the graph shape at
|
||||
+ // the loop entry is inappropriate.
|
||||
+ if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
return NULL;
|
||||
}
|
||||
- Node* p_f = iffm->in(0);
|
||||
+
|
||||
+ Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0);
|
||||
if (!p_f->is_IfFalse()) return NULL;
|
||||
if (!p_f->in(0)->is_CountedLoopEnd()) return NULL;
|
||||
- CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd();
|
||||
- if (!pre_end->loopnode()->is_pre_loop()) return NULL;
|
||||
+ CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();
|
||||
+ CountedLoopNode* loop_node = pre_end->loopnode();
|
||||
+ if (loop_node == NULL || !loop_node->is_pre_loop()) return NULL;
|
||||
return pre_end;
|
||||
}
|
||||
|
||||
CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();
|
||||
--
|
||||
2.19.0
|
||||
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
--- a/make/Javadoc.gmk 2016-04-01 16:53:41.069477682 +0200
|
||||
+++ b/make/Javadoc.gmk 2016-04-01 16:53:41.014477059 +0200
|
||||
@@ -220,6 +220,12 @@
|
||||
JRE_API_DOCSDIR = $(DOCSDIR)/jre/api
|
||||
PLATFORM_DOCSDIR = $(DOCSDIR)/platform
|
||||
|
||||
+
|
||||
+JAVADOC_ARCHIVE_NAME := jdk-$(FULL_VERSION)-docs.zip
|
||||
+JAVADOC_ARCHIVE_ASSEMBLY_DIR := $(DOCSTMPDIR)/zip-docs
|
||||
+JAVADOC_ARCHIVE_DIR := $(OUTPUT_ROOT)/bundles
|
||||
+JAVADOC_ARCHIVE := $(JAVADOC_ARCHIVE_DIR)/$(JAVADOC_ARCHIVE_NAME)
|
||||
+
|
||||
# The non-core api javadocs need to be able to access the root of the core
|
||||
# api directory, so for jdk/api or jre/api to get to the core api/
|
||||
# directory we would use this:
|
||||
@@ -319,6 +325,37 @@
|
||||
all: docs
|
||||
docs: coredocs otherdocs
|
||||
|
||||
+#
|
||||
+# Optional target which bundles all generated javadocs into a zip
|
||||
+# archive. The dependency on docs is handled in Main.gmk. Incremental
|
||||
+# building of docs is currently broken so if you invoke zip-docs after
|
||||
+# docs, the docs are always rebuilt.
|
||||
+#
|
||||
+
|
||||
+zip-docs: $(JAVADOC_ARCHIVE)
|
||||
+
|
||||
+#
|
||||
+# Add the core docs as prerequisite to the archive to trigger a rebuild
|
||||
+# if the core docs were rebuilt. Ideally any doc rebuild should trigger
|
||||
+# this, but the way prerequisites are currently setup in this file, that
|
||||
+# is hard to achieve.
|
||||
+#
|
||||
+
|
||||
+$(JAVADOC_ARCHIVE): $(COREAPI_INDEX_FILE)
|
||||
+ @$(ECHO) "Compressing javadoc to single $(JAVADOC_ARCHIVE_NAME)" ;
|
||||
+ $(MKDIR) -p $(JAVADOC_ARCHIVE_DIR) ;
|
||||
+ $(RM) -r $(JAVADOC_ARCHIVE_ASSEMBLY_DIR) ;
|
||||
+ $(MKDIR) -p $(JAVADOC_ARCHIVE_ASSEMBLY_DIR);
|
||||
+ all_roots=`$(FIND) $(DOCSDIR) | $(GREP) index.html `; \
|
||||
+ pushd $(JAVADOC_ARCHIVE_ASSEMBLY_DIR); \
|
||||
+ for index_file in $${all_roots} ; do \
|
||||
+ target_dir=`dirname $${index_file}`; \
|
||||
+ name=`$(ECHO) $${target_dir} | $(SED) "s;/spec;;" | $(SED) "s;.*/;;"`; \
|
||||
+ $(LN) -s $${target_dir} $${name}; \
|
||||
+ done; \
|
||||
+ $(ZIP) -q -r $(JAVADOC_ARCHIVE) * ; \
|
||||
+ popd ;
|
||||
+
|
||||
#################################################################
|
||||
# Production Targets -- USE THESE TARGETS WHEN:
|
||||
# a) You're generating docs outside of release engineering's
|
||||
--- a/make/Main.gmk 2016-04-01 16:53:41.311480424 +0200
|
||||
+++ b/make/Main.gmk 2016-04-01 16:53:41.266479914 +0200
|
||||
@@ -165,6 +165,12 @@
|
||||
@($(CD) $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs)
|
||||
@$(call TargetExit)
|
||||
|
||||
+zip-docs: docs zip-docs-only
|
||||
+zip-docs-only: start-make
|
||||
+ @$(call TargetEnter)
|
||||
+ @($(CD) $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk zip-docs)
|
||||
+ @$(call TargetExit)
|
||||
+
|
||||
sign-jars: jdk sign-jars-only
|
||||
sign-jars-only: start-make
|
||||
@$(call TargetEnter)
|
||||
@ -8,22 +8,22 @@ LLT:
|
||||
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8158946 https://bugs.openjdk.java.net/browse/JDK-8165808 https://bugs.openjdk.java.net/browse/JDK-8166583 https://bugs.openjdk.java.net/browse/JDK-8166862
|
||||
---
|
||||
hotspot/src/share/vm/classfile/javaClasses.cpp | 6 ++-
|
||||
.../compactibleFreeListSpace.cpp | 23 ++-------
|
||||
.../concurrentMarkSweepGeneration.cpp | 16 +++----
|
||||
.../src/share/vm/gc_interface/collectedHeap.cpp | 16 +++++++
|
||||
.../src/share/vm/gc_interface/collectedHeap.hpp | 6 +--
|
||||
.../share/vm/gc_interface/collectedHeap.inline.hpp | 54 ++++++++++++----------
|
||||
hotspot/src/share/vm/oops/instanceMirrorKlass.cpp | 7 ++-
|
||||
hotspot/src/share/vm/oops/oop.hpp | 2 +
|
||||
hotspot/src/share/vm/oops/oop.inline.hpp | 38 ++++++++++++---
|
||||
9 files changed, 104 insertions(+), 64 deletions(-)
|
||||
.../src/share/vm/classfile/javaClasses.cpp | 5 +-
|
||||
.../compactibleFreeListSpace.cpp | 23 ++------
|
||||
.../concurrentMarkSweepGeneration.cpp | 16 +++---
|
||||
.../share/vm/gc_interface/collectedHeap.cpp | 16 ++++++
|
||||
.../share/vm/gc_interface/collectedHeap.hpp | 6 +--
|
||||
.../vm/gc_interface/collectedHeap.inline.hpp | 54 ++++++++++---------
|
||||
.../src/share/vm/oops/instanceMirrorKlass.cpp | 7 ++-
|
||||
hotspot/src/share/vm/oops/oop.hpp | 2 +
|
||||
hotspot/src/share/vm/oops/oop.inline.hpp | 38 ++++++++++---
|
||||
9 files changed, 103 insertions(+), 64 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||
index a9b40d235e..cd28c758d0 100644
|
||||
index 1bad10334..719db22b7 100644
|
||||
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
|
||||
@@ -649,10 +649,14 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
@@ -651,10 +651,13 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
|
||||
int java_lang_Class::oop_size(oop java_class) {
|
||||
assert(_oop_size_offset != 0, "must be set");
|
||||
@ -31,16 +31,15 @@ index a9b40d235e..cd28c758d0 100644
|
||||
+ int size = java_class->int_field(_oop_size_offset);
|
||||
+ assert(size > 0, "Oop size must be greater than zero");
|
||||
+ return size;
|
||||
+
|
||||
}
|
||||
void java_lang_Class::set_oop_size(oop java_class, int size) {
|
||||
assert(_oop_size_offset != 0, "must be set");
|
||||
+ assert(size > 0, "Oop size must be greater than zero");
|
||||
java_class->int_field_put_raw(_oop_size_offset, size);
|
||||
java_class->int_field_put(_oop_size_offset, size);
|
||||
}
|
||||
int java_lang_Class::static_oop_field_count(oop java_class) {
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
|
||||
index e5a3a11069..2de68f7aeb 100644
|
||||
index e5a3a1106..2de68f7ae 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
|
||||
@@ -984,18 +984,13 @@ size_t CompactibleFreeListSpace::block_size(const HeapWord* p) const {
|
||||
@ -98,7 +97,7 @@ index e5a3a11069..2de68f7aeb 100644
|
||||
// Ignore mark word because it may have been used to
|
||||
// chain together promoted objects (the last one
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
index 2d7791138c..e3fdb6cf89 100644
|
||||
index 701231b4a..e3c0048da 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
@@ -6715,7 +6715,7 @@ size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
|
||||
@ -174,11 +173,11 @@ index 2d7791138c..e3fdb6cf89 100644
|
||||
// Ignore mark word because we are running concurrent with mutators
|
||||
assert(oop(addr)->is_oop(true), "live block should be an oop");
|
||||
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
|
||||
index 4f5e93bbe2..90207a8a4d 100644
|
||||
index 3ae8d61d0..e79251e13 100644
|
||||
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
|
||||
@@ -305,6 +305,22 @@ HeapWord* CollectedHeap::allocate_from_tlab_slow(KlassHandle klass, Thread* thre
|
||||
return Universe::heap()->tlab_post_allocation_setup(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
+void CollectedHeap::post_allocation_setup_class(KlassHandle klass,
|
||||
@ -201,7 +200,7 @@ index 4f5e93bbe2..90207a8a4d 100644
|
||||
MemRegion deferred = thread->deferred_card_mark();
|
||||
if (!deferred.is_empty()) {
|
||||
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
|
||||
index 03956b036b..48fd7e7c0a 100644
|
||||
index 898a660f2..c13d29780 100644
|
||||
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
|
||||
@@ -157,6 +157,8 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
@ -213,7 +212,7 @@ index 03956b036b..48fd7e7c0a 100644
|
||||
// Clears an allocated object.
|
||||
inline static void init_obj(HeapWord* obj, size_t size);
|
||||
|
||||
@@ -323,9 +325,7 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
@@ -321,9 +323,7 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
inline static oop obj_allocate(KlassHandle klass, int size, TRAPS);
|
||||
inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS);
|
||||
inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS);
|
||||
@ -222,10 +221,10 @@ index 03956b036b..48fd7e7c0a 100644
|
||||
- oop obj);
|
||||
+ inline static oop class_allocate(KlassHandle klass, int size, TRAPS);
|
||||
|
||||
virtual uint oop_extra_words();
|
||||
|
||||
// Raw memory allocation facilities
|
||||
// The obj and array allocate methods are covers for these methods.
|
||||
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
|
||||
index 9f3b885a9e..17e02c8f90 100644
|
||||
index 302d0c7cb..bdc97575f 100644
|
||||
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
|
||||
@@ -39,14 +39,22 @@
|
||||
@ -298,7 +297,7 @@ index 9f3b885a9e..17e02c8f90 100644
|
||||
assert(new_obj->is_array(), "must be an array");
|
||||
// notify jvmti and dtrace (must be after length is set for dtrace)
|
||||
post_allocation_notify(klass, new_obj, new_obj->size());
|
||||
@@ -208,6 +204,16 @@ oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
|
||||
@@ -206,6 +202,16 @@ oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
|
||||
return (oop)obj;
|
||||
}
|
||||
|
||||
@ -316,7 +315,7 @@ index 9f3b885a9e..17e02c8f90 100644
|
||||
int size,
|
||||
int length,
|
||||
diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
|
||||
index 5b4c7d0fd2..73da78e5a8 100644
|
||||
index 5b4c7d0fd..73da78e5a 100644
|
||||
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
|
||||
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
|
||||
@@ -363,13 +363,12 @@ instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
|
||||
@ -337,10 +336,10 @@ index 5b4c7d0fd2..73da78e5a8 100644
|
||||
|
||||
int InstanceMirrorKlass::oop_size(oop obj) const {
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp
|
||||
index 1643ba9f55..c8d1f99183 100644
|
||||
index 4b707abce..c1e9fd550 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.hpp
|
||||
@@ -104,10 +104,12 @@ class oopDesc {
|
||||
@@ -83,10 +83,12 @@ class oopDesc {
|
||||
|
||||
Klass* klass() const;
|
||||
Klass* klass_or_null() const volatile;
|
||||
@ -354,10 +353,10 @@ index 1643ba9f55..c8d1f99183 100644
|
||||
// For klass field compression
|
||||
int klass_gap() const;
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
index 535a7a8953..5d47e3f4dc 100644
|
||||
index 4632457bf..491f148b9 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
@@ -97,7 +97,6 @@ inline Klass* oopDesc::klass() const {
|
||||
@@ -85,7 +85,6 @@ inline Klass* oopDesc::klass() const {
|
||||
}
|
||||
|
||||
inline Klass* oopDesc::klass_or_null() const volatile {
|
||||
@ -365,7 +364,7 @@ index 535a7a8953..5d47e3f4dc 100644
|
||||
if (UseCompressedClassPointers) {
|
||||
return Klass::decode_klass(_metadata._compressed_klass);
|
||||
} else {
|
||||
@@ -110,6 +109,17 @@ inline int oopDesc::klass_gap_offset_in_bytes() {
|
||||
@@ -98,6 +97,17 @@ inline int oopDesc::klass_gap_offset_in_bytes() {
|
||||
return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass);
|
||||
}
|
||||
|
||||
@ -383,7 +382,7 @@ index 535a7a8953..5d47e3f4dc 100644
|
||||
inline Klass** oopDesc::klass_addr() {
|
||||
// Only used internally and with CMS and will not work with
|
||||
// UseCompressedOops
|
||||
@@ -122,10 +132,14 @@ inline narrowKlass* oopDesc::compressed_klass_addr() {
|
||||
@@ -110,10 +120,14 @@ inline narrowKlass* oopDesc::compressed_klass_addr() {
|
||||
return &_metadata._compressed_klass;
|
||||
}
|
||||
|
||||
@ -401,7 +400,7 @@ index 535a7a8953..5d47e3f4dc 100644
|
||||
if (UseCompressedClassPointers) {
|
||||
*compressed_klass_addr() = Klass::encode_klass_not_null(k);
|
||||
} else {
|
||||
@@ -133,6 +147,18 @@ inline void oopDesc::set_klass(Klass* k) {
|
||||
@@ -121,6 +135,18 @@ inline void oopDesc::set_klass(Klass* k) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +419,7 @@ index 535a7a8953..5d47e3f4dc 100644
|
||||
inline int oopDesc::klass_gap() const {
|
||||
return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
|
||||
}
|
||||
@@ -805,8 +831,8 @@ inline int oopDesc::size_given_klass(Klass* klass) {
|
||||
@@ -511,8 +537,8 @@ inline int oopDesc::size_given_klass(Klass* klass) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -432,5 +431,5 @@ index 535a7a8953..5d47e3f4dc 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.12.3
|
||||
2.19.0
|
||||
|
||||
|
||||
57
8171410-aarch64-long-multiplyExact-shifts-by-31-inst.patch
Normal file
57
8171410-aarch64-long-multiplyExact-shifts-by-31-inst.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 18161c97014b072d7c0628fada35f1ed050c7c78 Mon Sep 17 00:00:00 2001
|
||||
From: wuyan <wuyan34@huawei.com>
|
||||
Date: Thu, 16 Jan 2020 20:30:28 +0800
|
||||
Subject: [PATCH] 8171410: aarch64: long multiplyExact shifts by 31 instead of
|
||||
63
|
||||
|
||||
Summary: <c2>: long multiplyExact shifts by 31 instead of 63
|
||||
LLT: NA
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8171410
|
||||
---
|
||||
hotspot/src/cpu/aarch64/vm/aarch64.ad | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/aarch64.ad b/hotspot/src/cpu/aarch64/vm/aarch64.ad
|
||||
index a82629edda..b010a690c4 100644
|
||||
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad
|
||||
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad
|
||||
@@ -12438,7 +12438,7 @@ instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
|
||||
|
||||
format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
|
||||
"smulh rscratch2, $op1, $op2\n\t"
|
||||
- "cmp rscratch2, rscratch1, ASR #31\n\t"
|
||||
+ "cmp rscratch2, rscratch1, ASR #63\n\t"
|
||||
"movw rscratch1, #0x80000000\n\t"
|
||||
"cselw rscratch1, rscratch1, zr, NE\n\t"
|
||||
"cmpw rscratch1, #1" %}
|
||||
@@ -12446,7 +12446,7 @@ instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
|
||||
ins_encode %{
|
||||
__ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
|
||||
__ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
|
||||
- __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext
|
||||
+ __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
|
||||
__ movw(rscratch1, 0x80000000); // Develop 0 (EQ),
|
||||
__ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
|
||||
__ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS
|
||||
@@ -12464,7 +12464,7 @@ instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rF
|
||||
|
||||
format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
|
||||
"smulh rscratch2, $op1, $op2\n\t"
|
||||
- "cmp rscratch2, rscratch1, ASR #31\n\t"
|
||||
+ "cmp rscratch2, rscratch1, ASR #63\n\t"
|
||||
"b$cmp $labl" %}
|
||||
ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
|
||||
ins_encode %{
|
||||
@@ -12472,7 +12472,7 @@ instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rF
|
||||
Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
|
||||
__ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
|
||||
__ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
|
||||
- __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext
|
||||
+ __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
|
||||
__ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
|
||||
%}
|
||||
|
||||
--
|
||||
2.12.3
|
||||
|
||||
164
8190332-PngReader-throws-NegativeArraySizeException-.patch
Normal file
164
8190332-PngReader-throws-NegativeArraySizeException-.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 31cb3f58bf65518cf3b9e35cd09405af693a38bd Mon Sep 17 00:00:00 2001
|
||||
From: mashoubing <mashoubing1@huawei.com>
|
||||
Date: Thu, 21 Nov 2019 11:49:57 +0000
|
||||
Subject: [PATCH] 8190332: PngReader throws NegativeArraySizeException/OOM
|
||||
error when IHDR width is very large
|
||||
|
||||
Summary: <imageio>: PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large
|
||||
LLT:
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8190332
|
||||
---
|
||||
.../sun/imageio/plugins/png/PNGImageReader.java | 27 +++++--
|
||||
.../plugins/png/PngLargeIHDRDimensionTest.java | 86 ++++++++++++++++++++++
|
||||
2 files changed, 106 insertions(+), 7 deletions(-)
|
||||
create mode 100644 test/jdk/javax/imageio/plugins/png/PngLargeIHDRDimensionTest.java
|
||||
|
||||
diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java
|
||||
index 7da36e14b1..02a11d45f4 100644
|
||||
--- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java
|
||||
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2000, 2019, 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
|
||||
@@ -1305,14 +1305,18 @@ public class PNGImageReader extends ImageReader {
|
||||
this.pixelStream = new DataInputStream(is);
|
||||
|
||||
/*
|
||||
- * NB: the PNG spec declares that valid range for width
|
||||
+ * PNG spec declares that valid range for width
|
||||
* and height is [1, 2^31-1], so here we may fail to allocate
|
||||
* a buffer for destination image due to memory limitation.
|
||||
*
|
||||
- * However, the recovery strategy for this case should be
|
||||
- * defined on the level of application, so we will not
|
||||
- * try to estimate the required amount of the memory and/or
|
||||
- * handle OOM in any way.
|
||||
+ * If the read operation triggers OutOfMemoryError, the same
|
||||
+ * will be wrapped in an IIOException at PNGImageReader.read
|
||||
+ * method.
|
||||
+ *
|
||||
+ * The recovery strategy for this case should be defined at
|
||||
+ * the level of application, so we will not try to estimate
|
||||
+ * the required amount of the memory and/or handle OOM in
|
||||
+ * any way.
|
||||
*/
|
||||
theImage = getDestination(param,
|
||||
getImageTypes(0),
|
||||
@@ -1611,7 +1615,16 @@ public class PNGImageReader extends ImageReader {
|
||||
throw new IndexOutOfBoundsException("imageIndex != 0!");
|
||||
}
|
||||
|
||||
- readImage(param);
|
||||
+ try {
|
||||
+ readImage(param);
|
||||
+ } catch (IOException |
|
||||
+ IllegalStateException |
|
||||
+ IllegalArgumentException e)
|
||||
+ {
|
||||
+ throw e;
|
||||
+ } catch (Throwable e) {
|
||||
+ throw new IIOException("Caught exception during read: ", e);
|
||||
+ }
|
||||
return theImage;
|
||||
}
|
||||
|
||||
diff --git a/test/jdk/javax/imageio/plugins/png/PngLargeIHDRDimensionTest.java b/test/jdk/javax/imageio/plugins/png/PngLargeIHDRDimensionTest.java
|
||||
new file mode 100644
|
||||
index 0000000000..118a41f04f
|
||||
--- /dev/null
|
||||
+++ b/test/jdk/javax/imageio/plugins/png/PngLargeIHDRDimensionTest.java
|
||||
@@ -0,0 +1,86 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017, 2019, 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 8190332
|
||||
+ * @summary Test verifies whether PNGImageReader throws IIOException
|
||||
+ * or not when IHDR width value is very high.
|
||||
+ * @run main PngLargeIHDRDimensionTest
|
||||
+ */
|
||||
+
|
||||
+import java.io.ByteArrayInputStream;
|
||||
+import java.io.InputStream;
|
||||
+import java.util.Base64;
|
||||
+import javax.imageio.IIOException;
|
||||
+import javax.imageio.ImageIO;
|
||||
+
|
||||
+public class PngLargeIHDRDimensionTest {
|
||||
+
|
||||
+ /*
|
||||
+ * IHDR width is very large and when we try to create buffer to store
|
||||
+ * image information of each row it overflows and we get
|
||||
+ * NegativeArraySizeException without the fix for this bug.
|
||||
+ */
|
||||
+ private static String negativeArraySizeExceptionInput = "iVBORw0KGgoAAAANS"
|
||||
+ + "UhEUg////0AAAABEAIAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAAB"
|
||||
+ + "JRU5ErkJgggo=";
|
||||
+
|
||||
+ /*
|
||||
+ * IHDR width is ((2 to the power of 31) - 2), which is the maximum VM
|
||||
+ * limit to create an array we get OutOfMemoryError without the fix
|
||||
+ * for this bug.
|
||||
+ */
|
||||
+ private static String outOfMemoryErrorInput = "iVBORw0KGgoAAAANSUhEUgAAAAF/"
|
||||
+ + "///+CAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5"
|
||||
+ + "ErkJgggo=";
|
||||
+
|
||||
+ private static InputStream input;
|
||||
+ private static Boolean firstTestFailed = true, secondTestFailed = true;
|
||||
+ public static void main(String[] args) throws java.io.IOException {
|
||||
+ byte[] inputBytes = Base64.getDecoder().
|
||||
+ decode(negativeArraySizeExceptionInput);
|
||||
+ input = new ByteArrayInputStream(inputBytes);
|
||||
+
|
||||
+ try {
|
||||
+ ImageIO.read(input);
|
||||
+ } catch (IIOException e) {
|
||||
+ firstTestFailed = false;
|
||||
+ }
|
||||
+
|
||||
+ inputBytes = Base64.getDecoder().decode(outOfMemoryErrorInput);
|
||||
+ input = new ByteArrayInputStream(inputBytes);
|
||||
+
|
||||
+ try {
|
||||
+ ImageIO.read(input);
|
||||
+ } catch (IIOException e) {
|
||||
+ secondTestFailed = false;
|
||||
+ }
|
||||
+
|
||||
+ if (firstTestFailed || secondTestFailed) {
|
||||
+ throw new RuntimeException("Test doesn't throw required"
|
||||
+ + " IIOException");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
--
|
||||
2.12.3
|
||||
|
||||
163
8191915-java.lang.Math.multiplyExact-not-throw-an-ex.patch
Normal file
163
8191915-java.lang.Math.multiplyExact-not-throw-an-ex.patch
Normal file
@ -0,0 +1,163 @@
|
||||
From eeb0317f3582ae74dd7d42d149fdc457cd01d835 Mon Sep 17 00:00:00 2001
|
||||
From: c00229008 <chenshanyao@huawei.com>
|
||||
Date: Thu, 26 Dec 2019 20:04:58 +0000
|
||||
Subject: [PATCH] 8191915: java.lang.Math.multiplyExact not throw an exception
|
||||
for certain values
|
||||
|
||||
Summary: C2: java.lang.Math.multiplyExact not throw an exception for certain values
|
||||
LLT: hotspot/test/compiler/intrinsics/mathexact/LongMulOverflowTest.java
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8191915
|
||||
---
|
||||
hotspot/src/share/vm/opto/mathexactnode.cpp | 42 +++++++++------
|
||||
hotspot/src/share/vm/opto/mathexactnode.hpp | 4 +-
|
||||
.../intrinsics/mathexact/LongMulOverflowTest.java | 61 ++++++++++++++++++++++
|
||||
3 files changed, 90 insertions(+), 17 deletions(-)
|
||||
create mode 100644 hotspot/test/compiler/intrinsics/mathexact/LongMulOverflowTest.java
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/mathexactnode.cpp b/hotspot/src/share/vm/opto/mathexactnode.cpp
|
||||
index 00466ad3d5..661cc745bf 100644
|
||||
--- a/hotspot/src/share/vm/opto/mathexactnode.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/mathexactnode.cpp
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2013, 2018, 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
|
||||
@@ -117,23 +117,33 @@ bool OverflowSubLNode::will_overflow(jlong v1, jlong v2) const {
|
||||
return SubHelper<OverflowSubLNode>::will_overflow(v1, v2);
|
||||
}
|
||||
|
||||
-bool OverflowMulLNode::will_overflow(jlong val1, jlong val2) const {
|
||||
- jlong result = val1 * val2;
|
||||
- jlong ax = (val1 < 0 ? -val1 : val1);
|
||||
- jlong ay = (val2 < 0 ? -val2 : val2);
|
||||
-
|
||||
- bool overflow = false;
|
||||
- if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) {
|
||||
- // potential overflow if any bit in upper 32 bits are set
|
||||
- if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) {
|
||||
- // -1 * Long.MIN_VALUE will overflow
|
||||
- overflow = true;
|
||||
- } else if (val2 != 0 && (result / val2 != val1)) {
|
||||
- overflow = true;
|
||||
- }
|
||||
+bool OverflowMulLNode::is_overflow(jlong val1, jlong val2) {
|
||||
+ // x * { 0, 1 } will never overflow. Even for x = min_jlong
|
||||
+ if (val1 == 0 || val2 == 0 || val1 == 1 || val2 == 1) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // x * min_jlong for x not in { 0, 1 } overflows
|
||||
+ // even -1 as -1 * min_jlong is an overflow
|
||||
+ if (val1 == min_jlong || val2 == min_jlong) {
|
||||
+ return true;
|
||||
}
|
||||
|
||||
- return overflow;
|
||||
+ // if (x * y) / y == x there is no overflow
|
||||
+ //
|
||||
+ // the multiplication here is done as unsigned to avoid undefined behaviour which
|
||||
+ // can be used by the compiler to assume that the check further down (result / val2 != val1)
|
||||
+ // is always false and breaks the overflow check
|
||||
+ julong v1 = (julong) val1;
|
||||
+ julong v2 = (julong) val2;
|
||||
+ julong tmp = v1 * v2;
|
||||
+ jlong result = (jlong) tmp;
|
||||
+
|
||||
+ if (result / val2 != val1) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
}
|
||||
|
||||
bool OverflowAddINode::can_overflow(const Type* t1, const Type* t2) const {
|
||||
diff --git a/hotspot/src/share/vm/opto/mathexactnode.hpp b/hotspot/src/share/vm/opto/mathexactnode.hpp
|
||||
index 3e037cf568..0a59ebd96e 100644
|
||||
--- a/hotspot/src/share/vm/opto/mathexactnode.hpp
|
||||
+++ b/hotspot/src/share/vm/opto/mathexactnode.hpp
|
||||
@@ -129,8 +129,10 @@ public:
|
||||
OverflowMulLNode(Node* in1, Node* in2) : OverflowLNode(in1, in2) {}
|
||||
virtual int Opcode() const;
|
||||
|
||||
- virtual bool will_overflow(jlong v1, jlong v2) const;
|
||||
+ virtual bool will_overflow(jlong v1, jlong v2) const { return is_overflow(v1, v2); }
|
||||
virtual bool can_overflow(const Type* t1, const Type* t2) const;
|
||||
+
|
||||
+ static bool is_overflow(jlong v1, jlong v2);
|
||||
};
|
||||
|
||||
#endif
|
||||
diff --git a/hotspot/test/compiler/intrinsics/mathexact/LongMulOverflowTest.java b/hotspot/test/compiler/intrinsics/mathexact/LongMulOverflowTest.java
|
||||
new file mode 100644
|
||||
index 0000000000..69bd8f1579
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/compiler/intrinsics/mathexact/LongMulOverflowTest.java
|
||||
@@ -0,0 +1,61 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018, 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 8191915
|
||||
+ * @summary Regression test for multiplyExact intrinsic
|
||||
+ * @compile AddExactICondTest.java
|
||||
+ * @run main/othervm -Xcomp -XX:-TieredCompilation compiler.intrinsics.mathexact.LongMulOverflowTest
|
||||
+ */
|
||||
+
|
||||
+package compiler.intrinsics.mathexact;
|
||||
+
|
||||
+public class LongMulOverflowTest {
|
||||
+ public static void main(String[] args) {
|
||||
+ LongMulOverflowTest test = new LongMulOverflowTest();
|
||||
+ for (int i = 0; i < 10; ++i) {
|
||||
+ try {
|
||||
+ test.runTest();
|
||||
+ throw new RuntimeException("Error, runTest() did not overflow!");
|
||||
+ } catch (ArithmeticException e) {
|
||||
+ // success
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ test.runTestOverflow();
|
||||
+ throw new RuntimeException("Error, runTestOverflow() did not overflow!");
|
||||
+ } catch (ArithmeticException e) {
|
||||
+ // success
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void runTest() {
|
||||
+ java.lang.Math.multiplyExact(Long.MIN_VALUE, 7);
|
||||
+ }
|
||||
+
|
||||
+ public void runTestOverflow() {
|
||||
+ java.lang.Math.multiplyExact((Long.MAX_VALUE / 2) + 1, 2);
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.12.3
|
||||
|
||||
3693
8193255-Root-Certificates-should-be-stored-in-text-f.patch
Normal file
3693
8193255-Root-Certificates-should-be-stored-in-text-f.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,72 +0,0 @@
|
||||
From 480c546fa5d07a92d09fbe669a7a36e718baedca Mon Sep 17 00:00:00 2001
|
||||
From: xuwei <xuwei43@huawei.com>
|
||||
Date: Fri, 19 Apr 2019 16:15:04 +0000
|
||||
Subject: [PATCH] 8202076: test/jdk/java/io/File/WinSpecialFiles.java on windows with VS2017
|
||||
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8202076
|
||||
|
||||
---
|
||||
.../native/java/io/WinNTFileSystem_md.c | 40 +++++++++++++++----
|
||||
1 file changed, 33 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c
|
||||
index 4c61fa5817..8c8494743f 100644
|
||||
--- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c
|
||||
+++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
+#include <limits.h>
|
||||
+#include <wchar.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "io_util.h"
|
||||
@@ -525,13 +527,37 @@ Java_java_io_WinNTFileSystem_getLength(JNIEnv *env, jobject this, jobject file)
|
||||
}
|
||||
} else {
|
||||
if (GetLastError() == ERROR_SHARING_VIOLATION) {
|
||||
- /* The error is "share violation", which means the file/dir
|
||||
- must exists. Try _wstati64, we know this at least works
|
||||
- for pagefile.sys and hiberfil.sys.
|
||||
- */
|
||||
- struct _stati64 sb;
|
||||
- if (_wstati64(pathbuf, &sb) == 0) {
|
||||
- rv = sb.st_size;
|
||||
+ // The error is a "share violation", which means the file/dir
|
||||
+ // must exist. Try FindFirstFile, we know this at least works
|
||||
+ // for pagefile.sys.
|
||||
+ WIN32_FIND_DATAW fileData;
|
||||
+ HANDLE h = FindFirstFileW(pathbuf, &fileData);
|
||||
+ if (h != INVALID_HANDLE_VALUE) {
|
||||
+ if ((fileData.dwFileAttributes &
|
||||
+ FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
|
||||
+ WCHAR backslash = L'\\';
|
||||
+ WCHAR *pslash = wcsrchr(pathbuf, backslash);
|
||||
+ if (pslash == NULL) {
|
||||
+ pslash = pathbuf;
|
||||
+ } else {
|
||||
+ pslash++;
|
||||
+ }
|
||||
+ WCHAR *fslash = wcsrchr(fileData.cFileName, backslash);
|
||||
+ if (fslash == NULL) {
|
||||
+ fslash = fileData.cFileName;
|
||||
+ } else {
|
||||
+ fslash++;
|
||||
+ }
|
||||
+ if (wcscmp(pslash, fslash) == 0) {
|
||||
+ ULARGE_INTEGER length;
|
||||
+ length.LowPart = fileData.nFileSizeLow;
|
||||
+ length.HighPart = fileData.nFileSizeHigh;
|
||||
+ if (length.QuadPart <= _I64_MAX) {
|
||||
+ rv = (jlong)length.QuadPart;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ FindClose(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.19.0
|
||||
|
||||
105
8203196-C1-emits-incorrect-code-due-to-integer-overf.patch
Normal file
105
8203196-C1-emits-incorrect-code-due-to-integer-overf.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 0e8b56655778da1200e06bb7138f86f8d395aec5 Mon Sep 17 00:00:00 2001
|
||||
From: wangkaihui <wangkaihui4@huawei.com>
|
||||
Date: Sat, 28 Dec 2019 12:41:30 +0000
|
||||
Subject: [PATCH] 8203196: C1 emits incorrect code due to integer overflow in
|
||||
_tableswitch keys
|
||||
|
||||
Summary: <c1>: C1 emits incorrect code due to integer overflow in _tableswitch keys
|
||||
LLT: NA
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8203196
|
||||
---
|
||||
hotspot/src/share/vm/c1/c1_Instruction.hpp | 4 +--
|
||||
hotspot/src/share/vm/c1/c1_LIRGenerator.cpp | 2 +-
|
||||
hotspot/test/compiler/c1/SwitchTest.java | 46 +++++++++++++++++++++++++++++
|
||||
3 files changed, 49 insertions(+), 3 deletions(-)
|
||||
create mode 100644 hotspot/test/compiler/c1/SwitchTest.java
|
||||
|
||||
diff --git a/hotspot/src/share/vm/c1/c1_Instruction.hpp b/hotspot/src/share/vm/c1/c1_Instruction.hpp
|
||||
index 789dba62b2..ee4adbc483 100644
|
||||
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp
|
||||
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp
|
||||
@@ -2124,11 +2124,11 @@ LEAF(TableSwitch, Switch)
|
||||
// creation
|
||||
TableSwitch(Value tag, BlockList* sux, int lo_key, ValueStack* state_before, bool is_safepoint)
|
||||
: Switch(tag, sux, state_before, is_safepoint)
|
||||
- , _lo_key(lo_key) {}
|
||||
+ , _lo_key(lo_key) { assert(_lo_key <= hi_key(), "integer overflow"); }
|
||||
|
||||
// accessors
|
||||
int lo_key() const { return _lo_key; }
|
||||
- int hi_key() const { return _lo_key + length() - 1; }
|
||||
+ int hi_key() const { return _lo_key + (length() - 1); }
|
||||
};
|
||||
|
||||
|
||||
diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
|
||||
index 1cf9f0e8c4..3a48de9eb0 100644
|
||||
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
|
||||
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
|
||||
@@ -2602,8 +2602,8 @@ void LIRGenerator::do_TableSwitch(TableSwitch* x) {
|
||||
move_to_phi(x->state());
|
||||
|
||||
int lo_key = x->lo_key();
|
||||
- int hi_key = x->hi_key();
|
||||
int len = x->length();
|
||||
+ assert(lo_key <= (lo_key + (len - 1)), "integer overflow");
|
||||
LIR_Opr value = tag.result();
|
||||
if (UseTableRanges) {
|
||||
do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
|
||||
diff --git a/hotspot/test/compiler/c1/SwitchTest.java b/hotspot/test/compiler/c1/SwitchTest.java
|
||||
new file mode 100644
|
||||
index 0000000000..d18eccc0fb
|
||||
--- /dev/null
|
||||
+++ b/hotspot/test/compiler/c1/SwitchTest.java
|
||||
@@ -0,0 +1,46 @@
|
||||
+/*
|
||||
+ * @test
|
||||
+ * @bug 8203196
|
||||
+ * @summary C1 emits incorrect code due to integer overflow in _tableswitch keys
|
||||
+ * @run main/othervm -Xcomp SwitchTest
|
||||
+ */
|
||||
+public class SwitchTest {
|
||||
+ public static void main(String args[]) throws Exception {
|
||||
+ int test2 = 2147483647;
|
||||
+ int check2 = 0;
|
||||
+ switch (test2) {
|
||||
+ case 2147483640:
|
||||
+ check2 = 2147483640;
|
||||
+ break;
|
||||
+ case 2147483641:
|
||||
+ check2 = 2147483641;
|
||||
+ break;
|
||||
+ case 2147483642:
|
||||
+ check2 = 2147483642;
|
||||
+ break;
|
||||
+ case 2147483643:
|
||||
+ check2 = 2147483643;
|
||||
+ break;
|
||||
+ case 2147483644:
|
||||
+ check2 = 2147483644;
|
||||
+ break;
|
||||
+ case 2147483645:
|
||||
+ check2 = 2147483645;
|
||||
+ break;
|
||||
+ case 2147483646:
|
||||
+ check2 = 2147483646;
|
||||
+ break;
|
||||
+ case 2147483647:
|
||||
+ check2 = 2147483647;
|
||||
+ break;
|
||||
+ default:
|
||||
+ check2 = 123456;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (check2 != test2) {
|
||||
+ System.out.println("choose a wrong case");
|
||||
+ throw new Exception();
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -9,9 +9,7 @@ Bug url: https://bugs.openjdk.java.net/browse/JDK-8203699
|
||||
|
||||
---
|
||||
.../src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 6 +-
|
||||
.../invoke/lookup/TestDefenderMethodLookup.java | 167 +++++++++++++++++++++
|
||||
2 files changed, 172 insertions(+), 1 deletion(-)
|
||||
create mode 100644 jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
|
||||
1 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
|
||||
index 42b732f37a..4659d628db 100644
|
||||
@ -38,177 +36,6 @@ index 42b732f37a..4659d628db 100644
|
||||
mov(rscratch2, (address)&SharedRuntime::_partial_subtype_ctr);
|
||||
Address pst_counter_addr(rscratch2);
|
||||
diff --git a/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
|
||||
new file mode 100644
|
||||
index 0000000000..1d0ade9fe4
|
||||
--- /dev/null
|
||||
+++ b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
|
||||
@@ -0,0 +1,166 @@
|
||||
+/*
|
||||
+ * @test
|
||||
+ * @author zhangli
|
||||
+ * @bug 8203699
|
||||
+ * @summary see https://code.huawei.com/HuaweiJDK/JVM-team/JVM/issues/1368
|
||||
+ * @run testng/othervm test.java.lang.invoke.lookup.TestDefenderMethodLookup
|
||||
+ */
|
||||
+
|
||||
+package test.java.lang.invoke.lookup;
|
||||
+
|
||||
+import org.testng.annotations.Test;
|
||||
+import org.testng.Assert;
|
||||
+import java.lang.invoke.*;
|
||||
+import java.lang.invoke.MethodHandle;
|
||||
+import java.lang.invoke.MethodHandles;
|
||||
+import java.lang.invoke.MethodHandles.Lookup;
|
||||
+
|
||||
+//@Test(groups = { "level.sanity" })
|
||||
+public class TestDefenderMethodLookup {
|
||||
+ /**
|
||||
+ * Get a <b>SPECIAL</b> MethodHandle for the method "test()V" in the <b>DIRECT</b> super interface DefenderInterface. The method
|
||||
+ * has a default implementation in DefenderInterface and does <b>NOT</b> have an implementation in the class.
|
||||
+ * Invoke the MethodHandle, and assert that the DefenderInterface.test was invoked (should return "default").
|
||||
+ *
|
||||
+ * @throws Throwable No exceptions is expected. Any exception should be treated as an error.
|
||||
+ */
|
||||
+ @Test
|
||||
+ public void testDirectSuperInterface() throws Throwable {
|
||||
+ DefenderInterface impl = new DefenderInterface() {
|
||||
+ public MethodHandle run() throws Throwable {
|
||||
+ Lookup l = DefenderInterface.lookup();
|
||||
+ Class<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> target = DefenderInterface.class;
|
||||
+ MethodType mt = MethodType.methodType(String.class);
|
||||
+ return l.findSpecial(defc, "test", mt, target);
|
||||
+ }
|
||||
+ };
|
||||
+ MethodHandle mh = impl.run();
|
||||
+ String result = (String)mh.invoke(impl);
|
||||
+ Assert.assertEquals("default", result);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Same as <b>testDirectSuperInterface</b>, but with the findSpecial arguments <b>target</b> and <b>defc</b> switched.
|
||||
+ *
|
||||
+ * @throws Throwable No exceptions is expected. Any exception should be treated as an error.
|
||||
+ */
|
||||
+ @Test
|
||||
+ public void testDirectSuperInterfaceSwitchedTargetDefc() throws Throwable {
|
||||
+ DefenderInterface impl = new DefenderInterface() {
|
||||
+ public MethodHandle run() throws Throwable {
|
||||
+ Lookup l = MethodHandles.lookup();
|
||||
+ Class<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> target = DefenderInterface.class;
|
||||
+ MethodType mt = MethodType.methodType(String.class);
|
||||
+ // Switched target and defc
|
||||
+ return l.findSpecial(target, "test", mt, defc);
|
||||
+ }
|
||||
+ };
|
||||
+ MethodHandle mh = impl.run();
|
||||
+ String result = (String)mh.invoke(impl);
|
||||
+ Assert.assertEquals("default", result);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get a <b>SPECIAL</b> MethodHandle for the method "test()V" in the <b>DIRECT</b> super interface DefenderInterface. The method
|
||||
+ * has a default implementation in DefenderInterface and does <b>ALSO</b> have an implementation in the class.
|
||||
+ * Invoke the MethodHandle, and assert that the DefenderInterface.test was invoked (should return "default").
|
||||
+ *
|
||||
+ * @throws Throwable No exceptions is expected. Any exception should be treated as an error.
|
||||
+ */
|
||||
+ @Test
|
||||
+ public void testDirectSuperInterfaceWithOverride() throws Throwable {
|
||||
+ DefenderInterface impl = new DefenderInterface() {
|
||||
+ @Test
|
||||
+ @Override
|
||||
+ public String test() {
|
||||
+ return "impl";
|
||||
+ }
|
||||
+
|
||||
+ public MethodHandle run() throws Throwable {
|
||||
+ Lookup l = DefenderInterface.lookup();
|
||||
+ Class<? extends DefenderInterface> defc = DefenderInterface.class;
|
||||
+ Class<DefenderInterface> target = DefenderInterface.class;
|
||||
+ MethodType mt = MethodType.methodType(String.class);
|
||||
+ return l.findSpecial(defc, "test", mt, target);
|
||||
+ }
|
||||
+ };
|
||||
+ MethodHandle mh = impl.run();
|
||||
+ String result = (String)mh.invoke(impl);
|
||||
+ Assert.assertEquals("default", result);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Same as <b>testDirectSuperInterfaceWithOverride</b>, but with the findSpecial arguments <b>target</b> and <b>defc</b> switched.
|
||||
+ *
|
||||
+ * @throws Throwable No exceptions is expected. Any exception should be treated as an error.
|
||||
+ */
|
||||
+ @Test
|
||||
+ public void testDirectSuperInterfaceWithOverrideSwitchedTargetDefc() throws Throwable {
|
||||
+ DefenderInterface impl = new DefenderInterface() {
|
||||
+ @Override
|
||||
+ public String test() {
|
||||
+ return "impl";
|
||||
+ }
|
||||
+
|
||||
+ public MethodHandle run() throws Throwable {
|
||||
+ Lookup l = MethodHandles.lookup();
|
||||
+ Class<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> target = DefenderInterface.class;
|
||||
+ MethodType mt = MethodType.methodType(String.class);
|
||||
+ // Switched target and defc
|
||||
+ return l.findSpecial(target, "test", mt, defc);
|
||||
+ }
|
||||
+ };
|
||||
+ MethodHandle mh = impl.run();
|
||||
+ String result = (String)mh.invoke(impl);
|
||||
+ Assert.assertEquals("default", result);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * <b>NEGATIVE</b><br />
|
||||
+ * Try to get a <b>SPECIAL</b> MethodHandle for the method "test()V" in the <b>INDIRECT</b> super interface DefenderInterface
|
||||
+ * (through the interface <b>DefenderSubInterface</b>).
|
||||
+ *
|
||||
+ * @throws Throwable Expected exceptions are caught. Any other exception should be treated as an error.
|
||||
+ */
|
||||
+ @Test
|
||||
+ public void testIndirectSuperInterface() throws Throwable {
|
||||
+ DefenderSubInterface impl = new DefenderSubInterface() {
|
||||
+ public MethodHandle run() throws Throwable {
|
||||
+ Lookup l = DefenderSubInterface.lookup();
|
||||
+ Class<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> target = DefenderInterface.class;
|
||||
+ MethodType mt = MethodType.methodType(String.class);
|
||||
+ return l.findSpecial(defc, "test", mt, target);
|
||||
+ }
|
||||
+ };
|
||||
+ try {
|
||||
+ impl.run();
|
||||
+ Assert.fail("Successfully created supersend MethodHandle to INDIRECT super interface. Should fail with IllegalAccessException.");
|
||||
+ } catch (IllegalAccessException e) {}
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+interface DefenderInterface {
|
||||
+ public default String test() {
|
||||
+ return "default";
|
||||
+ }
|
||||
+
|
||||
+ public static Lookup lookup() {
|
||||
+ return MethodHandles.lookup();
|
||||
+ }
|
||||
+
|
||||
+ public MethodHandle run() throws Throwable;
|
||||
+}
|
||||
+
|
||||
+interface DefenderSubInterface extends DefenderInterface {
|
||||
+ public default String test() {
|
||||
+ return "subDefault";
|
||||
+ }
|
||||
+
|
||||
+ public static Lookup lookup() {
|
||||
+ return MethodHandles.lookup();
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.12.3
|
||||
|
||||
|
||||
888
8204947-Port-ShenandoahTaskTerminator-to-mainline-an.patch
Normal file
888
8204947-Port-ShenandoahTaskTerminator-to-mainline-an.patch
Normal file
@ -0,0 +1,888 @@
|
||||
From be9a6e1c3f15e798de03ef08c3bca91ef9589c80 Mon Sep 17 00:00:00 2001
|
||||
From: wuyan <wuyan34@huawei.com>
|
||||
Date: Thu, 12 Mar 2020 09:41:07 +0800
|
||||
Subject: [PATCH] 8204947: Port ShenandoahTaskTerminator to mainline and make
|
||||
it default
|
||||
|
||||
Summary: <gc>: Improve gc performance, port ShenandoahTaskTerminator to mainline and make it default
|
||||
LLT: jtreg
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8204947
|
||||
---
|
||||
.../concurrentMarkSweepGeneration.cpp | 72 ++++++++-
|
||||
.../vm/gc_implementation/g1/concurrentMark.cpp | 4 +-
|
||||
.../vm/gc_implementation/g1/concurrentMark.hpp | 12 +-
|
||||
.../vm/gc_implementation/g1/g1CollectedHeap.cpp | 10 +-
|
||||
.../gc_implementation/parNew/parNewGeneration.cpp | 16 +-
|
||||
.../gc_implementation/parNew/parNewGeneration.hpp | 2 +-
|
||||
.../gc_implementation/parallelScavenge/pcTasks.cpp | 4 +-
|
||||
.../parallelScavenge/psParallelCompact.cpp | 8 +-
|
||||
.../parallelScavenge/psScavenge.cpp | 11 +-
|
||||
.../shared/owstTaskTerminator.cpp | 173 +++++++++++++++++++++
|
||||
.../shared/owstTaskTerminator.hpp | 80 ++++++++++
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 4 +
|
||||
hotspot/src/share/vm/utilities/taskqueue.cpp | 23 +++
|
||||
hotspot/src/share/vm/utilities/taskqueue.hpp | 47 +++++-
|
||||
hotspot/src/share/vm/utilities/workgroup.hpp | 4 +-
|
||||
15 files changed, 424 insertions(+), 46 deletions(-)
|
||||
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.cpp
|
||||
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.hpp
|
||||
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
index 9d457fd1d6..e42c8b5f39 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "gc_implementation/shared/gcTrace.hpp"
|
||||
#include "gc_implementation/shared/gcTraceTime.hpp"
|
||||
#include "gc_implementation/shared/isGCActiveMark.hpp"
|
||||
+#include "gc_implementation/shared/owstTaskTerminator.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/cardTableRS.hpp"
|
||||
@@ -3887,7 +3888,7 @@ bool CMSCollector::markFromRootsWork(bool asynch) {
|
||||
// Forward decl
|
||||
class CMSConcMarkingTask;
|
||||
|
||||
-class CMSConcMarkingTerminator: public ParallelTaskTerminator {
|
||||
+class CMSConcMarkingParallelTerminator: public ParallelTaskTerminator {
|
||||
CMSCollector* _collector;
|
||||
CMSConcMarkingTask* _task;
|
||||
public:
|
||||
@@ -3897,7 +3898,7 @@ class CMSConcMarkingTerminator: public ParallelTaskTerminator {
|
||||
// "queue_set" is a set of work queues of other threads.
|
||||
// "collector" is the CMS collector associated with this task terminator.
|
||||
// "yield" indicates whether we need the gang as a whole to yield.
|
||||
- CMSConcMarkingTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
|
||||
+ CMSConcMarkingParallelTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
|
||||
ParallelTaskTerminator(n_threads, queue_set),
|
||||
_collector(collector) { }
|
||||
|
||||
@@ -3906,6 +3907,45 @@ class CMSConcMarkingTerminator: public ParallelTaskTerminator {
|
||||
}
|
||||
};
|
||||
|
||||
+class CMSConcMarkingOWSTTerminator: public OWSTTaskTerminator {
|
||||
+ CMSCollector* _collector;
|
||||
+ CMSConcMarkingTask* _task;
|
||||
+ public:
|
||||
+ virtual void yield();
|
||||
+
|
||||
+ // "n_threads" is the number of threads to be terminated.
|
||||
+ // "queue_set" is a set of work queues of other threads.
|
||||
+ // "collector" is the CMS collector associated with this task terminator.
|
||||
+ // "yield" indicates whether we need the gang as a whole to yield.
|
||||
+ CMSConcMarkingOWSTTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
|
||||
+ OWSTTaskTerminator(n_threads, queue_set),
|
||||
+ _collector(collector) { }
|
||||
+
|
||||
+ void set_task(CMSConcMarkingTask* task) {
|
||||
+ _task = task;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+class CMSConcMarkingTaskTerminator {
|
||||
+ private:
|
||||
+ ParallelTaskTerminator* _term;
|
||||
+ public:
|
||||
+ CMSConcMarkingTaskTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) {
|
||||
+ if (UseOWSTTaskTerminator) {
|
||||
+ _term = new CMSConcMarkingOWSTTerminator(n_threads, queue_set, collector);
|
||||
+ } else {
|
||||
+ _term = new CMSConcMarkingParallelTerminator(n_threads, queue_set, collector);
|
||||
+ }
|
||||
+ }
|
||||
+ ~CMSConcMarkingTaskTerminator() {
|
||||
+ assert(_term != NULL, "Must not be NULL");
|
||||
+ delete _term;
|
||||
+ }
|
||||
+
|
||||
+ void set_task(CMSConcMarkingTask* task);
|
||||
+ ParallelTaskTerminator* terminator() const { return _term; }
|
||||
+};
|
||||
+
|
||||
class CMSConcMarkingTerminatorTerminator: public TerminatorTerminator {
|
||||
CMSConcMarkingTask* _task;
|
||||
public:
|
||||
@@ -3934,7 +3974,7 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask {
|
||||
OopTaskQueueSet* _task_queues;
|
||||
|
||||
// Termination (and yielding) support
|
||||
- CMSConcMarkingTerminator _term;
|
||||
+ CMSConcMarkingTaskTerminator _term;
|
||||
CMSConcMarkingTerminatorTerminator _term_term;
|
||||
|
||||
public:
|
||||
@@ -3964,7 +4004,7 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask {
|
||||
|
||||
HeapWord*volatile* global_finger_addr() { return &_global_finger; }
|
||||
|
||||
- CMSConcMarkingTerminator* terminator() { return &_term; }
|
||||
+ ParallelTaskTerminator* terminator() { return _term.terminator(); }
|
||||
|
||||
virtual void set_for_termination(int active_workers) {
|
||||
terminator()->reset_for_reuse(active_workers);
|
||||
@@ -3983,7 +4023,7 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask {
|
||||
void reset(HeapWord* ra) {
|
||||
assert(_global_finger >= _cms_space->end(), "Postcondition of ::work(i)");
|
||||
_restart_addr = _global_finger = ra;
|
||||
- _term.reset_for_reuse();
|
||||
+ _term.terminator()->reset_for_reuse();
|
||||
}
|
||||
|
||||
static bool get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
|
||||
@@ -4004,7 +4044,7 @@ bool CMSConcMarkingTerminatorTerminator::should_exit_termination() {
|
||||
// thread has yielded.
|
||||
}
|
||||
|
||||
-void CMSConcMarkingTerminator::yield() {
|
||||
+void CMSConcMarkingParallelTerminator::yield() {
|
||||
if (_task->should_yield()) {
|
||||
_task->yield();
|
||||
} else {
|
||||
@@ -4012,6 +4052,22 @@ void CMSConcMarkingTerminator::yield() {
|
||||
}
|
||||
}
|
||||
|
||||
+void CMSConcMarkingOWSTTerminator::yield() {
|
||||
+ if (_task->should_yield()) {
|
||||
+ _task->yield();
|
||||
+ } else {
|
||||
+ OWSTTaskTerminator::yield();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void CMSConcMarkingTaskTerminator::set_task(CMSConcMarkingTask* task) {
|
||||
+ if (UseOWSTTaskTerminator) {
|
||||
+ ((CMSConcMarkingOWSTTerminator*)_term)->set_task(task);
|
||||
+ } else {
|
||||
+ ((CMSConcMarkingParallelTerminator*)_term)->set_task(task);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Concurrent Marking Algorithm Sketch
|
||||
////////////////////////////////////////////////////////////////
|
||||
@@ -5290,7 +5346,7 @@ class CMSParRemarkTask: public CMSParMarkTask {
|
||||
|
||||
// The per-thread work queues, available here for stealing.
|
||||
OopTaskQueueSet* _task_queues;
|
||||
- ParallelTaskTerminator _term;
|
||||
+ TaskTerminator _term;
|
||||
|
||||
public:
|
||||
// A value of 0 passed to n_workers will cause the number of
|
||||
@@ -5309,7 +5365,7 @@ class CMSParRemarkTask: public CMSParMarkTask {
|
||||
|
||||
OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
|
||||
|
||||
- ParallelTaskTerminator* terminator() { return &_term; }
|
||||
+ ParallelTaskTerminator* terminator() { return _term.terminator(); }
|
||||
int n_workers() { return _n_workers; }
|
||||
|
||||
void work(uint worker_id);
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
index 0c12478f2f..28dd5aadaa 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
@@ -549,7 +549,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev
|
||||
// _active_tasks set in set_non_marking_state
|
||||
// _tasks set inside the constructor
|
||||
_task_queues(new CMTaskQueueSet((int) _max_worker_id)),
|
||||
- _terminator(ParallelTaskTerminator((int) _max_worker_id, _task_queues)),
|
||||
+ _terminator((int) _max_worker_id, _task_queues),
|
||||
|
||||
_has_overflown(false),
|
||||
_concurrent(false),
|
||||
@@ -816,7 +816,7 @@ void ConcurrentMark::set_concurrency(uint active_tasks) {
|
||||
_active_tasks = active_tasks;
|
||||
// Need to update the three data structures below according to the
|
||||
// number of active threads for this phase.
|
||||
- _terminator = ParallelTaskTerminator((int) active_tasks, _task_queues);
|
||||
+ _terminator = TaskTerminator((int) active_tasks, _task_queues);
|
||||
_first_overflow_barrier_sync.set_n_workers((int) active_tasks);
|
||||
_second_overflow_barrier_sync.set_n_workers((int) active_tasks);
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
index 4c6262415e..02a0cb1843 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
@@ -427,8 +427,8 @@ protected:
|
||||
uint _max_worker_id;// maximum worker id
|
||||
uint _active_tasks; // task num currently active
|
||||
CMTask** _tasks; // task queue array (max_worker_id len)
|
||||
- CMTaskQueueSet* _task_queues; // task queue set
|
||||
- ParallelTaskTerminator _terminator; // for termination
|
||||
+ CMTaskQueueSet* _task_queues; // Task queue set
|
||||
+ TaskTerminator _terminator; // For termination
|
||||
|
||||
// Two sync barriers that are used to synchronise tasks when an
|
||||
// overflow occurs. The algorithm is the following. All tasks enter
|
||||
@@ -528,10 +528,10 @@ protected:
|
||||
return _parallel_workers != NULL;
|
||||
}
|
||||
|
||||
- HeapWord* finger() { return _finger; }
|
||||
- bool concurrent() { return _concurrent; }
|
||||
- uint active_tasks() { return _active_tasks; }
|
||||
- ParallelTaskTerminator* terminator() { return &_terminator; }
|
||||
+ HeapWord* finger() { return _finger; }
|
||||
+ bool concurrent() { return _concurrent; }
|
||||
+ uint active_tasks() { return _active_tasks; }
|
||||
+ ParallelTaskTerminator* terminator() const { return _terminator.terminator(); }
|
||||
|
||||
// It claims the next available region to be scanned by a marking
|
||||
// task/thread. It might return NULL if the next region is empty or
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
|
||||
index 2380cf791e..6e575e07e4 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
|
||||
@@ -4650,7 +4650,7 @@ protected:
|
||||
G1CollectedHeap* _g1h;
|
||||
RefToScanQueueSet *_queues;
|
||||
G1RootProcessor* _root_processor;
|
||||
- ParallelTaskTerminator _terminator;
|
||||
+ TaskTerminator _terminator;
|
||||
uint _n_workers;
|
||||
|
||||
Mutex _stats_lock;
|
||||
@@ -4672,7 +4672,7 @@ public:
|
||||
return queues()->queue(i);
|
||||
}
|
||||
|
||||
- ParallelTaskTerminator* terminator() { return &_terminator; }
|
||||
+ ParallelTaskTerminator* terminator() { return _terminator.terminator(); }
|
||||
|
||||
virtual void set_for_termination(int active_workers) {
|
||||
_root_processor->set_num_workers(active_workers);
|
||||
@@ -4787,7 +4787,7 @@ public:
|
||||
|
||||
{
|
||||
double start = os::elapsedTime();
|
||||
- G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
|
||||
+ G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, _terminator.terminator());
|
||||
evac.do_void();
|
||||
double elapsed_sec = os::elapsedTime() - start;
|
||||
double term_sec = pss.term_time();
|
||||
@@ -5484,8 +5484,8 @@ public:
|
||||
void G1STWRefProcTaskExecutor::execute(ProcessTask& proc_task) {
|
||||
assert(_workers != NULL, "Need parallel worker threads.");
|
||||
|
||||
- ParallelTaskTerminator terminator(_active_workers, _queues);
|
||||
- G1STWRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _queues, &terminator);
|
||||
+ TaskTerminator terminator(_active_workers, _queues);
|
||||
+ G1STWRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _queues, terminator.terminator());
|
||||
|
||||
_g1h->set_par_threads(_active_workers);
|
||||
_workers->run_task(&proc_task_proxy);
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
|
||||
index 2b9fb53293..67867d4edb 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
|
||||
@@ -68,7 +68,7 @@ ParScanThreadState::ParScanThreadState(Space* to_space_,
|
||||
ObjToScanQueueSet* work_queue_set_,
|
||||
Stack<oop, mtGC>* overflow_stacks_,
|
||||
size_t desired_plab_sz_,
|
||||
- ParallelTaskTerminator& term_) :
|
||||
+ TaskTerminator& term_) :
|
||||
_to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_),
|
||||
_work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false),
|
||||
_overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL),
|
||||
@@ -79,7 +79,7 @@ ParScanThreadState::ParScanThreadState(Space* to_space_,
|
||||
_older_gen_closure(gen_, this),
|
||||
_evacuate_followers(this, &_to_space_closure, &_old_gen_closure,
|
||||
&_to_space_root_closure, gen_, &_old_gen_root_closure,
|
||||
- work_queue_set_, &term_),
|
||||
+ work_queue_set_, term_.terminator()),
|
||||
_is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this),
|
||||
_keep_alive_closure(&_scan_weak_ref_closure),
|
||||
_strong_roots_time(0.0), _term_time(0.0)
|
||||
@@ -309,7 +309,7 @@ public:
|
||||
ObjToScanQueueSet& queue_set,
|
||||
Stack<oop, mtGC>* overflow_stacks_,
|
||||
size_t desired_plab_sz,
|
||||
- ParallelTaskTerminator& term);
|
||||
+ TaskTerminator& term);
|
||||
|
||||
~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); }
|
||||
|
||||
@@ -330,12 +330,12 @@ public:
|
||||
#endif // TASKQUEUE_STATS
|
||||
|
||||
private:
|
||||
- ParallelTaskTerminator& _term;
|
||||
+ TaskTerminator& _term;
|
||||
ParNewGeneration& _gen;
|
||||
Generation& _next_gen;
|
||||
public:
|
||||
bool is_valid(int id) const { return id < length(); }
|
||||
- ParallelTaskTerminator* terminator() { return &_term; }
|
||||
+ ParallelTaskTerminator* terminator() { return _term.terminator(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ ParScanThreadStateSet::ParScanThreadStateSet(
|
||||
int num_threads, Space& to_space, ParNewGeneration& gen,
|
||||
Generation& old_gen, ObjToScanQueueSet& queue_set,
|
||||
Stack<oop, mtGC>* overflow_stacks,
|
||||
- size_t desired_plab_sz, ParallelTaskTerminator& term)
|
||||
+ size_t desired_plab_sz, TaskTerminator& term)
|
||||
: ResourceArray(sizeof(ParScanThreadState), num_threads),
|
||||
_gen(gen), _next_gen(old_gen), _term(term)
|
||||
{
|
||||
@@ -375,7 +375,7 @@ void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) {
|
||||
|
||||
void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed)
|
||||
{
|
||||
- _term.reset_for_reuse(active_threads);
|
||||
+ _term.terminator()->reset_for_reuse(active_threads);
|
||||
if (promotion_failed) {
|
||||
for (int i = 0; i < length(); ++i) {
|
||||
thread_state(i).print_promotion_failure_size();
|
||||
@@ -983,7 +983,7 @@ void ParNewGeneration::collect(bool full,
|
||||
|
||||
// Always set the terminator for the active number of workers
|
||||
// because only those workers go through the termination protocol.
|
||||
- ParallelTaskTerminator _term(n_workers, task_queues());
|
||||
+ TaskTerminator _term(n_workers, task_queues());
|
||||
ParScanThreadStateSet thread_state_set(workers->active_workers(),
|
||||
*to(), *this, *_next_gen, *task_queues(),
|
||||
_overflow_stacks, desired_plab_sz(), _term);
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
|
||||
index 5c6b6181fa..fa4265a2dc 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
|
||||
@@ -132,7 +132,7 @@ class ParScanThreadState {
|
||||
ObjToScanQueueSet* work_queue_set_,
|
||||
Stack<oop, mtGC>* overflow_stacks_,
|
||||
size_t desired_plab_sz_,
|
||||
- ParallelTaskTerminator& term_);
|
||||
+ TaskTerminator& term_);
|
||||
|
||||
public:
|
||||
ageTable* age_table() {return &_ageTable;}
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
|
||||
index 7d85c34947..35ea2992b7 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
|
||||
@@ -172,7 +172,7 @@ void RefProcTaskExecutor::execute(ProcessTask& task)
|
||||
uint parallel_gc_threads = heap->gc_task_manager()->workers();
|
||||
uint active_gc_threads = heap->gc_task_manager()->active_workers();
|
||||
OopTaskQueueSet* qset = ParCompactionManager::stack_array();
|
||||
- ParallelTaskTerminator terminator(active_gc_threads, qset);
|
||||
+ TaskTerminator terminator(active_gc_threads, qset);
|
||||
GCTaskQueue* q = GCTaskQueue::create();
|
||||
for(uint i=0; i<parallel_gc_threads; i++) {
|
||||
q->enqueue(new RefProcTaskProxy(task, i));
|
||||
@@ -180,7 +180,7 @@ void RefProcTaskExecutor::execute(ProcessTask& task)
|
||||
if (task.marks_oops_alive()) {
|
||||
if (parallel_gc_threads>1) {
|
||||
for (uint j=0; j<active_gc_threads; j++) {
|
||||
- q->enqueue(new StealMarkingTask(&terminator));
|
||||
+ q->enqueue(new StealMarkingTask(terminator.terminator()));
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
|
||||
index bdf254d61d..001b365d88 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
|
||||
@@ -2356,7 +2356,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
|
||||
uint parallel_gc_threads = heap->gc_task_manager()->workers();
|
||||
uint active_gc_threads = heap->gc_task_manager()->active_workers();
|
||||
TaskQueueSetSuper* qset = ParCompactionManager::stack_array();
|
||||
- ParallelTaskTerminator terminator(active_gc_threads, qset);
|
||||
+ TaskTerminator terminator(active_gc_threads, qset);
|
||||
|
||||
PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
|
||||
PSParallelCompact::FollowStackClosure follow_stack_closure(cm);
|
||||
@@ -2385,7 +2385,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
|
||||
|
||||
if (active_gc_threads > 1) {
|
||||
for (uint j = 0; j < active_gc_threads; j++) {
|
||||
- q->enqueue(new StealMarkingTask(&terminator));
|
||||
+ q->enqueue(new StealMarkingTask(terminator.terminator()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2692,12 +2692,12 @@ void PSParallelCompact::compact() {
|
||||
uint parallel_gc_threads = heap->gc_task_manager()->workers();
|
||||
uint active_gc_threads = heap->gc_task_manager()->active_workers();
|
||||
TaskQueueSetSuper* qset = ParCompactionManager::region_array();
|
||||
- ParallelTaskTerminator terminator(active_gc_threads, qset);
|
||||
+ TaskTerminator terminator(active_gc_threads, qset);
|
||||
|
||||
GCTaskQueue* q = GCTaskQueue::create();
|
||||
enqueue_region_draining_tasks(q, active_gc_threads);
|
||||
enqueue_dense_prefix_tasks(q, active_gc_threads);
|
||||
- enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
|
||||
+ enqueue_region_stealing_tasks(q, terminator.terminator(), active_gc_threads);
|
||||
|
||||
{
|
||||
GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
|
||||
index 5d7e99bd2c..12e282eeb1 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
|
||||
@@ -189,11 +189,11 @@ void PSRefProcTaskExecutor::execute(ProcessTask& task)
|
||||
for(uint i=0; i < manager->active_workers(); i++) {
|
||||
q->enqueue(new PSRefProcTaskProxy(task, i));
|
||||
}
|
||||
- ParallelTaskTerminator terminator(manager->active_workers(),
|
||||
+ TaskTerminator terminator(manager->active_workers(),
|
||||
(TaskQueueSetSuper*) PSPromotionManager::stack_array_depth());
|
||||
if (task.marks_oops_alive() && manager->active_workers() > 1) {
|
||||
for (uint j = 0; j < manager->active_workers(); j++) {
|
||||
- q->enqueue(new StealTask(&terminator));
|
||||
+ q->enqueue(new StealTask(terminator.terminator()));
|
||||
}
|
||||
}
|
||||
manager->execute_and_wait(q);
|
||||
@@ -422,12 +422,11 @@ bool PSScavenge::invoke_no_policy() {
|
||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
|
||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
|
||||
|
||||
- ParallelTaskTerminator terminator(
|
||||
- active_workers,
|
||||
- (TaskQueueSetSuper*) promotion_manager->stack_array_depth());
|
||||
+ TaskTerminator terminator(active_workers,
|
||||
+ (TaskQueueSetSuper*) promotion_manager->stack_array_depth());
|
||||
if (active_workers > 1) {
|
||||
for (uint j = 0; j < active_workers; j++) {
|
||||
- q->enqueue(new StealTask(&terminator));
|
||||
+ q->enqueue(new StealTask(terminator.terminator()));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.cpp b/hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.cpp
|
||||
new file mode 100644
|
||||
index 0000000000..9438f6a9ea
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.cpp
|
||||
@@ -0,0 +1,173 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * 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 "owstTaskTerminator.hpp"
|
||||
+
|
||||
+bool OWSTTaskTerminator::exit_termination(size_t tasks, TerminatorTerminator* terminator) {
|
||||
+ return tasks > 0 || (terminator != NULL && terminator->should_exit_termination());
|
||||
+}
|
||||
+
|
||||
+bool OWSTTaskTerminator::offer_termination(TerminatorTerminator* terminator) {
|
||||
+ assert(_n_threads > 0, "Initialization is incorrect");
|
||||
+ assert(_offered_termination < _n_threads, "Invariant");
|
||||
+ assert(_blocker != NULL, "Invariant");
|
||||
+
|
||||
+ // Single worker, done
|
||||
+ if (_n_threads == 1) {
|
||||
+ _offered_termination = 1;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ _blocker->lock_without_safepoint_check();
|
||||
+ // All arrived, done
|
||||
+ _offered_termination++;
|
||||
+ if (_offered_termination == _n_threads) {
|
||||
+ _blocker->notify_all();
|
||||
+ _blocker->unlock();
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ Thread* the_thread = Thread::current();
|
||||
+ while (true) {
|
||||
+ if (_spin_master == NULL) {
|
||||
+ _spin_master = the_thread;
|
||||
+
|
||||
+ _blocker->unlock();
|
||||
+
|
||||
+ if (do_spin_master_work(terminator)) {
|
||||
+ assert(_offered_termination == _n_threads, "termination condition");
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ _blocker->lock_without_safepoint_check();
|
||||
+ }
|
||||
+ } else {
|
||||
+ _blocker->wait(true, WorkStealingSleepMillis);
|
||||
+
|
||||
+ if (_offered_termination == _n_threads) {
|
||||
+ _blocker->unlock();
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ size_t tasks = tasks_in_queue_set();
|
||||
+ if (exit_termination(tasks, terminator)) {
|
||||
+ _offered_termination--;
|
||||
+ _blocker->unlock();
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+bool OWSTTaskTerminator::do_spin_master_work(TerminatorTerminator* terminator) {
|
||||
+ uint yield_count = 0;
|
||||
+ // Number of hard spin loops done since last yield
|
||||
+ uint hard_spin_count = 0;
|
||||
+ // Number of iterations in the hard spin loop.
|
||||
+ uint hard_spin_limit = WorkStealingHardSpins;
|
||||
+
|
||||
+ // If WorkStealingSpinToYieldRatio is 0, no hard spinning is done.
|
||||
+ // If it is greater than 0, then start with a small number
|
||||
+ // of spins and increase number with each turn at spinning until
|
||||
+ // the count of hard spins exceeds WorkStealingSpinToYieldRatio.
|
||||
+ // Then do a yield() call and start spinning afresh.
|
||||
+ if (WorkStealingSpinToYieldRatio > 0) {
|
||||
+ hard_spin_limit = WorkStealingHardSpins >> WorkStealingSpinToYieldRatio;
|
||||
+ hard_spin_limit = MAX2(hard_spin_limit, 1U);
|
||||
+ }
|
||||
+ // Remember the initial spin limit.
|
||||
+ uint hard_spin_start = hard_spin_limit;
|
||||
+
|
||||
+ // Loop waiting for all threads to offer termination or
|
||||
+ // more work.
|
||||
+ while (true) {
|
||||
+ // Look for more work.
|
||||
+ // Periodically sleep() instead of yield() to give threads
|
||||
+ // waiting on the cores the chance to grab this code
|
||||
+ if (yield_count <= WorkStealingYieldsBeforeSleep) {
|
||||
+ // Do a yield or hardspin. For purposes of deciding whether
|
||||
+ // to sleep, count this as a yield.
|
||||
+ yield_count++;
|
||||
+
|
||||
+ // Periodically call yield() instead spinning
|
||||
+ // After WorkStealingSpinToYieldRatio spins, do a yield() call
|
||||
+ // and reset the counts and starting limit.
|
||||
+ if (hard_spin_count > WorkStealingSpinToYieldRatio) {
|
||||
+ yield();
|
||||
+ hard_spin_count = 0;
|
||||
+ hard_spin_limit = hard_spin_start;
|
||||
+#ifdef TRACESPINNING
|
||||
+ _total_yields++;
|
||||
+#endif
|
||||
+ } else {
|
||||
+ // Hard spin this time
|
||||
+ // Increase the hard spinning period but only up to a limit.
|
||||
+ hard_spin_limit = MIN2(2*hard_spin_limit,
|
||||
+ (uint) WorkStealingHardSpins);
|
||||
+ for (uint j = 0; j < hard_spin_limit; j++) {
|
||||
+ SpinPause();
|
||||
+ }
|
||||
+ hard_spin_count++;
|
||||
+#ifdef TRACESPINNING
|
||||
+ _total_spins++;
|
||||
+#endif
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (PrintGCDetails && Verbose) {
|
||||
+ gclog_or_tty->print_cr("OWSTTaskTerminator::do_spin_master_work() thread " PTR_FORMAT " sleeps after %u yields",
|
||||
+ p2i(Thread::current()), yield_count);
|
||||
+ }
|
||||
+ yield_count = 0;
|
||||
+
|
||||
+ MonitorLockerEx locker(_blocker, Mutex::_no_safepoint_check_flag);
|
||||
+ _spin_master = NULL;
|
||||
+ locker.wait(Mutex::_no_safepoint_check_flag, WorkStealingSleepMillis);
|
||||
+ if (_spin_master == NULL) {
|
||||
+ _spin_master = Thread::current();
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#ifdef TRACESPINNING
|
||||
+ _total_peeks++;
|
||||
+#endif
|
||||
+ size_t tasks = tasks_in_queue_set();
|
||||
+ if (exit_termination(tasks, terminator)) {
|
||||
+ MonitorLockerEx locker(_blocker, Mutex::_no_safepoint_check_flag);
|
||||
+ if ((int) tasks >= _offered_termination - 1) {
|
||||
+ locker.notify_all();
|
||||
+ } else {
|
||||
+ for (; tasks > 1; tasks--) {
|
||||
+ locker.notify();
|
||||
+ }
|
||||
+ }
|
||||
+ _spin_master = NULL;
|
||||
+ return false;
|
||||
+ } else if (_offered_termination == _n_threads) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.hpp b/hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.hpp
|
||||
new file mode 100644
|
||||
index 0000000000..ad50889d43
|
||||
--- /dev/null
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/shared/owstTaskTerminator.hpp
|
||||
@@ -0,0 +1,80 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * 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 SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
|
||||
+#define SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
|
||||
+
|
||||
+#include "runtime/mutex.hpp"
|
||||
+#include "runtime/thread.hpp"
|
||||
+#include "utilities/taskqueue.hpp"
|
||||
+
|
||||
+/*
|
||||
+ * OWST stands for Optimized Work Stealing Threads
|
||||
+ *
|
||||
+ * This is an enhanced implementation of Google's work stealing
|
||||
+ * protocol, which is described in the paper:
|
||||
+ * "Wessam Hassanein. 2016. Understanding and improving JVM GC work
|
||||
+ * stealing at the data center scale. In Proceedings of the 2016 ACM
|
||||
+ * SIGPLAN International Symposium on Memory Management (ISMM 2016). ACM,
|
||||
+ * New York, NY, USA, 46-54. DOI: https://doi.org/10.1145/2926697.2926706"
|
||||
+ *
|
||||
+ * Instead of a dedicated spin-master, our implementation will let spin-master relinquish
|
||||
+ * the role before it goes to sleep/wait, allowing newly arrived threads to compete for the role.
|
||||
+ * The intention of above enhancement is to reduce spin-master's latency on detecting new tasks
|
||||
+ * for stealing and termination condition.
|
||||
+ */
|
||||
+
|
||||
+class OWSTTaskTerminator: public ParallelTaskTerminator {
|
||||
+private:
|
||||
+ Monitor* _blocker;
|
||||
+ Thread* _spin_master;
|
||||
+
|
||||
+public:
|
||||
+ OWSTTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
|
||||
+ ParallelTaskTerminator(n_threads, queue_set), _spin_master(NULL) {
|
||||
+ _blocker = new Monitor(Mutex::leaf, "OWSTTaskTerminator", false);
|
||||
+ }
|
||||
+
|
||||
+ virtual ~OWSTTaskTerminator() {
|
||||
+ assert(_blocker != NULL, "Can not be NULL");
|
||||
+ delete _blocker;
|
||||
+ }
|
||||
+
|
||||
+ bool offer_termination(TerminatorTerminator* terminator);
|
||||
+
|
||||
+protected:
|
||||
+ // If should exit current termination protocol
|
||||
+ virtual bool exit_termination(size_t tasks, TerminatorTerminator* terminator);
|
||||
+
|
||||
+private:
|
||||
+ size_t tasks_in_queue_set() { return _queue_set->tasks(); }
|
||||
+
|
||||
+ /*
|
||||
+ * Perform spin-master task.
|
||||
+ * Return true if termination condition is detected, otherwise return false
|
||||
+ */
|
||||
+ bool do_spin_master_work(TerminatorTerminator* terminator);
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#endif // SHARE_VM_GC_SHARED_OWSTTASKTERMINATOR_HPP
|
||||
+
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index 0cf5ac1a8c..28e1bfd8e1 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -2020,6 +2020,10 @@ class CommandLineFlags {
|
||||
develop(uintx, PromotionFailureALotInterval, 5, \
|
||||
"Total collections between promotion failures alot") \
|
||||
\
|
||||
+ diagnostic(bool, UseOWSTTaskTerminator, true, \
|
||||
+ "Use Optimized Work Stealing Threads task termination " \
|
||||
+ "protocol") \
|
||||
+ \
|
||||
experimental(uintx, WorkStealingSleepMillis, 1, \
|
||||
"Sleep time when sleep is used for yields") \
|
||||
\
|
||||
diff --git a/hotspot/src/share/vm/utilities/taskqueue.cpp b/hotspot/src/share/vm/utilities/taskqueue.cpp
|
||||
index da2e928b8a..0f4dcc90ba 100644
|
||||
--- a/hotspot/src/share/vm/utilities/taskqueue.cpp
|
||||
+++ b/hotspot/src/share/vm/utilities/taskqueue.cpp
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/stack.inline.hpp"
|
||||
#include "utilities/taskqueue.hpp"
|
||||
+#include "gc_implementation/shared/owstTaskTerminator.hpp"
|
||||
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
@@ -268,3 +269,25 @@ void ParallelTaskTerminator::reset_for_reuse(int n_threads) {
|
||||
reset_for_reuse();
|
||||
_n_threads = n_threads;
|
||||
}
|
||||
+
|
||||
+TaskTerminator::TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
|
||||
+ _terminator(UseOWSTTaskTerminator ? new OWSTTaskTerminator(n_threads, queue_set)
|
||||
+ : new ParallelTaskTerminator(n_threads, queue_set)) {
|
||||
+}
|
||||
+
|
||||
+TaskTerminator::~TaskTerminator() {
|
||||
+ if (_terminator != NULL) {
|
||||
+ delete _terminator;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// Move assignment
|
||||
+TaskTerminator& TaskTerminator::operator=(const TaskTerminator& o) {
|
||||
+ if (_terminator != NULL) {
|
||||
+ delete _terminator;
|
||||
+ }
|
||||
+ _terminator = o.terminator();
|
||||
+ const_cast<TaskTerminator&>(o)._terminator = NULL;
|
||||
+ return *this;
|
||||
+}
|
||||
+
|
||||
diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
index 34ad795e62..dec76c51cc 100644
|
||||
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
@@ -500,6 +500,8 @@ protected:
|
||||
public:
|
||||
// Returns "true" if some TaskQueue in the set contains a task.
|
||||
virtual bool peek() = 0;
|
||||
+ // Tasks in queue
|
||||
+ virtual uint tasks() const = 0;
|
||||
virtual size_t tasks() = 0;
|
||||
};
|
||||
|
||||
@@ -537,6 +539,7 @@ public:
|
||||
bool steal(uint queue_num, int* seed, E& t);
|
||||
|
||||
bool peek();
|
||||
+ uint tasks() const;
|
||||
size_t tasks();
|
||||
|
||||
uint size() const { return _n; }
|
||||
@@ -606,6 +609,15 @@ size_t GenericTaskQueueSet<T, F>::tasks() {
|
||||
return n;
|
||||
}
|
||||
|
||||
+template<class T, MEMFLAGS F>
|
||||
+uint GenericTaskQueueSet<T, F>::tasks() const {
|
||||
+ uint n = 0;
|
||||
+ for (uint j = 0; j < _n; j++) {
|
||||
+ n += _queues[j]->size();
|
||||
+ }
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
// When to terminate from the termination protocol.
|
||||
class TerminatorTerminator: public CHeapObj<mtInternal> {
|
||||
public:
|
||||
@@ -617,7 +629,7 @@ public:
|
||||
|
||||
#undef TRACESPINNING
|
||||
|
||||
-class ParallelTaskTerminator: public StackObj {
|
||||
+class ParallelTaskTerminator: public CHeapObj<mtGC> {
|
||||
protected:
|
||||
int _n_threads;
|
||||
TaskQueueSetSuper* _queue_set;
|
||||
@@ -653,7 +665,7 @@ public:
|
||||
// As above, but it also terminates if the should_exit_termination()
|
||||
// method of the terminator parameter returns true. If terminator is
|
||||
// NULL, then it is ignored.
|
||||
- bool offer_termination(TerminatorTerminator* terminator);
|
||||
+ virtual bool offer_termination(TerminatorTerminator* terminator);
|
||||
|
||||
// Reset the terminator, so that it may be reused again.
|
||||
// The caller is responsible for ensuring that this is done
|
||||
@@ -672,6 +684,37 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
+#ifdef _MSC_VER
|
||||
+#pragma warning(push)
|
||||
+// warning C4521: multiple copy constructors specified
|
||||
+#pragma warning(disable:4521)
|
||||
+// warning C4522: multiple assignment operators specified
|
||||
+#pragma warning(disable:4522)
|
||||
+#endif
|
||||
+
|
||||
+class TaskTerminator : public StackObj {
|
||||
+private:
|
||||
+ ParallelTaskTerminator* _terminator;
|
||||
+
|
||||
+ // Disable following copy constructors and assignment operator
|
||||
+ TaskTerminator(TaskTerminator& o) { }
|
||||
+ TaskTerminator(const TaskTerminator& o) { }
|
||||
+ TaskTerminator& operator=(TaskTerminator& o) { return *this; }
|
||||
+public:
|
||||
+ TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
|
||||
+ ~TaskTerminator();
|
||||
+
|
||||
+ // Move assignment
|
||||
+ TaskTerminator& operator=(const TaskTerminator& o);
|
||||
+
|
||||
+ ParallelTaskTerminator* terminator() const {
|
||||
+ return _terminator;
|
||||
+ }
|
||||
+};
|
||||
+#ifdef _MSC_VER
|
||||
+#pragma warning(pop)
|
||||
+#endif
|
||||
+
|
||||
template<class E, MEMFLAGS F, unsigned int N> inline bool
|
||||
GenericTaskQueue<E, F, N>::push(E t) {
|
||||
uint localBot = _bottom;
|
||||
diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp
|
||||
index ef2dff4932..dd95651572 100644
|
||||
--- a/hotspot/src/share/vm/utilities/workgroup.hpp
|
||||
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp
|
||||
@@ -97,11 +97,11 @@ public:
|
||||
|
||||
class AbstractGangTaskWOopQueues : public AbstractGangTask {
|
||||
OopTaskQueueSet* _queues;
|
||||
- ParallelTaskTerminator _terminator;
|
||||
+ TaskTerminator _terminator;
|
||||
public:
|
||||
AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues) :
|
||||
AbstractGangTask(name), _queues(queues), _terminator(0, _queues) {}
|
||||
- ParallelTaskTerminator* terminator() { return &_terminator; }
|
||||
+ ParallelTaskTerminator* terminator() { return _terminator.terminator(); }
|
||||
virtual void set_for_termination(int active_workers) {
|
||||
terminator()->reset_for_reuse(active_workers);
|
||||
}
|
||||
--
|
||||
2.12.3
|
||||
|
||||
668
8205921-Optimizing-best-of-2-work-stealing-queue-sel.patch
Normal file
668
8205921-Optimizing-best-of-2-work-stealing-queue-sel.patch
Normal file
@ -0,0 +1,668 @@
|
||||
From b325bb23c804a9ff2e1b8bf67dfc421ba1bdd0ab Mon Sep 17 00:00:00 2001
|
||||
From: wuyan <wuyan34@huawei.com>
|
||||
Date: Thu, 12 Mar 2020 11:09:48 +0800
|
||||
Subject: [PATCH] 8205921: Optimizing best-of-2 work stealing queue selection
|
||||
|
||||
Summary: <gc>: Improve gc performance, optimizing best-of-2 work stealing queue selection
|
||||
LLT: jtreg
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8205921
|
||||
---
|
||||
.../concurrentMarkSweepGeneration.cpp | 29 ++----
|
||||
.../concurrentMarkSweepGeneration.hpp | 3 -
|
||||
.../vm/gc_implementation/g1/concurrentMark.cpp | 4 +-
|
||||
.../vm/gc_implementation/g1/concurrentMark.hpp | 6 +-
|
||||
.../gc_implementation/g1/g1ParScanThreadState.cpp | 2 +-
|
||||
.../gc_implementation/g1/g1ParScanThreadState.hpp | 2 -
|
||||
.../g1/g1ParScanThreadState.inline.hpp | 2 +-
|
||||
.../gc_implementation/parNew/parNewGeneration.cpp | 2 -
|
||||
.../gc_implementation/parNew/parNewGeneration.hpp | 2 -
|
||||
.../gc_implementation/parallelScavenge/pcTasks.cpp | 8 +-
|
||||
.../parallelScavenge/psCompactionManager.hpp | 12 +--
|
||||
.../parallelScavenge/psPromotionManager.hpp | 4 +-
|
||||
.../gc_implementation/parallelScavenge/psTasks.cpp | 3 +-
|
||||
.../shenandoah/shenandoahConcurrentMark.cpp | 3 +-
|
||||
.../shenandoah/shenandoahTraversalGC.cpp | 4 +-
|
||||
hotspot/src/share/vm/memory/padded.hpp | 6 ++
|
||||
hotspot/src/share/vm/utilities/taskqueue.cpp | 18 ----
|
||||
hotspot/src/share/vm/utilities/taskqueue.hpp | 106 +++++++++++++++++----
|
||||
18 files changed, 121 insertions(+), 95 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
index e42c8b5f39..84bc2eeeb8 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
|
||||
@@ -680,11 +680,6 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
|
||||
warning("task_queues allocation failure.");
|
||||
return;
|
||||
}
|
||||
- _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues, mtGC);
|
||||
- if (_hash_seed == NULL) {
|
||||
- warning("_hash_seed array allocation failure");
|
||||
- return;
|
||||
- }
|
||||
|
||||
typedef Padded<OopTaskQueue> PaddedOopTaskQueue;
|
||||
for (i = 0; i < num_queues; i++) {
|
||||
@@ -697,7 +692,6 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
|
||||
}
|
||||
for (i = 0; i < num_queues; i++) {
|
||||
_task_queues->queue(i)->initialize();
|
||||
- _hash_seed[i] = 17; // copied from ParNew
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4394,7 +4388,6 @@ void CMSConcMarkingTask::do_work_steal(int i) {
|
||||
oop obj_to_scan;
|
||||
CMSBitMap* bm = &(_collector->_markBitMap);
|
||||
CMSMarkStack* ovflw = &(_collector->_markStack);
|
||||
- int* seed = _collector->hash_seed(i);
|
||||
Par_ConcMarkingClosure cl(_collector, this, work_q, bm, ovflw);
|
||||
while (true) {
|
||||
cl.trim_queue(0);
|
||||
@@ -4404,7 +4397,7 @@ void CMSConcMarkingTask::do_work_steal(int i) {
|
||||
// overflow stack may already have been stolen from us.
|
||||
// assert(work_q->size() > 0, "Work from overflow stack");
|
||||
continue;
|
||||
- } else if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
|
||||
+ } else if (task_queues()->steal(i, /* reference */ obj_to_scan)) {
|
||||
assert(obj_to_scan->is_oop(), "Should be an oop");
|
||||
assert(bm->isMarked((HeapWord*)obj_to_scan), "Grey object");
|
||||
obj_to_scan->oop_iterate(&cl);
|
||||
@@ -5376,7 +5369,7 @@ class CMSParRemarkTask: public CMSParMarkTask {
|
||||
Par_MarkRefsIntoAndScanClosure* cl);
|
||||
|
||||
// ... work stealing for the above
|
||||
- void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl, int* seed);
|
||||
+ void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl);
|
||||
};
|
||||
|
||||
class RemarkKlassClosure : public KlassClosure {
|
||||
@@ -5542,7 +5535,7 @@ void CMSParRemarkTask::work(uint worker_id) {
|
||||
// ---------- ... and drain overflow list.
|
||||
_timer.reset();
|
||||
_timer.start();
|
||||
- do_work_steal(worker_id, &par_mrias_cl, _collector->hash_seed(worker_id));
|
||||
+ do_work_steal(worker_id, &par_mrias_cl);
|
||||
_timer.stop();
|
||||
if (PrintCMSStatistics != 0) {
|
||||
gclog_or_tty->print_cr(
|
||||
@@ -5699,8 +5692,7 @@ CMSParRemarkTask::do_dirty_card_rescan_tasks(
|
||||
|
||||
// . see if we can share work_queues with ParNew? XXX
|
||||
void
|
||||
-CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
|
||||
- int* seed) {
|
||||
+CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl) {
|
||||
OopTaskQueue* work_q = work_queue(i);
|
||||
NOT_PRODUCT(int num_steals = 0;)
|
||||
oop obj_to_scan;
|
||||
@@ -5731,7 +5723,7 @@ CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
|
||||
// Verify that we have no work before we resort to stealing
|
||||
assert(work_q->size() == 0, "Have work, shouldn't steal");
|
||||
// Try to steal from other queues that have work
|
||||
- if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
|
||||
+ if (task_queues()->steal(i,/* reference */ obj_to_scan)) {
|
||||
NOT_PRODUCT(num_steals++;)
|
||||
assert(obj_to_scan->is_oop(), "Oops, not an oop!");
|
||||
assert(bm->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
|
||||
@@ -6144,8 +6136,7 @@ public:
|
||||
|
||||
void do_work_steal(int i,
|
||||
CMSParDrainMarkingStackClosure* drain,
|
||||
- CMSParKeepAliveClosure* keep_alive,
|
||||
- int* seed);
|
||||
+ CMSParKeepAliveClosure* keep_alive);
|
||||
|
||||
virtual void work(uint worker_id);
|
||||
};
|
||||
@@ -6163,8 +6154,7 @@ void CMSRefProcTaskProxy::work(uint worker_id) {
|
||||
CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map);
|
||||
_task.work(worker_id, is_alive_closure, par_keep_alive, par_drain_stack);
|
||||
if (_task.marks_oops_alive()) {
|
||||
- do_work_steal(worker_id, &par_drain_stack, &par_keep_alive,
|
||||
- _collector->hash_seed(worker_id));
|
||||
+ do_work_steal(worker_id, &par_drain_stack, &par_keep_alive);
|
||||
}
|
||||
assert(work_queue(worker_id)->size() == 0, "work_queue should be empty");
|
||||
assert(_collector->_overflow_list == NULL, "non-empty _overflow_list");
|
||||
@@ -6199,8 +6189,7 @@ CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
|
||||
// . see if we can share work_queues with ParNew? XXX
|
||||
void CMSRefProcTaskProxy::do_work_steal(int i,
|
||||
CMSParDrainMarkingStackClosure* drain,
|
||||
- CMSParKeepAliveClosure* keep_alive,
|
||||
- int* seed) {
|
||||
+ CMSParKeepAliveClosure* keep_alive) {
|
||||
OopTaskQueue* work_q = work_queue(i);
|
||||
NOT_PRODUCT(int num_steals = 0;)
|
||||
oop obj_to_scan;
|
||||
@@ -6229,7 +6218,7 @@ void CMSRefProcTaskProxy::do_work_steal(int i,
|
||||
// Verify that we have no work before we resort to stealing
|
||||
assert(work_q->size() == 0, "Have work, shouldn't steal");
|
||||
// Try to steal from other queues that have work
|
||||
- if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
|
||||
+ if (task_queues()->steal(i, /* reference */ obj_to_scan)) {
|
||||
NOT_PRODUCT(num_steals++;)
|
||||
assert(obj_to_scan->is_oop(), "Oops, not an oop!");
|
||||
assert(_mark_bit_map->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
|
||||
index 8b65d34268..ca3fee21b8 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
|
||||
@@ -563,8 +563,6 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
Stack<oop, mtGC> _preserved_oop_stack;
|
||||
Stack<markOop, mtGC> _preserved_mark_stack;
|
||||
|
||||
- int* _hash_seed;
|
||||
-
|
||||
// In support of multi-threaded concurrent phases
|
||||
YieldingFlexibleWorkGang* _conc_workers;
|
||||
|
||||
@@ -741,7 +739,6 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
bool stop_world_and_do(CMS_op_type op);
|
||||
|
||||
OopTaskQueueSet* task_queues() { return _task_queues; }
|
||||
- int* hash_seed(int i) { return &_hash_seed[i]; }
|
||||
YieldingFlexibleWorkGang* conc_workers() { return _conc_workers; }
|
||||
|
||||
// Support for parallelizing Eden rescan in CMS remark phase
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
index 28dd5aadaa..271b33a577 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
|
||||
@@ -4421,7 +4421,7 @@ void CMTask::do_marking_step(double time_target_ms,
|
||||
oop obj;
|
||||
statsOnly( ++_steal_attempts );
|
||||
|
||||
- if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) {
|
||||
+ if (_cm->try_stealing(_worker_id, obj)) {
|
||||
if (_cm->verbose_medium()) {
|
||||
gclog_or_tty->print_cr("[%u] stolen " PTR_FORMAT " successfully",
|
||||
_worker_id, p2i((void*) obj));
|
||||
@@ -4605,7 +4605,7 @@ CMTask::CMTask(uint worker_id,
|
||||
: _g1h(G1CollectedHeap::heap()),
|
||||
_worker_id(worker_id), _cm(cm),
|
||||
_claimed(false),
|
||||
- _nextMarkBitMap(NULL), _hash_seed(17),
|
||||
+ _nextMarkBitMap(NULL),
|
||||
_task_queue(task_queue),
|
||||
_task_queues(task_queues),
|
||||
_cm_oop_closure(NULL),
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
index 02a0cb1843..1d785c1962 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
|
||||
@@ -679,8 +679,8 @@ public:
|
||||
}
|
||||
|
||||
// Attempts to steal an object from the task queues of other tasks
|
||||
- bool try_stealing(uint worker_id, int* hash_seed, oop& obj) {
|
||||
- return _task_queues->steal(worker_id, hash_seed, obj);
|
||||
+ bool try_stealing(uint worker_id, oop& obj) {
|
||||
+ return _task_queues->steal(worker_id, obj);
|
||||
}
|
||||
|
||||
ConcurrentMark(G1CollectedHeap* g1h,
|
||||
@@ -1004,8 +1004,6 @@ private:
|
||||
// it was decreased).
|
||||
size_t _real_refs_reached_limit;
|
||||
|
||||
- // used by the work stealing stuff
|
||||
- int _hash_seed;
|
||||
// if this is true, then the task has aborted for some reason
|
||||
bool _has_aborted;
|
||||
// set when the task aborts because it has met its time quota
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp
|
||||
index fc86a50cf8..7e2a61c1a1 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp
|
||||
@@ -36,7 +36,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num,
|
||||
_dcq(&g1h->dirty_card_queue_set()),
|
||||
_ct_bs(g1h->g1_barrier_set()),
|
||||
_g1_rem(g1h->g1_rem_set()),
|
||||
- _hash_seed(17), _queue_num(queue_num),
|
||||
+ _queue_num(queue_num),
|
||||
_term_attempts(0),
|
||||
_tenuring_threshold(g1h->g1_policy()->tenuring_threshold()),
|
||||
_age_table(false), _scanner(g1h, rp),
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp
|
||||
index d5350310e1..ce6e85c4b0 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp
|
||||
@@ -59,7 +59,6 @@ class G1ParScanThreadState : public StackObj {
|
||||
|
||||
OopsInHeapRegionClosure* _evac_failure_cl;
|
||||
|
||||
- int _hash_seed;
|
||||
uint _queue_num;
|
||||
|
||||
size_t _term_attempts;
|
||||
@@ -129,7 +128,6 @@ class G1ParScanThreadState : public StackObj {
|
||||
|
||||
OopsInHeapRegionClosure* evac_failure_closure() { return _evac_failure_cl; }
|
||||
|
||||
- int* hash_seed() { return &_hash_seed; }
|
||||
uint queue_num() { return _queue_num; }
|
||||
|
||||
size_t term_attempts() const { return _term_attempts; }
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp
|
||||
index 1b03f8caae..7dedb15178 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp
|
||||
@@ -131,7 +131,7 @@ inline void G1ParScanThreadState::dispatch_reference(StarTask ref) {
|
||||
|
||||
void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) {
|
||||
StarTask stolen_task;
|
||||
- while (task_queues->steal(queue_num(), hash_seed(), stolen_task)) {
|
||||
+ while (task_queues->steal(queue_num(), stolen_task)) {
|
||||
assert(verify_task(stolen_task), "sanity");
|
||||
dispatch_reference(stolen_task);
|
||||
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
|
||||
index 67867d4edb..107a10cab7 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
|
||||
@@ -92,7 +92,6 @@ ParScanThreadState::ParScanThreadState(Space* to_space_,
|
||||
|
||||
_survivor_chunk_array =
|
||||
(ChunkArray*) old_gen()->get_data_recorder(thread_num());
|
||||
- _hash_seed = 17; // Might want to take time-based random value.
|
||||
_start = os::elapsedTime();
|
||||
_old_gen_closure.set_generation(old_gen_);
|
||||
_old_gen_root_closure.set_generation(old_gen_);
|
||||
@@ -560,7 +559,6 @@ void ParEvacuateFollowersClosure::do_void() {
|
||||
|
||||
// attempt to steal work from promoted.
|
||||
if (task_queues()->steal(par_scan_state()->thread_num(),
|
||||
- par_scan_state()->hash_seed(),
|
||||
obj_to_scan)) {
|
||||
bool res = work_q->push(obj_to_scan);
|
||||
assert(res, "Empty queue should have room for a push.");
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
|
||||
index fa4265a2dc..ea527fdb56 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
|
||||
@@ -95,7 +95,6 @@ class ParScanThreadState {
|
||||
|
||||
HeapWord *_young_old_boundary;
|
||||
|
||||
- int _hash_seed;
|
||||
int _thread_num;
|
||||
ageTable _ageTable;
|
||||
|
||||
@@ -161,7 +160,6 @@ class ParScanThreadState {
|
||||
// Is new_obj a candidate for scan_partial_array_and_push_remainder method.
|
||||
inline bool should_be_partially_scanned(oop new_obj, oop old_obj) const;
|
||||
|
||||
- int* hash_seed() { return &_hash_seed; }
|
||||
int thread_num() { return _thread_num; }
|
||||
|
||||
// Allocate a to-space block of size "sz", or else return NULL.
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
|
||||
index 35ea2992b7..37610f3d14 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
|
||||
@@ -217,14 +217,13 @@ void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
|
||||
|
||||
oop obj = NULL;
|
||||
ObjArrayTask task;
|
||||
- int random_seed = 17;
|
||||
do {
|
||||
- while (ParCompactionManager::steal_objarray(which, &random_seed, task)) {
|
||||
+ while (ParCompactionManager::steal_objarray(which, task)) {
|
||||
ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
|
||||
k->oop_follow_contents(cm, task.obj(), task.index());
|
||||
cm->follow_marking_stacks();
|
||||
}
|
||||
- while (ParCompactionManager::steal(which, &random_seed, obj)) {
|
||||
+ while (ParCompactionManager::steal(which, obj)) {
|
||||
obj->follow_contents(cm);
|
||||
cm->follow_marking_stacks();
|
||||
}
|
||||
@@ -280,13 +279,12 @@ void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
|
||||
cm->drain_region_stacks();
|
||||
|
||||
size_t region_index = 0;
|
||||
- int random_seed = 17;
|
||||
|
||||
// If we're the termination task, try 10 rounds of stealing before
|
||||
// setting the termination flag
|
||||
|
||||
while(true) {
|
||||
- if (ParCompactionManager::steal(which, &random_seed, region_index)) {
|
||||
+ if (ParCompactionManager::steal(which, region_index)) {
|
||||
PSParallelCompact::fill_and_update_region(cm, region_index);
|
||||
cm->drain_region_stacks();
|
||||
} else {
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
|
||||
index 7d7a9f495a..a16a167623 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
|
||||
@@ -177,16 +177,16 @@ private:
|
||||
// Access function for compaction managers
|
||||
static ParCompactionManager* gc_thread_compaction_manager(int index);
|
||||
|
||||
- static bool steal(int queue_num, int* seed, oop& t) {
|
||||
- return stack_array()->steal(queue_num, seed, t);
|
||||
+ static bool steal(int queue_num, oop& t) {
|
||||
+ return stack_array()->steal(queue_num, t);
|
||||
}
|
||||
|
||||
- static bool steal_objarray(int queue_num, int* seed, ObjArrayTask& t) {
|
||||
- return _objarray_queues->steal(queue_num, seed, t);
|
||||
+ static bool steal_objarray(int queue_num, ObjArrayTask& t) {
|
||||
+ return _objarray_queues->steal(queue_num, t);
|
||||
}
|
||||
|
||||
- static bool steal(int queue_num, int* seed, size_t& region) {
|
||||
- return region_array()->steal(queue_num, seed, region);
|
||||
+ static bool steal(int queue_num, size_t& region) {
|
||||
+ return region_array()->steal(queue_num, region);
|
||||
}
|
||||
|
||||
// Process tasks remaining on any marking stack
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
|
||||
index 69292400f3..6983249509 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
|
||||
@@ -160,8 +160,8 @@ class PSPromotionManager VALUE_OBJ_CLASS_SPEC {
|
||||
static PSPromotionManager* gc_thread_promotion_manager(int index);
|
||||
static PSPromotionManager* vm_thread_promotion_manager();
|
||||
|
||||
- static bool steal_depth(int queue_num, int* seed, StarTask& t) {
|
||||
- return stack_array_depth()->steal(queue_num, seed, t);
|
||||
+ static bool steal_depth(int queue_num, StarTask& t) {
|
||||
+ return stack_array_depth()->steal(queue_num, t);
|
||||
}
|
||||
|
||||
PSPromotionManager();
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
|
||||
index f829e93440..4fe869fd63 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
|
||||
@@ -151,10 +151,9 @@ void StealTask::do_it(GCTaskManager* manager, uint which) {
|
||||
guarantee(pm->stacks_empty(),
|
||||
"stacks should be empty at this point");
|
||||
|
||||
- int random_seed = 17;
|
||||
while(true) {
|
||||
StarTask p;
|
||||
- if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
|
||||
+ if (PSPromotionManager::steal_depth(which, p)) {
|
||||
TASKQUEUE_STATS_ONLY(pm->record_steal(p));
|
||||
pm->process_popped_location_depth(p);
|
||||
pm->drain_stacks_depth(true);
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp
|
||||
index d26d25e102..a54ecf7451 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp
|
||||
@@ -922,7 +922,6 @@ void ShenandoahConcurrentMark::mark_loop_prework(uint w, ShenandoahTaskTerminato
|
||||
|
||||
template <class T, bool CANCELLABLE>
|
||||
void ShenandoahConcurrentMark::mark_loop_work(T* cl, jushort* live_data, uint worker_id, ShenandoahTaskTerminator *terminator) {
|
||||
- int seed = 17;
|
||||
uintx stride = ShenandoahMarkLoopStride;
|
||||
|
||||
ShenandoahHeap* heap = ShenandoahHeap::heap();
|
||||
@@ -982,7 +981,7 @@ void ShenandoahConcurrentMark::mark_loop_work(T* cl, jushort* live_data, uint wo
|
||||
uint work = 0;
|
||||
for (uint i = 0; i < stride; i++) {
|
||||
if (q->pop(t) ||
|
||||
- queues->steal(worker_id, &seed, t)) {
|
||||
+ queues->steal(worker_id, t)) {
|
||||
do_task<T>(q, cl, live_data, &t);
|
||||
work++;
|
||||
} else {
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp b/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp
|
||||
index 8c523f78e9..16aee14109 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahTraversalGC.cpp
|
||||
@@ -605,8 +605,6 @@ void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worke
|
||||
ShenandoahTraversalSATBBufferClosure drain_satb(q);
|
||||
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
|
||||
|
||||
- int seed = 17;
|
||||
-
|
||||
while (true) {
|
||||
if (_heap->cancelled_gc()) return;
|
||||
|
||||
@@ -617,7 +615,7 @@ void ShenandoahTraversalGC::main_loop_work(T* cl, jushort* live_data, uint worke
|
||||
uint work = 0;
|
||||
for (uint i = 0; i < stride; i++) {
|
||||
if (q->pop(task) ||
|
||||
- queues->steal(worker_id, &seed, task)) {
|
||||
+ queues->steal(worker_id, task)) {
|
||||
conc_mark->do_task<T>(q, cl, live_data, &task);
|
||||
work++;
|
||||
} else {
|
||||
diff --git a/hotspot/src/share/vm/memory/padded.hpp b/hotspot/src/share/vm/memory/padded.hpp
|
||||
index 9ddd14f857..34eccd6646 100644
|
||||
--- a/hotspot/src/share/vm/memory/padded.hpp
|
||||
+++ b/hotspot/src/share/vm/memory/padded.hpp
|
||||
@@ -80,6 +80,12 @@ class PaddedEnd : public PaddedEndImpl<T, PADDED_END_SIZE(T, alignment)> {
|
||||
// super class that is specialized for the pad_size == 0 case.
|
||||
};
|
||||
|
||||
+// Similar to PaddedEnd, this macro defines a _pad_buf#id field
|
||||
+// that is (alignment - size) bytes in size. This macro is used
|
||||
+// to add padding in between non-class fields in a class or struct.
|
||||
+#define DEFINE_PAD_MINUS_SIZE(id, alignment, size) \
|
||||
+ char _pad_buf##id[(alignment) - (size)]
|
||||
+
|
||||
// Helper class to create an array of PaddedEnd<T> objects. All elements will
|
||||
// start at a multiple of alignment and the size will be aligned to alignment.
|
||||
template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
|
||||
diff --git a/hotspot/src/share/vm/utilities/taskqueue.cpp b/hotspot/src/share/vm/utilities/taskqueue.cpp
|
||||
index 0f4dcc90ba..37f4066ab9 100644
|
||||
--- a/hotspot/src/share/vm/utilities/taskqueue.cpp
|
||||
+++ b/hotspot/src/share/vm/utilities/taskqueue.cpp
|
||||
@@ -112,24 +112,6 @@ void TaskQueueStats::verify() const
|
||||
#endif // ASSERT
|
||||
#endif // TASKQUEUE_STATS
|
||||
|
||||
-int TaskQueueSetSuper::randomParkAndMiller(int *seed0) {
|
||||
- const int a = 16807;
|
||||
- const int m = 2147483647;
|
||||
- const int q = 127773; /* m div a */
|
||||
- const int r = 2836; /* m mod a */
|
||||
- assert(sizeof(int) == 4, "I think this relies on that");
|
||||
- int seed = *seed0;
|
||||
- int hi = seed / q;
|
||||
- int lo = seed % q;
|
||||
- int test = a * lo - r * hi;
|
||||
- if (test > 0)
|
||||
- seed = test;
|
||||
- else
|
||||
- seed = test + m;
|
||||
- *seed0 = seed;
|
||||
- return seed;
|
||||
-}
|
||||
-
|
||||
ParallelTaskTerminator::
|
||||
ParallelTaskTerminator(int n_threads, TaskQueueSetSuper* queue_set) :
|
||||
_n_threads(n_threads),
|
||||
diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
index dec76c51cc..5b03ccfa82 100644
|
||||
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
+#include "memory/padded.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/orderAccess.inline.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
@@ -307,12 +308,30 @@ public:
|
||||
void oops_do(OopClosure* f);
|
||||
|
||||
private:
|
||||
+ DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
// Element array.
|
||||
volatile E* _elems;
|
||||
+
|
||||
+ DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(E*));
|
||||
+ // Queue owner local variables. Not to be accessed by other threads.
|
||||
+
|
||||
+ static const uint InvalidQueueId = uint(-1);
|
||||
+ uint _last_stolen_queue_id; // The id of the queue we last stole from
|
||||
+
|
||||
+ int _seed; // Current random seed used for selecting a random queue during stealing.
|
||||
+
|
||||
+ DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(uint) + sizeof(int));
|
||||
+public:
|
||||
+ int next_random_queue_id();
|
||||
+
|
||||
+ void set_last_stolen_queue_id(uint id) { _last_stolen_queue_id = id; }
|
||||
+ uint last_stolen_queue_id() const { return _last_stolen_queue_id; }
|
||||
+ bool is_last_stolen_queue_id_valid() const { return _last_stolen_queue_id != InvalidQueueId; }
|
||||
+ void invalidate_last_stolen_queue_id() { _last_stolen_queue_id = InvalidQueueId; }
|
||||
};
|
||||
|
||||
template<class E, MEMFLAGS F, unsigned int N>
|
||||
-GenericTaskQueue<E, F, N>::GenericTaskQueue() {
|
||||
+GenericTaskQueue<E, F, N>::GenericTaskQueue() : _last_stolen_queue_id(InvalidQueueId), _seed(17 /* random number */) {
|
||||
assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
|
||||
}
|
||||
|
||||
@@ -426,6 +445,30 @@ bool GenericTaskQueue<E, F, N>::pop_global(volatile E& t) {
|
||||
return resAge == oldAge;
|
||||
}
|
||||
|
||||
+inline int randomParkAndMiller(int *seed0) {
|
||||
+ const int a = 16807;
|
||||
+ const int m = 2147483647;
|
||||
+ const int q = 127773; /* m div a */
|
||||
+ const int r = 2836; /* m mod a */
|
||||
+ STATIC_ASSERT(sizeof(int) == 4);
|
||||
+ int seed = *seed0;
|
||||
+ int hi = seed / q;
|
||||
+ int lo = seed % q;
|
||||
+ int test = a * lo - r * hi;
|
||||
+ if (test > 0) {
|
||||
+ seed = test;
|
||||
+ } else {
|
||||
+ seed = test + m;
|
||||
+ }
|
||||
+ *seed0 = seed;
|
||||
+ return seed;
|
||||
+}
|
||||
+
|
||||
+template<class E, MEMFLAGS F, unsigned int N>
|
||||
+int GenericTaskQueue<E, F, N>::next_random_queue_id() {
|
||||
+ return randomParkAndMiller(&_seed);
|
||||
+}
|
||||
+
|
||||
template<class E, MEMFLAGS F, unsigned int N>
|
||||
GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
|
||||
FREE_C_HEAP_ARRAY(E, _elems, F);
|
||||
@@ -495,8 +538,6 @@ bool OverflowTaskQueue<E, F, N>::try_push_to_taskqueue(E t) {
|
||||
return taskqueue_t::push(t);
|
||||
}
|
||||
class TaskQueueSetSuper {
|
||||
-protected:
|
||||
- static int randomParkAndMiller(int* seed0);
|
||||
public:
|
||||
// Returns "true" if some TaskQueue in the set contains a task.
|
||||
virtual bool peek() = 0;
|
||||
@@ -517,27 +558,23 @@ private:
|
||||
public:
|
||||
typedef typename T::element_type E;
|
||||
|
||||
- GenericTaskQueueSet(int n) : _n(n) {
|
||||
+ GenericTaskQueueSet(uint n) : _n(n) {
|
||||
typedef T* GenericTaskQueuePtr;
|
||||
_queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F);
|
||||
- for (int i = 0; i < n; i++) {
|
||||
+ for (uint i = 0; i < n; i++) {
|
||||
_queues[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- bool steal_best_of_2(uint queue_num, int* seed, E& t);
|
||||
+ bool steal_best_of_2(uint queue_num, E& t);
|
||||
|
||||
void register_queue(uint i, T* q);
|
||||
|
||||
T* queue(uint n);
|
||||
|
||||
- // The thread with queue number "queue_num" (and whose random number seed is
|
||||
- // at "seed") is trying to steal a task from some other queue. (It may try
|
||||
- // several queues, according to some configuration parameter.) If some steal
|
||||
- // succeeds, returns "true" and sets "t" to the stolen task, otherwise returns
|
||||
- // false.
|
||||
- bool steal(uint queue_num, int* seed, E& t);
|
||||
-
|
||||
+ // Try to steal a task from some other queue than queue_num. It may perform several attempts at doing so.
|
||||
+ // Returns if stealing succeeds, and sets "t" to the stolen task.
|
||||
+ bool steal(uint queue_num, E& t);
|
||||
bool peek();
|
||||
uint tasks() const;
|
||||
size_t tasks();
|
||||
@@ -557,9 +594,9 @@ GenericTaskQueueSet<T, F>::queue(uint i) {
|
||||
}
|
||||
|
||||
template<class T, MEMFLAGS F> bool
|
||||
-GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) {
|
||||
+GenericTaskQueueSet<T, F>::steal(uint queue_num, E& t) {
|
||||
for (uint i = 0; i < 2 * _n; i++) {
|
||||
- if (steal_best_of_2(queue_num, seed, t)) {
|
||||
+ if (steal_best_of_2(queue_num, t)) {
|
||||
TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true));
|
||||
return true;
|
||||
}
|
||||
@@ -569,17 +606,46 @@ GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) {
|
||||
}
|
||||
|
||||
template<class T, MEMFLAGS F> bool
|
||||
-GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) {
|
||||
+GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, E& t) {
|
||||
if (_n > 2) {
|
||||
+ T* const local_queue = _queues[queue_num];
|
||||
uint k1 = queue_num;
|
||||
- while (k1 == queue_num) k1 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
|
||||
+
|
||||
+ if (local_queue->is_last_stolen_queue_id_valid()) {
|
||||
+ k1 = local_queue->last_stolen_queue_id();
|
||||
+ assert(k1 != queue_num, "Should not be the same");
|
||||
+ } else {
|
||||
+ while (k1 == queue_num) {
|
||||
+ k1 = local_queue->next_random_queue_id() % _n;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
uint k2 = queue_num;
|
||||
- while (k2 == queue_num || k2 == k1) k2 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
|
||||
+ while (k2 == queue_num || k2 == k1) {
|
||||
+ k2 = local_queue->next_random_queue_id() % _n;
|
||||
+ }
|
||||
// Sample both and try the larger.
|
||||
uint sz1 = _queues[k1]->size();
|
||||
uint sz2 = _queues[k2]->size();
|
||||
- if (sz2 > sz1) return _queues[k2]->pop_global(t);
|
||||
- else return _queues[k1]->pop_global(t);
|
||||
+
|
||||
+ uint sel_k = 0;
|
||||
+ bool suc = false;
|
||||
+
|
||||
+ if (sz2 > sz1) {
|
||||
+ sel_k = k2;
|
||||
+ suc = _queues[k2]->pop_global(t);
|
||||
+ } else if (sz1 > 0) {
|
||||
+ sel_k = k1;
|
||||
+ suc = _queues[k1]->pop_global(t);
|
||||
+ }
|
||||
+
|
||||
+ if (suc) {
|
||||
+ local_queue->set_last_stolen_queue_id(sel_k);
|
||||
+ } else {
|
||||
+ local_queue->invalidate_last_stolen_queue_id();
|
||||
+ }
|
||||
+
|
||||
+ return suc;
|
||||
} else if (_n == 2) {
|
||||
// Just try the other one.
|
||||
uint k = (queue_num + 1) % 2;
|
||||
--
|
||||
2.12.3
|
||||
|
||||
86
8227662-freetype-seeks-to-index-at-the-end-of-the-fo.patch
Normal file
86
8227662-freetype-seeks-to-index-at-the-end-of-the-fo.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From df8278f141b2fa1ea2a685fb1352428ecf84d50b Mon Sep 17 00:00:00 2001
|
||||
From: hedongbo <hedongbo@huawei.com>
|
||||
Date: Thu, 13 Feb 2020 17:32:14 +0000
|
||||
Subject: [PATCH] 8227662: freetype seeks to index at the end of the font data
|
||||
|
||||
Summary: <freetype>: freetype seeks to index at the end of the font data
|
||||
LLT: jdk/test/java/awt/FontMetrics/SpaceAdvance.java
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8237400
|
||||
---
|
||||
jdk/src/share/native/sun/font/freetypeScaler.c | 2 +-
|
||||
jdk/test/java/awt/FontMetrics/SpaceAdvance.java | 49 +++++++++++++++++++++++++
|
||||
2 files changed, 50 insertions(+), 1 deletion(-)
|
||||
create mode 100644 jdk/test/java/awt/FontMetrics/SpaceAdvance.java
|
||||
|
||||
diff --git a/jdk/src/share/native/sun/font/freetypeScaler.c b/jdk/src/share/native/sun/font/freetypeScaler.c
|
||||
index 48a024a3df..36a2b86271 100644
|
||||
--- a/jdk/src/share/native/sun/font/freetypeScaler.c
|
||||
+++ b/jdk/src/share/native/sun/font/freetypeScaler.c
|
||||
@@ -163,7 +163,7 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
|
||||
*/
|
||||
|
||||
if (numBytes == 0) {
|
||||
- if (offset >= scalerInfo->fileSize) {
|
||||
+ if (offset > scalerInfo->fileSize) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
diff --git a/jdk/test/java/awt/FontMetrics/SpaceAdvance.java b/jdk/test/java/awt/FontMetrics/SpaceAdvance.java
|
||||
new file mode 100644
|
||||
index 0000000000..e2c7acb6f9
|
||||
--- /dev/null
|
||||
+++ b/jdk/test/java/awt/FontMetrics/SpaceAdvance.java
|
||||
@@ -0,0 +1,49 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2019, 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 8227662
|
||||
+ */
|
||||
+
|
||||
+import java.awt.Font;
|
||||
+import java.awt.FontMetrics ;
|
||||
+import java.awt.Graphics2D;
|
||||
+import java.awt.image.BufferedImage;
|
||||
+
|
||||
+public class SpaceAdvance {
|
||||
+ public static void main(String[] args) throws Exception {
|
||||
+
|
||||
+ BufferedImage bi = new BufferedImage(1,1,1);
|
||||
+ Graphics2D g2d = bi.createGraphics();
|
||||
+ Font font = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||
+ if (!font.canDisplay(' ')) {
|
||||
+ return;
|
||||
+ }
|
||||
+ g2d.setFont(font);
|
||||
+ FontMetrics fm = g2d.getFontMetrics();
|
||||
+ if (fm.charWidth(' ') == 0) {
|
||||
+ throw new RuntimeException("Space has char width of 0");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
From b5af97426c82ead4df42f3824a32e9ee634585a4 Mon Sep 17 00:00:00 2001
|
||||
From: wuyan <wuyan34@huawei.com>
|
||||
Date: Sat, 21 Sep 2019 15:47:05 +0800
|
||||
Subject: [PATCH] Backport of JDK-8229169
|
||||
|
||||
Summary: [Backport of JDK-8229169] False failure of GenericTaskQueue::pop_local on architectures with weak memory model
|
||||
LLT:
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8229169
|
||||
|
||||
---
|
||||
hotspot/src/share/vm/utilities/taskqueue.hpp | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
index 6ebd185b76..798f9aa183 100644
|
||||
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp
|
||||
@@ -724,6 +724,11 @@ GenericTaskQueue<E, F, N>::pop_local(volatile E& t) {
|
||||
} else {
|
||||
// Otherwise, the queue contained exactly one element; we take the slow
|
||||
// path.
|
||||
+
|
||||
+ // The barrier is required to prevent reordering the two reads of _age:
|
||||
+ // one is the _age.get() below, and the other is _age.top() above the if-stmt.
|
||||
+ // The algorithm may fail if _age.get() reads an older value than _age.top().
|
||||
+ OrderAccess::loadload();
|
||||
return pop_local_slow(localBot, _age.get());
|
||||
}
|
||||
}
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -1,376 +0,0 @@
|
||||
From 219a986b26fe9813730939038b3b1d70255d19a6 Mon Sep 17 00:00:00 2001
|
||||
From: wangshuai <wangshuai94@huawei.com>
|
||||
Date: Mon, 11 Nov 2019 19:42:17 +0000
|
||||
Subject: [PATCH] 8231584:Deadlock with ClassLoader.findLibrary and
|
||||
System.loadLibrary call
|
||||
|
||||
Summary:<java.lang>:Deadlock with ClassLoader.findLibrary and System.loadLibrary call
|
||||
LLT:FileSystemsDeadlockTest.java
|
||||
Patch Type:backport
|
||||
bug url: https://bugs.openjdk.java.net/browse/JDK-8231584
|
||||
---
|
||||
jdk/src/share/classes/java/lang/ClassLoader.java | 32 +++--
|
||||
jdk/src/share/classes/java/lang/Runtime.java | 7 +-
|
||||
jdk/src/share/classes/java/lang/System.java | 2 +
|
||||
.../lang/Runtime/loadLibrary/LoadLibraryTest.java | 156 +++++++++++++++++++++
|
||||
jdk/test/java/lang/Runtime/loadLibrary/Target.java | 34 +++++
|
||||
.../java/lang/Runtime/loadLibrary/Target2.java | 29 ++++
|
||||
6 files changed, 247 insertions(+), 13 deletions(-)
|
||||
create mode 100644 jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
|
||||
create mode 100644 jdk/test/java/lang/Runtime/loadLibrary/Target.java
|
||||
create mode 100644 jdk/test/java/lang/Runtime/loadLibrary/Target2.java
|
||||
|
||||
diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java
|
||||
index 2e98092f63..925fdacce3 100644
|
||||
--- a/jdk/src/share/classes/java/lang/ClassLoader.java
|
||||
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2019, Azul Systems, Inc. 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
|
||||
@@ -1467,6 +1468,17 @@ public abstract class ClassLoader {
|
||||
}
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Initialize default paths for native libraries search.
|
||||
+ * Must be done early as JDK may load libraries during bootstrap.
|
||||
+ *
|
||||
+ * @see java.lang.System#initPhase1
|
||||
+ */
|
||||
+ static void initLibraryPaths() {
|
||||
+ usr_paths = initializePath("java.library.path");
|
||||
+ sys_paths = initializePath("sun.boot.library.path");
|
||||
+ }
|
||||
+
|
||||
// Returns true if the specified class loader can be found in this class
|
||||
// loader's delegation chain.
|
||||
boolean isAncestor(ClassLoader cl) {
|
||||
@@ -1809,10 +1821,9 @@ public abstract class ClassLoader {
|
||||
boolean isAbsolute) {
|
||||
ClassLoader loader =
|
||||
(fromClass == null) ? null : fromClass.getClassLoader();
|
||||
- if (sys_paths == null) {
|
||||
- usr_paths = initializePath("java.library.path");
|
||||
- sys_paths = initializePath("sun.boot.library.path");
|
||||
- }
|
||||
+ assert sys_paths != null : "should be initialized at this point";
|
||||
+ assert usr_paths != null : "should be initialized at this point";
|
||||
+
|
||||
if (isAbsolute) {
|
||||
if (loadLibrary0(fromClass, new File(name))) {
|
||||
return;
|
||||
@@ -1902,13 +1913,14 @@ public abstract class ClassLoader {
|
||||
name +
|
||||
" already loaded in another classloader");
|
||||
}
|
||||
- /* If the library is being loaded (must be by the same thread,
|
||||
- * because Runtime.load and Runtime.loadLibrary are
|
||||
- * synchronous). The reason is can occur is that the JNI_OnLoad
|
||||
- * function can cause another loadLibrary invocation.
|
||||
+ /*
|
||||
+ * When a library is being loaded, JNI_OnLoad function can cause
|
||||
+ * another loadLibrary invocation that should succeed.
|
||||
*
|
||||
- * Thus we can use a static stack to hold the list of libraries
|
||||
- * we are loading.
|
||||
+ * We use a static stack to hold the list of libraries we are
|
||||
+ * loading because this can happen only when called by the
|
||||
+ * same thread because Runtime.load and Runtime.loadLibrary
|
||||
+ * are synchronous.
|
||||
*
|
||||
* If there is a pending load operation for the library, we
|
||||
* immediately return success; otherwise, we raise
|
||||
diff --git a/jdk/src/share/classes/java/lang/Runtime.java b/jdk/src/share/classes/java/lang/Runtime.java
|
||||
index 9e53dc939e..5039059149 100644
|
||||
--- a/jdk/src/share/classes/java/lang/Runtime.java
|
||||
+++ b/jdk/src/share/classes/java/lang/Runtime.java
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2019, Azul Systems, Inc. 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
|
||||
@@ -797,7 +798,7 @@ public class Runtime {
|
||||
load0(Reflection.getCallerClass(), filename);
|
||||
}
|
||||
|
||||
- synchronized void load0(Class<?> fromClass, String filename) {
|
||||
+ void load0(Class<?> fromClass, String filename) {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkLink(filename);
|
||||
@@ -858,14 +859,14 @@ public class Runtime {
|
||||
loadLibrary0(Reflection.getCallerClass(), libname);
|
||||
}
|
||||
|
||||
- synchronized void loadLibrary0(Class<?> fromClass, String libname) {
|
||||
+ void loadLibrary0(Class<?> fromClass, String libname) {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkLink(libname);
|
||||
}
|
||||
if (libname.indexOf((int)File.separatorChar) != -1) {
|
||||
throw new UnsatisfiedLinkError(
|
||||
- "Directory separator should not appear in library name: " + libname);
|
||||
+ "Directory separator should not appear in library name: " + libname);
|
||||
}
|
||||
ClassLoader.loadLibrary(fromClass, libname, false);
|
||||
}
|
||||
diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java
|
||||
index b2747fa7a4..7bc235beff 100644
|
||||
--- a/jdk/src/share/classes/java/lang/System.java
|
||||
+++ b/jdk/src/share/classes/java/lang/System.java
|
||||
@@ -1192,6 +1192,8 @@ public final class System {
|
||||
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
|
||||
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
|
||||
|
||||
+ ClassLoader.initLibraryPaths();
|
||||
+
|
||||
// Load the zip library now in order to keep java.util.zip.ZipFile
|
||||
// from trying to use itself to load this library later.
|
||||
loadLibrary("zip");
|
||||
diff --git a/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java b/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
|
||||
new file mode 100644
|
||||
index 0000000000..62eac12e18
|
||||
--- /dev/null
|
||||
+++ b/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
|
||||
@@ -0,0 +1,156 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018, Amazon and/or its affiliates. All rights reserved.
|
||||
+ * Copyright (c) 2019, Azul Systems, Inc. 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 8231584
|
||||
+ * @library /lib/testlibrary
|
||||
+ * @run main/othervm LoadLibraryTest
|
||||
+ */
|
||||
+
|
||||
+import java.nio.file.FileSystems;
|
||||
+import java.nio.file.Files;
|
||||
+import java.nio.file.Paths;
|
||||
+import java.nio.file.Path;
|
||||
+import java.net.MalformedURLException;
|
||||
+import java.net.URLClassLoader;
|
||||
+import java.net.URL;
|
||||
+
|
||||
+public class LoadLibraryTest {
|
||||
+ static Thread thread1 = null;
|
||||
+ static Thread thread2 = null;
|
||||
+
|
||||
+ static volatile boolean thread1Ready = false;
|
||||
+
|
||||
+ private static final String TEST_SRC = System.getProperty("test.src");
|
||||
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||
+ private static final Path CLS_DIR = Paths.get("classes");
|
||||
+
|
||||
+ static TestClassLoader loader;
|
||||
+ static void someLibLoad() {
|
||||
+ try {
|
||||
+/*
|
||||
+ FileSystems.getDefault();
|
||||
+
|
||||
+ // jdk/jdk: loads directly from Bootstrap Classloader (doesn't take lock on Runtime)
|
||||
+ java.net.NetworkInterface.getNetworkInterfaces();
|
||||
+
|
||||
+ System.out.println(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
|
||||
+*/
|
||||
+ Class c = Class.forName("Target2", true, loader);
|
||||
+ } catch (Exception e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static class TestClassLoader extends URLClassLoader {
|
||||
+ boolean passed = false;
|
||||
+
|
||||
+ public boolean passed() {
|
||||
+ return passed;
|
||||
+ }
|
||||
+
|
||||
+ TestClassLoader() throws MalformedURLException {
|
||||
+ super(new URL[] { new URL("file://" + CLS_DIR.toAbsolutePath().toString() + '/') });
|
||||
+ }
|
||||
+
|
||||
+ public String findLibrary(String name) {
|
||||
+ System.out.println("findLibrary " + name);
|
||||
+
|
||||
+ if ("someLibrary".equals(name)) {
|
||||
+ try {
|
||||
+ synchronized(thread1) {
|
||||
+ while(!thread1Ready) {
|
||||
+ thread1.wait();
|
||||
+ }
|
||||
+ thread1.notifyAll();
|
||||
+ }
|
||||
+
|
||||
+ Thread.sleep(10000);
|
||||
+
|
||||
+ System.out.println("Thread2 load");
|
||||
+ someLibLoad();
|
||||
+
|
||||
+ // no deadlock happened
|
||||
+ passed = true;
|
||||
+ } catch (Exception e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return super.findLibrary(name);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ public static void main(String[] args) throws Exception {
|
||||
+ loader = new TestClassLoader();
|
||||
+
|
||||
+ if (!CompilerUtils.compile(SRC_DIR, CLS_DIR)) {
|
||||
+ throw new Exception("Can't compile");
|
||||
+ }
|
||||
+
|
||||
+ thread1 = new Thread() {
|
||||
+ public void run() {
|
||||
+ try {
|
||||
+ synchronized(this) {
|
||||
+ thread1Ready = true;
|
||||
+ thread1.notifyAll();
|
||||
+ thread1.wait();
|
||||
+ }
|
||||
+ } catch(InterruptedException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+
|
||||
+ System.out.println("Thread1 load");
|
||||
+ someLibLoad();
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ thread2 = new Thread() {
|
||||
+ public void run() {
|
||||
+ try {
|
||||
+ Class c = Class.forName("Target", true, loader);
|
||||
+ System.out.println(c);
|
||||
+ } catch (Exception e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ thread1.setDaemon(true);
|
||||
+ thread2.setDaemon(true);
|
||||
+
|
||||
+ thread1.start();
|
||||
+ thread2.start();
|
||||
+
|
||||
+ thread1.join();
|
||||
+ thread2.join();
|
||||
+
|
||||
+ if (!loader.passed()) {
|
||||
+ throw new RuntimeException("FAIL");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/jdk/test/java/lang/Runtime/loadLibrary/Target.java b/jdk/test/java/lang/Runtime/loadLibrary/Target.java
|
||||
new file mode 100644
|
||||
index 0000000000..fc51481053
|
||||
--- /dev/null
|
||||
+++ b/jdk/test/java/lang/Runtime/loadLibrary/Target.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2019, Azul Systems, Inc. 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.
|
||||
+ */
|
||||
+
|
||||
+class Target {
|
||||
+ static {
|
||||
+ try {
|
||||
+ System.loadLibrary("someLibrary");
|
||||
+ throw new RuntimeException("someLibrary was loaded");
|
||||
+ } catch (UnsatisfiedLinkError e) {
|
||||
+ // expected: we do not have a someLibrary
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
diff --git a/jdk/test/java/lang/Runtime/loadLibrary/Target2.java b/jdk/test/java/lang/Runtime/loadLibrary/Target2.java
|
||||
new file mode 100644
|
||||
index 0000000000..bc8dfc5e63
|
||||
--- /dev/null
|
||||
+++ b/jdk/test/java/lang/Runtime/loadLibrary/Target2.java
|
||||
@@ -0,0 +1,29 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2019, Azul Systems, Inc. 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.
|
||||
+ */
|
||||
+
|
||||
+class Target2 {
|
||||
+ static {
|
||||
+ System.loadLibrary("awt");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
From d73c61c26fd00e3cb8daa24fa254b756c48309ca Mon Sep 17 00:00:00 2001
|
||||
From: wanghuang <wanghuang3@huawei.com>
|
||||
Date: Sun, 29 Sep 2019 15:57:24 +0000
|
||||
Subject: [PATCH] 8231988: Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop
|
||||
|
||||
Summary: Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop
|
||||
LLT:
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8231988
|
||||
---
|
||||
hotspot/src/share/vm/opto/loopTransform.cpp | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp
|
||||
index caf7a9b758..c7bb19763c 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopTransform.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp
|
||||
@@ -2215,6 +2215,12 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
|
||||
// We also need to replace the original limit to collapse loop exit.
|
||||
Node* cmp = cl->loopexit()->cmp_node();
|
||||
assert(cl->limit() == cmp->in(2), "sanity");
|
||||
+ if (cmp->outcnt() > 1) { //we have more than one BoolNode here
|
||||
+ cmp = cmp->clone();
|
||||
+ cmp = phase->_igvn.register_new_node_with_optimizer(cmp);
|
||||
+ BoolNode *bl = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool();
|
||||
+ phase->_igvn.replace_input_of(bl, 1, cmp); // put BoolNode on worklist
|
||||
+ }
|
||||
phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist
|
||||
phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist
|
||||
}
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From 485dd83220fa3f41b979d5f6bc3fe5866f673ca7 Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
Date: Mon, 11 Nov 2019 14:18:42 +0000
|
||||
Subject: [PATCH] 8233839-aarch64: missing memory barrier in NewObjectArrayStub
|
||||
and NewTypeArrayStub
|
||||
|
||||
Summary: aarch64: missing memory barrier in NewObjectArrayStub and NewTypeArrayStub
|
||||
LLT: org.openjdk.jcstress.tests.defaultValues.arrays.small.plain.StringTest
|
||||
Patch Type: backport
|
||||
Bug url: https://bugs.openjdk.java.net/browse/JDK-8233839
|
||||
---
|
||||
hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp
|
||||
index 20a35432d1..c1e48ac97c 100644
|
||||
--- a/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp
|
||||
+++ b/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp
|
||||
@@ -877,6 +877,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ sub(arr_size, arr_size, t1); // body length
|
||||
__ add(t1, t1, obj); // body start
|
||||
__ initialize_body(t1, arr_size, 0, t2);
|
||||
+ __ membar(Assembler::StoreStore);
|
||||
__ verify_oop(obj);
|
||||
|
||||
__ ret(lr);
|
||||
@@ -905,6 +906,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ sub(arr_size, arr_size, t1); // body length
|
||||
__ add(t1, t1, obj); // body start
|
||||
__ initialize_body(t1, arr_size, 0, t2);
|
||||
+ __ membar(Assembler::StoreStore);
|
||||
__ verify_oop(obj);
|
||||
|
||||
__ ret(lr);
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -33,7 +33,7 @@ index d8d1ec11ba..645b690dae 100644
|
||||
- else
|
||||
- size += 176;
|
||||
+ } else {
|
||||
+ // itable code size limit, see issue
|
||||
+ // itable code size limit
|
||||
+ size += 192;
|
||||
+ }
|
||||
return size;
|
||||
|
||||
68
Add-ability-to-configure-third-port-for-remote-JMX.patch
Normal file
68
Add-ability-to-configure-third-port-for-remote-JMX.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From b3b4fb064edf3a9537e5580dfaec69761b49f717 Mon Sep 17 00:00:00 2001
|
||||
From: hedongbo <hedongbo@huawei.com>
|
||||
Date: Mon, 6 Jan 2020 15:49:40 +0000
|
||||
Subject: [PATCH] Add ability to configure third port for remote JMX
|
||||
|
||||
Summary: <jmx>:<Add ability to configure third port for remote JMX>
|
||||
LLT: NA
|
||||
Bug url: NA
|
||||
---
|
||||
.../sun/management/AgentConfigurationError.java | 2 ++
|
||||
.../sun/management/jmxremote/ConnectorBootstrap.java | 19 ++++++++++++++++++-
|
||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/jdk/src/share/classes/sun/management/AgentConfigurationError.java b/jdk/src/share/classes/sun/management/AgentConfigurationError.java
|
||||
index 56c4301611..d3d67ff313 100644
|
||||
--- a/jdk/src/share/classes/sun/management/AgentConfigurationError.java
|
||||
+++ b/jdk/src/share/classes/sun/management/AgentConfigurationError.java
|
||||
@@ -55,6 +55,8 @@ public class AgentConfigurationError extends Error {
|
||||
"agent.err.invalid.jmxremote.port";
|
||||
public static final String INVALID_JMXREMOTE_RMI_PORT =
|
||||
"agent.err.invalid.jmxremote.rmi.port";
|
||||
+ public static final String INVALID_JMXLOCAL_PORT =
|
||||
+ "agent.err.invalid.jmxlocal.port";
|
||||
public static final String PASSWORD_FILE_NOT_SET =
|
||||
"agent.err.password.file.notset";
|
||||
public static final String PASSWORD_FILE_NOT_READABLE =
|
||||
diff --git a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
|
||||
index 56287edbd0..0a82c65d10 100644
|
||||
--- a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
|
||||
+++ b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
|
||||
@@ -117,6 +117,8 @@ public final class ConnectorBootstrap {
|
||||
"com.sun.management.jmxremote.host";
|
||||
public static final String RMI_PORT =
|
||||
"com.sun.management.jmxremote.rmi.port";
|
||||
+ public static final String LOCAL_PORT =
|
||||
+ "com.sun.management.jmxlocal.port";
|
||||
public static final String CONFIG_FILE_NAME =
|
||||
"com.sun.management.config.file";
|
||||
public static final String USE_LOCAL_ONLY =
|
||||
@@ -530,9 +532,24 @@ public final class ConnectorBootstrap {
|
||||
localhost = "127.0.0.1";
|
||||
}
|
||||
|
||||
+ // User can specify a port to be used to start Local Connector Server,
|
||||
+ // if port is not specified random one will be allocated.
|
||||
+ int localPort = 0;
|
||||
+ String localPortStr = System.getProperty(PropertyNames.LOCAL_PORT);
|
||||
+ try {
|
||||
+ if (localPortStr != null) {
|
||||
+ localPort = Integer.parseInt(localPortStr);
|
||||
+ }
|
||||
+ } catch (NumberFormatException x) {
|
||||
+ throw new AgentConfigurationError(INVALID_JMXLOCAL_PORT, x, localPortStr);
|
||||
+ }
|
||||
+ if (localPort < 0) {
|
||||
+ throw new AgentConfigurationError(INVALID_JMXLOCAL_PORT, localPortStr);
|
||||
+ }
|
||||
+
|
||||
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||
try {
|
||||
- JMXServiceURL url = new JMXServiceURL("rmi", localhost, 0);
|
||||
+ JMXServiceURL url = new JMXServiceURL("rmi", localhost, localPort);
|
||||
// Do we accept connections from local interfaces only?
|
||||
Properties props = Agent.getManagementProperties();
|
||||
if (props == null) {
|
||||
--
|
||||
2.12.3
|
||||
|
||||
58
PS-GC-adding-acquire_size-method-for-PSParallelCompa.patch
Normal file
58
PS-GC-adding-acquire_size-method-for-PSParallelCompa.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 8f0acd949be2c01c445e402ae81421d4554f7d2b Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
Date: Fri, 13 Dec 2019 12:02:23 +0000
|
||||
Subject: [PATCH] PS GC: adding acquire_size method for
|
||||
PSParallelCompact::mark_obj.
|
||||
|
||||
Summary: GC: adding acquire_size method for PSParallelCompact::mark_obj.
|
||||
LLT: NA
|
||||
Bug url:
|
||||
---
|
||||
.../share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp | 2 +-
|
||||
hotspot/src/share/vm/oops/oop.hpp | 1 +
|
||||
hotspot/src/share/vm/oops/oop.inline.hpp | 4 ++++
|
||||
3 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
|
||||
index 881f380cea..f971383a09 100644
|
||||
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
|
||||
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
|
||||
@@ -1326,7 +1326,7 @@ class PSParallelCompact : AllStatic {
|
||||
};
|
||||
|
||||
inline bool PSParallelCompact::mark_obj(oop obj) {
|
||||
- const int obj_size = obj->size();
|
||||
+ const int obj_size = obj->acquire_size();
|
||||
if (mark_bitmap()->mark_obj(obj, obj_size)) {
|
||||
_summary_data.add_obj(obj, obj_size);
|
||||
return true;
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp
|
||||
index 142ab2769c..42ad9307f7 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.hpp
|
||||
@@ -123,6 +123,7 @@ class oopDesc {
|
||||
|
||||
// Returns the actual oop size of the object
|
||||
int size();
|
||||
+ int acquire_size();
|
||||
|
||||
// Sometimes (for complicated concurrency-related reasons), it is useful
|
||||
// to be able to figure out the size of an object knowing its klass.
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
index b519d86118..803080c9e7 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
@@ -839,6 +839,10 @@ inline int oopDesc::size() {
|
||||
return size_given_klass(klass());
|
||||
}
|
||||
|
||||
+inline int oopDesc::acquire_size() {
|
||||
+ return size_given_klass(klass_or_null_acquire());
|
||||
+}
|
||||
+
|
||||
inline void update_barrier_set(void* p, oop v, bool release = false) {
|
||||
assert(oopDesc::bs() != NULL, "Uninitialized bs in oop!");
|
||||
oopDesc::bs()->write_ref_field(p, v, release);
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -6,7 +6,6 @@ Subject: [PATCH] Reduce the probability of the crash related to
|
||||
|
||||
Summary: <interpreter>: add load acquire barriers when profiling klass
|
||||
LLT:
|
||||
Patch Type: huawei
|
||||
Bug url:
|
||||
---
|
||||
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 10 ++++++++++
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
From 6b96a97e8e04d62f4ab4b03c05682765516c0872 Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
Date: Mon, 23 Sep 2019 10:43:46 +0000
|
||||
Subject: [PATCH] X500Name implemation change to avoid OOM
|
||||
|
||||
Summary: X500Name implemation change.
|
||||
LLT:
|
||||
bug link:
|
||||
---
|
||||
jdk/src/share/classes/sun/security/x509/X500Name.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/jdk/src/share/classes/sun/security/x509/X500Name.java b/jdk/src/share/classes/sun/security/x509/X500Name.java
|
||||
index 447395c503..2062dc9747 100644
|
||||
--- a/jdk/src/share/classes/sun/security/x509/X500Name.java
|
||||
+++ b/jdk/src/share/classes/sun/security/x509/X500Name.java
|
||||
@@ -1108,7 +1108,7 @@ public class X500Name implements GeneralNameInterface, Principal {
|
||||
* and speed recognition of common X.500 attributes.
|
||||
*/
|
||||
static ObjectIdentifier intern(ObjectIdentifier oid) {
|
||||
- ObjectIdentifier interned = internedOIDs.putIfAbsent(oid, oid);
|
||||
+ ObjectIdentifier interned = internedOIDs.getOrDefault(oid, oid);
|
||||
return (interned == null) ? oid : interned;
|
||||
}
|
||||
|
||||
--
|
||||
2.12.3
|
||||
|
||||
Binary file not shown.
@ -1,608 +0,0 @@
|
||||
From 455904c69b9f3e7590559d7f3367bc4518fea74d Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
Date: Fri, 19 Apr 2019 22:40:50 +0000
|
||||
Subject: [PATCH] delete read/write barriers in ShenandoahGC
|
||||
|
||||
---
|
||||
hotspot/src/share/vm/oops/oop.hpp | 16 +-
|
||||
hotspot/src/share/vm/oops/oop.inline.hpp | 399 +++++++++++++++++------
|
||||
hotspot/src/share/vm/runtime/globals.hpp | 7 +-
|
||||
3 files changed, 311 insertions(+), 111 deletions(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp
|
||||
index 7e31327a2b..a9461b45ba 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.hpp
|
||||
@@ -70,14 +70,22 @@ class oopDesc {
|
||||
|
||||
public:
|
||||
markOop mark() const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return p->_mark;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return p->_mark;
|
||||
+ } else {
|
||||
+ return _mark;
|
||||
+ }
|
||||
}
|
||||
markOop* mark_addr() const { return (markOop*) &_mark; }
|
||||
|
||||
void set_mark(volatile markOop m) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- p->_mark = m;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ p->_mark = m;
|
||||
+ } else {
|
||||
+ _mark = m;
|
||||
+ }
|
||||
}
|
||||
|
||||
void set_mark_raw(volatile markOop m) {
|
||||
diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
index 93a803e830..e0ebd1edcf 100644
|
||||
--- a/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp
|
||||
@@ -65,13 +65,21 @@
|
||||
// We need a separate file to avoid circular references
|
||||
|
||||
inline void oopDesc::release_set_mark(markOop m) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store_ptr(&p->_mark, m);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store_ptr(&p->_mark, m);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store_ptr(&_mark, m);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- return (markOop) Atomic::cmpxchg_ptr(new_mark, &p->_mark, old_mark);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ return (markOop) Atomic::cmpxchg_ptr(new_mark, &p->_mark, old_mark);
|
||||
+ } else {
|
||||
+ return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline Klass* oopDesc::klass() const {
|
||||
@@ -307,10 +315,16 @@ inline oop oopDesc::atomic_exchange_oop(oop exchange_value, volatile HeapWord *d
|
||||
// In order to put or get a field out of an instance, must first check
|
||||
// if the field has been compressed and uncompress it.
|
||||
inline oop oopDesc::obj_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return UseCompressedOops ?
|
||||
- load_decode_heap_oop(p->obj_field_addr<narrowOop>(offset)) :
|
||||
- load_decode_heap_oop(p->obj_field_addr<oop>(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return UseCompressedOops ?
|
||||
+ load_decode_heap_oop(p->obj_field_addr<narrowOop>(offset)) :
|
||||
+ load_decode_heap_oop(p->obj_field_addr<oop>(offset));
|
||||
+ } else {
|
||||
+ return UseCompressedOops ?
|
||||
+ load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
|
||||
+ load_decode_heap_oop(obj_field_addr<oop>(offset));
|
||||
+ }
|
||||
}
|
||||
inline volatile oop oopDesc::obj_field_volatile(int offset) const {
|
||||
volatile oop value = obj_field(offset);
|
||||
@@ -318,28 +332,47 @@ inline volatile oop oopDesc::obj_field_volatile(int offset) const {
|
||||
return value;
|
||||
}
|
||||
inline void oopDesc::obj_field_put(int offset, oop value) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- value = bs()->read_barrier(value);
|
||||
- UseCompressedOops ? oop_store(p->obj_field_addr<narrowOop>(offset), value) :
|
||||
- oop_store(p->obj_field_addr<oop>(offset), value);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ value = bs()->read_barrier(value);
|
||||
+ UseCompressedOops ? oop_store(p->obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store(p->obj_field_addr<oop>(offset), value);
|
||||
+ } else {
|
||||
+ UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store(obj_field_addr<oop>(offset), value);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline Metadata* oopDesc::metadata_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return *p->metadata_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return *p->metadata_field_addr(offset);
|
||||
+ } else {
|
||||
+ return *metadata_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline void oopDesc::metadata_field_put(int offset, Metadata* value) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->metadata_field_addr(offset) = value;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->metadata_field_addr(offset) = value;
|
||||
+ } else {
|
||||
+ *metadata_field_addr(offset) = value;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline void oopDesc::obj_field_put_raw(int offset, oop value) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- value = bs()->read_barrier(value);
|
||||
- UseCompressedOops ?
|
||||
- encode_store_heap_oop(p->obj_field_addr<narrowOop>(offset), value) :
|
||||
- encode_store_heap_oop(p->obj_field_addr<oop>(offset), value);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ value = bs()->read_barrier(value);
|
||||
+ UseCompressedOops ?
|
||||
+ encode_store_heap_oop(p->obj_field_addr<narrowOop>(offset), value) :
|
||||
+ encode_store_heap_oop(p->obj_field_addr<oop>(offset), value);
|
||||
+ } else {
|
||||
+ UseCompressedOops ?
|
||||
+ encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
|
||||
+ encode_store_heap_oop(obj_field_addr<oop>(offset), value);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::obj_field_put_volatile(int offset, oop value) {
|
||||
OrderAccess::release();
|
||||
@@ -348,184 +381,342 @@ inline void oopDesc::obj_field_put_volatile(int offset, oop value) {
|
||||
}
|
||||
|
||||
inline jbyte oopDesc::byte_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return (jbyte) *p->byte_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return (jbyte) *p->byte_field_addr(offset);
|
||||
+ } else {
|
||||
+ return (jbyte) *byte_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::byte_field_put(int offset, jbyte contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->byte_field_addr(offset) = (jint) contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->byte_field_addr(offset) = (jint) contents;
|
||||
+ } else {
|
||||
+ *byte_field_addr(offset) = (jint) contents;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jboolean oopDesc::bool_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return (jboolean) *p->bool_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return (jboolean) *p->bool_field_addr(offset);
|
||||
+ } else {
|
||||
+ return (jboolean) *bool_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::bool_field_put(int offset, jboolean contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->bool_field_addr(offset) = (( (jint) contents) & 1);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->bool_field_addr(offset) = (((jint) contents) & 1);
|
||||
+ } else {
|
||||
+ *bool_field_addr(offset) = (((jint) contents) & 1);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jchar oopDesc::char_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return (jchar) *p->char_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return (jchar) *p->char_field_addr(offset);
|
||||
+ } else {
|
||||
+ return (jchar) *char_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::char_field_put(int offset, jchar contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->char_field_addr(offset) = (jint) contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->char_field_addr(offset) = (jint) contents;
|
||||
+ } else {
|
||||
+ *char_field_addr(offset) = (jint) contents;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jint oopDesc::int_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return *p->int_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return *p->int_field_addr(offset);
|
||||
+ } else {
|
||||
+ return *int_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::int_field_put(int offset, jint contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->int_field_addr(offset) = contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->int_field_addr(offset) = contents;
|
||||
+ } else {
|
||||
+ *int_field_addr(offset) = contents;
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::int_field_put_raw(int offset, jint contents) {
|
||||
*int_field_addr(offset) = contents;
|
||||
}
|
||||
|
||||
inline jshort oopDesc::short_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return (jshort) *p->short_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return (jshort) *p->short_field_addr(offset);
|
||||
+ } else {
|
||||
+ return (jshort) *short_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::short_field_put(int offset, jshort contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->short_field_addr(offset) = (jint) contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->short_field_addr(offset) = (jint) contents;
|
||||
+ } else {
|
||||
+ *short_field_addr(offset) = (jint) contents;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jlong oopDesc::long_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return *p->long_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return *p->long_field_addr(offset);
|
||||
+ } else {
|
||||
+ return *long_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::long_field_put(int offset, jlong contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->long_field_addr(offset) = contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->long_field_addr(offset) = contents;
|
||||
+ } else {
|
||||
+ *long_field_addr(offset) = contents;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jfloat oopDesc::float_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return *p->float_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return *p->float_field_addr(offset);
|
||||
+ } else {
|
||||
+ return *float_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::float_field_put(int offset, jfloat contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->float_field_addr(offset) = contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->float_field_addr(offset) = contents;
|
||||
+ } else {
|
||||
+ *float_field_addr(offset) = contents;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jdouble oopDesc::double_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return *p->double_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return *p->double_field_addr(offset);
|
||||
+ } else {
|
||||
+ return *double_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::double_field_put(int offset, jdouble contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->double_field_addr(offset) = contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->double_field_addr(offset) = contents;
|
||||
+ } else {
|
||||
+ *double_field_addr(offset) = contents;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline address oopDesc::address_field(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return *p->address_field_addr(offset);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return *p->address_field_addr(offset);
|
||||
+ } else {
|
||||
+ return *address_field_addr(offset);
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::address_field_put(int offset, address contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- *p->address_field_addr(offset) = contents;
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ *p->address_field_addr(offset) = contents;
|
||||
+ } else {
|
||||
+ *address_field_addr(offset) = contents;
|
||||
+ }
|
||||
}
|
||||
|
||||
inline oop oopDesc::obj_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return UseCompressedOops ?
|
||||
- decode_heap_oop((narrowOop)
|
||||
- OrderAccess::load_acquire(p->obj_field_addr<narrowOop>(offset)))
|
||||
- : decode_heap_oop((oop)
|
||||
- OrderAccess::load_ptr_acquire(p->obj_field_addr<oop>(offset)));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return UseCompressedOops ?
|
||||
+ decode_heap_oop((narrowOop)
|
||||
+ OrderAccess::load_acquire(p->obj_field_addr<narrowOop>(offset)))
|
||||
+ : decode_heap_oop((oop)
|
||||
+ OrderAccess::load_ptr_acquire(p->obj_field_addr<oop>(offset)));
|
||||
+ } else {
|
||||
+ return UseCompressedOops ?
|
||||
+ decode_heap_oop((narrowOop)
|
||||
+ OrderAccess::load_acquire(obj_field_addr<narrowOop>(offset)))
|
||||
+ : decode_heap_oop((oop)
|
||||
+ OrderAccess::load_ptr_acquire(obj_field_addr<oop>(offset)));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_obj_field_put(int offset, oop value) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- value = bs()->read_barrier(value);
|
||||
- UseCompressedOops ?
|
||||
- oop_store((volatile narrowOop*)p->obj_field_addr<narrowOop>(offset), value) :
|
||||
- oop_store((volatile oop*) p->obj_field_addr<oop>(offset), value);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ value = bs()->read_barrier(value);
|
||||
+ UseCompressedOops ?
|
||||
+ oop_store((volatile narrowOop*)p->obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store((volatile oop*) p->obj_field_addr<oop>(offset), value);
|
||||
+ } else {
|
||||
+ UseCompressedOops ?
|
||||
+ oop_store((volatile narrowOop*)obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store((volatile oop*) obj_field_addr<oop>(offset), value);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jbyte oopDesc::byte_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return OrderAccess::load_acquire(p->byte_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return OrderAccess::load_acquire(p->byte_field_addr(offset));
|
||||
+ } else {
|
||||
+ return OrderAccess::load_acquire(byte_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_byte_field_put(int offset, jbyte contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->byte_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->byte_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(byte_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jboolean oopDesc::bool_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return OrderAccess::load_acquire(p->bool_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return OrderAccess::load_acquire(p->bool_field_addr(offset));
|
||||
+ } else {
|
||||
+ return OrderAccess::load_acquire(bool_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_bool_field_put(int offset, jboolean contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->bool_field_addr(offset), (contents & 1));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->bool_field_addr(offset), (contents & 1));
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(bool_field_addr(offset), (contents & 1));
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jchar oopDesc::char_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return OrderAccess::load_acquire(p->char_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return OrderAccess::load_acquire(p->char_field_addr(offset));
|
||||
+ } else {
|
||||
+ return OrderAccess::load_acquire(char_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_char_field_put(int offset, jchar contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->char_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->char_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(char_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jint oopDesc::int_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return OrderAccess::load_acquire(p->int_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return OrderAccess::load_acquire(p->int_field_addr(offset));
|
||||
+ } else {
|
||||
+ return OrderAccess::load_acquire(int_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_int_field_put(int offset, jint contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->int_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->int_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(int_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jshort oopDesc::short_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return (jshort)OrderAccess::load_acquire(p->short_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return (jshort)OrderAccess::load_acquire(p->short_field_addr(offset));
|
||||
+ } else {
|
||||
+ return (jshort)OrderAccess::load_acquire(short_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_short_field_put(int offset, jshort contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->short_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->short_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(short_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jlong oopDesc::long_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return OrderAccess::load_acquire(p->long_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return OrderAccess::load_acquire(p->long_field_addr(offset));
|
||||
+ } else {
|
||||
+ return OrderAccess::load_acquire(long_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_long_field_put(int offset, jlong contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->long_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->long_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(long_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jfloat oopDesc::float_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return OrderAccess::load_acquire(p->float_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return OrderAccess::load_acquire(p->float_field_addr(offset));
|
||||
+ } else {
|
||||
+ return OrderAccess::load_acquire(float_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_float_field_put(int offset, jfloat contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->float_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->float_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(float_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline jdouble oopDesc::double_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return OrderAccess::load_acquire(p->double_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return OrderAccess::load_acquire(p->double_field_addr(offset));
|
||||
+ } else {
|
||||
+ return OrderAccess::load_acquire(double_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_double_field_put(int offset, jdouble contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store(p->double_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store(p->double_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store(double_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline address oopDesc::address_field_acquire(int offset) const {
|
||||
- oop p = bs()->read_barrier((oop) this);
|
||||
- return (address) OrderAccess::load_ptr_acquire(p->address_field_addr(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return (address) OrderAccess::load_ptr_acquire(p->address_field_addr(offset));
|
||||
+ } else {
|
||||
+ return (address) OrderAccess::load_ptr_acquire(address_field_addr(offset));
|
||||
+ }
|
||||
}
|
||||
inline void oopDesc::release_address_field_put(int offset, address contents) {
|
||||
- oop p = bs()->write_barrier(this);
|
||||
- OrderAccess::release_store_ptr(p->address_field_addr(offset), contents);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ OrderAccess::release_store_ptr(p->address_field_addr(offset), contents);
|
||||
+ } else {
|
||||
+ OrderAccess::release_store_ptr(address_field_addr(offset), contents);
|
||||
+ }
|
||||
}
|
||||
|
||||
inline int oopDesc::size_given_klass(Klass* klass) {
|
||||
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
index a45c522449..e7c1721c03 100644
|
||||
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
||||
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
||||
@@ -216,6 +216,10 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
||||
|
||||
#endif // no compilers
|
||||
|
||||
+// Since Shenandoah GC will add read/write barrier, that wii affect the
|
||||
+// performance of critical, it will disabled forcibly.
|
||||
+#define UseShenandoahGC false
|
||||
+
|
||||
// string type aliases used only in this file
|
||||
typedef const char* ccstr;
|
||||
typedef const char* ccstrlist; // represents string arguments which accumulate
|
||||
@@ -1427,9 +1431,6 @@ class CommandLineFlags {
|
||||
product(bool, UseParallelOldGC, false, \
|
||||
"Use the Parallel Old garbage collector") \
|
||||
\
|
||||
- product(bool, UseShenandoahGC, false, \
|
||||
- "Use the Shenandoah garbage collector") \
|
||||
- \
|
||||
product(uintx, HeapMaximumCompactionInterval, 20, \
|
||||
"How often should we maximally compact the heap (not allowing " \
|
||||
"any dead space)") \
|
||||
--
|
||||
2.19.0
|
||||
|
||||
@ -6,7 +6,6 @@ Subject: [PATCH] disable UseLSE on ARMv8.1 by default
|
||||
Summary: <UseLSE>: disable UseLSE by default and set UseLSE to
|
||||
experimental
|
||||
LLT: java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal
|
||||
Patch Type: huawei
|
||||
Bug url: NA
|
||||
---
|
||||
.../hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp | 2 +-
|
||||
|
||||
38
fix-incorrect-offset-for-oop-field-with-weak-memory-.patch
Normal file
38
fix-incorrect-offset-for-oop-field-with-weak-memory-.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 7c73365615f00951272310db44dec2939b91b48e Mon Sep 17 00:00:00 2001
|
||||
From: songyaofei <songyaofei2@huawei.com>
|
||||
Date: Wed, 19 Feb 2020 19:09:39 +0000
|
||||
Subject: [PATCH] fix incorrect offset for oop field with weak memory model
|
||||
|
||||
Summary: <interpreter>: add loadload membar in fast_storefield and fast_accessfield to avoid loading a incorrect offset
|
||||
LLT: N/A
|
||||
Bug url: N/A
|
||||
---
|
||||
hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
|
||||
index 5a619566ae..aa9545ee9c 100644
|
||||
--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
|
||||
+++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
|
||||
@@ -2922,6 +2922,8 @@ void TemplateTable::fast_storefield(TosState state)
|
||||
// access constant pool cache
|
||||
__ get_cache_and_index_at_bcp(r2, r1, 1);
|
||||
|
||||
+ __ membar(MacroAssembler::LoadLoad);
|
||||
+
|
||||
// test for volatile with r3
|
||||
__ ldrw(r3, Address(r2, in_bytes(base +
|
||||
ConstantPoolCacheEntry::flags_offset())));
|
||||
@@ -3013,6 +3015,9 @@ void TemplateTable::fast_accessfield(TosState state)
|
||||
|
||||
// access constant pool cache
|
||||
__ get_cache_and_index_at_bcp(r2, r1, 1);
|
||||
+
|
||||
+ __ membar(MacroAssembler::LoadLoad);
|
||||
+
|
||||
__ ldr(r1, Address(r2, in_bytes(ConstantPoolCache::base_offset() +
|
||||
ConstantPoolCacheEntry::f2_offset())));
|
||||
__ ldrw(r3, Address(r2, in_bytes(ConstantPoolCache::base_offset() +
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -22,7 +22,7 @@ index c7d34aac64..fa721facea 100644
|
||||
- return JDK_Version::is_gte_jdk17x_version() ?
|
||||
- "Oracle Corporation" : "Sun Microsystems Inc.";
|
||||
-#endif
|
||||
+ return "openEuler";
|
||||
+ return "Huawei Technologies Co., Ltd";
|
||||
}
|
||||
|
||||
|
||||
@ -35,15 +35,15 @@ index ff80b0abdd..758cfabb39 100644
|
||||
/* Third party may overwrite these values. */
|
||||
#ifndef VENDOR
|
||||
-#define VENDOR "Oracle Corporation"
|
||||
+#define VENDOR "openEuler"
|
||||
+#define VENDOR "Huawei Technologies Co., Ltd"
|
||||
#endif
|
||||
#ifndef VENDOR_URL
|
||||
-#define VENDOR_URL "http://java.oracle.com/"
|
||||
+#define VENDOR_URL "https://openeuler.org/"
|
||||
+#define VENDOR_URL "http://jdk.rnd.huawei.com/"
|
||||
#endif
|
||||
#ifndef VENDOR_URL_BUG
|
||||
-#define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/"
|
||||
+#define VENDOR_URL_BUG "https://gitee.com/openeuler/"
|
||||
+#define VENDOR_URL_BUG "http://jdk.rnd.huawei.com/"
|
||||
#endif
|
||||
|
||||
#define JAVA_MAX_SUPPORTED_VERSION 52
|
||||
|
||||
@ -167,7 +167,7 @@
|
||||
# note, following three variables are sedded from update_sources if used correctly. Hardcode them rather there.
|
||||
%global shenandoah_project aarch64-port
|
||||
%global shenandoah_repo jdk8u-shenandoah
|
||||
%global shenandoah_revision aarch64-shenandoah-jdk8u232-b09
|
||||
%global shenandoah_revision aarch64-shenandoah-jdk8u242-b08
|
||||
# Define old aarch64/jdk8u tree variables for compatibility
|
||||
%global project %{shenandoah_project}
|
||||
%global repo %{shenandoah_repo}
|
||||
@ -190,7 +190,7 @@
|
||||
# images stub
|
||||
%global jdkimage j2sdk-image
|
||||
# output dir stub
|
||||
%define buildoutputdir() %{expand:aarch64-shenandoah-jdk8u232-b09/build/jdk8.build%{?1}}
|
||||
%define buildoutputdir() %{expand:aarch64-shenandoah-jdk8u242-b08/build/jdk8.build%{?1}}
|
||||
# we can copy the javadoc to not arched dir, or make it not noarch
|
||||
%define uniquejavadocdir() %{expand:%{fullversion}%{?1}}
|
||||
# main id and dir of this jdk
|
||||
@ -427,24 +427,6 @@ exit 0
|
||||
exit 0
|
||||
}
|
||||
|
||||
%define post_javadoc_zip() %{expand:
|
||||
|
||||
PRIORITY=%{priority}
|
||||
if [ "%{?1}" == %{debug_suffix} ]; then
|
||||
let PRIORITY=PRIORITY-1
|
||||
fi
|
||||
|
||||
alternatives \\
|
||||
--install %{_javadocdir}/java-zip javadoczip %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip \\
|
||||
$PRIORITY --family %{name}
|
||||
exit 0
|
||||
}
|
||||
|
||||
%define postun_javadoc_zip() %{expand:
|
||||
alternatives --remove javadoczip %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip
|
||||
exit 0
|
||||
}
|
||||
|
||||
%define files_jre() %{expand:
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/jre/lib/%{archinstall}/libjsoundalsa.so
|
||||
%{_jvmdir}/%{sdkdir -- %{?1}}/jre/lib/%{archinstall}/libsplashscreen.so
|
||||
@ -691,12 +673,6 @@ exit 0
|
||||
%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/LICENSE
|
||||
}
|
||||
|
||||
%define files_javadoc_zip() %{expand:
|
||||
%defattr(-,root,root,-)
|
||||
%doc %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip
|
||||
%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/LICENSE
|
||||
}
|
||||
|
||||
# not-duplicated requires/provides/obsoletes for normal/debug packages
|
||||
%define java_rpo() %{expand:
|
||||
Requires: fontconfig%{?_isa}
|
||||
@ -823,7 +799,7 @@ Provides: java-%{javaver}-%{origin}-src%{?1} = %{epoch}:%{version}-%{release}
|
||||
|
||||
Name: java-%{javaver}-%{origin}
|
||||
Version: %{javaver}.%{updatever}.%{buildver}
|
||||
Release: 1.h4
|
||||
Release: 1.h5
|
||||
Epoch: 1
|
||||
Summary: %{origin_nice} Runtime Environment %{majorver}
|
||||
Group: Development/Languages
|
||||
@ -861,8 +837,6 @@ Source13: TestCryptoLevel.java
|
||||
Source14: TestECDSA.java
|
||||
|
||||
Patch1: 8160300.patch
|
||||
Patch2: 8202076.patch
|
||||
Patch7: delete-read-write-barriers-in-ShenandoahGC.patch
|
||||
Patch8: replace-vector-to-improve-performance-of-xml.validat.patch
|
||||
Patch9: AARCH64-fix-itable-stub-code-size-limit.patch
|
||||
Patch10: 8221658.patch
|
||||
@ -898,25 +872,32 @@ Patch48: 8158946-JDK-8165808-JDK-8166583-JDK-.patch
|
||||
Patch49: 8146792.patch
|
||||
Patch50: 8047212.patch
|
||||
Patch51: add-with-company-name-option.patch
|
||||
Patch52: set_HongKong_timezone_to_CTT.patch
|
||||
Patch53: 8229169.patch
|
||||
Patch54: X500Name-implemation-change-to-avoid-OOM.patch
|
||||
Patch55: 8231988.patch
|
||||
Patch56: 8160369.patch
|
||||
Patch57: 8031085.patch
|
||||
Patch58: Reduce-the-probability-of-the-crash-related-to-ciObj.patch
|
||||
Patch60: 8233839-aarch64-missing-memory-barrier-in-NewObjectA.patch
|
||||
Patch61: 8231584-Deadlock-with-ClassLoader.findLibrary-and-Sy.patch
|
||||
Patch62: 8165857-CMS-_overflow_list-is-missing-volatile-speci.patch
|
||||
Patch63: 8033552-Fix-missing-missing-volatile-specifiers-in-C.patch
|
||||
Patch64: 8182397-race-in-field-updates.patch
|
||||
Patch65: 8234264-Incorrrect-8047434-JDK-8-backport-in-8219677.patch
|
||||
Patch67: 8165860-WorkGroup-classes-are-missing-volatile-speci.patch
|
||||
Patch68: 8194154-System-property-user.dir-should-not-be-chang.patch
|
||||
Patch70: 8164948.patch
|
||||
Patch71: 8154313.patch
|
||||
Patch72: inline-optimize-for-aarch64.patch
|
||||
|
||||
# 8u242
|
||||
Patch73: PS-GC-adding-acquire_size-method-for-PSParallelCompa.patch
|
||||
Patch74: 8191915-java.lang.Math.multiplyExact-not-throw-an-ex.patch
|
||||
Patch75: Add-ability-to-configure-third-port-for-remote-JMX.patch
|
||||
Patch76: 8203196-C1-emits-incorrect-code-due-to-integer-overf.patch
|
||||
Patch77: 8190332-PngReader-throws-NegativeArraySizeException-.patch
|
||||
Patch78: 8171410-aarch64-long-multiplyExact-shifts-by-31-inst.patch
|
||||
Patch79: 8193255-Root-Certificates-should-be-stored-in-text-f.patch
|
||||
Patch80: 8227662-freetype-seeks-to-index-at-the-end-of-the-fo.patch
|
||||
Patch81: fix-incorrect-offset-for-oop-field-with-weak-memory-.patch
|
||||
Patch82: prohibition-of-irreducible-loop-in-mergers.patch
|
||||
Patch83: 8204947-Port-ShenandoahTaskTerminator-to-mainline-an.patch
|
||||
Patch84: 8205921-Optimizing-best-of-2-work-stealing-queue-sel.patch
|
||||
Patch85: 8139041-Redundant-DMB-instructions.patch
|
||||
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: automake
|
||||
BuildRequires: alsa-lib-devel
|
||||
@ -1077,19 +1058,6 @@ BuildArch: noarch
|
||||
The %{origin_nice} %{majorver} API documentation.
|
||||
%endif
|
||||
|
||||
%if %{include_normal_build}
|
||||
%package javadoc-zip
|
||||
Summary: %{origin_nice} %{majorver} API documentation compressed in single archive
|
||||
Group: Documentation
|
||||
Requires: javapackages-filesystem
|
||||
BuildArch: noarch
|
||||
|
||||
%{java_javadoc_rpo %{nil}}
|
||||
|
||||
%description javadoc-zip
|
||||
The %{origin_nice} %{majorver} API documentation compressed in single archive.
|
||||
%endif
|
||||
|
||||
%if %{include_debug_build}
|
||||
%package javadoc-slowdebug
|
||||
Summary: %{origin_nice} %{majorver} API documentation %{for_debug}
|
||||
@ -1103,19 +1071,6 @@ BuildArch: noarch
|
||||
The %{origin_nice} %{majorver} API documentation %{for_debug}.
|
||||
%endif
|
||||
|
||||
%if %{include_debug_build}
|
||||
%package javadoc-zip-slowdebug
|
||||
Summary: %{origin_nice} %{majorver} API documentation compressed in single archive %{for_debug}
|
||||
Group: Documentation
|
||||
Requires: javapackages-filesystem
|
||||
BuildArch: noarch
|
||||
|
||||
%{java_javadoc_rpo -- %{debug_suffix_unquoted}}
|
||||
|
||||
%description javadoc-zip-slowdebug
|
||||
The %{origin_nice} %{majorver} API documentation compressed in single archive %{for_debug}.
|
||||
%endif
|
||||
|
||||
%prep
|
||||
if [ %{include_normal_build} -eq 0 -o %{include_normal_build} -eq 1 ] ; then
|
||||
echo "include_normal_build is %{include_normal_build}"
|
||||
@ -1145,8 +1100,6 @@ pushd %{top_level_dir_name}
|
||||
# OpenJDK patches
|
||||
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
@ -1182,24 +1135,29 @@ pushd %{top_level_dir_name}
|
||||
%patch49 -p1
|
||||
%patch50 -p1
|
||||
%patch51 -p1
|
||||
%patch52 -p1
|
||||
%patch53 -p1
|
||||
%patch54 -p1
|
||||
%patch55 -p1
|
||||
%patch56 -p1
|
||||
%patch57 -p1
|
||||
%patch58 -p1
|
||||
%patch60 -p1
|
||||
%patch61 -p1
|
||||
%patch62 -p1
|
||||
%patch63 -p1
|
||||
%patch64 -p1
|
||||
%patch65 -p1
|
||||
%patch67 -p1
|
||||
%patch68 -p1
|
||||
%patch70 -p1
|
||||
%patch71 -p1
|
||||
%patch72 -p1
|
||||
%patch73 -p1
|
||||
%patch74 -p1
|
||||
%patch75 -p1
|
||||
%patch76 -p1
|
||||
%patch77 -p1
|
||||
%patch78 -p1
|
||||
%patch79 -p1
|
||||
%patch80 -p1
|
||||
%patch81 -p1
|
||||
%patch82 -p1
|
||||
%patch83 -p1
|
||||
%patch84 -p1
|
||||
%patch85 -p1
|
||||
|
||||
popd
|
||||
|
||||
@ -1266,8 +1224,6 @@ make \
|
||||
SCTP_WERROR= \
|
||||
%{targets} || ( pwd; find $top_dir_abs_path -name "hs_err_pid*.log" | xargs cat && false )
|
||||
|
||||
make zip-docs
|
||||
|
||||
# the build (erroneously) removes read permissions from some jars
|
||||
# this is a regression in OpenJDK 7 (our compiler):
|
||||
# http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1437
|
||||
@ -1435,11 +1391,6 @@ popd
|
||||
# Install Javadoc documentation
|
||||
install -d -m 755 $RPM_BUILD_ROOT%{_javadocdir}
|
||||
cp -a %{buildoutputdir -- $suffix}/docs $RPM_BUILD_ROOT%{_javadocdir}/%{uniquejavadocdir -- $suffix}
|
||||
built_doc_archive=`echo "jdk-%{javaver}_%{updatever}$suffix-%{buildver}-docs.zip" | sed s/slowdebug/debug/`
|
||||
cp -a %{buildoutputdir -- $suffix}/bundles/$built_doc_archive $RPM_BUILD_ROOT%{_javadocdir}/%{uniquejavadocdir -- $suffix}.zip
|
||||
|
||||
# FIXME: remove SONAME entries from demo DSOs. See
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=436497
|
||||
|
||||
# Find non-documentation demo files.
|
||||
find $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir -- $suffix}/demo \
|
||||
@ -1540,11 +1491,6 @@ require "copy_jdk_configs.lua"
|
||||
%postun javadoc
|
||||
%{postun_javadoc %{nil}}
|
||||
|
||||
%post javadoc-zip
|
||||
%{post_javadoc_zip %{nil}}
|
||||
|
||||
%postun javadoc-zip
|
||||
%{postun_javadoc_zip %{nil}}
|
||||
%endif
|
||||
|
||||
%if %{include_debug_build}
|
||||
@ -1578,11 +1524,6 @@ require "copy_jdk_configs.lua"
|
||||
%postun javadoc-slowdebug
|
||||
%{postun_javadoc -- %{debug_suffix_unquoted}}
|
||||
|
||||
%post javadoc-zip-slowdebug
|
||||
%{post_javadoc_zip -- %{debug_suffix_unquoted}}
|
||||
|
||||
%postun javadoc-zip-slowdebug
|
||||
%{postun_javadoc_zip -- %{debug_suffix_unquoted}}
|
||||
%endif
|
||||
|
||||
%if %{include_normal_build}
|
||||
@ -1597,8 +1538,6 @@ require "copy_jdk_configs.lua"
|
||||
|
||||
%if %{include_normal_build}
|
||||
%files headless
|
||||
# important note, see https://bugzilla.redhat.com/show_bug.cgi?id=1038092 for whole issue
|
||||
# all config/noreplace files (and more) have to be declared in pretrans. See pretrans
|
||||
%{files_jre_headless %{nil}}
|
||||
|
||||
%files devel
|
||||
@ -1613,15 +1552,12 @@ require "copy_jdk_configs.lua"
|
||||
%files javadoc
|
||||
%{files_javadoc %{nil}}
|
||||
|
||||
# this puts huge file to /usr/share
|
||||
# unluckily ti is really a documentation file
|
||||
# and unluckily it really is architecture-dependent, as eg. aot and grail are now x86_64 only
|
||||
# same for debug variant
|
||||
%files javadoc-zip
|
||||
%{files_javadoc_zip %{nil}}
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Mar 20 2020 jdkboy <guoge1@huawei.com> - 1:1.8.0.242-b08.5
|
||||
- upgrade openjdk to jdk8u242-b08
|
||||
|
||||
* Tue Mar 12 2020 jdkboy <guoge1@huawei.com> - 1:1.8.0.232-b09.4
|
||||
- add inline optimize for aarch64
|
||||
|
||||
|
||||
28
prohibition-of-irreducible-loop-in-mergers.patch
Normal file
28
prohibition-of-irreducible-loop-in-mergers.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 34712f6bbc3c2c664ee641c78d4a2f8cfe427880 Mon Sep 17 00:00:00 2001
|
||||
From: zhouyong <zhouyong44@huawei.com>
|
||||
Date: Fri, 28 Feb 2020 15:17:44 +0000
|
||||
Subject: [PATCH] prohibition of irreducible loop in mergers
|
||||
|
||||
Summary: C2Compiler: irreducible loop should not enter merge_many_backedges
|
||||
LLT: NA
|
||||
Bug url: NA
|
||||
---
|
||||
hotspot/src/share/vm/opto/loopnode.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
index e2c0645cf8..bbb2e2bf98 100644
|
||||
--- a/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
+++ b/hotspot/src/share/vm/opto/loopnode.cpp
|
||||
@@ -1542,7 +1542,7 @@ bool IdealLoopTree::beautify_loops( PhaseIdealLoop *phase ) {
|
||||
// If I am a shared header (multiple backedges), peel off the many
|
||||
// backedges into a private merge point and use the merge point as
|
||||
// the one true backedge.
|
||||
- if( _head->req() > 3 ) {
|
||||
+ if( _head->req() > 3 && !_irreducible) {
|
||||
// Merge the many backedges into a single backedge but leave
|
||||
// the hottest backedge as separate edge for the following peel.
|
||||
merge_many_backedges( phase );
|
||||
--
|
||||
2.12.3
|
||||
|
||||
@ -1,268 +0,0 @@
|
||||
From 09d4f8a17aff883e7937c048a2da6bcf3feb7894 Mon Sep 17 00:00:00 2001
|
||||
From: wangshuai <wangshuai94@huawei.com>
|
||||
Date: Thu, 5 Sep 2019 21:45:57 +0000
|
||||
Subject: [PATCH]
|
||||
|
||||
Summary: The timezone of HongKong is different from that of other cities in China.
|
||||
LLT: Local passed the jcstress and JTREG
|
||||
Bug url:
|
||||
|
||||
---
|
||||
jdk/src/share/classes/sun/util/resources/TimeZoneNames.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java | 4 ++--
|
||||
jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java | 4 ++--
|
||||
11 files changed, 22 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java
|
||||
index 2c4b56da7e..27526e3928 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java
|
||||
@@ -634,7 +634,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Hovd Time", "HOVT",
|
||||
"Hovd Summer Time", "HOVST",
|
||||
"Hovd Time", "HOVT"}},
|
||||
@@ -864,7 +864,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java b/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
|
||||
index e258618c9d..b8e3dde8ea 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Hovd Zeit", "HOVT",
|
||||
"Hovd Sommerzeit", "HOVST",
|
||||
"Hovd Zeit", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java b/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
|
||||
index ea8887e139..93b24d893e 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Hora de Hovd", "HOVT",
|
||||
"Hora de verano de Hovd", "HOVST",
|
||||
"Hora de Hovd", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java b/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
|
||||
index 58891022d3..f443a028d1 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Heure de Hovd", "HOVT",
|
||||
"Heure d'\u00e9t\u00e9 de Hovd", "HOVST",
|
||||
"Heure de Hovd", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java b/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
|
||||
index 53ab4a6d73..fecfc9474e 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Ora di Hovd", "HOVT",
|
||||
"Ora estiva di Hovd", "HOVST",
|
||||
"Ora di Hovd", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java b/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
|
||||
index 8bec0d7db0..7af8ffc042 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"\u30db\u30d6\u30c9\u6642\u9593", "HOVT",
|
||||
"\u30db\u30d6\u30c9\u590f\u6642\u9593", "HOVST",
|
||||
"\u30DB\u30D6\u30C9\u6642\u9593", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java b/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
|
||||
index 7c72073b73..d8b90b4d3e 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Hovd \uc2dc\uac04", "HOVT",
|
||||
"Hovd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "HOVST",
|
||||
"\uD638\uBE0C\uB4DC \uD45C\uC900\uC2DC", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java b/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
|
||||
index c65dfa5da7..a202fec6b9 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Fuso hor\u00e1rio de Hovd", "HOVT",
|
||||
"Fuso hor\u00e1rio de ver\u00e3o de Hovd", "HOVST",
|
||||
"Hor\u00E1rio de Hovd", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java b/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
|
||||
index 6ce81e8011..dcaaf6ddeb 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"Hovd, normaltid", "HOVT",
|
||||
"Hovd, sommartid", "HOVST",
|
||||
"Hovd-tid", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
|
||||
index 3e81b6b42c..9360808ca5 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"\u79d1\u5e03\u591a\u65f6\u95f4", "HOVT",
|
||||
"\u79d1\u5e03\u591a\u590f\u4ee4\u65f6", "HOVST",
|
||||
"\u79D1\u5E03\u591A\u65F6\u95F4", "HOVT"}},
|
||||
@@ -862,7 +862,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
diff --git a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
|
||||
index 0233a53f4f..1bfcee78d5 100644
|
||||
--- a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
|
||||
+++ b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
|
||||
@@ -635,7 +635,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle {
|
||||
{"Asia/Harbin", CTT},
|
||||
{"Asia/Hebron", EET},
|
||||
{"Asia/Ho_Chi_Minh", ICT},
|
||||
- {"Asia/Hong_Kong", HKT},
|
||||
+ {"Asia/Hong_Kong", CTT},
|
||||
{"Asia/Hovd", new String[] {"\u4faf\u5fb7 (Hovd) \u6642\u9593", "HOVT",
|
||||
"\u4faf\u5fb7 (Hovd) \u590f\u4ee4\u6642\u9593", "HOVST",
|
||||
"\u4FAF\u5FB7 (Hovd) \u6642\u9593", "HOVT"}},
|
||||
@@ -864,7 +864,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle {
|
||||
{"GB", GMTBST},
|
||||
{"GB-Eire", GMTBST},
|
||||
{"Greenwich", GMT},
|
||||
- {"Hongkong", HKT},
|
||||
+ {"Hongkong", CTT},
|
||||
{"Iceland", GMT},
|
||||
{"Iran", IRT},
|
||||
{"IST", IST},
|
||||
--
|
||||
2.12.3
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user