upgrade to aarch64-shenandoah-jdk8u242-b08

This commit is contained in:
jdkboy 2020-03-20 23:16:56 +08:00 committed by Zhipeng Xie
parent f128e41137
commit dda01ec71b
31 changed files with 6243 additions and 1860 deletions

View 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

View File

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

View File

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

View File

@ -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 ++-
.../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, 104 insertions(+), 64 deletions(-)
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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View File

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

View 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

View File

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

View 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

View 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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View 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

View File

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