Initial build from OpenJDK 11.0.6

This commit is contained in:
jvmboy 2020-04-26 19:46:07 +08:00
commit a935af4ab7
21 changed files with 16514 additions and 0 deletions

View File

@ -0,0 +1,184 @@
From 476ec6be3f75c70c50bd1552c624abca098ddba2 Mon Sep 17 00:00:00 2001
Date: Wed, 18 Mar 2020 10:25:06 +0000
Subject: [PATCH] 8209375: ZGC: Use dynamic base address for mark stack space
Summary: <gc>: <mark stack needs atomic change>
LLT: jdk11u/test/hotspot/jtreg/vmTestbase/gc/gctests/SoftReference/soft004/soft004.java
Bug url: https://bugs.openjdk.java.net/browse/JDK-8209375
---
src/hotspot/share/gc/z/zGlobals.hpp | 7 +---
src/hotspot/share/gc/z/zMarkStack.cpp | 74 +++++++++++++++--------------------
src/hotspot/share/gc/z/zMarkStack.hpp | 1 +
src/hotspot/share/gc/z/z_globals.hpp | 6 +--
4 files changed, 38 insertions(+), 50 deletions(-)
diff --git a/src/hotspot/share/gc/z/zGlobals.hpp b/src/hotspot/share/gc/z/zGlobals.hpp
index 080ea5c0e..0f9e9dcb4 100644
--- a/src/hotspot/share/gc/z/zGlobals.hpp
+++ b/src/hotspot/share/gc/z/zGlobals.hpp
@@ -117,11 +117,8 @@ extern uintptr_t ZAddressWeakBadMask;
// Marked state
extern uintptr_t ZAddressMetadataMarked;
-// Address space for mark stack allocations
-const size_t ZMarkStackSpaceSizeShift = 40; // 1TB
-const size_t ZMarkStackSpaceSize = (size_t)1 << ZMarkStackSpaceSizeShift;
-const uintptr_t ZMarkStackSpaceStart = ZAddressSpaceEnd + ZMarkStackSpaceSize;
-const uintptr_t ZMarkStackSpaceEnd = ZMarkStackSpaceStart + ZMarkStackSpaceSize;
+// Mark stack space
+extern uintptr_t ZMarkStackSpaceStart;
const size_t ZMarkStackSpaceExpandSize = (size_t)1 << 25; // 32M
// Mark stack and magazine sizes
diff --git a/src/hotspot/share/gc/z/zMarkStack.cpp b/src/hotspot/share/gc/z/zMarkStack.cpp
index 52fe51ece..9cc768956 100644
--- a/src/hotspot/share/gc/z/zMarkStack.cpp
+++ b/src/hotspot/share/gc/z/zMarkStack.cpp
@@ -28,58 +28,44 @@
#include "gc/z/zMarkStack.inline.hpp"
#include "logging/log.hpp"
#include "runtime/atomic.hpp"
+#include "runtime/os.hpp"
#include "utilities/debug.hpp"
-#include <sys/mman.h>
-#include <sys/types.h>
+uintptr_t ZMarkStackSpaceStart;
ZMarkStackSpace::ZMarkStackSpace() :
_expand_lock(),
+ _start(0),
_top(0),
_end(0) {
- assert(ZMarkStacksMax >= ZMarkStackSpaceExpandSize, "ZMarkStacksMax too small");
- assert(ZMarkStacksMax <= ZMarkStackSpaceSize, "ZMarkStacksMax too large");
-
+ assert(ZMarkStackSpaceLimit >= ZMarkStackSpaceExpandSize, "ZMarkStackSpaceLimit too small");
// Reserve address space
- const void* res = mmap((void*)ZMarkStackSpaceStart, ZMarkStackSpaceSize,
- PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
- if (res != (void*)ZMarkStackSpaceStart) {
- log_error(gc, marking)("Failed to reserve address space for marking stacks");
+ const size_t size = ZMarkStackSpaceLimit;
+ const size_t alignment = (size_t)os::vm_allocation_granularity();
+ const uintptr_t addr = (uintptr_t)os::reserve_memory(size, NULL, alignment, mtGC);
+ if (addr == 0) {
+ log_error(gc, marking)("Failed to reserve address space for mark stacks");
return;
}
// Successfully initialized
- _top = _end = ZMarkStackSpaceStart;
-}
+ _start = _top = _end = addr;
-bool ZMarkStackSpace::is_initialized() const {
- return _top != 0;
+ // Register mark stack space start
+ ZMarkStackSpaceStart = _start;
}
-bool ZMarkStackSpace::expand() {
- const size_t max = ZMarkStackSpaceStart + ZMarkStacksMax;
- if (_end + ZMarkStackSpaceExpandSize > max) {
- // Expansion limit reached
- return false;
- }
-
- void* const res = mmap((void*)_end, ZMarkStackSpaceExpandSize,
- PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
- if (res == MAP_FAILED) {
- ZErrno err;
- log_error(gc, marking)("Failed to map memory for marking stacks (%s)", err.to_string());
- return false;
- }
-
- return true;
+bool ZMarkStackSpace::is_initialized() const {
+ return _start != 0;
}
uintptr_t ZMarkStackSpace::alloc_space(size_t size) {
- uintptr_t top = _top;
+ uintptr_t top = Atomic::load(&_top);
for (;;) {
+ const uintptr_t end = Atomic::load(&_end);
const uintptr_t new_top = top + size;
- if (new_top > _end) {
+ if (new_top > end) {
// Not enough space left
return 0;
}
@@ -104,24 +90,28 @@ uintptr_t ZMarkStackSpace::expand_and_alloc_space(size_t size) {
return addr;
}
- // Expand stack space
- if (!expand()) {
- // We currently can't handle the situation where we
- // are running out of mark stack space.
- fatal("Mark stack overflow (allocated " SIZE_FORMAT "M, size " SIZE_FORMAT "M, max " SIZE_FORMAT "M),"
- " use -XX:ZMarkStacksMax=? to increase this limit",
- (_end - ZMarkStackSpaceStart) / M, size / M, ZMarkStacksMax / M);
- return 0;
+ // Check expansion limit
+ const size_t expand_size = ZMarkStackSpaceExpandSize;
+ const size_t old_size = _end - _start;
+ const size_t new_size = old_size + expand_size;
+ if (new_size > ZMarkStackSpaceLimit) {
+ // Expansion limit reached. This is a fatal error since we
+ // currently can't recover from running out of mark stack space.
+ fatal("Mark stack space exhausted. Use -XX:ZMarkStackSpaceLimit=<size> to increase the "
+ "maximum number of bytes allocated for mark stacks. Current limit is " SIZE_FORMAT "M.",
+ ZMarkStackSpaceLimit / M);
}
log_debug(gc, marking)("Expanding mark stack space: " SIZE_FORMAT "M->" SIZE_FORMAT "M",
- (_end - ZMarkStackSpaceStart) / M,
- (_end - ZMarkStackSpaceStart + ZMarkStackSpaceExpandSize) / M);
+ old_size / M, new_size / M);
+
+ // Expand
+ os::commit_memory_or_exit((char*)_end, expand_size, false /* executable */, "Mark stack space");
// Increment top before end to make sure another
// thread can't steal out newly expanded space.
addr = Atomic::add(size, &_top) - size;
- _end += ZMarkStackSpaceExpandSize;
+ Atomic::add(expand_size, &_end);
return addr;
}
diff --git a/src/hotspot/share/gc/z/zMarkStack.hpp b/src/hotspot/share/gc/z/zMarkStack.hpp
index b68b9faa3..12f3e4eca 100644
--- a/src/hotspot/share/gc/z/zMarkStack.hpp
+++ b/src/hotspot/share/gc/z/zMarkStack.hpp
@@ -76,6 +76,7 @@ typedef ZStackList<ZMarkStackMagazine> ZMarkStackMagazineList;
class ZMarkStackSpace {
private:
ZLock _expand_lock;
+ uintptr_t _start;
volatile uintptr_t _top;
volatile uintptr_t _end;
diff --git a/src/hotspot/share/gc/z/z_globals.hpp b/src/hotspot/share/gc/z/z_globals.hpp
index 9e0f8985b..8cee59be7 100644
--- a/src/hotspot/share/gc/z/z_globals.hpp
+++ b/src/hotspot/share/gc/z/z_globals.hpp
@@ -53,9 +53,9 @@
"Allow Java threads to stall and wait for GC to complete " \
"instead of immediately throwing an OutOfMemoryError") \
\
- product(size_t, ZMarkStacksMax, NOT_LP64(512*M) LP64_ONLY(8*G), \
- "Maximum number of bytes allocated for marking stacks") \
- range(32*M, NOT_LP64(512*M) LP64_ONLY(1024*G)) \
+ product(size_t, ZMarkStackSpaceLimit, 8*G, \
+ "Maximum number of bytes allocated for mark stacks") \
+ range(32*M, 1024*G) \
\
product(uint, ZCollectionInterval, 0, \
"Force GC at a fixed time interval (in seconds)") \
--
2.12.3

View File

@ -0,0 +1,94 @@
From 7ca249ae82c6b6c60c524781806f9d12ef3f8f98 Mon Sep 17 00:00:00 2001
Date: Mon, 16 Mar 2020 16:24:43 +0800
Subject: [PATCH] 8209894: ZGC: Cap number of GC workers based on heap size
Summary: <gc>: <cap number of GC workers based on heap size>
LLT: jdk11u/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/disableCollection/disablecollection002/TestDescription.java
Bug url: https://bugs.openjdk.java.net/browse/JDK-8209894
---
src/hotspot/share/gc/z/zWorkers.cpp | 23 ++++++++++++++++++-----
src/hotspot/share/gc/z/zWorkers.hpp | 4 +---
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/hotspot/share/gc/z/zWorkers.cpp b/src/hotspot/share/gc/z/zWorkers.cpp
index 0686ec7af..6a0c2561d 100644
--- a/src/hotspot/share/gc/z/zWorkers.cpp
+++ b/src/hotspot/share/gc/z/zWorkers.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -22,14 +22,27 @@
*/
#include "precompiled.hpp"
+#include "gc/z/zGlobals.hpp"
#include "gc/z/zTask.hpp"
#include "gc/z/zWorkers.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
-uint ZWorkers::calculate_ncpus(double share_in_percent) {
- return ceil(os::initial_active_processor_count() * share_in_percent / 100.0);
+static uint calculate_nworkers_based_on_ncpus(double cpu_share_in_percent) {
+ return ceil(os::initial_active_processor_count() * cpu_share_in_percent / 100.0);
+}
+
+static uint calculate_nworkers_based_on_heap_size(double reserve_share_in_percent) {
+ const int nworkers = ((MaxHeapSize * (reserve_share_in_percent / 100.0)) - ZPageSizeMedium) / ZPageSizeSmall;
+ return MAX2(nworkers, 1);
+}
+
+static uint calculate_nworkers(double cpu_share_in_percent) {
+ // Cap number of workers so that we never use more than 10% of the max heap
+ // for the reserve. This is useful when using small heaps on large machines.
+ return MIN2(calculate_nworkers_based_on_ncpus(cpu_share_in_percent),
+ calculate_nworkers_based_on_heap_size(10.0));
}
uint ZWorkers::calculate_nparallel() {
@@ -38,7 +51,7 @@ uint ZWorkers::calculate_nparallel() {
// close to the number of processors tends to lead to over-provisioning and
// scheduling latency issues. Using 60% of the active processors appears to
// be a fairly good balance.
- return calculate_ncpus(60.0);
+ return calculate_nworkers(60.0);
}
uint ZWorkers::calculate_nconcurrent() {
@@ -48,7 +61,7 @@ uint ZWorkers::calculate_nconcurrent() {
// throughput, while using too few threads will prolong the GC-cycle and
// we then risk being out-run by the application. Using 12.5% of the active
// processors appears to be a fairly good balance.
- return calculate_ncpus(12.5);
+ return calculate_nworkers(12.5);
}
class ZWorkersWarmupTask : public ZTask {
diff --git a/src/hotspot/share/gc/z/zWorkers.hpp b/src/hotspot/share/gc/z/zWorkers.hpp
index 36a3c61fd..6ce09c447 100644
--- a/src/hotspot/share/gc/z/zWorkers.hpp
+++ b/src/hotspot/share/gc/z/zWorkers.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -34,8 +34,6 @@ private:
bool _boost;
WorkGang _workers;
- static uint calculate_ncpus(double share_in_percent);
-
void run(ZTask* task, uint nworkers);
public:
--
2.12.3

View File

@ -0,0 +1,73 @@
From 557d2ea5560c2d0e9cae7f9a792329dfc5cb9573 Mon Sep 17 00:00:00 2001
Date: Fri, 29 Nov 2019 18:03:11 +0000
Subject: [PATCH] 8214345: infinite recursion while checking super class
Summary: <javac>: infinite recursion while checking super class
LLT: ClassBoundCheckingOverflow.java ClassBoundCheckingOverflow.out
Bug url: https://bugs.openjdk.java.net/browse/JDK-8214345
---
.../share/classes/com/sun/tools/javac/comp/Check.java | 5 ++++-
.../tools/javac/generics/ClassBoundCheckingOverflow.java | 12 ++++++++++++
.../tools/javac/generics/ClassBoundCheckingOverflow.out | 3 +++
3 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.java
create mode 100644 test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.out
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
index 90cb9d189..b1f4abcb6 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -2716,6 +2716,8 @@ public class Check {
if (type.isErroneous()) return;
for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
Type it = l.head;
+ if (type.hasTag(CLASS) && !it.hasTag(CLASS)) continue; // JLS 8.1.5
+
Type oldit = seensofar.put(it.tsym, it);
if (oldit != null) {
List<Type> oldparams = oldit.allparams();
@@ -2729,6 +2731,7 @@ public class Check {
checkClassBounds(pos, seensofar, it);
}
Type st = types.supertype(type);
+ if (type.hasTag(CLASS) && !st.hasTag(CLASS)) return; // JLS 8.1.4
if (st != Type.noType) checkClassBounds(pos, seensofar, st);
}
diff --git a/test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.java b/test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.java
new file mode 100644
index 000000000..1aeb7d71a
--- /dev/null
+++ b/test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.java
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8214345
+ * @summary infinite recursion while checking super class
+ *
+ * @compile/fail/ref=ClassBoundCheckingOverflow.out -XDrawDiagnostics ClassBoundCheckingOverflow.java
+ */
+
+public class ClassBoundCheckingOverflow {
+ abstract class InfiniteLoop1<E extends InfiniteLoop1<E>> extends E {}
+ abstract class InfiniteLoop2<E extends InfiniteLoop2<E>> implements E {}
+}
diff --git a/test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.out b/test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.out
new file mode 100644
index 000000000..bed6acfd7
--- /dev/null
+++ b/test/langtools/tools/javac/generics/ClassBoundCheckingOverflow.out
@@ -0,0 +1,3 @@
+ClassBoundCheckingOverflow.java:10:70: compiler.err.type.found.req: (compiler.misc.type.parameter: E), (compiler.misc.type.req.class)
+ClassBoundCheckingOverflow.java:11:73: compiler.err.type.found.req: (compiler.misc.type.parameter: E), (compiler.misc.type.req.class)
+2 errors
--
2.12.3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,924 @@
From 12c28e19bf70b610a723828ce8395902381436fb Mon Sep 17 00:00:00 2001
Date: Tue, 18 Feb 2020 18:03:42 +0800
Subject: [PATCH] 8217856: ZGC: Break out C2 matching rules into separate AD
file
Summary: <gc>: <separate AD files to handle C2 matching rules>
LLT: jtreg
Bug url: https://bugs.openjdk.java.net/browse/JDK-8217856
---
make/hotspot/gensrc/GensrcAdlc.gmk | 6 +
src/hotspot/cpu/aarch64/aarch64.ad | 244 ---------------------------
src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad | 268 ++++++++++++++++++++++++++++++
src/hotspot/cpu/x86/gc/z/z_x86_64.ad | 168 +++++++++++++++++++
src/hotspot/cpu/x86/x86_64.ad | 151 -----------------
5 files changed, 442 insertions(+), 395 deletions(-)
create mode 100644 src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad
create mode 100644 src/hotspot/cpu/x86/gc/z/z_x86_64.ad
diff --git a/make/hotspot/gensrc/GensrcAdlc.gmk b/make/hotspot/gensrc/GensrcAdlc.gmk
index 92b030b69..1eaed25d9 100644
--- a/make/hotspot/gensrc/GensrcAdlc.gmk
+++ b/make/hotspot/gensrc/GensrcAdlc.gmk
@@ -136,6 +136,12 @@ ifeq ($(call check-jvm-feature, compiler2), true)
$d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH).ad \
)))
+ ifeq ($(call check-jvm-feature, zgc), true)
+ AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
+ $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/gc/z/z_$(HOTSPOT_TARGET_CPU).ad \
+ )))
+ endif
+
SINGLE_AD_SRCFILE := $(ADLC_SUPPORT_DIR)/all-ad-src.ad
INSERT_FILENAME_AWK_SCRIPT := \
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index 93dd78e51..3cca2da5b 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -1128,13 +1128,6 @@ definitions %{
int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST);
%}
-source_hpp %{
-
-#include "gc/z/c2/zBarrierSetC2.hpp"
-#include "gc/z/zThreadLocalData.hpp"
-
-%}
-
//----------SOURCE BLOCK-------------------------------------------------------
// This is a block of C++ code which provides values, functions, and
// definitions necessary in the rest of the architecture description
@@ -17487,243 +17480,6 @@ instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{
ins_pipe(vshift128_imm);
%}
-source %{
-
-static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
- ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
- __ ldr(tmp, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
- __ andr(tmp, tmp, ref);
- __ cbnz(tmp, *stub->entry());
- __ bind(*stub->continuation());
-}
-
-static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
- ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
- __ b(*stub->entry());
- __ bind(*stub->continuation());
-}
-
-%}
-
-// Load Pointer
-instruct zLoadP(iRegPNoSp dst, memory mem, rFlagsReg cr)
-%{
- match(Set dst (LoadP mem));
- predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierStrong));
- effect(TEMP dst, KILL cr);
-
- ins_cost(4 * INSN_COST);
-
- format %{ "ldr $dst, $mem" %}
-
- ins_encode %{
- const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
- __ ldr($dst$$Register, ref_addr);
- if (barrier_data() != ZLoadBarrierElided) {
- z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, false /* weak */);
- }
- %}
-
- ins_pipe(iload_reg_mem);
-%}
-
-// Load Weak Pointer
-instruct zLoadWeakP(iRegPNoSp dst, memory mem, rFlagsReg cr)
-%{
- match(Set dst (LoadP mem));
- predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierWeak));
- effect(TEMP dst, KILL cr);
-
- ins_cost(4 * INSN_COST);
-
- format %{ "ldr $dst, $mem" %}
-
- ins_encode %{
- const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
- __ ldr($dst$$Register, ref_addr);
- z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, true /* weak */);
- %}
-
- ins_pipe(iload_reg_mem);
-%}
-
-// Load Pointer Volatile
-instruct zLoadPVolatile(iRegPNoSp dst, indirect mem /* sync_memory */, rFlagsReg cr)
-%{
- match(Set dst (LoadP mem));
- predicate(UseZGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
- effect(TEMP dst, KILL cr);
-
- ins_cost(VOLATILE_REF_COST);
-
- format %{ "ldar $dst, $mem\t" %}
-
- ins_encode %{
- __ ldar($dst$$Register, $mem$$Register);
- if (barrier_data() != ZLoadBarrierElided) {
- z_load_barrier(_masm, this, Address($mem$$Register), $dst$$Register, rscratch2 /* tmp */, false /* weak */);
- }
- %}
-
- ins_pipe(pipe_serial);
-%}
-
-instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
- match(Set res (CompareAndSwapP mem (Binary oldval newval)));
- match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
- predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
- effect(KILL cr, TEMP_DEF res);
-
- ins_cost(2 * VOLATILE_REF_COST);
-
- format %{ "cmpxchg $mem, $oldval, $newval\n\t"
- "cset $res, EQ" %}
-
- ins_encode %{
- guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- false /* acquire */, true /* release */, false /* weak */, rscratch2);
- __ cset($res$$Register, Assembler::EQ);
- if (barrier_data() != ZLoadBarrierElided) {
- Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
- __ andr(rscratch1, rscratch1, rscratch2);
- __ cbz(rscratch1, good);
- z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */);
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- false /* acquire */, true /* release */, false /* weak */, rscratch2);
- __ cset($res$$Register, Assembler::EQ);
- __ bind(good);
- }
- %}
-
- ins_pipe(pipe_slow);
-%}
-
-instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
- match(Set res (CompareAndSwapP mem (Binary oldval newval)));
- match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
- predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
- effect(KILL cr, TEMP_DEF res);
-
- ins_cost(2 * VOLATILE_REF_COST);
-
- format %{ "cmpxchg $mem, $oldval, $newval\n\t"
- "cset $res, EQ" %}
-
- ins_encode %{
- guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- true /* acquire */, true /* release */, false /* weak */, rscratch2);
- __ cset($res$$Register, Assembler::EQ);
- if (barrier_data() != ZLoadBarrierElided) {
- Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
- __ andr(rscratch1, rscratch1, rscratch2);
- __ cbz(rscratch1, good);
- z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */ );
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- true /* acquire */, true /* release */, false /* weak */, rscratch2);
- __ cset($res$$Register, Assembler::EQ);
- __ bind(good);
- }
- %}
-
- ins_pipe(pipe_slow);
-%}
-
-instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
- match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
- predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
- effect(TEMP_DEF res, KILL cr);
-
- ins_cost(2 * VOLATILE_REF_COST);
-
- format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
-
- ins_encode %{
- guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- false /* acquire */, true /* release */, false /* weak */, $res$$Register);
- if (barrier_data() != ZLoadBarrierElided) {
- Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
- __ andr(rscratch1, rscratch1, $res$$Register);
- __ cbz(rscratch1, good);
- z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- false /* acquire */, true /* release */, false /* weak */, $res$$Register);
- __ bind(good);
- }
- %}
-
- ins_pipe(pipe_slow);
-%}
-
-instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
- match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
- predicate(UseZGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
- effect(TEMP_DEF res, KILL cr);
-
- ins_cost(2 * VOLATILE_REF_COST);
-
- format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
-
- ins_encode %{
- guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- true /* acquire */, true /* release */, false /* weak */, $res$$Register);
- if (barrier_data() != ZLoadBarrierElided) {
- Label good;
- __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
- __ andr(rscratch1, rscratch1, $res$$Register);
- __ cbz(rscratch1, good);
- z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
- __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
- true /* acquire */, true /* release */, false /* weak */, $res$$Register);
- __ bind(good);
- }
- %}
-
- ins_pipe(pipe_slow);
-%}
-
-instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
- match(Set prev (GetAndSetP mem newv));
- predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
- effect(TEMP_DEF prev, KILL cr);
-
- ins_cost(2 * VOLATILE_REF_COST);
-
- format %{ "atomic_xchg $prev, $newv, [$mem]" %}
-
- ins_encode %{
- __ atomic_xchg($prev$$Register, $newv$$Register, $mem$$Register);
- if (barrier_data() != ZLoadBarrierElided) {
- z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
- }
- %}
-
- ins_pipe(pipe_serial);
-%}
-
-instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
- match(Set prev (GetAndSetP mem newv));
- predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
- effect(TEMP_DEF prev, KILL cr);
-
- ins_cost(VOLATILE_REF_COST);
-
- format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
-
- ins_encode %{
- __ atomic_xchgal($prev$$Register, $newv$$Register, $mem$$Register);
- if (barrier_data() != ZLoadBarrierElided) {
- z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
- }
- %}
- ins_pipe(pipe_serial);
-%}
//----------PEEPHOLE RULES-----------------------------------------------------
// These must follow all instruction definitions as they use the names
diff --git a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad
new file mode 100644
index 000000000..50cc6f924
--- /dev/null
+++ b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad
@@ -0,0 +1,268 @@
+//
+// 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.
+//
+
+source_hpp %{
+
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+
+%}
+
+source %{
+
+static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
+ ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
+ __ ldr(tmp, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ __ andr(tmp, tmp, ref);
+ __ cbnz(tmp, *stub->entry());
+ __ bind(*stub->continuation());
+}
+
+static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
+ ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
+ __ b(*stub->entry());
+ __ bind(*stub->continuation());
+}
+
+%}
+
+// Load Pointer
+instruct zLoadP(iRegPNoSp dst, memory mem, rFlagsReg cr)
+%{
+ match(Set dst (LoadP mem));
+ predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierStrong));
+ effect(TEMP dst, KILL cr);
+
+ ins_cost(4 * INSN_COST);
+
+ format %{ "ldr $dst, $mem" %}
+
+ ins_encode %{
+ const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
+ __ ldr($dst$$Register, ref_addr);
+ if (barrier_data() != ZLoadBarrierElided) {
+ z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, false /* weak */);
+ }
+ %}
+
+ ins_pipe(iload_reg_mem);
+%}
+
+// Load Weak Pointer
+instruct zLoadWeakP(iRegPNoSp dst, memory mem, rFlagsReg cr)
+%{
+ match(Set dst (LoadP mem));
+ predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierWeak));
+ effect(TEMP dst, KILL cr);
+
+ ins_cost(4 * INSN_COST);
+
+ format %{ "ldr $dst, $mem" %}
+
+ ins_encode %{
+ const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
+ __ ldr($dst$$Register, ref_addr);
+ z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, true /* weak */);
+ %}
+
+ ins_pipe(iload_reg_mem);
+%}
+
+// Load Pointer Volatile
+instruct zLoadPVolatile(iRegPNoSp dst, indirect mem /* sync_memory */, rFlagsReg cr)
+%{
+ match(Set dst (LoadP mem));
+ predicate(UseZGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
+ effect(TEMP dst, KILL cr);
+
+ ins_cost(VOLATILE_REF_COST);
+
+ format %{ "ldar $dst, $mem\t" %}
+
+ ins_encode %{
+ __ ldar($dst$$Register, $mem$$Register);
+ if (barrier_data() != ZLoadBarrierElided) {
+ z_load_barrier(_masm, this, Address($mem$$Register), $dst$$Register, rscratch2 /* tmp */, false /* weak */);
+ }
+ %}
+
+ ins_pipe(pipe_serial);
+%}
+
+instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+ match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+ match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
+ predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+ effect(KILL cr, TEMP_DEF res);
+
+ ins_cost(2 * VOLATILE_REF_COST);
+
+ format %{ "cmpxchg $mem, $oldval, $newval\n\t"
+ "cset $res, EQ" %}
+
+ ins_encode %{
+ guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ false /* acquire */, true /* release */, false /* weak */, rscratch2);
+ __ cset($res$$Register, Assembler::EQ);
+ if (barrier_data() != ZLoadBarrierElided) {
+ Label good;
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ __ andr(rscratch1, rscratch1, rscratch2);
+ __ cbz(rscratch1, good);
+ z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */);
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ false /* acquire */, true /* release */, false /* weak */, rscratch2);
+ __ cset($res$$Register, Assembler::EQ);
+ __ bind(good);
+ }
+ %}
+
+ ins_pipe(pipe_slow);
+%}
+
+instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+ match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+ match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
+ predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
+ effect(KILL cr, TEMP_DEF res);
+
+ ins_cost(2 * VOLATILE_REF_COST);
+
+ format %{ "cmpxchg $mem, $oldval, $newval\n\t"
+ "cset $res, EQ" %}
+
+ ins_encode %{
+ guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ true /* acquire */, true /* release */, false /* weak */, rscratch2);
+ __ cset($res$$Register, Assembler::EQ);
+ if (barrier_data() != ZLoadBarrierElided) {
+ Label good;
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ __ andr(rscratch1, rscratch1, rscratch2);
+ __ cbz(rscratch1, good);
+ z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */ );
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ true /* acquire */, true /* release */, false /* weak */, rscratch2);
+ __ cset($res$$Register, Assembler::EQ);
+ __ bind(good);
+ }
+ %}
+
+ ins_pipe(pipe_slow);
+%}
+
+instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+ match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
+ predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+ effect(TEMP_DEF res, KILL cr);
+
+ ins_cost(2 * VOLATILE_REF_COST);
+
+ format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
+
+ ins_encode %{
+ guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ false /* acquire */, true /* release */, false /* weak */, $res$$Register);
+ if (barrier_data() != ZLoadBarrierElided) {
+ Label good;
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ __ andr(rscratch1, rscratch1, $res$$Register);
+ __ cbz(rscratch1, good);
+ z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ false /* acquire */, true /* release */, false /* weak */, $res$$Register);
+ __ bind(good);
+ }
+ %}
+
+ ins_pipe(pipe_slow);
+%}
+
+instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+ match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
+ predicate(UseZGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+ effect(TEMP_DEF res, KILL cr);
+
+ ins_cost(2 * VOLATILE_REF_COST);
+
+ format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
+
+ ins_encode %{
+ guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ true /* acquire */, true /* release */, false /* weak */, $res$$Register);
+ if (barrier_data() != ZLoadBarrierElided) {
+ Label good;
+ __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+ __ andr(rscratch1, rscratch1, $res$$Register);
+ __ cbz(rscratch1, good);
+ z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
+ __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+ true /* acquire */, true /* release */, false /* weak */, $res$$Register);
+ __ bind(good);
+ }
+ %}
+
+ ins_pipe(pipe_slow);
+%}
+
+instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
+ match(Set prev (GetAndSetP mem newv));
+ predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+ effect(TEMP_DEF prev, KILL cr);
+
+ ins_cost(2 * VOLATILE_REF_COST);
+
+ format %{ "atomic_xchg $prev, $newv, [$mem]" %}
+
+ ins_encode %{
+ __ atomic_xchg($prev$$Register, $newv$$Register, $mem$$Register);
+ if (barrier_data() != ZLoadBarrierElided) {
+ z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
+ }
+ %}
+
+ ins_pipe(pipe_serial);
+%}
+
+instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
+ match(Set prev (GetAndSetP mem newv));
+ predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
+ effect(TEMP_DEF prev, KILL cr);
+
+ ins_cost(VOLATILE_REF_COST);
+
+ format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
+
+ ins_encode %{
+ __ atomic_xchgal($prev$$Register, $newv$$Register, $mem$$Register);
+ if (barrier_data() != ZLoadBarrierElided) {
+ z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
+ }
+ %}
+ ins_pipe(pipe_serial);
+%}
+
diff --git a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad
new file mode 100644
index 000000000..38c2e926b
--- /dev/null
+++ b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad
@@ -0,0 +1,168 @@
+//
+// Copyright (c) 2015, 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.
+//
+
+source_hpp %{
+
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+
+%}
+
+source %{
+
+static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
+ ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
+ __ testptr(ref, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
+ __ jcc(Assembler::notZero, *stub->entry());
+ __ bind(*stub->continuation());
+}
+
+static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
+ ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
+ __ jmp(*stub->entry());
+ __ bind(*stub->continuation());
+}
+
+%}
+
+// Load Pointer
+instruct zLoadP(rRegP dst, memory mem, rFlagsReg cr)
+%{
+ predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
+ match(Set dst (LoadP mem));
+ effect(KILL cr, TEMP dst);
+
+ ins_cost(125);
+
+ format %{ "movq $dst, $mem" %}
+
+ ins_encode %{
+ __ movptr($dst$$Register, $mem$$Address);
+ if (barrier_data() != ZLoadBarrierElided) {
+ z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, false /* weak */);
+ }
+ %}
+
+ ins_pipe(ialu_reg_mem);
+%}
+
+// Load Weak Pointer
+instruct zLoadWeakP(rRegP dst, memory mem, rFlagsReg cr)
+%{
+ predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierWeak);
+ match(Set dst (LoadP mem));
+ effect(KILL cr, TEMP dst);
+
+ ins_cost(125);
+
+ format %{ "movq $dst, $mem" %}
+
+ ins_encode %{
+ __ movptr($dst$$Register, $mem$$Address);
+ z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, true /* weak */);
+ %}
+
+ ins_pipe(ialu_reg_mem);
+%}
+
+instruct zCompareAndExchangeP(memory mem, rax_RegP oldval, rRegP newval, rRegP tmp, rFlagsReg cr) %{
+ match(Set oldval (CompareAndExchangeP mem (Binary oldval newval)));
+ predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+ effect(KILL cr, TEMP tmp);
+
+ format %{ "lock\n\t"
+ "cmpxchgq $newval, $mem" %}
+
+ ins_encode %{
+ if (barrier_data() != ZLoadBarrierElided) {
+ __ movptr($tmp$$Register, $oldval$$Register);
+ }
+ __ lock();
+ __ cmpxchgptr($newval$$Register, $mem$$Address);
+ if (barrier_data() != ZLoadBarrierElided) {
+ Label good;
+ __ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
+ __ jcc(Assembler::zero, good);
+ z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
+ __ movptr($oldval$$Register, $tmp$$Register);
+ __ lock();
+ __ cmpxchgptr($newval$$Register, $mem$$Address);
+ __ bind(good);
+ }
+ %}
+
+ ins_pipe(pipe_cmpxchg);
+%}
+
+instruct zCompareAndSwapP(rRegI res, memory mem, rRegP newval, rRegP tmp, rFlagsReg cr, rax_RegP oldval) %{
+ match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+ match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
+ predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+ effect(KILL cr, KILL oldval, TEMP tmp);
+
+ format %{ "lock\n\t"
+ "cmpxchgq $newval, $mem\n\t"
+ "sete $res\n\t"
+ "movzbl $res, $res" %}
+
+ ins_encode %{
+ if (barrier_data() != ZLoadBarrierElided) {
+ __ movptr($tmp$$Register, $oldval$$Register);
+ }
+ __ lock();
+ __ cmpxchgptr($newval$$Register, $mem$$Address);
+ if (barrier_data() != ZLoadBarrierElided) {
+ Label good;
+ __ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
+ __ jcc(Assembler::zero, good);
+ z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
+ __ movptr($oldval$$Register, $tmp$$Register);
+ __ lock();
+ __ cmpxchgptr($newval$$Register, $mem$$Address);
+ __ bind(good);
+ __ cmpptr($tmp$$Register, $oldval$$Register);
+ }
+ __ setb(Assembler::equal, $res$$Register);
+ __ movzbl($res$$Register, $res$$Register);
+ %}
+
+ ins_pipe(pipe_cmpxchg);
+%}
+
+instruct zXChgP(memory mem, rRegP newval, rFlagsReg cr) %{
+ match(Set newval (GetAndSetP mem newval));
+ predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+ effect(KILL cr);
+
+ format %{ "xchgq $newval, $mem" %}
+
+ ins_encode %{
+ __ xchgptr($newval$$Register, $mem$$Address);
+ if (barrier_data() != ZLoadBarrierElided) {
+ z_load_barrier(_masm, this, Address(noreg, 0), $newval$$Register, noreg /* tmp */, false /* weak */);
+ }
+ %}
+
+ ins_pipe(pipe_cmpxchg);
+%}
+
diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad
index f795fb823..7879547ce 100644
--- a/src/hotspot/cpu/x86/x86_64.ad
+++ b/src/hotspot/cpu/x86/x86_64.ad
@@ -538,19 +538,6 @@ reg_class int_rdi_reg(RDI);
%}
-source_hpp %{
-
-#include "gc/z/c2/zBarrierSetC2.hpp"
-#include "gc/z/zThreadLocalData.hpp"
-
-%}
-
-source_hpp %{
-#if INCLUDE_ZGC
-#include "gc/z/zBarrierSetAssembler.hpp"
-#endif
-%}
-
//----------SOURCE BLOCK-------------------------------------------------------
// This is a block of C++ code which provides values, functions, and
// definitions necessary in the rest of the architecture description
@@ -1801,19 +1788,6 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() {
return NO_REG_mask();
}
-static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
- ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
- __ testptr(ref, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
- __ jcc(Assembler::notZero, *stub->entry());
- __ bind(*stub->continuation());
-}
-
-static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
- ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
- __ jmp(*stub->entry());
- __ bind(*stub->continuation());
-}
-
%}
//----------ENCODING BLOCK-----------------------------------------------------
@@ -12520,131 +12494,6 @@ instruct RethrowException()
ins_pipe(pipe_jmp);
%}
-//
-// Execute ZGC load barrier (strong) slow path
-//
-
-// Load Pointer
-instruct zLoadP(rRegP dst, memory mem, rFlagsReg cr)
-%{
- predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
- match(Set dst (LoadP mem));
- effect(KILL cr, TEMP dst);
-
- ins_cost(125);
-
- format %{ "movq $dst, $mem" %}
-
- ins_encode %{
- __ movptr($dst$$Register, $mem$$Address);
- if (barrier_data() != ZLoadBarrierElided) {
- z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, false /* weak */);
- }
- %}
-
- ins_pipe(ialu_reg_mem);
-%}
-
-// Load Weak Pointer
-instruct zLoadWeakP(rRegP dst, memory mem, rFlagsReg cr)
-%{
- predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierWeak);
- match(Set dst (LoadP mem));
- effect(KILL cr, TEMP dst);
-
- ins_cost(125);
-
- format %{ "movq $dst, $mem" %}
- ins_encode %{
- __ movptr($dst$$Register, $mem$$Address);
- z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, true /* weak */);
- %}
-
- ins_pipe(ialu_reg_mem);
-%}
-
-instruct zCompareAndExchangeP(memory mem, rax_RegP oldval, rRegP newval, rRegP tmp, rFlagsReg cr) %{
- match(Set oldval (CompareAndExchangeP mem (Binary oldval newval)));
- predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
- effect(KILL cr, TEMP tmp);
-
- format %{ "lock\n\t"
- "cmpxchgq $newval, $mem" %}
-
- ins_encode %{
- if (barrier_data() != ZLoadBarrierElided) {
- __ movptr($tmp$$Register, $oldval$$Register);
- }
- __ lock();
- __ cmpxchgptr($newval$$Register, $mem$$Address);
- if (barrier_data() != ZLoadBarrierElided) {
- Label good;
- __ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
- __ jcc(Assembler::zero, good);
- z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
- __ movptr($oldval$$Register, $tmp$$Register);
- __ lock();
- __ cmpxchgptr($newval$$Register, $mem$$Address);
- __ bind(good);
- }
- %}
-
- ins_pipe(pipe_cmpxchg);
-%}
-
-
-instruct zCompareAndSwapP(rRegI res, memory mem, rRegP newval, rRegP tmp, rFlagsReg cr, rax_RegP oldval) %{
- match(Set res (CompareAndSwapP mem (Binary oldval newval)));
- match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
- predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
- effect(KILL cr, KILL oldval, TEMP tmp);
-
- format %{ "lock\n\t"
- "cmpxchgq $newval, $mem\n\t"
- "sete $res\n\t"
- "movzbl $res, $res" %}
-
- ins_encode %{
- if (barrier_data() != ZLoadBarrierElided) {
- __ movptr($tmp$$Register, $oldval$$Register);
- }
- __ lock();
- __ cmpxchgptr($newval$$Register, $mem$$Address);
- if (barrier_data() != ZLoadBarrierElided) {
- Label good;
- __ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
- __ jcc(Assembler::zero, good);
- z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
- __ movptr($oldval$$Register, $tmp$$Register);
- __ lock();
- __ cmpxchgptr($newval$$Register, $mem$$Address);
- __ bind(good);
- __ cmpptr($tmp$$Register, $oldval$$Register);
- }
- __ setb(Assembler::equal, $res$$Register);
- __ movzbl($res$$Register, $res$$Register);
- %}
-
- ins_pipe(pipe_cmpxchg);
-%}
-
-instruct zXChgP(memory mem, rRegP newval, rFlagsReg cr) %{
- match(Set newval (GetAndSetP mem newval));
- predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
- effect(KILL cr);
-
- format %{ "xchgq $newval, $mem" %}
-
- ins_encode %{
- __ xchgptr($newval$$Register, $mem$$Address);
- if (barrier_data() != ZLoadBarrierElided) {
- z_load_barrier(_masm, this, Address(noreg, 0), $newval$$Register, noreg /* tmp */, false /* weak */);
- }
- %}
-
- ins_pipe(pipe_cmpxchg);
-%}
-
// ============================================================================
// This name is KNOWN by the ADLC and cannot be changed.
// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
--
2.12.3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
From 96ac09c507a663b853235c29a607aca2c1edfc10 Mon Sep 17 00:00:00 2001
Date: Mon, 2 Dec 2019 17:42:17 +0000
Subject: [PATCH] 8225648: [TESTBUG]java/lang/annotation/loaderLeak/Main.java
fails with -Xcomp
Summary: <loaderLeak>: annotations cause memory leak
LLT: NA
Bug url: https://bugs.openjdk.java.net/browse/JDK-8225648
---
test/jdk/java/lang/annotation/loaderLeak/Main.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/test/jdk/java/lang/annotation/loaderLeak/Main.java b/test/jdk/java/lang/annotation/loaderLeak/Main.java
index 7e249ebc1..4245008f8 100644
--- a/test/jdk/java/lang/annotation/loaderLeak/Main.java
+++ b/test/jdk/java/lang/annotation/loaderLeak/Main.java
@@ -54,6 +54,7 @@ public class Main {
System.gc();
System.gc();
if (c.get() == null) throw new AssertionError();
+ Reference.reachabilityFence(loader);
System.gc();
System.gc();
loader = null;
--
2.12.3

View File

@ -0,0 +1,76 @@
From 7a656d6c14da1ec666ee5ebf55995c6b6bf4ab7f Mon Sep 17 00:00:00 2001
Date: Tue, 17 Mar 2020 11:06:41 +0800
Subject: [PATCH] 8226536: Catch OOM from deopt that fails rematerializing
objects
Summary: <test>: fix testcase, catch OOM from deopt that fails rematerializing objects
LLT: jtreg
Bug url: https://bugs.openjdk.java.net/browse/JDK-8226536
---
.../vmTestbase/nsk/share/gc/gp/GarbageUtils.java | 36 ++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java
index 333bf070b..4d18a6871 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java
@@ -26,6 +26,7 @@ package nsk.share.gc.gp;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.invoke.*;
import java.util.*;
import nsk.share.gc.gp.array.*;
import nsk.share.gc.gp.string.*;
@@ -193,6 +194,36 @@ public final class GarbageUtils {
return eatMemory(stresser, gp, initialFactor, minMemoryChunk, factor, OOM_TYPE.ANY);
}
+ static int numberOfOOMEs = 0;
+
+ /**
+ * Minimal wrapper of the main implementation. Catches any OOM
+ * that might be thrown when rematerializing Objects when deoptimizing.
+ *
+ * It is Important that the impl is not inlined.
+ */
+
+ public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
+ try {
+ // Using a methodhandle invoke of eatMemoryImpl to prevent inlining of it
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(
+ int.class,
+ ExecutionController.class,
+ GarbageProducer.class,
+ long.class,
+ long.class,
+ long.class,
+ OOM_TYPE.class);
+ MethodHandle eat = lookup.findStatic(GarbageUtils.class, "eatMemoryImpl", mt);
+ return (int) eat.invoke(stresser, gp, initialFactor, minMemoryChunk, factor, type);
+ } catch (OutOfMemoryError e) {
+ return numberOfOOMEs++;
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
/**
* Eat memory using given garbage producer.
*
@@ -210,8 +241,9 @@ public final class GarbageUtils {
* @param type of OutOfMemory Exception: Java heap space or Metadata space
* @return number of OOME occured
*/
- public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
- int numberOfOOMEs = 0;
+
+ public static int eatMemoryImpl(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
+ numberOfOOMEs = 0;
try {
StringWriter sw = new StringWriter(10000);
PrintWriter pw = new PrintWriter(sw);
--
2.12.3

View File

@ -0,0 +1,365 @@
From 54e889ba40a633fdac60674e54a1ca948fa3d3bf Mon Sep 17 00:00:00 2001
Date: Wed, 27 Nov 2019 15:11:50 +0000
Subject: [PATCH] 8231584: Deadlock with ClassLoader.findLibrary and
System.loadLibrary call
Summary: <java.lang>: Deadlock with ClassLoader.findLibrary and System.loadLibrary call
LLT: LoadLibraryTest.java
Bug url: https://bugs.openjdk.java.net/browse/JDK-8231584
---
.../share/classes/java/lang/ClassLoader.java | 23 ++-
src/java.base/share/classes/java/lang/Runtime.java | 8 +-
src/java.base/share/classes/java/lang/System.java | 2 +
.../lang/Runtime/loadLibrary/LoadLibraryTest.java | 158 +++++++++++++++++++++
.../java/lang/Runtime/loadLibrary/src/Target.java | 34 +++++
.../java/lang/Runtime/loadLibrary/src/Target2.java | 29 ++++
6 files changed, 243 insertions(+), 11 deletions(-)
create mode 100644 test/jdk/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
create mode 100644 test/jdk/java/lang/Runtime/loadLibrary/src/Target.java
create mode 100644 test/jdk/java/lang/Runtime/loadLibrary/src/Target2.java
diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java
index aa211b079..7fb707508 100644
--- a/src/java.base/share/classes/java/lang/ClassLoader.java
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, 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
@@ -1994,6 +1994,17 @@ public abstract class ClassLoader {
return scl;
}
+ /*
+ * 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) {
@@ -2463,8 +2474,7 @@ public abstract class ClassLoader {
*
* 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.
+ * same thread because this block is synchronous
*
* If there is a pending load operation for the library, we
* immediately return success; otherwise, we raise
@@ -2609,10 +2619,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;
diff --git a/src/java.base/share/classes/java/lang/Runtime.java b/src/java.base/share/classes/java/lang/Runtime.java
index 128e6dbc8..3a9a7d838 100644
--- a/src/java.base/share/classes/java/lang/Runtime.java
+++ b/src/java.base/share/classes/java/lang/Runtime.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2018, 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
@@ -755,7 +755,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);
@@ -817,14 +817,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/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java
index 2bb5390c0..216f33586 100644
--- a/src/java.base/share/classes/java/lang/System.java
+++ b/src/java.base/share/classes/java/lang/System.java
@@ -1988,6 +1988,8 @@ public final class System {
// register shared secrets
setJavaLangAccess();
+ ClassLoader.initLibraryPaths();
+
// Subsystems that are invoked during initialization can invoke
// VM.isBooted() in order to avoid doing things that should
// wait until the VM is fully initialized. The initialization level
diff --git a/test/jdk/java/lang/Runtime/loadLibrary/LoadLibraryTest.java b/test/jdk/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
new file mode 100644
index 000000000..f08c60dfa
--- /dev/null
+++ b/test/jdk/java/lang/Runtime/loadLibrary/LoadLibraryTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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 /test/lib
+ * @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;
+
+import jdk.test.lib.compiler.CompilerUtils;
+
+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/test/jdk/java/lang/Runtime/loadLibrary/src/Target.java b/test/jdk/java/lang/Runtime/loadLibrary/src/Target.java
new file mode 100644
index 000000000..fc5148105
--- /dev/null
+++ b/test/jdk/java/lang/Runtime/loadLibrary/src/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/test/jdk/java/lang/Runtime/loadLibrary/src/Target2.java b/test/jdk/java/lang/Runtime/loadLibrary/src/Target2.java
new file mode 100644
index 000000000..bc8dfc5e6
--- /dev/null
+++ b/test/jdk/java/lang/Runtime/loadLibrary/src/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

@ -0,0 +1,101 @@
From d2137837d518a8bdb8e075109e502e78bd2f9fa9 Mon Sep 17 00:00:00 2001
Date: Wed, 19 Feb 2020 17:36:32 +0800
Subject: [PATCH] 8233061: ZGC: Enforce memory ordering in segmented bit maps
Summary: <gc>: <resolves try_mark and relocate crash>
LLT: renaissance
Bug url: https://bugs.openjdk.java.net/browse/JDK-8233061
---
src/hotspot/share/gc/z/zLiveMap.cpp | 20 +++++++++-----------
src/hotspot/share/gc/z/zLiveMap.inline.hpp | 9 +++++----
2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/src/hotspot/share/gc/z/zLiveMap.cpp b/src/hotspot/share/gc/z/zLiveMap.cpp
index 7187b6166..c1d79b794 100644
--- a/src/hotspot/share/gc/z/zLiveMap.cpp
+++ b/src/hotspot/share/gc/z/zLiveMap.cpp
@@ -50,7 +50,9 @@ void ZLiveMap::reset(size_t index) {
// Multiple threads can enter here, make sure only one of them
// resets the marking information while the others busy wait.
- for (uint32_t seqnum = _seqnum; seqnum != ZGlobalSeqNum; seqnum = _seqnum) {
+ for (uint32_t seqnum = OrderAccess::load_acquire(&_seqnum);
+ seqnum != ZGlobalSeqNum;
+ seqnum = OrderAccess::load_acquire(&_seqnum)) {
if ((seqnum != seqnum_initializing) &&
(Atomic::cmpxchg(seqnum_initializing, &_seqnum, seqnum) == seqnum)) {
// Reset marking information
@@ -61,13 +63,13 @@ void ZLiveMap::reset(size_t index) {
segment_live_bits().clear();
segment_claim_bits().clear();
- // Make sure the newly reset marking information is
- // globally visible before updating the page seqnum.
- OrderAccess::storestore();
-
- // Update seqnum
assert(_seqnum == seqnum_initializing, "Invalid");
- _seqnum = ZGlobalSeqNum;
+
+ // Make sure the newly reset marking information is ordered
+ // before the update of the page seqnum, such that when the
+ // up-to-date seqnum is load acquired, the bit maps will not
+ // contain stale information.
+ OrderAccess::release_store(&_seqnum, ZGlobalSeqNum);
break;
}
@@ -89,10 +91,6 @@ void ZLiveMap::reset_segment(BitMap::idx_t segment) {
if (!claim_segment(segment)) {
// Already claimed, wait for live bit to be set
while (!is_segment_live(segment)) {
- // Busy wait. The loadload barrier is needed to make
- // sure we re-read the live bit every time we loop.
- OrderAccess::loadload();
-
// Mark reset contention
if (!contention) {
// Count contention once
diff --git a/src/hotspot/share/gc/z/zLiveMap.inline.hpp b/src/hotspot/share/gc/z/zLiveMap.inline.hpp
index 1e4d56f41..fb45a892c 100644
--- a/src/hotspot/share/gc/z/zLiveMap.inline.hpp
+++ b/src/hotspot/share/gc/z/zLiveMap.inline.hpp
@@ -30,6 +30,7 @@
#include "gc/z/zOop.inline.hpp"
#include "gc/z/zUtils.inline.hpp"
#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/debug.hpp"
@@ -38,7 +39,7 @@ inline void ZLiveMap::reset() {
}
inline bool ZLiveMap::is_marked() const {
- return _seqnum == ZGlobalSeqNum;
+ return OrderAccess::load_acquire(&_seqnum) == ZGlobalSeqNum;
}
inline uint32_t ZLiveMap::live_objects() const {
@@ -68,15 +69,15 @@ inline BitMapView ZLiveMap::segment_claim_bits() {
}
inline bool ZLiveMap::is_segment_live(BitMap::idx_t segment) const {
- return segment_live_bits().at(segment);
+ return segment_live_bits().par_at(segment);
}
inline bool ZLiveMap::set_segment_live_atomic(BitMap::idx_t segment) {
- return segment_live_bits().par_set_bit(segment);
+ return segment_live_bits().par_set_bit(segment, memory_order_release);
}
inline bool ZLiveMap::claim_segment(BitMap::idx_t segment) {
- return segment_claim_bits().par_set_bit(segment);
+ return segment_claim_bits().par_set_bit(segment, memory_order_acq_rel);
}
inline BitMap::idx_t ZLiveMap::first_live_segment() const {
--
2.12.3

View File

@ -0,0 +1,180 @@
From d1c89ec547d6d59c56874b458fc49f56e25011b2 Mon Sep 17 00:00:00 2001
Date: Wed, 19 Feb 2020 17:17:43 +0800
Subject: [PATCH] 8233073: Make BitMap accessors more memory ordering friendly
Summary: <gc>: <the dependency of 8233061 which resolves try_mark and relocate crash>
LLT: renaissance
Bug url: https://bugs.openjdk.java.net/browse/JDK-8233073
---
src/hotspot/share/c1/c1_Instruction.cpp | 1 +
src/hotspot/share/opto/graphKit.cpp | 1 +
src/hotspot/share/opto/parse1.cpp | 1 +
src/hotspot/share/utilities/bitMap.hpp | 17 +++++++++++---
src/hotspot/share/utilities/bitMap.inline.hpp | 34 ++++++++++++++++++++++-----
5 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/src/hotspot/share/c1/c1_Instruction.cpp b/src/hotspot/share/c1/c1_Instruction.cpp
index ee3be899a..62d8b48bc 100644
--- a/src/hotspot/share/c1/c1_Instruction.cpp
+++ b/src/hotspot/share/c1/c1_Instruction.cpp
@@ -29,6 +29,7 @@
#include "c1/c1_ValueStack.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciTypeArrayKlass.hpp"
+#include "utilities/bitMap.inline.hpp"
// Implementation of Instruction
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 2ceb3a6ae..981d6b860 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -43,6 +43,7 @@
#include "opto/runtime.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "utilities/bitMap.inline.hpp"
//----------------------------GraphKit-----------------------------------------
// Main utility constructor.
diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp
index a6408b493..0b30303a3 100644
--- a/src/hotspot/share/opto/parse1.cpp
+++ b/src/hotspot/share/opto/parse1.cpp
@@ -41,6 +41,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "utilities/bitMap.inline.hpp"
#include "utilities/copy.hpp"
// Static array so we can figure out which bytecodes stop us from compiling
diff --git a/src/hotspot/share/utilities/bitMap.hpp b/src/hotspot/share/utilities/bitMap.hpp
index 656e11fb7..4d6749f5b 100644
--- a/src/hotspot/share/utilities/bitMap.hpp
+++ b/src/hotspot/share/utilities/bitMap.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_UTILITIES_BITMAP_HPP
#include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
#include "utilities/align.hpp"
// Forward decl;
@@ -94,6 +95,8 @@ class BitMap {
void set_word (idx_t word) { set_word(word, ~(bm_word_t)0); }
void clear_word(idx_t word) { _map[word] = 0; }
+ static inline const bm_word_t load_word_ordered(const volatile bm_word_t* const addr, atomic_memory_order memory_order);
+
// Utilities for ranges of bits. Ranges are half-open [beg, end).
// Ranges within a single word.
@@ -193,6 +196,9 @@ class BitMap {
return (*word_addr(index) & bit_mask(index)) != 0;
}
+ // memory_order must be memory_order_relaxed or memory_order_acquire.
+ bool par_at(idx_t index, atomic_memory_order memory_order = memory_order_acquire) const;
+
// Align bit index up or down to the next bitmap word boundary, or check
// alignment.
static idx_t word_align_up(idx_t bit) {
@@ -209,9 +215,14 @@ class BitMap {
inline void set_bit(idx_t bit);
inline void clear_bit(idx_t bit);
- // Atomically set or clear the specified bit.
- inline bool par_set_bit(idx_t bit);
- inline bool par_clear_bit(idx_t bit);
+ // Attempts to change a bit to a desired value. The operation returns true if
+ // this thread changed the value of the bit. It was changed with a RMW operation
+ // using the specified memory_order. The operation returns false if the change
+ // could not be set due to the bit already being observed in the desired state.
+ // The atomic access that observed the bit in the desired state has acquire
+ // semantics, unless memory_order is memory_order_relaxed or memory_order_release.
+ inline bool par_set_bit(idx_t bit, atomic_memory_order memory_order = memory_order_conservative);
+ inline bool par_clear_bit(idx_t bit, atomic_memory_order memory_order = memory_order_conservative);
// Put the given value at the given offset. The parallel version
// will CAS the value into the bitmap and is quite a bit slower.
diff --git a/src/hotspot/share/utilities/bitMap.inline.hpp b/src/hotspot/share/utilities/bitMap.inline.hpp
index b10726d18..7a7e2ad43 100644
--- a/src/hotspot/share/utilities/bitMap.inline.hpp
+++ b/src/hotspot/share/utilities/bitMap.inline.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_UTILITIES_BITMAP_INLINE_HPP
#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
#include "utilities/bitMap.hpp"
inline void BitMap::set_bit(idx_t bit) {
@@ -38,18 +39,39 @@ inline void BitMap::clear_bit(idx_t bit) {
*word_addr(bit) &= ~bit_mask(bit);
}
-inline bool BitMap::par_set_bit(idx_t bit) {
+inline const BitMap::bm_word_t BitMap::load_word_ordered(const volatile bm_word_t* const addr, atomic_memory_order memory_order) {
+ if (memory_order == memory_order_relaxed || memory_order == memory_order_release) {
+ return Atomic::load(addr);
+ } else {
+ assert(memory_order == memory_order_acq_rel ||
+ memory_order == memory_order_acquire ||
+ memory_order == memory_order_conservative,
+ "unexpected memory ordering");
+ return OrderAccess::load_acquire(addr);
+ }
+}
+
+inline bool BitMap::par_at(idx_t index, atomic_memory_order memory_order) const {
+ verify_index(index);
+ assert(memory_order == memory_order_acquire ||
+ memory_order == memory_order_relaxed,
+ "unexpected memory ordering");
+ const volatile bm_word_t* const addr = word_addr(index);
+ return (load_word_ordered(addr, memory_order) & bit_mask(index)) != 0;
+}
+
+inline bool BitMap::par_set_bit(idx_t bit, atomic_memory_order memory_order) {
verify_index(bit);
volatile bm_word_t* const addr = word_addr(bit);
const bm_word_t mask = bit_mask(bit);
- bm_word_t old_val = *addr;
+ bm_word_t old_val = load_word_ordered(addr, memory_order);
do {
const bm_word_t new_val = old_val | mask;
if (new_val == old_val) {
return false; // Someone else beat us to it.
}
- const bm_word_t cur_val = Atomic::cmpxchg(new_val, addr, old_val);
+ const bm_word_t cur_val = Atomic::cmpxchg(new_val, addr, old_val, memory_order);
if (cur_val == old_val) {
return true; // Success.
}
@@ -57,18 +79,18 @@ inline bool BitMap::par_set_bit(idx_t bit) {
} while (true);
}
-inline bool BitMap::par_clear_bit(idx_t bit) {
+inline bool BitMap::par_clear_bit(idx_t bit, atomic_memory_order memory_order) {
verify_index(bit);
volatile bm_word_t* const addr = word_addr(bit);
const bm_word_t mask = ~bit_mask(bit);
- bm_word_t old_val = *addr;
+ bm_word_t old_val = load_word_ordered(addr, memory_order);
do {
const bm_word_t new_val = old_val & mask;
if (new_val == old_val) {
return false; // Someone else beat us to it.
}
- const bm_word_t cur_val = Atomic::cmpxchg(new_val, addr, old_val);
+ const bm_word_t cur_val = Atomic::cmpxchg(new_val, addr, old_val, memory_order);
if (cur_val == old_val) {
return true; // Success.
}
--
2.12.3

View File

@ -0,0 +1,472 @@
From aa824cddc917b1fcac41a0efe5e8c794f2d5cff9 Mon Sep 17 00:00:00 2001
Date: Thu, 26 Mar 2020 16:17:45 +0000
Subject: [PATCH] 8233506:ZGC: the load for Reference.get() can be converted to
a load for strong refs Summary: <gc>: <ZGC: the load for Reference.get() can
be converted to a load for strong refs> LLT: JDK8233506
Bug url: https://bugs.openjdk.java.net/browse/JDK-8233506
---
src/hotspot/share/gc/shared/c2/barrierSetC2.cpp | 73 +++++++++++++++----------
src/hotspot/share/gc/shared/c2/barrierSetC2.hpp | 7 ++-
src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp | 42 +++++---------
src/hotspot/share/opto/graphKit.cpp | 9 +--
src/hotspot/share/opto/graphKit.hpp | 10 ++--
src/hotspot/share/opto/memnode.cpp | 9 ++-
src/hotspot/share/opto/memnode.hpp | 7 ++-
7 files changed, 85 insertions(+), 72 deletions(-)
diff --git a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp
index 545275644..48fe04b08 100644
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp
+++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp
@@ -115,10 +115,13 @@ Node* BarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) con
Node* load;
if (in_native) {
- load = kit->make_load(control, adr, val_type, access.type(), mo);
+ load = kit->make_load(control, adr, val_type, access.type(), mo, dep,
+ requires_atomic_access, unaligned,
+ mismatched, unsafe, access.barrier_data());
} else {
load = kit->make_load(control, adr, val_type, access.type(), adr_type, mo,
- dep, requires_atomic_access, unaligned, mismatched, unsafe);
+ dep, requires_atomic_access, unaligned, mismatched, unsafe,
+ access.barrier_data());
}
access.set_raw_access(load);
@@ -348,28 +351,28 @@ Node* BarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node*
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop()));
Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop()));
- load_store = kit->gvn().transform(new CompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo));
+ load_store = new CompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo);
} else
#endif
{
- load_store = kit->gvn().transform(new CompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo));
+ load_store = new CompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo);
}
} else {
switch (access.type()) {
case T_BYTE: {
- load_store = kit->gvn().transform(new CompareAndExchangeBNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo));
+ load_store = new CompareAndExchangeBNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
break;
}
case T_SHORT: {
- load_store = kit->gvn().transform(new CompareAndExchangeSNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo));
+ load_store = new CompareAndExchangeSNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
break;
}
case T_INT: {
- load_store = kit->gvn().transform(new CompareAndExchangeINode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo));
+ load_store = new CompareAndExchangeINode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
break;
}
case T_LONG: {
- load_store = kit->gvn().transform(new CompareAndExchangeLNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo));
+ load_store = new CompareAndExchangeLNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
break;
}
default:
@@ -377,6 +380,9 @@ Node* BarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node*
}
}
+ load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
+ load_store = kit->gvn().transform(load_store);
+
access.set_raw_access(load_store);
pin_atomic_op(access);
@@ -405,50 +411,50 @@ Node* BarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node
Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop()));
Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop()));
if (is_weak_cas) {
- load_store = kit->gvn().transform(new WeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
+ load_store = new WeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo);
} else {
- load_store = kit->gvn().transform(new CompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
+ load_store = new CompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo);
}
} else
#endif
{
if (is_weak_cas) {
- load_store = kit->gvn().transform(new WeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new WeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo);
} else {
- load_store = kit->gvn().transform(new CompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new CompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo);
}
}
} else {
switch(access.type()) {
case T_BYTE: {
if (is_weak_cas) {
- load_store = kit->gvn().transform(new WeakCompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new WeakCompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo);
} else {
- load_store = kit->gvn().transform(new CompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new CompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo);
}
break;
}
case T_SHORT: {
if (is_weak_cas) {
- load_store = kit->gvn().transform(new WeakCompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new WeakCompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo);
} else {
- load_store = kit->gvn().transform(new CompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new CompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo);
}
break;
}
case T_INT: {
if (is_weak_cas) {
- load_store = kit->gvn().transform(new WeakCompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new WeakCompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo);
} else {
- load_store = kit->gvn().transform(new CompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new CompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo);
}
break;
}
case T_LONG: {
if (is_weak_cas) {
- load_store = kit->gvn().transform(new WeakCompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new WeakCompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo);
} else {
- load_store = kit->gvn().transform(new CompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo));
+ load_store = new CompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo);
}
break;
}
@@ -457,6 +463,9 @@ Node* BarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node
}
}
+ load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
+ load_store = kit->gvn().transform(load_store);
+
access.set_raw_access(load_store);
pin_atomic_op(access);
@@ -478,27 +487,30 @@ Node* BarrierSetC2::atomic_xchg_at_resolved(C2AtomicAccess& access, Node* new_va
} else
#endif
{
- load_store = kit->gvn().transform(new GetAndSetPNode(kit->control(), mem, adr, new_val, adr_type, value_type->is_oopptr()));
+ load_store = new GetAndSetPNode(kit->control(), mem, adr, new_val, adr_type, value_type->is_oopptr());
}
} else {
switch (access.type()) {
case T_BYTE:
- load_store = kit->gvn().transform(new GetAndSetBNode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndSetBNode(kit->control(), mem, adr, new_val, adr_type);
break;
case T_SHORT:
- load_store = kit->gvn().transform(new GetAndSetSNode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndSetSNode(kit->control(), mem, adr, new_val, adr_type);
break;
case T_INT:
- load_store = kit->gvn().transform(new GetAndSetINode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndSetINode(kit->control(), mem, adr, new_val, adr_type);
break;
case T_LONG:
- load_store = kit->gvn().transform(new GetAndSetLNode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndSetLNode(kit->control(), mem, adr, new_val, adr_type);
break;
default:
ShouldNotReachHere();
}
}
+ load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
+ load_store = kit->gvn().transform(load_store);
+
access.set_raw_access(load_store);
pin_atomic_op(access);
@@ -520,21 +532,24 @@ Node* BarrierSetC2::atomic_add_at_resolved(C2AtomicAccess& access, Node* new_val
switch(access.type()) {
case T_BYTE:
- load_store = kit->gvn().transform(new GetAndAddBNode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndAddBNode(kit->control(), mem, adr, new_val, adr_type);
break;
case T_SHORT:
- load_store = kit->gvn().transform(new GetAndAddSNode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndAddSNode(kit->control(), mem, adr, new_val, adr_type);
break;
case T_INT:
- load_store = kit->gvn().transform(new GetAndAddINode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndAddINode(kit->control(), mem, adr, new_val, adr_type);
break;
case T_LONG:
- load_store = kit->gvn().transform(new GetAndAddLNode(kit->control(), mem, adr, new_val, adr_type));
+ load_store = new GetAndAddLNode(kit->control(), mem, adr, new_val, adr_type);
break;
default:
ShouldNotReachHere();
}
+ load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
+ load_store = kit->gvn().transform(load_store);
+
access.set_raw_access(load_store);
pin_atomic_op(access);
diff --git a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp
index 487988bd8..8b4be7d11 100644
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp
+++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp
@@ -96,6 +96,7 @@ protected:
Node* _base;
C2AccessValuePtr& _addr;
Node* _raw_access;
+ uint8_t _barrier_data;
void fixup_decorators();
void* barrier_set_state() const;
@@ -108,7 +109,8 @@ public:
_type(type),
_base(base),
_addr(addr),
- _raw_access(NULL)
+ _raw_access(NULL),
+ _barrier_data(0)
{
fixup_decorators();
}
@@ -122,6 +124,9 @@ public:
bool is_raw() const { return (_decorators & AS_RAW) != 0; }
Node* raw_access() const { return _raw_access; }
+ uint8_t barrier_data() const { return _barrier_data; }
+ void set_barrier_data(uint8_t data) { _barrier_data = data; }
+
void set_raw_access(Node* raw_access) { _raw_access = raw_access; }
virtual void set_memory() {} // no-op for normal accesses, but not for atomic accesses.
diff --git a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
index a12973464..e178761a0 100644
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
@@ -174,48 +174,36 @@ int ZBarrierSetC2::estimate_stub_size() const {
return size;
}
-static bool barrier_needed(C2Access access) {
- return ZBarrierSet::barrier_needed(access.decorators(), access.type());
-}
-
-Node* ZBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
- Node* result = BarrierSetC2::load_at_resolved(access, val_type);
- if (barrier_needed(access) && access.raw_access()->is_Mem()) {
- if ((access.decorators() & ON_WEAK_OOP_REF) != 0) {
- access.raw_access()->as_Load()->set_barrier_data(ZLoadBarrierWeak);
+static void set_barrier_data(C2Access& access) {
+ if (ZBarrierSet::barrier_needed(access.decorators(), access.type())) {
+ if (access.decorators() & ON_WEAK_OOP_REF) {
+ access.set_barrier_data(ZLoadBarrierWeak);
} else {
- access.raw_access()->as_Load()->set_barrier_data(ZLoadBarrierStrong);
+ access.set_barrier_data(ZLoadBarrierStrong);
}
}
+}
- return result;
+Node* ZBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
+ set_barrier_data(access);
+ return BarrierSetC2::load_at_resolved(access, val_type);
}
Node* ZBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node* expected_val,
Node* new_val, const Type* val_type) const {
- Node* result = BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, val_type);
- if (barrier_needed(access)) {
- access.raw_access()->as_LoadStore()->set_barrier_data(ZLoadBarrierStrong);
- }
- return result;
+ set_barrier_data(access);
+ return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, val_type);
}
Node* ZBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node* expected_val,
Node* new_val, const Type* value_type) const {
- Node* result = BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type);
- if (barrier_needed(access)) {
- access.raw_access()->as_LoadStore()->set_barrier_data(ZLoadBarrierStrong);
- }
- return result;
-
+ set_barrier_data(access);
+ return BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type);
}
Node* ZBarrierSetC2::atomic_xchg_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const {
- Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, new_val, val_type);
- if (barrier_needed(access)) {
- access.raw_access()->as_LoadStore()->set_barrier_data(ZLoadBarrierStrong);
- }
- return result;
+ set_barrier_data(access);
+ return BarrierSetC2::atomic_xchg_at_resolved(access, new_val, val_type);
}
bool ZBarrierSetC2::array_copy_requires_gc_barriers(BasicType type) const {
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 7bf2f6cfb..a1547b42f 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -1493,18 +1493,19 @@ Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
bool require_atomic_access,
bool unaligned,
bool mismatched,
- bool unsafe) {
+ bool unsafe,
+ uint8_t barrier_data) {
assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
const TypePtr* adr_type = NULL; // debug-mode-only argument
debug_only(adr_type = C->get_adr_type(adr_idx));
Node* mem = memory(adr_idx);
Node* ld;
if (require_atomic_access && bt == T_LONG) {
- ld = LoadLNode::make_atomic(ctl, mem, adr, adr_type, t, mo, control_dependency, unaligned, mismatched, unsafe);
+ ld = LoadLNode::make_atomic(ctl, mem, adr, adr_type, t, mo, control_dependency, unaligned, mismatched, unsafe, barrier_data);
} else if (require_atomic_access && bt == T_DOUBLE) {
- ld = LoadDNode::make_atomic(ctl, mem, adr, adr_type, t, mo, control_dependency, unaligned, mismatched, unsafe);
+ ld = LoadDNode::make_atomic(ctl, mem, adr, adr_type, t, mo, control_dependency, unaligned, mismatched, unsafe, barrier_data);
} else {
- ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo, control_dependency, unaligned, mismatched, unsafe);
+ ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo, control_dependency, unaligned, mismatched, unsafe, barrier_data);
}
ld = _gvn.transform(ld);
if (((bt == T_OBJECT) && C->do_escape_analysis()) || C->eliminate_boxing()) {
diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp
index 07c20bbd5..df5d18ccc 100644
--- a/src/hotspot/share/opto/graphKit.hpp
+++ b/src/hotspot/share/opto/graphKit.hpp
@@ -518,27 +518,27 @@ class GraphKit : public Phase {
Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
MemNode::MemOrd mo, LoadNode::ControlDependency control_dependency = LoadNode::DependsOnlyOnTest,
bool require_atomic_access = false, bool unaligned = false,
- bool mismatched = false, bool unsafe = false) {
+ bool mismatched = false, bool unsafe = false, uint8_t barrier_data = 0) {
// This version computes alias_index from bottom_type
return make_load(ctl, adr, t, bt, adr->bottom_type()->is_ptr(),
mo, control_dependency, require_atomic_access,
- unaligned, mismatched, unsafe);
+ unaligned, mismatched, unsafe, barrier_data);
}
Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, const TypePtr* adr_type,
MemNode::MemOrd mo, LoadNode::ControlDependency control_dependency = LoadNode::DependsOnlyOnTest,
bool require_atomic_access = false, bool unaligned = false,
- bool mismatched = false, bool unsafe = false) {
+ bool mismatched = false, bool unsafe = false, uint8_t barrier_data = 0) {
// This version computes alias_index from an address type
assert(adr_type != NULL, "use other make_load factory");
return make_load(ctl, adr, t, bt, C->get_alias_index(adr_type),
mo, control_dependency, require_atomic_access,
- unaligned, mismatched, unsafe);
+ unaligned, mismatched, unsafe, barrier_data);
}
// This is the base version which is given an alias index.
Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, int adr_idx,
MemNode::MemOrd mo, LoadNode::ControlDependency control_dependency = LoadNode::DependsOnlyOnTest,
bool require_atomic_access = false, bool unaligned = false,
- bool mismatched = false, bool unsafe = false);
+ bool mismatched = false, bool unsafe = false, uint8_t barrier_data = 0);
// Create & transform a StoreNode and store the effect into the
// parser's memory state.
diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp
index ee0f09e11..ff0a5726c 100644
--- a/src/hotspot/share/opto/memnode.cpp
+++ b/src/hotspot/share/opto/memnode.cpp
@@ -808,7 +808,7 @@ bool LoadNode::is_immutable_value(Node* adr) {
//----------------------------LoadNode::make-----------------------------------
// Polymorphic factory method:
Node *LoadNode::make(PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt, MemOrd mo,
- ControlDependency control_dependency, bool unaligned, bool mismatched, bool unsafe) {
+ ControlDependency control_dependency, bool unaligned, bool mismatched, bool unsafe, uint8_t barrier_data) {
Compile* C = gvn.C;
// sanity check the alias category against the created node type
@@ -859,6 +859,7 @@ Node *LoadNode::make(PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypeP
if (unsafe) {
load->set_unsafe_access();
}
+ load->set_barrier_data(barrier_data);
if (load->Opcode() == Op_LoadN) {
Node* ld = gvn.transform(load);
return new DecodeNNode(ld, ld->bottom_type()->make_ptr());
@@ -868,7 +869,7 @@ Node *LoadNode::make(PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypeP
}
LoadLNode* LoadLNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo,
- ControlDependency control_dependency, bool unaligned, bool mismatched, bool unsafe) {
+ ControlDependency control_dependency, bool unaligned, bool mismatched, bool unsafe, uint8_t barrier_data) {
bool require_atomic = true;
LoadLNode* load = new LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, control_dependency, require_atomic);
if (unaligned) {
@@ -880,11 +881,12 @@ LoadLNode* LoadLNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr
if (unsafe) {
load->set_unsafe_access();
}
+ load->set_barrier_data(barrier_data);
return load;
}
LoadDNode* LoadDNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo,
- ControlDependency control_dependency, bool unaligned, bool mismatched, bool unsafe) {
+ ControlDependency control_dependency, bool unaligned, bool mismatched, bool unsafe, uint8_t barrier_data) {
bool require_atomic = true;
LoadDNode* load = new LoadDNode(ctl, mem, adr, adr_type, rt, mo, control_dependency, require_atomic);
if (unaligned) {
@@ -896,6 +898,7 @@ LoadDNode* LoadDNode::make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr
if (unsafe) {
load->set_unsafe_access();
}
+ load->set_barrier_data(barrier_data);
return load;
}
diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp
index 7468abdbc..14a4a67c6 100644
--- a/src/hotspot/share/opto/memnode.hpp
+++ b/src/hotspot/share/opto/memnode.hpp
@@ -227,7 +227,8 @@ public:
static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
const TypePtr* at, const Type *rt, BasicType bt,
MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest,
- bool unaligned = false, bool mismatched = false, bool unsafe = false);
+ bool unaligned = false, bool mismatched = false, bool unsafe = false,
+ uint8_t barrier_data = 0);
virtual uint hash() const; // Check the type
@@ -408,7 +409,7 @@ public:
bool require_atomic_access() const { return _require_atomic_access; }
static LoadLNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
const Type* rt, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest,
- bool unaligned = false, bool mismatched = false, bool unsafe = false);
+ bool unaligned = false, bool mismatched = false, bool unsafe = false, uint8_t barrier_data = 0);
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const {
LoadNode::dump_spec(st);
@@ -460,7 +461,7 @@ public:
bool require_atomic_access() const { return _require_atomic_access; }
static LoadDNode* make_atomic(Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
const Type* rt, MemOrd mo, ControlDependency control_dependency = DependsOnlyOnTest,
- bool unaligned = false, bool mismatched = false, bool unsafe = false);
+ bool unaligned = false, bool mismatched = false, bool unsafe = false, uint8_t barrier_data = 0);
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const {
LoadNode::dump_spec(st);
--
2.12.3

View File

@ -0,0 +1,67 @@
From b2ff55a515ffbead944a6cc64c77af0fb5bb9116 Mon Sep 17 00:00:00 2001
Date: Mon, 6 Jan 2020 16:25:39 +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
---
.../jdk/internal/agent/AgentConfigurationError.java | 2 ++
.../sun/management/jmxremote/ConnectorBootstrap.java | 19 ++++++++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/jdk.management.agent/share/classes/jdk/internal/agent/AgentConfigurationError.java b/src/jdk.management.agent/share/classes/jdk/internal/agent/AgentConfigurationError.java
index fb00b9f79..5f5e1672f 100644
--- a/src/jdk.management.agent/share/classes/jdk/internal/agent/AgentConfigurationError.java
+++ b/src/jdk.management.agent/share/classes/jdk/internal/agent/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/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
index 8d2031f88..12848cbeb 100644
--- a/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
+++ b/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
@@ -116,6 +116,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 =
@@ -539,9 +541,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,37 @@
From 954a4ad3a2a8bb54fb64a524b53f9c87c54cb7a1 Mon Sep 17 00:00:00 2001
Date: Wed, 26 Feb 2020 09:47:33 +0800
Subject: [PATCH] aarch64: add_loadload_membar_to_avoid_loading_a_incorrect_offset
Summary: <interpreter>: <add loadload membar in fast_storefield and fast_accessfield to avoid loading a incorrect offset>
LLT: jtreg
Bug url: NA
---
src/hotspot/cpu/aarch64/templateTable_aarch64.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
index b8a9a46a8..019a4aadd 100644
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
@@ -2963,6 +2963,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())));
@@ -3055,6 +3057,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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
From 425112071e77e2fb599d1f96ce48689d45461261 Mon Sep 17 00:00:00 2001
Date: Mon, 17 Feb 2020 18:55:47 +0800
Subject: [PATCH] ZGC: aarch64: not using zr register avoid sigill in
MacroAssembler::push_fp and pop_fp
Summary: <gc>: <instruction ldp doesn't support two same register>
LLT: jtreg
Bug url: NA
---
src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 46 +++++++++++++---------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
index 611f13b0e..6db979b57 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -2100,57 +2100,59 @@ int MacroAssembler::pop(unsigned int bitset, Register stack) {
// Push lots of registers in the bit set supplied. Don't push sp.
// Return the number of words pushed
int MacroAssembler::push_fp(unsigned int bitset, Register stack) {
- int words_pushed = 0;
-
// Scan bitset to accumulate register pairs
unsigned char regs[32];
int count = 0;
+ int i = 0;
for (int reg = 0; reg <= 31; reg++) {
if (1 & bitset)
regs[count++] = reg;
bitset >>= 1;
}
- regs[count++] = zr->encoding_nocheck();
- count &= ~1; // Only push an even number of regs
- // Always pushing full 128 bit registers.
- if (count) {
- stpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(pre(stack, -count * wordSize * 2)));
- words_pushed += 2;
+ if (!count) {
+ return 0;
}
- for (int i = 2; i < count; i += 2) {
+
+ add(stack, stack, -count * wordSize * 2);
+
+ if (count & 1) {
+ strq(as_FloatRegister(regs[0]), Address(stack));
+ i += 1;
+ }
+
+ for (; i < count; i += 2) {
stpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
- words_pushed += 2;
}
- assert(words_pushed == count, "oops, pushed != count");
return count;
}
int MacroAssembler::pop_fp(unsigned int bitset, Register stack) {
- int words_pushed = 0;
-
// Scan bitset to accumulate register pairs
unsigned char regs[32];
int count = 0;
+ int i = 0;
for (int reg = 0; reg <= 31; reg++) {
if (1 & bitset)
regs[count++] = reg;
bitset >>= 1;
}
- regs[count++] = zr->encoding_nocheck();
- count &= ~1;
- for (int i = 2; i < count; i += 2) {
- ldpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
- words_pushed += 2;
+ if (!count) {
+ return 0;
}
- if (count) {
- ldpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(post(stack, count * wordSize * 2)));
- words_pushed += 2;
+
+ if (count & 1) {
+ ldrq(as_FloatRegister(regs[0]), Address(stack));
+ i += 1;
}
- assert(words_pushed == count, "oops, pushed != count");
+ for (; i < count; i += 2) {
+ ldpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
+ }
+
+ add(stack, stack, count * wordSize * 2);
return count;
}

View File

@ -0,0 +1,54 @@
From 1ab27951c430bbe0820321c7194e89f63b9ac78b Mon Sep 17 00:00:00 2001
Date: Tue, 30 Jul 2019 14:20:57 +0000
Subject: [PATCH] change vendor to Huawei Technologies Co., LTD
Summary: change VENDOR to openEuler Community, as
well as VENDOR_URL & VENDOR_URL_BUG
LLT: java -XshowSettings:properties
Bug url: NA
---
src/hotspot/share/runtime/vm_version.cpp | 6 +-----
src/java.base/share/native/libjava/System.c | 6 +++---
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/hotspot/share/runtime/vm_version.cpp b/src/hotspot/share/runtime/vm_version.cpp
index eb05460ad..bb070895f 100644
--- a/src/hotspot/share/runtime/vm_version.cpp
+++ b/src/hotspot/share/runtime/vm_version.cpp
@@ -114,11 +114,7 @@ const char* Abstract_VM_Version::vm_name() {
const char* Abstract_VM_Version::vm_vendor() {
-#ifdef VENDOR
- return VENDOR;
-#else
- return "Oracle Corporation";
-#endif
+ return "openEuler Community";
}
diff --git a/src/java.base/share/native/libjava/System.c b/src/java.base/share/native/libjava/System.c
index 3a33f1179..65a44d5a1 100644
--- a/src/java.base/share/native/libjava/System.c
+++ b/src/java.base/share/native/libjava/System.c
@@ -110,13 +110,13 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
/* Third party may overwrite these values. */
#ifndef VENDOR
-#define VENDOR "Oracle Corporation"
+#define VENDOR "openEuler Community"
#endif
#ifndef VENDOR_URL
-#define VENDOR_URL "http://java.oracle.com/"
+#define VENDOR_URL "https://openeuler.org/"
#endif
#ifndef VENDOR_URL_BUG
-#define VENDOR_URL_BUG "http://bugreport.java.com/bugreport/"
+#define VENDOR_URL_BUG "https://openeuler.org/"
#endif
#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
--
2.19.0

View File

@ -0,0 +1,84 @@
From f8e686fda7c681d1b27e266d3f954d6441aee83a Mon Sep 17 00:00:00 2001
Date: Thu, 13 Feb 2020 19:07:20 +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: test/jdk/java/awt/FontMetrics/SpaceAdvance.java
Bug url: https://bugs.openjdk.java.net/browse/JDK-8237381
---
.../share/native/libfontmanager/freetypeScaler.c | 2 +-
test/jdk/java/awt/FontMetrics/SpaceAdvance.java | 49 ++++++++++++++++++++++
2 files changed, 50 insertions(+), 1 deletion(-)
create mode 100644 test/jdk/java/awt/FontMetrics/SpaceAdvance.java
diff --git a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
index bca003d31..cc8432866 100644
--- a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
+++ b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
@@ -161,7 +161,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/test/jdk/java/awt/FontMetrics/SpaceAdvance.java b/test/jdk/java/awt/FontMetrics/SpaceAdvance.java
new file mode 100644
index 000000000..e2c7acb6f
--- /dev/null
+++ b/test/jdk/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

1736
java-11-openjdk.spec Normal file

File diff suppressed because it is too large Load Diff

BIN
openjdk-11.0.6-ga.tar.xz Normal file

Binary file not shown.

View File

@ -0,0 +1,27 @@
From fd0b27781fdc8a8d4089aeca7acfcaf7cfb1a82c Mon Sep 17 00:00:00 2001
Date: Thu, 19 Mar 2020 15:07:23 +0800
Subject: [PATCH] prohibition of irreducible loop in mergers
Summary: C2Compiler: irreducible loop should not enter merge_many_backedges
LLT: NA
Bug url: NA
---
src/hotspot/share/opto/loopnode.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp
index da81c3a5d..5c01a44e4 100644
--- a/src/hotspot/share/opto/loopnode.cpp
+++ b/src/hotspot/share/opto/loopnode.cpp
@@ -2089,7 +2089,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