Update to 11.0.8+10 (GA)

This commit is contained in:
hedongbo 2020-07-18 20:49:32 +08:00
parent 41344fb3a3
commit 20674d8e41
12 changed files with 173 additions and 1276 deletions

View File

@ -1,63 +0,0 @@
From 06c663befa33d4a71faed3f58ae47faab753b658 Mon Sep 17 00:00:00 2001
Date: Sat, 28 Mar 2020 12:00:06 +0000
Subject: [PATCH] 8210303 VM_HandshakeAllThreads fails assert with "failed:
blocked and not walkable"
Summary: <gc>: <vmthread can process handshake in more conditions>
LLT: jdk11u/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java
Bug url: https://bugs.openjdk.java.net/browse/JDK-8210303
---
src/hotspot/share/runtime/handshake.cpp | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/runtime/handshake.cpp b/src/hotspot/share/runtime/handshake.cpp
index 7aac489..1891623 100644
--- a/src/hotspot/share/runtime/handshake.cpp
+++ b/src/hotspot/share/runtime/handshake.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -343,6 +343,27 @@ bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
return SafepointSynchronize::safepoint_safe(target, target->thread_state());
}
+static bool possibly_vmthread_can_process_handshake(JavaThread* target) {
+ // An externally suspended thread cannot be resumed while the
+ // Threads_lock is held so it is safe.
+ // Note that this method is allowed to produce false positives.
+ assert(Threads_lock->owned_by_self(), "Not holding Threads_lock.");
+ if (target->is_ext_suspended()) {
+ return true;
+ }
+ switch (target->thread_state()) {
+ case _thread_in_native:
+ // native threads are safe if they have no java stack or have walkable stack
+ return !target->has_last_Java_frame() || target->frame_anchor()->walkable();
+
+ case _thread_blocked:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
bool HandshakeState::claim_handshake_for_vmthread() {
if (!_semaphore.trywait()) {
return false;
@@ -362,7 +383,7 @@ void HandshakeState::process_by_vmthread(JavaThread* target) {
return;
}
- if (!vmthread_can_process_handshake(target)) {
+ if (!possibly_vmthread_can_process_handshake(target)) {
// JT is observed in an unsafe state, it must notice the handshake itself
return;
}
--
1.8.3.1

View File

@ -1,359 +0,0 @@
From ae26670a6db1950136b2838c2f57864cfd9964d0 Mon Sep 17 00:00:00 2001
Date: Wed, 1 Apr 2020 21:22:56 +0000
Subject: [PATCH] 8212933: Thread-SMR: requesting a VM operation whilst holding
a ThreadsListHandle can cause deadlocks
Summary: <gc>: <vmthread process handshake in condition of a exiting java thread>
LLT: test/hotspot/jtreg/runtime/handshake/HandshakeWalkSuspendExitTest.java
Bug url: https://bugs.openjdk.java.net/browse/JDK-8212933
---
src/hotspot/share/runtime/handshake.cpp | 69 ++++++----------
src/hotspot/share/runtime/handshake.hpp | 9 +--
src/hotspot/share/runtime/thread.cpp | 3 -
src/hotspot/share/runtime/thread.hpp | 4 -
src/hotspot/share/runtime/threadSMR.cpp | 5 --
.../handshake/HandshakeWalkSuspendExitTest.java | 93 ++++++++++++++++++++++
6 files changed, 117 insertions(+), 66 deletions(-)
create mode 100644 test/hotspot/jtreg/runtime/handshake/HandshakeWalkSuspendExitTest.java
diff --git a/src/hotspot/share/runtime/handshake.cpp b/src/hotspot/share/runtime/handshake.cpp
index b84bf22..025861f 100644
--- a/src/hotspot/share/runtime/handshake.cpp
+++ b/src/hotspot/share/runtime/handshake.cpp
@@ -41,7 +41,6 @@
class HandshakeOperation: public StackObj {
public:
virtual void do_handshake(JavaThread* thread) = 0;
- virtual void cancel_handshake(JavaThread* thread) = 0;
};
class HandshakeThreadsOperation: public HandshakeOperation {
@@ -51,8 +50,6 @@ class HandshakeThreadsOperation: public HandshakeOperation {
public:
HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {}
void do_handshake(JavaThread* thread);
- void cancel_handshake(JavaThread* thread) { _done.signal(); };
-
bool thread_has_completed() { return _done.trywait(); }
#ifdef ASSERT
@@ -122,15 +119,11 @@ class VM_HandshakeOneThread: public VM_Handshake {
DEBUG_ONLY(_op->check_state();)
TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
- {
- ThreadsListHandle tlh;
- if (tlh.includes(_target)) {
- set_handshake(_target);
- _thread_alive = true;
- }
- }
-
- if (!_thread_alive) {
+ ThreadsListHandle tlh;
+ if (tlh.includes(_target)) {
+ set_handshake(_target);
+ _thread_alive = true;
+ } else {
return;
}
@@ -148,20 +141,9 @@ class VM_HandshakeOneThread: public VM_Handshake {
// We need to re-think this with SMR ThreadsList.
// There is an assumption in the code that the Threads_lock should be
// locked during certain phases.
- MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
- ThreadsListHandle tlh;
- if (tlh.includes(_target)) {
- // Warning _target's address might be re-used.
- // handshake_process_by_vmthread will check the semaphore for us again.
- // Since we can't have more then one handshake in flight a reuse of
- // _target's address should be okay since the new thread will not have
- // an operation.
+ {
+ MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
_target->handshake_process_by_vmthread();
- } else {
- // We can't warn here since the thread does cancel_handshake after
- // it has been removed from the ThreadsList. So we should just keep
- // looping here until while below returns false. If we have a bug,
- // then we hang here, which is good for debugging.
}
} while (!poll_for_completed_thread());
DEBUG_ONLY(_op->check_state();)
@@ -180,8 +162,9 @@ class VM_HandshakeAllThreads: public VM_Handshake {
DEBUG_ONLY(_op->check_state();)
TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
+ JavaThreadIteratorWithHandle jtiwh;
int number_of_threads_issued = 0;
- for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
+ for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
set_handshake(thr);
number_of_threads_issued++;
}
@@ -211,8 +194,9 @@ class VM_HandshakeAllThreads: public VM_Handshake {
// We need to re-think this with SMR ThreadsList.
// There is an assumption in the code that the Threads_lock should
// be locked during certain phases.
+ jtiwh.rewind();
MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
- for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
+ for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
// A new thread on the ThreadsList will not have an operation,
// hence it is skipped in handshake_process_by_vmthread.
thr->handshake_process_by_vmthread();
@@ -263,7 +247,11 @@ void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
- _thread_cl->do_thread(thread);
+
+ // Only actually execute the operation for non terminated threads.
+ if (!thread->is_terminated()) {
+ _thread_cl->do_thread(thread);
+ }
// Use the semaphore to inform the VM thread that we have completed the operation
_done.signal();
@@ -307,12 +295,7 @@ void HandshakeState::clear_handshake(JavaThread* target) {
void HandshakeState::process_self_inner(JavaThread* thread) {
assert(Thread::current() == thread, "should call from thread");
-
- if (thread->is_terminated()) {
- // If thread is not on threads list but armed, cancel.
- thread->cancel_handshake();
- return;
- }
+ assert(!thread->is_terminated(), "should not be a terminated thread");
ThreadInVMForHandshake tivm(thread);
if (!_semaphore.trywait()) {
@@ -329,18 +312,8 @@ void HandshakeState::process_self_inner(JavaThread* thread) {
_semaphore.signal();
}
-void HandshakeState::cancel_inner(JavaThread* thread) {
- assert(Thread::current() == thread, "should call from thread");
- assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
- HandshakeOperation* op = _operation;
- clear_handshake(thread);
- if (op != NULL) {
- op->cancel_handshake(thread);
- }
-}
-
bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
- return SafepointSynchronize::safepoint_safe(target, target->thread_state());
+ return SafepointSynchronize::safepoint_safe(target, target->thread_state()) || target->is_terminated();
}
static bool possibly_vmthread_can_process_handshake(JavaThread* target) {
@@ -357,6 +330,9 @@ static bool possibly_vmthread_can_process_handshake(JavaThread* target) {
if (target->is_ext_suspended()) {
return true;
}
+ if (target->is_terminated()) {
+ return true;
+ }
switch (target->thread_state()) {
case _thread_in_native:
// native threads are safe if they have no java stack or have walkable stack
@@ -383,6 +359,8 @@ bool HandshakeState::claim_handshake_for_vmthread() {
void HandshakeState::process_by_vmthread(JavaThread* target) {
assert(Thread::current()->is_VM_thread(), "should call from vm thread");
+ // Threads_lock must be held here, but that is assert()ed in
+ // possibly_vmthread_can_process_handshake().
if (!has_operation()) {
// JT has already cleared its handshake
@@ -404,7 +382,6 @@ void HandshakeState::process_by_vmthread(JavaThread* target) {
// getting caught by the semaphore.
if (vmthread_can_process_handshake(target)) {
guarantee(!_semaphore.trywait(), "we should already own the semaphore");
-
_operation->do_handshake(target);
// Disarm after VM thread have executed the operation.
clear_handshake(target);
diff --git a/src/hotspot/share/runtime/handshake.hpp b/src/hotspot/share/runtime/handshake.hpp
index 88dcd7e..a735d1e 100644
--- a/src/hotspot/share/runtime/handshake.hpp
+++ b/src/hotspot/share/runtime/handshake.hpp
@@ -60,7 +60,6 @@ class HandshakeState {
bool vmthread_can_process_handshake(JavaThread* target);
void clear_handshake(JavaThread* thread);
- void cancel_inner(JavaThread* thread);
void process_self_inner(JavaThread* thread);
public:
@@ -72,19 +71,13 @@ public:
return _operation != NULL;
}
- void cancel(JavaThread* thread) {
- if (!_thread_in_process_handshake) {
- FlagSetting fs(_thread_in_process_handshake, true);
- cancel_inner(thread);
- }
- }
-
void process_by_self(JavaThread* thread) {
if (!_thread_in_process_handshake) {
FlagSetting fs(_thread_in_process_handshake, true);
process_self_inner(thread);
}
}
+
void process_by_vmthread(JavaThread* target);
};
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp
index d794ae8..7846525 100644
--- a/src/hotspot/share/runtime/thread.cpp
+++ b/src/hotspot/share/runtime/thread.cpp
@@ -4258,9 +4258,6 @@ bool Threads::destroy_vm() {
before_exit(thread);
thread->exit(true);
- // thread will never call smr_delete, instead of implicit cancel
- // in wait_for_vm_thread_exit we do it explicit.
- thread->cancel_handshake();
// Stop VM thread.
{
diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp
index 90cb7cb..fc469c8 100644
--- a/src/hotspot/share/runtime/thread.hpp
+++ b/src/hotspot/share/runtime/thread.hpp
@@ -1228,10 +1228,6 @@ class JavaThread: public Thread {
return _handshake.has_operation();
}
- void cancel_handshake() {
- _handshake.cancel(this);
- }
-
void handshake_process_by_self() {
_handshake.process_by_self(this);
}
diff --git a/src/hotspot/share/runtime/threadSMR.cpp b/src/hotspot/share/runtime/threadSMR.cpp
index 8b232fb..ba18aa4 100644
--- a/src/hotspot/share/runtime/threadSMR.cpp
+++ b/src/hotspot/share/runtime/threadSMR.cpp
@@ -989,11 +989,6 @@ void ThreadsSMRSupport::smr_delete(JavaThread *thread) {
// Retry the whole scenario.
}
- if (ThreadLocalHandshakes) {
- // The thread is about to be deleted so cancel any handshake.
- thread->cancel_handshake();
- }
-
delete thread;
if (EnableThreadSMRStatistics) {
timer.stop();
diff --git a/test/hotspot/jtreg/runtime/handshake/HandshakeWalkSuspendExitTest.java b/test/hotspot/jtreg/runtime/handshake/HandshakeWalkSuspendExitTest.java
new file mode 100644
index 0000000..26b6f63
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/handshake/HandshakeWalkSuspendExitTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test HandshakeWalkSuspendExitTest
+ * @summary This test tries to stress the handshakes with new and exiting threads while suspending them.
+ * @library /testlibrary /test/lib
+ * @build HandshakeWalkSuspendExitTest
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI HandshakeWalkSuspendExitTest
+ */
+
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+public class HandshakeWalkSuspendExitTest implements Runnable {
+
+ static final int _test_threads = 8;
+ static final int _test_exit_threads = 128;
+ static Thread[] _threads = new Thread[_test_threads];
+ static volatile boolean exit_now = false;
+ static java.util.concurrent.Semaphore _sem = new java.util.concurrent.Semaphore(0);
+
+ @Override
+ public void run() {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+ while (!exit_now) {
+ _sem.release();
+ // We only suspend threads on even index and not ourself.
+ // Otherwise we can accidentially suspend all threads.
+ for (int i = 0; i < _threads.length; i += 2) {
+ wb.handshakeWalkStack(null /* ignored */, true /* stackwalk all threads */);
+ if (Thread.currentThread() != _threads[i]) {
+ _threads[i].suspend();
+ _threads[i].resume();
+ }
+ }
+ for (int i = 0; i < _threads.length; i += 2) {
+ wb.handshakeWalkStack(_threads[i] /* thread to stackwalk */, false /* stackwalk one thread */);
+ if (Thread.currentThread() != _threads[i]) {
+ _threads[i].suspend();
+ _threads[i].resume();
+ }
+ }
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ HandshakeWalkSuspendExitTest test = new HandshakeWalkSuspendExitTest();
+
+ for (int i = 0; i < _threads.length; i++) {
+ _threads[i] = new Thread(test);
+ _threads[i].start();
+ }
+ for (int i = 0; i < _test_threads; i++) {
+ _sem.acquire();
+ }
+ Thread[] exit_threads = new Thread[_test_exit_threads];
+ for (int i = 0; i < _test_exit_threads; i++) {
+ exit_threads[i] = new Thread(new Runnable() { public void run() {} });
+ exit_threads[i].start();
+ }
+ exit_now = true;
+ for (int i = 0; i < _threads.length; i++) {
+ _threads[i].join();
+ }
+ for (int i = 0; i < exit_threads.length; i++) {
+ exit_threads[i].join();
+ }
+ }
+}
--
1.8.3.1

View File

@ -1,73 +0,0 @@
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

View File

@ -1,15 +0,0 @@
diff --git a/src/hotspot/share/memory/filemap.cpp b/src/hotspot/share/memory/filemap.cpp
index 85d55bd8f..46060101e 100644
--- a/src/hotspot/share/memory/filemap.cpp
+++ b/src/hotspot/share/memory/filemap.cpp
@@ -1287,7 +1287,9 @@ bool FileMapInfo::initialize() {
}
init_from_file(_fd);
- if (!validate_header()) {
+ // UseSharedSpaces could be disabled if the checking of some of the header fields in
+ // init_from_file has failed.
+ if (!UseSharedSpaces || !validate_header()) {
return false;
}
return true;

View File

@ -1,365 +0,0 @@
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

@ -1,18 +1,3 @@
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 diff --git a/src/hotspot/share/c1/c1_Instruction.cpp b/src/hotspot/share/c1/c1_Instruction.cpp
index ee3be899a..62d8b48bc 100644 index ee3be899a..62d8b48bc 100644
--- a/src/hotspot/share/c1/c1_Instruction.cpp --- a/src/hotspot/share/c1/c1_Instruction.cpp
@ -26,7 +11,7 @@ index ee3be899a..62d8b48bc 100644
// Implementation of Instruction // Implementation of Instruction
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 2ceb3a6ae..981d6b860 100644 index 852b763c1..31b8ffa21 100644
--- a/src/hotspot/share/opto/graphKit.cpp --- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp
@@ -43,6 +43,7 @@ @@ -43,6 +43,7 @@
@ -38,7 +23,7 @@ index 2ceb3a6ae..981d6b860 100644
//----------------------------GraphKit----------------------------------------- //----------------------------GraphKit-----------------------------------------
// Main utility constructor. // Main utility constructor.
diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp
index a6408b493..0b30303a3 100644 index 177663653..eae7673f9 100644
--- a/src/hotspot/share/opto/parse1.cpp --- a/src/hotspot/share/opto/parse1.cpp
+++ b/src/hotspot/share/opto/parse1.cpp +++ b/src/hotspot/share/opto/parse1.cpp
@@ -41,6 +41,7 @@ @@ -41,6 +41,7 @@
@ -50,7 +35,7 @@ index a6408b493..0b30303a3 100644
// Static array so we can figure out which bytecodes stop us from compiling // 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 diff --git a/src/hotspot/share/utilities/bitMap.hpp b/src/hotspot/share/utilities/bitMap.hpp
index 656e11fb7..4d6749f5b 100644 index c671535c9..e26f34687 100644
--- a/src/hotspot/share/utilities/bitMap.hpp --- a/src/hotspot/share/utilities/bitMap.hpp
+++ b/src/hotspot/share/utilities/bitMap.hpp +++ b/src/hotspot/share/utilities/bitMap.hpp
@@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
@ -59,9 +44,9 @@ index 656e11fb7..4d6749f5b 100644
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
+#include "runtime/atomic.hpp" +#include "runtime/atomic.hpp"
#include "utilities/align.hpp" #include "utilities/align.hpp"
#include "utilities/globalDefinitions.hpp"
// Forward decl; @@ -95,6 +96,8 @@ class BitMap {
@@ -94,6 +95,8 @@ class BitMap {
void set_word (idx_t word) { set_word(word, ~(bm_word_t)0); } void set_word (idx_t word) { set_word(word, ~(bm_word_t)0); }
void clear_word(idx_t word) { _map[word] = 0; } void clear_word(idx_t word) { _map[word] = 0; }
@ -70,7 +55,7 @@ index 656e11fb7..4d6749f5b 100644
// Utilities for ranges of bits. Ranges are half-open [beg, end). // Utilities for ranges of bits. Ranges are half-open [beg, end).
// Ranges within a single word. // Ranges within a single word.
@@ -193,6 +196,9 @@ class BitMap { @@ -194,6 +197,9 @@ class BitMap {
return (*word_addr(index) & bit_mask(index)) != 0; return (*word_addr(index) & bit_mask(index)) != 0;
} }
@ -80,7 +65,7 @@ index 656e11fb7..4d6749f5b 100644
// Align bit index up or down to the next bitmap word boundary, or check // Align bit index up or down to the next bitmap word boundary, or check
// alignment. // alignment.
static idx_t word_align_up(idx_t bit) { static idx_t word_align_up(idx_t bit) {
@@ -209,9 +215,14 @@ class BitMap { @@ -210,9 +216,14 @@ class BitMap {
inline void set_bit(idx_t bit); inline void set_bit(idx_t bit);
inline void clear_bit(idx_t bit); inline void clear_bit(idx_t bit);
@ -175,6 +160,3 @@ index b10726d18..7a7e2ad43 100644
if (cur_val == old_val) { if (cur_val == old_val) {
return true; // Success. return true; // Success.
} }
--
2.12.3

View File

@ -7,45 +7,9 @@ Summary: <gc>: <expand C2 load barrier in load instruction avoid safepoint betwe
LLT: jtreg LLT: jtreg
Bug url: https://bugs.openjdk.java.net/browse/JDK-8230565 Bug url: https://bugs.openjdk.java.net/browse/JDK-8230565
--- ---
src/hotspot/cpu/aarch64/aarch64.ad | 362 +++--
.../aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp | 246 +--
.../aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp | 26 +-
src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 59 +
src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp | 6 +
src/hotspot/cpu/aarch64/register_aarch64.hpp | 5 +
.../templateInterpreterGenerator_aarch64.cpp | 4 +-
.../cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp | 403 +++--
.../cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp | 30 +-
src/hotspot/cpu/x86/x86.ad | 136 +-
src/hotspot/cpu/x86/x86_64.ad | 492 ++----
src/hotspot/share/adlc/formssel.cpp | 8 -
src/hotspot/share/compiler/compilerDirectives.hpp | 3 +-
src/hotspot/share/gc/shared/c2/barrierSetC2.hpp | 8 +-
src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp | 1646 ++++----------------
src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp | 181 +--
src/hotspot/share/gc/z/zBarrierSetAssembler.hpp | 5 +-
src/hotspot/share/opto/classes.cpp | 3 -
src/hotspot/share/opto/classes.hpp | 11 -
src/hotspot/share/opto/compile.cpp | 52 +-
src/hotspot/share/opto/compile.hpp | 25 +-
src/hotspot/share/opto/escape.cpp | 15 -
src/hotspot/share/opto/lcm.cpp | 1 -
src/hotspot/share/opto/loopnode.cpp | 13 -
src/hotspot/share/opto/loopopts.cpp | 3 -
src/hotspot/share/opto/machnode.hpp | 9 +-
src/hotspot/share/opto/matcher.cpp | 45 +-
src/hotspot/share/opto/memnode.cpp | 5 +-
src/hotspot/share/opto/memnode.hpp | 46 +-
src/hotspot/share/opto/node.cpp | 7 -
src/hotspot/share/opto/node.hpp | 6 -
src/hotspot/share/opto/output.cpp | 424 ++---
src/hotspot/share/opto/output.hpp | 5 +-
src/hotspot/share/opto/phaseX.cpp | 8 +-
src/hotspot/share/opto/vectornode.cpp | 1 -
35 files changed, 1529 insertions(+), 2770 deletions(-)
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index 3b898f548..93dd78e51 100644 index d64566b81..b6e5d7267 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad --- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -1131,6 +1131,7 @@ definitions %{ @@ -1131,6 +1131,7 @@ definitions %{
@ -150,7 +114,7 @@ index 3b898f548..93dd78e51 100644
ins_cost(VOLATILE_REF_COST); ins_cost(VOLATILE_REF_COST);
format %{ "ldar $dst, $mem\t# ptr" %} format %{ "ldar $dst, $mem\t# ptr" %}
@@ -8511,6 +8520,7 @@ instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoS @@ -8500,6 +8509,7 @@ instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoS
instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
match(Set res (CompareAndSwapP mem (Binary oldval newval))); match(Set res (CompareAndSwapP mem (Binary oldval newval)));
@ -158,7 +122,7 @@ index 3b898f548..93dd78e51 100644
ins_cost(2 * VOLATILE_REF_COST); ins_cost(2 * VOLATILE_REF_COST);
effect(KILL cr); effect(KILL cr);
@@ -8624,7 +8634,7 @@ instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegL @@ -8613,7 +8623,7 @@ instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegL
instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
@ -167,7 +131,7 @@ index 3b898f548..93dd78e51 100644
match(Set res (CompareAndSwapP mem (Binary oldval newval))); match(Set res (CompareAndSwapP mem (Binary oldval newval)));
ins_cost(VOLATILE_REF_COST); ins_cost(VOLATILE_REF_COST);
@@ -8755,6 +8765,7 @@ instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN ne @@ -8744,6 +8754,7 @@ instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN ne
%} %}
instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
@ -175,7 +139,7 @@ index 3b898f548..93dd78e51 100644
match(Set res (CompareAndExchangeP mem (Binary oldval newval))); match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
ins_cost(2 * VOLATILE_REF_COST); ins_cost(2 * VOLATILE_REF_COST);
effect(TEMP_DEF res, KILL cr); effect(TEMP_DEF res, KILL cr);
@@ -8854,7 +8865,7 @@ instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN @@ -8843,7 +8854,7 @@ instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN
%} %}
instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
@ -184,7 +148,7 @@ index 3b898f548..93dd78e51 100644
match(Set res (CompareAndExchangeP mem (Binary oldval newval))); match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
ins_cost(VOLATILE_REF_COST); ins_cost(VOLATILE_REF_COST);
effect(TEMP_DEF res, KILL cr); effect(TEMP_DEF res, KILL cr);
@@ -8955,6 +8966,7 @@ instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN ne @@ -8944,6 +8955,7 @@ instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN ne
%} %}
instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
@ -192,7 +156,7 @@ index 3b898f548..93dd78e51 100644
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
ins_cost(2 * VOLATILE_REF_COST); ins_cost(2 * VOLATILE_REF_COST);
effect(KILL cr); effect(KILL cr);
@@ -9062,8 +9074,8 @@ instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN @@ -9051,8 +9063,8 @@ instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN
%} %}
instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
@ -202,7 +166,7 @@ index 3b898f548..93dd78e51 100644
ins_cost(VOLATILE_REF_COST); ins_cost(VOLATILE_REF_COST);
effect(KILL cr); effect(KILL cr);
format %{ format %{
@@ -9113,6 +9125,7 @@ instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ @@ -9102,6 +9114,7 @@ instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
%} %}
instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
@ -210,7 +174,7 @@ index 3b898f548..93dd78e51 100644
match(Set prev (GetAndSetP mem newv)); match(Set prev (GetAndSetP mem newv));
ins_cost(2 * VOLATILE_REF_COST); ins_cost(2 * VOLATILE_REF_COST);
format %{ "atomic_xchg $prev, $newv, [$mem]" %} format %{ "atomic_xchg $prev, $newv, [$mem]" %}
@@ -9156,7 +9169,7 @@ instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ @@ -9145,7 +9158,7 @@ instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
%} %}
instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
@ -219,7 +183,7 @@ index 3b898f548..93dd78e51 100644
match(Set prev (GetAndSetP mem newv)); match(Set prev (GetAndSetP mem newv));
ins_cost(VOLATILE_REF_COST); ins_cost(VOLATILE_REF_COST);
format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
@@ -17476,145 +17489,238 @@ instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ @@ -17465,145 +17478,238 @@ instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{
source %{ source %{
@ -974,7 +938,7 @@ index 7e8be01cc..cca873825 100644
#endif // CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP #endif // CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
index 508c13c27..611f13b0e 100644 index c0d093191..bd6ebb28b 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -2096,6 +2096,65 @@ int MacroAssembler::pop(unsigned int bitset, Register stack) { @@ -2096,6 +2096,65 @@ int MacroAssembler::pop(unsigned int bitset, Register stack) {
@ -1083,10 +1047,10 @@ index 8cda52a0a..5f7662c89 100644
return RegSet(r1); return RegSet(r1);
} }
diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
index 45e47f19e..026f441fc 100644 index 2144a78f3..4ba3a6326 100644
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
@@ -873,8 +873,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { @@ -872,8 +872,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
} }
// Get mirror and store it in the frame as GC root for this Method* // Get mirror and store it in the frame as GC root for this Method*
@ -1098,7 +1062,7 @@ index 45e47f19e..026f441fc 100644
__ ldr(rcpool, Address(rmethod, Method::const_offset())); __ ldr(rcpool, Address(rmethod, Method::const_offset()));
__ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset())); __ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset()));
diff --git a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp diff --git a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp
index 3aa3f8579..18f455086 100644 index 381211ecc..d88ecf7b8 100644
--- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp
@@ -27,16 +27,16 @@ @@ -27,16 +27,16 @@
@ -1613,7 +1577,7 @@ index 3687754e7..e433882a4 100644
#endif // CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP #endif // CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad
index 7052ccba6..8f0e2225a 100644 index 1052ea6e3..e21074b4a 100644
--- a/src/hotspot/cpu/x86/x86.ad --- a/src/hotspot/cpu/x86/x86.ad
+++ b/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad
@@ -1097,138 +1097,6 @@ reg_class vectorz_reg_legacy(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0 @@ -1097,138 +1097,6 @@ reg_class vectorz_reg_legacy(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0
@ -1767,7 +1731,7 @@ index 7052ccba6..8f0e2225a 100644
// into scratch buffer is used to get size in 64-bit VM. // into scratch buffer is used to get size in 64-bit VM.
LP64_ONLY( assert(!do_size, "this method calculates size only for 32-bit VM"); ) LP64_ONLY( assert(!do_size, "this method calculates size only for 32-bit VM"); )
diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad
index 97c396875..f795fb823 100644 index 84bed19aa..8b975311e 100644
--- a/src/hotspot/cpu/x86/x86_64.ad --- a/src/hotspot/cpu/x86/x86_64.ad
+++ b/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad
@@ -541,6 +541,7 @@ reg_class int_rdi_reg(RDI); @@ -541,6 +541,7 @@ reg_class int_rdi_reg(RDI);
@ -1954,7 +1918,7 @@ index 97c396875..f795fb823 100644
ins_cost(125); // XXX ins_cost(125); // XXX
format %{ "movq $dst, $mem\t# ptr" %} format %{ "movq $dst, $mem\t# ptr" %}
@@ -7526,6 +7411,7 @@ instruct storePConditional(memory heap_top_ptr, @@ -7515,6 +7400,7 @@ instruct storePConditional(memory heap_top_ptr,
rax_RegP oldval, rRegP newval, rax_RegP oldval, rRegP newval,
rFlagsReg cr) rFlagsReg cr)
%{ %{
@ -1962,7 +1926,7 @@ index 97c396875..f795fb823 100644
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
@@ -7577,7 +7463,7 @@ instruct compareAndSwapP(rRegI res, @@ -7566,7 +7452,7 @@ instruct compareAndSwapP(rRegI res,
rax_RegP oldval, rRegP newval, rax_RegP oldval, rRegP newval,
rFlagsReg cr) rFlagsReg cr)
%{ %{
@ -1971,7 +1935,7 @@ index 97c396875..f795fb823 100644
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
@@ -7819,7 +7705,7 @@ instruct compareAndExchangeP( @@ -7808,7 +7694,7 @@ instruct compareAndExchangeP(
rax_RegP oldval, rRegP newval, rax_RegP oldval, rRegP newval,
rFlagsReg cr) rFlagsReg cr)
%{ %{
@ -1980,7 +1944,7 @@ index 97c396875..f795fb823 100644
match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
effect(KILL cr); effect(KILL cr);
@@ -7964,6 +7850,7 @@ instruct xchgL( memory mem, rRegL newval) %{ @@ -7953,6 +7839,7 @@ instruct xchgL( memory mem, rRegL newval) %{
instruct xchgP( memory mem, rRegP newval) %{ instruct xchgP( memory mem, rRegP newval) %{
match(Set newval (GetAndSetP mem newval)); match(Set newval (GetAndSetP mem newval));
@ -1988,7 +1952,7 @@ index 97c396875..f795fb823 100644
format %{ "XCHGQ $newval,[$mem]" %} format %{ "XCHGQ $newval,[$mem]" %}
ins_encode %{ ins_encode %{
__ xchgq($newval$$Register, $mem$$Address); __ xchgq($newval$$Register, $mem$$Address);
@@ -11614,6 +11501,7 @@ instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) @@ -11603,6 +11490,7 @@ instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
%{ %{
match(Set cr (CmpP op1 (LoadP op2))); match(Set cr (CmpP op1 (LoadP op2)));
@ -1996,7 +1960,7 @@ index 97c396875..f795fb823 100644
ins_cost(500); // XXX ins_cost(500); // XXX
format %{ "cmpq $op1, $op2\t# ptr" %} format %{ "cmpq $op1, $op2\t# ptr" %}
@@ -11639,7 +11527,8 @@ instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) @@ -11628,7 +11516,8 @@ instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
// and raw pointers have no anti-dependencies. // and raw pointers have no anti-dependencies.
instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
%{ %{
@ -2006,7 +1970,7 @@ index 97c396875..f795fb823 100644
match(Set cr (CmpP op1 (LoadP op2))); match(Set cr (CmpP op1 (LoadP op2)));
format %{ "cmpq $op1, $op2\t# raw ptr" %} format %{ "cmpq $op1, $op2\t# raw ptr" %}
@@ -11664,7 +11553,8 @@ instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) @@ -11653,7 +11542,8 @@ instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
// any compare to a zero should be eq/neq. // any compare to a zero should be eq/neq.
instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
%{ %{
@ -2016,7 +1980,7 @@ index 97c396875..f795fb823 100644
match(Set cr (CmpP (LoadP op) zero)); match(Set cr (CmpP (LoadP op) zero));
ins_cost(500); // XXX ins_cost(500); // XXX
@@ -11677,7 +11567,9 @@ instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) @@ -11666,7 +11556,9 @@ instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
%{ %{
@ -2027,7 +1991,7 @@ index 97c396875..f795fb823 100644
match(Set cr (CmpP (LoadP mem) zero)); match(Set cr (CmpP (LoadP mem) zero));
format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
@@ -12632,274 +12524,126 @@ instruct RethrowException() @@ -12621,274 +12513,126 @@ instruct RethrowException()
// Execute ZGC load barrier (strong) slow path // Execute ZGC load barrier (strong) slow path
// //
@ -2418,7 +2382,7 @@ index 2845cf6d8..c41ac52c7 100644
}; };
int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*); int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp
index 5c9fc98e1..e689c77c5 100644 index 8eba28f94..b20cd73d9 100644
--- a/src/hotspot/share/compiler/compilerDirectives.hpp --- a/src/hotspot/share/compiler/compilerDirectives.hpp
+++ b/src/hotspot/share/compiler/compilerDirectives.hpp +++ b/src/hotspot/share/compiler/compilerDirectives.hpp
@@ -66,8 +66,7 @@ NOT_PRODUCT(cflags(TraceOptoOutput, bool, TraceOptoOutput, TraceOptoOutput)) @@ -66,8 +66,7 @@ NOT_PRODUCT(cflags(TraceOptoOutput, bool, TraceOptoOutput, TraceOptoOutput))
@ -2462,10 +2426,10 @@ index eea74674f..487988bd8 100644
#endif // SHARE_GC_SHARED_C2_BARRIERSETC2_HPP #endif // SHARE_GC_SHARED_C2_BARRIERSETC2_HPP
diff --git a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp diff --git a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
index 1c77a4f63..a12973464 100644 index bf0bd43af..a12973464 100644
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
@@ -22,444 +22,156 @@ @@ -22,443 +22,156 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
@ -2520,40 +2484,35 @@ index 1c77a4f63..a12973464 100644
-LoadBarrierNode* ZBarrierSetC2State::load_barrier_node(int idx) const { -LoadBarrierNode* ZBarrierSetC2State::load_barrier_node(int idx) const {
- return _load_barrier_nodes->at(idx); - return _load_barrier_nodes->at(idx);
-} -}
-
-void* ZBarrierSetC2::create_barrier_state(Arena* comp_arena) const { -void* ZBarrierSetC2::create_barrier_state(Arena* comp_arena) const {
- return new(comp_arena) ZBarrierSetC2State(comp_arena); - return new(comp_arena) ZBarrierSetC2State(comp_arena);
-} -}
-ZBarrierSetC2State* ZBarrierSetC2::state() const {
- return reinterpret_cast<ZBarrierSetC2State*>(Compile::current()->barrier_set_state());
-}
+class ZBarrierSetC2State : public ResourceObj { +class ZBarrierSetC2State : public ResourceObj {
+private: +private:
+ GrowableArray<ZLoadBarrierStubC2*>* _stubs; + GrowableArray<ZLoadBarrierStubC2*>* _stubs;
+ Node_Array _live; + Node_Array _live;
-ZBarrierSetC2State* ZBarrierSetC2::state() const { -bool ZBarrierSetC2::is_gc_barrier_node(Node* node) const {
- return reinterpret_cast<ZBarrierSetC2State*>(Compile::current()->barrier_set_state()); - // 1. This step follows potential oop projections of a load barrier before expansion
-} - if (node->is_Proj()) {
- node = node->in(0);
- }
+public: +public:
+ ZBarrierSetC2State(Arena* arena) : + ZBarrierSetC2State(Arena* arena) :
+ _stubs(new (arena) GrowableArray<ZLoadBarrierStubC2*>(arena, 8, 0, NULL)), + _stubs(new (arena) GrowableArray<ZLoadBarrierStubC2*>(arena, 8, 0, NULL)),
+ _live(arena) {} + _live(arena) {}
-bool ZBarrierSetC2::is_gc_barrier_node(Node* node) const {
- // 1. This step follows potential oop projections of a load barrier before expansion
- if (node->is_Proj()) {
- node = node->in(0);
+ GrowableArray<ZLoadBarrierStubC2*>* stubs() {
+ return _stubs;
}
- // 2. This step checks for unexpanded load barriers - // 2. This step checks for unexpanded load barriers
- if (node->is_LoadBarrier()) { - if (node->is_LoadBarrier()) {
- return true; - return true;
- } + GrowableArray<ZLoadBarrierStubC2*>* stubs() {
+ RegMask* live(const Node* node) { + return _stubs;
+ if (!node->is_Mach()) { }
+ // Don't need liveness for non-MachNodes
+ return NULL;
+ }
- // 3. This step checks for the phi corresponding to an optimized load barrier expansion - // 3. This step checks for the phi corresponding to an optimized load barrier expansion
- if (node->is_Phi()) { - if (node->is_Phi()) {
@ -2561,38 +2520,41 @@ index 1c77a4f63..a12973464 100644
- Node* n = phi->in(1); - Node* n = phi->in(1);
- if (n != NULL && (n->is_LoadBarrierSlowReg())) { - if (n != NULL && (n->is_LoadBarrierSlowReg())) {
- return true; - return true;
+ const MachNode* const mach = node->as_Mach(); + RegMask* live(const Node* node) {
+ if (mach->barrier_data() != ZLoadBarrierStrong && + if (!node->is_Mach()) {
+ mach->barrier_data() != ZLoadBarrierWeak) { + // Don't need liveness for non-MachNodes
+ // Don't need liveness data for nodes without barriers
+ return NULL; + return NULL;
} }
- } - }
- return false; - return false;
-} -}
+ const MachNode* const mach = node->as_Mach();
+ if (mach->barrier_data() != ZLoadBarrierStrong &&
+ mach->barrier_data() != ZLoadBarrierWeak) {
+ // Don't need liveness data for nodes without barriers
+ return NULL;
+ }
-void ZBarrierSetC2::register_potential_barrier_node(Node* node) const {
- if (node->is_LoadBarrier()) {
- state()->add_load_barrier_node(node->as_LoadBarrier());
- }
-}
+ RegMask* live = (RegMask*)_live[node->_idx]; + RegMask* live = (RegMask*)_live[node->_idx];
+ if (live == NULL) { + if (live == NULL) {
+ live = new (Compile::current()->comp_arena()->Amalloc_D(sizeof(RegMask))) RegMask(); + live = new (Compile::current()->comp_arena()->Amalloc_D(sizeof(RegMask))) RegMask();
+ _live.map(node->_idx, (Node*)live); + _live.map(node->_idx, (Node*)live);
+ } + }
-void ZBarrierSetC2::register_potential_barrier_node(Node* node) const { -void ZBarrierSetC2::unregister_potential_barrier_node(Node* node) const {
- if (node->is_LoadBarrier()) { - if (node->is_LoadBarrier()) {
- state()->add_load_barrier_node(node->as_LoadBarrier()); - state()->remove_load_barrier_node(node->as_LoadBarrier());
+ return live; + return live;
} }
-} -}
+}; +};
-void ZBarrierSetC2::unregister_potential_barrier_node(Node* node) const {
- if (node->is_LoadBarrier()) {
- state()->remove_load_barrier_node(node->as_LoadBarrier());
- }
+static ZBarrierSetC2State* barrier_set_state() {
+ return reinterpret_cast<ZBarrierSetC2State*>(Compile::current()->barrier_set_state());
}
-void ZBarrierSetC2::eliminate_useless_gc_barriers(Unique_Node_List &useful) const { -void ZBarrierSetC2::eliminate_useless_gc_barriers(Unique_Node_List &useful) const {
- // Remove useless LoadBarrier nodes - // Remove useless LoadBarrier nodes
- ZBarrierSetC2State* s = state(); - ZBarrierSetC2State* s = state();
@ -2601,41 +2563,33 @@ index 1c77a4f63..a12973464 100644
- if (!useful.member(n)) { - if (!useful.member(n)) {
- unregister_potential_barrier_node(n); - unregister_potential_barrier_node(n);
- } - }
- }
+static ZBarrierSetC2State* barrier_set_state() {
+ return reinterpret_cast<ZBarrierSetC2State*>(Compile::current()->barrier_set_state());
}
-void ZBarrierSetC2::enqueue_useful_gc_barrier(Unique_Node_List &worklist, Node* node) const {
- if (node->is_LoadBarrier() && !node->as_LoadBarrier()->has_true_uses()) {
- worklist.push(node);
+ZLoadBarrierStubC2* ZLoadBarrierStubC2::create(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) { +ZLoadBarrierStubC2* ZLoadBarrierStubC2::create(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
+ ZLoadBarrierStubC2* const stub = new (Compile::current()->comp_arena()) ZLoadBarrierStubC2(node, ref_addr, ref, tmp, weak); + ZLoadBarrierStubC2* const stub = new (Compile::current()->comp_arena()) ZLoadBarrierStubC2(node, ref_addr, ref, tmp, weak);
+ if (!Compile::current()->in_scratch_emit_size()) { + if (!Compile::current()->in_scratch_emit_size()) {
+ barrier_set_state()->stubs()->append(stub); + barrier_set_state()->stubs()->append(stub);
} }
-} -}
-
-void ZBarrierSetC2::enqueue_useful_gc_barrier(Unique_Node_List &worklist, Node* node) const {
- if (node->is_LoadBarrier() && !node->as_LoadBarrier()->has_true_uses()) {
- worklist.push(node);
- }
+ return stub;
}
-static bool load_require_barrier(LoadNode* load) { return ((load->barrier_data() & RequireBarrier) != 0); } -static bool load_require_barrier(LoadNode* load) { return ((load->barrier_data() & RequireBarrier) != 0); }
-static bool load_has_weak_barrier(LoadNode* load) { return ((load->barrier_data() & WeakBarrier) != 0); } -static bool load_has_weak_barrier(LoadNode* load) { return ((load->barrier_data() & WeakBarrier) != 0); }
-static bool load_has_expanded_barrier(LoadNode* load) { return ((load->barrier_data() & ExpandedBarrier) != 0); } -static bool load_has_expanded_barrier(LoadNode* load) { return ((load->barrier_data() & ExpandedBarrier) != 0); }
-static void load_set_expanded_barrier(LoadNode* load) { return load->set_barrier_data(ExpandedBarrier); } -static void load_set_expanded_barrier(LoadNode* load) { return load->set_barrier_data(ExpandedBarrier); }
-
-static void load_set_barrier(LoadNode* load, bool weak) { -static void load_set_barrier(LoadNode* load, bool weak) {
- if (weak) { - if (weak) {
- load->set_barrier_data(WeakBarrier); - load->set_barrier_data(WeakBarrier);
- } else { - } else {
- load->set_barrier_data(RequireBarrier); - load->set_barrier_data(RequireBarrier);
- } - }
+ZLoadBarrierStubC2::ZLoadBarrierStubC2(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) : + return stub;
+ _node(node),
+ _ref_addr(ref_addr),
+ _ref(ref),
+ _tmp(tmp),
+ _weak(weak),
+ _entry(),
+ _continuation() {
+ assert_different_registers(ref, ref_addr.base());
+ assert_different_registers(ref, ref_addr.index());
} }
-// == LoadBarrierNode == -// == LoadBarrierNode ==
@ -2657,21 +2611,29 @@ index 1c77a4f63..a12973464 100644
- init_class_id(Class_LoadBarrier); - init_class_id(Class_LoadBarrier);
- BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); - BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
- bs->register_potential_barrier_node(this); - bs->register_potential_barrier_node(this);
+Address ZLoadBarrierStubC2::ref_addr() const { +ZLoadBarrierStubC2::ZLoadBarrierStubC2(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) :
+ return _ref_addr; + _node(node),
+ _ref_addr(ref_addr),
+ _ref(ref),
+ _tmp(tmp),
+ _weak(weak),
+ _entry(),
+ _continuation() {
+ assert_different_registers(ref, ref_addr.base());
+ assert_different_registers(ref, ref_addr.index());
} }
-uint LoadBarrierNode::size_of() const { -uint LoadBarrierNode::size_of() const {
- return sizeof(*this); - return sizeof(*this);
+Register ZLoadBarrierStubC2::ref() const { +Address ZLoadBarrierStubC2::ref_addr() const {
+ return _ref; + return _ref_addr;
} }
-uint LoadBarrierNode::cmp(const Node& n) const { -uint LoadBarrierNode::cmp(const Node& n) const {
- ShouldNotReachHere(); - ShouldNotReachHere();
- return 0; - return 0;
+Register ZLoadBarrierStubC2::tmp() const { +Register ZLoadBarrierStubC2::ref() const {
+ return _tmp; + return _ref;
} }
-const Type *LoadBarrierNode::bottom_type() const { -const Type *LoadBarrierNode::bottom_type() const {
@ -2681,16 +2643,15 @@ index 1c77a4f63..a12973464 100644
- floadbarrier[Memory] = Type::MEMORY; - floadbarrier[Memory] = Type::MEMORY;
- floadbarrier[Oop] = in_oop == NULL ? Type::TOP : in_oop->bottom_type(); - floadbarrier[Oop] = in_oop == NULL ? Type::TOP : in_oop->bottom_type();
- return TypeTuple::make(Number_of_Outputs, floadbarrier); - return TypeTuple::make(Number_of_Outputs, floadbarrier);
+address ZLoadBarrierStubC2::slow_path() const { +Register ZLoadBarrierStubC2::tmp() const {
+ const DecoratorSet decorators = _weak ? ON_WEAK_OOP_REF : ON_STRONG_OOP_REF; + return _tmp;
+ return ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators);
} }
-const TypePtr* LoadBarrierNode::adr_type() const { -const TypePtr* LoadBarrierNode::adr_type() const {
- ShouldNotReachHere(); - return TypeRawPtr::BOTTOM;
- return NULL; +address ZLoadBarrierStubC2::slow_path() const {
+RegMask& ZLoadBarrierStubC2::live() const { + const DecoratorSet decorators = _weak ? ON_WEAK_OOP_REF : ON_STRONG_OOP_REF;
+ return *barrier_set_state()->live(_node); + return ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators);
} }
-const Type *LoadBarrierNode::Value(PhaseGVN *phase) const { -const Type *LoadBarrierNode::Value(PhaseGVN *phase) const {
@ -2700,12 +2661,8 @@ index 1c77a4f63..a12973464 100644
- floadbarrier[Memory] = Type::MEMORY; - floadbarrier[Memory] = Type::MEMORY;
- floadbarrier[Oop] = val_t; - floadbarrier[Oop] = val_t;
- return TypeTuple::make(Number_of_Outputs, floadbarrier); - return TypeTuple::make(Number_of_Outputs, floadbarrier);
+Label* ZLoadBarrierStubC2::entry() { +RegMask& ZLoadBarrierStubC2::live() const {
+ // The _entry will never be bound when in_scratch_emit_size() is true. + return *barrier_set_state()->live(_node);
+ // However, we still need to return a label that is not bound now, but
+ // will eventually be bound. Any lable will do, as it will only act as
+ // a placeholder, so we return the _continuation label.
+ return Compile::current()->in_scratch_emit_size() ? &_continuation : &_entry;
} }
-bool LoadBarrierNode::is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n) { -bool LoadBarrierNode::is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n) {
@ -2721,8 +2678,12 @@ index 1c77a4f63..a12973464 100644
- } - }
- -
- return false; - return false;
+Label* ZLoadBarrierStubC2::continuation() { +Label* ZLoadBarrierStubC2::entry() {
+ return &_continuation; + // The _entry will never be bound when in_scratch_emit_size() is true.
+ // However, we still need to return a label that is not bound now, but
+ // will eventually be bound. Any lable will do, as it will only act as
+ // a placeholder, so we return the _continuation label.
+ return Compile::current()->in_scratch_emit_size() ? &_continuation : &_entry;
} }
-LoadBarrierNode* LoadBarrierNode::has_dominating_barrier(PhaseIdealLoop* phase, bool linear_only, bool look_for_similar) { -LoadBarrierNode* LoadBarrierNode::has_dominating_barrier(PhaseIdealLoop* phase, bool linear_only, bool look_for_similar) {
@ -2817,8 +2778,10 @@ index 1c77a4f63..a12973464 100644
- } - }
- -
- return NULL; - return NULL;
-} +Label* ZLoadBarrierStubC2::continuation() {
- + return &_continuation;
}
-void LoadBarrierNode::push_dominated_barriers(PhaseIterGVN* igvn) const { -void LoadBarrierNode::push_dominated_barriers(PhaseIterGVN* igvn) const {
- // Change to that barrier may affect a dominated barrier so re-push those - // Change to that barrier may affect a dominated barrier so re-push those
- assert(!is_weak(), "sanity"); - assert(!is_weak(), "sanity");
@ -2873,24 +2836,16 @@ index 1c77a4f63..a12973464 100644
- Node *mem = in(Memory); - Node *mem = in(Memory);
- Node *ctrl = in(Control); - Node *ctrl = in(Control);
- assert(val->Opcode() != Op_DecodeN, ""); - assert(val->Opcode() != Op_DecodeN, "");
+void ZBarrierSetC2::emit_stubs(CodeBuffer& cb) const { -
+ MacroAssembler masm(&cb);
+ GrowableArray<ZLoadBarrierStubC2*>* const stubs = barrier_set_state()->stubs();
- if (mem->is_MergeMem()) { - if (mem->is_MergeMem()) {
- Node *new_mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw); - Node *new_mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
- set_req(Memory, new_mem); - set_req(Memory, new_mem);
- if (mem->outcnt() == 0 && can_reshape) { - if (mem->outcnt() == 0 && can_reshape) {
- phase->is_IterGVN()->_worklist.push(mem); - phase->is_IterGVN()->_worklist.push(mem);
+ for (int i = 0; i < stubs->length(); i++) { - }
+ // Make sure there is enough space in the code buffer
+ if (cb.insts()->maybe_expand_to_ensure_remaining(Compile::MAX_inst_size) && cb.blob() == NULL) {
+ ciEnv::current()->record_failure("CodeCache is full");
+ return;
}
- return this; - return this;
- } - }
-
- LoadBarrierNode *dominating_barrier = NULL; - LoadBarrierNode *dominating_barrier = NULL;
- if (!is_weak()) { - if (!is_weak()) {
- dominating_barrier = has_dominating_barrier(NULL, !can_reshape, !phase->C->major_progress()); - dominating_barrier = has_dominating_barrier(NULL, !can_reshape, !phase->C->major_progress());
@ -2899,8 +2854,7 @@ index 1c77a4f63..a12973464 100644
- set_req(Similar, dominating_barrier->proj_out(Oop)); - set_req(Similar, dominating_barrier->proj_out(Oop));
- return this; - return this;
- } - }
+ ZBarrierSet::assembler()->generate_c2_load_barrier_stub(&masm, stubs->at(i)); - }
}
- -
- bool eliminate = can_reshape && (dominating_barrier != NULL || !has_true_uses()); - bool eliminate = can_reshape && (dominating_barrier != NULL || !has_true_uses());
- if (eliminate) { - if (eliminate) {
@ -2933,7 +2887,10 @@ index 1c77a4f63..a12973464 100644
- set_req(Similar, phase->C->top()); - set_req(Similar, phase->C->top());
- return this; - return this;
- } - }
- +void ZBarrierSetC2::emit_stubs(CodeBuffer& cb) const {
+ MacroAssembler masm(&cb);
+ GrowableArray<ZLoadBarrierStubC2*>* const stubs = barrier_set_state()->stubs();
- if (can_reshape && !is_weak()) { - if (can_reshape && !is_weak()) {
- // If this barrier is linked through the Similar edge by a - // If this barrier is linked through the Similar edge by a
- // dominated barrier and both barriers have the same Oop field, - // dominated barrier and both barriers have the same Oop field,
@ -2951,10 +2908,16 @@ index 1c77a4f63..a12973464 100644
- assert(!u->as_LoadBarrier()->is_weak(), "Sanity"); - assert(!u->as_LoadBarrier()->is_weak(), "Sanity");
- igvn->_worklist.push(u); - igvn->_worklist.push(u);
- } - }
- } + for (int i = 0; i < stubs->length(); i++) {
- + // Make sure there is enough space in the code buffer
+ if (cb.insts()->maybe_expand_to_ensure_remaining(Compile::MAX_inst_size) && cb.blob() == NULL) {
+ ciEnv::current()->record_failure("CodeCache is full");
+ return;
}
- push_dominated_barriers(igvn); - push_dominated_barriers(igvn);
- } + ZBarrierSet::assembler()->generate_c2_load_barrier_stub(&masm, stubs->at(i));
}
- -
- return NULL; - return NULL;
+ masm.flush(); + masm.flush();
@ -3006,7 +2969,7 @@ index 1c77a4f63..a12973464 100644
} }
static bool barrier_needed(C2Access access) { static bool barrier_needed(C2Access access) {
@@ -467,1071 +179,253 @@ static bool barrier_needed(C2Access access) { @@ -466,1071 +179,253 @@ static bool barrier_needed(C2Access access) {
} }
Node* ZBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const { Node* ZBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
@ -4496,10 +4459,10 @@ index e8ac3a61d..eec705013 100644
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Build a table of virtual functions to map from Nodes to dense integer // Build a table of virtual functions to map from Nodes to dense integer
diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp
index f6b588685..2fae8dd26 100644 index cdca7e7c0..da01e4811 100644
--- a/src/hotspot/share/opto/classes.hpp --- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp +++ b/src/hotspot/share/opto/classes.hpp
@@ -189,17 +189,6 @@ macro(LoadP) @@ -188,17 +188,6 @@ macro(LoadP)
macro(LoadN) macro(LoadN)
macro(LoadRange) macro(LoadRange)
macro(LoadS) macro(LoadS)
@ -4518,7 +4481,7 @@ index f6b588685..2fae8dd26 100644
macro(Loop) macro(Loop)
macro(LoopLimit) macro(LoopLimit)
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index ba61967bc..3145d1e2f 100644 index ef4a6ab13..b6980c4e7 100644
--- a/src/hotspot/share/opto/compile.cpp --- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp
@@ -79,9 +79,6 @@ @@ -79,9 +79,6 @@
@ -4594,21 +4557,21 @@ index ba61967bc..3145d1e2f 100644
_node_arena(mtCompiler), _node_arena(mtCompiler),
_old_arena(mtCompiler), _old_arena(mtCompiler),
_Compile_types(mtCompiler), _Compile_types(mtCompiler),
@@ -2366,13 +2364,6 @@ void Compile::Optimize() { @@ -2398,13 +2396,6 @@ void Compile::Optimize() {
bs->verify_gc_barriers(false); igvn.optimize();
#endif }
- bs->barrier_insertion_phase(C, igvn);
- if (failing()) return;
-
-#ifdef ASSERT -#ifdef ASSERT
- bs->verify_gc_barriers(false); - bs->verify_gc_barriers(false);
-#endif -#endif
- -
{ - bs->barrier_insertion_phase(C, igvn);
TracePhase tp("macroExpand", &timers[_t_macroExpand]); - if (failing()) return;
PhaseMacroExpand mex(igvn); -
@@ -2933,29 +2924,6 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) { #ifdef ASSERT
bs->verify_gc_barriers(false);
#endif
@@ -2969,29 +2960,6 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) {
break; break;
} }
@ -4639,7 +4602,7 @@ index ba61967bc..3145d1e2f 100644
Node *addp = n->in(AddPNode::Address); Node *addp = n->in(AddPNode::Address);
assert( !addp->is_AddP() || assert( !addp->is_AddP() ||
diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp
index d58758db7..bb5622221 100644 index bfd85d032..a885d9f8d 100644
--- a/src/hotspot/share/opto/compile.hpp --- a/src/hotspot/share/opto/compile.hpp
+++ b/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp
@@ -55,7 +55,6 @@ class ConnectionGraph; @@ -55,7 +55,6 @@ class ConnectionGraph;
@ -4650,7 +4613,7 @@ index d58758db7..bb5622221 100644
class Matcher; class Matcher;
class MachConstantNode; class MachConstantNode;
class MachConstantBaseNode; class MachConstantBaseNode;
@@ -1168,11 +1167,7 @@ class Compile : public Phase { @@ -1181,11 +1180,7 @@ class Compile : public Phase {
bool in_scratch_emit_size() const { return _in_scratch_emit_size; } bool in_scratch_emit_size() const { return _in_scratch_emit_size; }
enum ScratchBufferBlob { enum ScratchBufferBlob {
@ -4662,7 +4625,7 @@ index d58758db7..bb5622221 100644
MAX_locs_size = 128, // number of relocInfo elements MAX_locs_size = 128, // number of relocInfo elements
MAX_const_size = 128, MAX_const_size = 128,
MAX_stubs_size = 128 MAX_stubs_size = 128
@@ -1247,14 +1242,30 @@ class Compile : public Phase { @@ -1260,14 +1255,30 @@ class Compile : public Phase {
// Process an OopMap Element while emitting nodes // Process an OopMap Element while emitting nodes
void Process_OopMap_Node(MachNode *mach, int code_offset); void Process_OopMap_Node(MachNode *mach, int code_offset);
@ -4696,7 +4659,7 @@ index d58758db7..bb5622221 100644
// Compute the size of first NumberOfLoopInstrToAlign instructions // Compute the size of first NumberOfLoopInstrToAlign instructions
// at the head of a loop. // at the head of a loop.
diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp
index 47c83766e..934e2acb9 100644 index 235b31c4c..15d483f33 100644
--- a/src/hotspot/share/opto/escape.cpp --- a/src/hotspot/share/opto/escape.cpp
+++ b/src/hotspot/share/opto/escape.cpp +++ b/src/hotspot/share/opto/escape.cpp
@@ -487,13 +487,6 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de @@ -487,13 +487,6 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
@ -4741,10 +4704,10 @@ index 05ec9fa9f..16b80bfc3 100644
case Op_LoadS: case Op_LoadS:
case Op_LoadKlass: case Op_LoadKlass:
diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp
index d99e2f81b..da81c3a5d 100644 index 7c3033162..25fab93cf 100644
--- a/src/hotspot/share/opto/loopnode.cpp --- a/src/hotspot/share/opto/loopnode.cpp
+++ b/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp
@@ -997,18 +997,6 @@ void LoopNode::verify_strip_mined(int expect_skeleton) const { @@ -1001,18 +1001,6 @@ void LoopNode::verify_strip_mined(int expect_skeleton) const {
} }
} }
@ -4763,7 +4726,7 @@ index d99e2f81b..da81c3a5d 100644
CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd(); CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd();
assert(cle == inner->loopexit_or_null(), "mismatch"); assert(cle == inner->loopexit_or_null(), "mismatch");
bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0; bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0;
@@ -4230,7 +4218,6 @@ void PhaseIdealLoop::build_loop_late_post( Node *n ) { @@ -4250,7 +4238,6 @@ void PhaseIdealLoop::build_loop_late_post( Node *n ) {
case Op_LoadL: case Op_LoadL:
case Op_LoadS: case Op_LoadS:
case Op_LoadP: case Op_LoadP:
@ -4772,7 +4735,7 @@ index d99e2f81b..da81c3a5d 100644
case Op_LoadRange: case Op_LoadRange:
case Op_LoadD_unaligned: case Op_LoadD_unaligned:
diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp
index 411cf0841..3a1034244 100644 index 5793f51f2..6b85529f4 100644
--- a/src/hotspot/share/opto/loopopts.cpp --- a/src/hotspot/share/opto/loopopts.cpp
+++ b/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp
@@ -41,9 +41,6 @@ @@ -41,9 +41,6 @@
@ -4786,7 +4749,7 @@ index 411cf0841..3a1034244 100644
//============================================================================= //=============================================================================
//------------------------------split_thru_phi--------------------------------- //------------------------------split_thru_phi---------------------------------
diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp
index bceaf1df1..6794e8ab2 100644 index 66adf9be1..90d5b0af1 100644
--- a/src/hotspot/share/opto/machnode.hpp --- a/src/hotspot/share/opto/machnode.hpp
+++ b/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp
@@ -197,7 +197,7 @@ public: @@ -197,7 +197,7 @@ public:
@ -4820,10 +4783,10 @@ index bceaf1df1..6794e8ab2 100644
// more leafs. Must be set by MachNode constructor to point to an // more leafs. Must be set by MachNode constructor to point to an
// internal array of MachOpers. The MachOper array is sized by // internal array of MachOpers. The MachOper array is sized by
diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp
index bdcf9c424..c75854e65 100644 index 79b366fd5..41d92b3d0 100644
--- a/src/hotspot/share/opto/matcher.cpp --- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp
@@ -1745,6 +1745,13 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) { @@ -1752,6 +1752,13 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
_shared_nodes.map(leaf->_idx, ex); _shared_nodes.map(leaf->_idx, ex);
} }
@ -4837,7 +4800,7 @@ index bdcf9c424..c75854e65 100644
return ex; return ex;
} }
@@ -2164,17 +2171,6 @@ void Matcher::find_shared( Node *n ) { @@ -2171,17 +2178,6 @@ void Matcher::find_shared( Node *n ) {
case Op_SafePoint: case Op_SafePoint:
mem_op = true; mem_op = true;
break; break;
@ -4855,7 +4818,7 @@ index bdcf9c424..c75854e65 100644
default: default:
if( n->is_Store() ) { if( n->is_Store() ) {
// Do match stores, despite no ideal reg // Do match stores, despite no ideal reg
@@ -2279,33 +2275,6 @@ void Matcher::find_shared( Node *n ) { @@ -2286,33 +2282,6 @@ void Matcher::find_shared( Node *n ) {
n->del_req(LoadStoreConditionalNode::ExpectedIn); n->del_req(LoadStoreConditionalNode::ExpectedIn);
break; break;
} }
@ -4890,7 +4853,7 @@ index bdcf9c424..c75854e65 100644
case Op_CMoveF: case Op_CMoveF:
case Op_CMoveI: case Op_CMoveI:
diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp
index 6fa851af2..ee0f09e11 100644 index 2de221a1e..4147c6d46 100644
--- a/src/hotspot/share/opto/memnode.cpp --- a/src/hotspot/share/opto/memnode.cpp
+++ b/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp
@@ -49,9 +49,6 @@ @@ -49,9 +49,6 @@
@ -4903,7 +4866,7 @@ index 6fa851af2..ee0f09e11 100644
// Portions of code courtesy of Clifford Click // Portions of code courtesy of Clifford Click
@@ -2812,7 +2809,7 @@ LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const Ty @@ -2818,7 +2815,7 @@ LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const Ty
: Node(required), : Node(required),
_type(rt), _type(rt),
_adr_type(at), _adr_type(at),
@ -4913,7 +4876,7 @@ index 6fa851af2..ee0f09e11 100644
init_req(MemNode::Control, c ); init_req(MemNode::Control, c );
init_req(MemNode::Memory , mem); init_req(MemNode::Memory , mem);
diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp
index 084a91c49..7468abdbc 100644 index e2bd6a6d8..3bf3dc420 100644
--- a/src/hotspot/share/opto/memnode.hpp --- a/src/hotspot/share/opto/memnode.hpp
+++ b/src/hotspot/share/opto/memnode.hpp +++ b/src/hotspot/share/opto/memnode.hpp
@@ -43,6 +43,8 @@ private: @@ -43,6 +43,8 @@ private:
@ -5039,7 +5002,7 @@ index 084a91c49..7468abdbc 100644
//------------------------------CompareAndSwapBNode--------------------------- //------------------------------CompareAndSwapBNode---------------------------
diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp
index 2ff9bb2cd..ed5524b83 100644 index 9bfc3a3b9..8d0475f53 100644
--- a/src/hotspot/share/opto/node.cpp --- a/src/hotspot/share/opto/node.cpp
+++ b/src/hotspot/share/opto/node.cpp +++ b/src/hotspot/share/opto/node.cpp
@@ -546,9 +546,6 @@ Node *Node::clone() const { @@ -546,9 +546,6 @@ Node *Node::clone() const {
@ -5052,7 +5015,7 @@ index 2ff9bb2cd..ed5524b83 100644
return n; // Return the clone return n; // Return the clone
} }
@@ -1468,10 +1465,6 @@ bool Node::needs_anti_dependence_check() const { @@ -1471,10 +1468,6 @@ bool Node::needs_anti_dependence_check() const {
if( req() < 2 || (_flags & Flag_needs_anti_dependence_check) == 0 ) { if( req() < 2 || (_flags & Flag_needs_anti_dependence_check) == 0 ) {
return false; return false;
} }
@ -5064,7 +5027,7 @@ index 2ff9bb2cd..ed5524b83 100644
} }
diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp
index 49f415a31..9c0aedcad 100644 index d69974be2..cf0975e37 100644
--- a/src/hotspot/share/opto/node.hpp --- a/src/hotspot/share/opto/node.hpp
+++ b/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp
@@ -82,8 +82,6 @@ class JVMState; @@ -82,8 +82,6 @@ class JVMState;
@ -5084,7 +5047,7 @@ index 49f415a31..9c0aedcad 100644
DEFINE_CLASS_ID(Mach, Node, 1) DEFINE_CLASS_ID(Mach, Node, 1)
DEFINE_CLASS_ID(MachReturn, Mach, 0) DEFINE_CLASS_ID(MachReturn, Mach, 0)
@@ -691,7 +688,6 @@ public: @@ -690,7 +687,6 @@ public:
DEFINE_CLASS_ID(Mem, Node, 4) DEFINE_CLASS_ID(Mem, Node, 4)
DEFINE_CLASS_ID(Load, Mem, 0) DEFINE_CLASS_ID(Load, Mem, 0)
DEFINE_CLASS_ID(LoadVector, Load, 0) DEFINE_CLASS_ID(LoadVector, Load, 0)
@ -5092,7 +5055,7 @@ index 49f415a31..9c0aedcad 100644
DEFINE_CLASS_ID(Store, Mem, 1) DEFINE_CLASS_ID(Store, Mem, 1)
DEFINE_CLASS_ID(StoreVector, Store, 0) DEFINE_CLASS_ID(StoreVector, Store, 0)
DEFINE_CLASS_ID(LoadStore, Mem, 2) DEFINE_CLASS_ID(LoadStore, Mem, 2)
@@ -834,8 +830,6 @@ public: @@ -833,8 +829,6 @@ public:
DEFINE_CLASS_QUERY(Load) DEFINE_CLASS_QUERY(Load)
DEFINE_CLASS_QUERY(LoadStore) DEFINE_CLASS_QUERY(LoadStore)
DEFINE_CLASS_QUERY(LoadStoreConditional) DEFINE_CLASS_QUERY(LoadStoreConditional)
@ -5828,10 +5791,10 @@ index ab3c1a304..ec3cc2981 100644
//------------------------------Scheduling---------------------------------- //------------------------------Scheduling----------------------------------
diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp
index 880efe991..4ea04b63c 100644 index d1177a56e..f9b883ef6 100644
--- a/src/hotspot/share/opto/phaseX.cpp --- a/src/hotspot/share/opto/phaseX.cpp
+++ b/src/hotspot/share/opto/phaseX.cpp +++ b/src/hotspot/share/opto/phaseX.cpp
@@ -1655,14 +1655,14 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) { @@ -1650,14 +1650,14 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
// of the mirror load depends on the type of 'n'. See LoadNode::Value(). // of the mirror load depends on the type of 'n'. See LoadNode::Value().
// LoadBarrier?(LoadP(LoadP(AddP(foo:Klass, #java_mirror)))) // LoadBarrier?(LoadP(LoadP(AddP(foo:Klass, #java_mirror))))
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
@ -5848,7 +5811,7 @@ index 880efe991..4ea04b63c 100644
// Search for load barriers behind the load // Search for load barriers behind the load
for (DUIterator_Fast i3max, i3 = u->fast_outs(i3max); i3 < i3max; i3++) { for (DUIterator_Fast i3max, i3 = u->fast_outs(i3max); i3 < i3max; i3++) {
Node* b = u->fast_out(i3); Node* b = u->fast_out(i3);
@@ -1813,14 +1813,14 @@ void PhaseCCP::analyze() { @@ -1811,14 +1811,14 @@ void PhaseCCP::analyze() {
// Loading the java mirror from a Klass requires two loads and the type // Loading the java mirror from a Klass requires two loads and the type
// of the mirror load depends on the type of 'n'. See LoadNode::Value(). // of the mirror load depends on the type of 'n'. See LoadNode::Value().
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
@ -5877,6 +5840,4 @@ index b40587ba5..e0bf8410a 100644
*start = 0; *start = 0;
*end = 0; // no vector operands *end = 0; // no vector operands
break; break;
--
2.12.3

View File

@ -1,54 +0,0 @@
From 1ab27951c430bbe0820321c7194e89f63b9ac78b Mon Sep 17 00:00:00 2001
Date: Tue, 30 Jul 2019 14:20:57 +0000
Subject: [PATCH] change vendor to openEuler Community
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

@ -1,84 +0,0 @@
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

View File

@ -114,15 +114,13 @@
# New Version-String scheme-style defines # New Version-String scheme-style defines
%global majorver 11 %global majorver 11
%global securityver 7 %global securityver 8
# buildjdkver is usually same as %%{majorver}, # buildjdkver is usually same as %%{majorver},
# but in time of bootstrap of next jdk, it is majorver-1, # but in time of bootstrap of next jdk, it is majorver-1,
# and this it is better to change it here, on single place # and this it is better to change it here, on single place
%global buildjdkver %{majorver} %global buildjdkver %{majorver}
#Used via new version scheme. JDK 11 was %global vendor_version_string Boole
# GA'ed in September 2018 => 18.9
%global vendor_version_string 18.9
# Define IcedTea version used for SystemTap tapsets and desktop file # Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 3.15.0 %global icedteaver 3.15.0
@ -732,7 +730,7 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release}
Name: java-%{javaver}-%{origin} Name: java-%{javaver}-%{origin}
Version: %{fulljavaver}.%{buildver} Version: %{fulljavaver}.%{buildver}
Release: 5 Release: 0
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages # and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a # also included the epoch in their virtual provides. This created a
@ -793,7 +791,6 @@ Patch1000: rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch
# #
############################################# #############################################
Patch1: change-vendor-to-openEuler_Community.patch
Patch2: 8225648-TESTBUG-java-lang-annotation-loaderLeak-Main.patch Patch2: 8225648-TESTBUG-java-lang-annotation-loaderLeak-Main.patch
Patch5: Add-ability-to-configure-third-port-for-remote-JMX.patch Patch5: Add-ability-to-configure-third-port-for-remote-JMX.patch
Patch6: 8214527-AArch64-ZGC-for-Aarch64.patch Patch6: 8214527-AArch64-ZGC-for-Aarch64.patch
@ -809,13 +806,8 @@ Patch18: 8209375-ZGC-Use-dynamic-base-address-for-mark-stack-.patch
Patch20: 8209894-ZGC-Cap-number-of-GC-workers-based-on-heap-s.patch Patch20: 8209894-ZGC-Cap-number-of-GC-workers-based-on-heap-s.patch
Patch22: 8233506-ZGC-the-load-for-Reference.get-can-be-conver.patch Patch22: 8233506-ZGC-the-load-for-Reference.get-can-be-conver.patch
Patch23: add-missing-inline.patch Patch23: add-missing-inline.patch
Patch24: 8210303-VM_HandshakeAllThreads-fails-assert-with-fai.patch
Patch25: 8212933-Thread-SMR-requesting-a-VM-operation-whilst-.patch
Patch26: ZGC-aarch64-fix-system-call-number-of-memfd_create.patch Patch26: ZGC-aarch64-fix-system-call-number-of-memfd_create.patch
# 11.0.8
Patch27: 8228407.patch
BuildRequires: autoconf BuildRequires: autoconf
BuildRequires: alsa-lib-devel BuildRequires: alsa-lib-devel
BuildRequires: binutils BuildRequires: binutils
@ -1044,7 +1036,6 @@ fi
pushd %{top_level_dir_name} pushd %{top_level_dir_name}
# OpenJDK patches # OpenJDK patches
%patch1 -p1
%patch2 -p1 %patch2 -p1
%patch5 -p1 %patch5 -p1
%patch6 -p1 %patch6 -p1
@ -1060,10 +1051,7 @@ pushd %{top_level_dir_name}
%patch20 -p1 %patch20 -p1
%patch22 -p1 %patch22 -p1
%patch23 -p1 %patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1 %patch26 -p1
%patch27 -p1
popd # openjdk popd # openjdk
%patch1000 %patch1000
@ -1155,6 +1143,10 @@ bash ../configure \
--with-version-pre="" \ --with-version-pre="" \
--with-version-opt="" \ --with-version-opt="" \
--with-vendor-version-string="%{vendor_version_string}" \ --with-vendor-version-string="%{vendor_version_string}" \
--with-vendor-name="Boole" \
--with-vendor-url="https://openeuler.org/" \
--with-vendor-bug-url="https://gitee.com/src-openeuler/openjdk-11/issues/" \
--with-vendor-vm-bug-url="https://gitee.com/src-openeuler/openjdk-11/issues/" \
--with-boot-jdk=/usr/lib/jvm/java-%{buildjdkver}-openjdk \ --with-boot-jdk=/usr/lib/jvm/java-%{buildjdkver}-openjdk \
--with-debug-level=$debugbuild \ --with-debug-level=$debugbuild \
--with-native-debug-symbols=internal \ --with-native-debug-symbols=internal \
@ -1171,7 +1163,6 @@ bash ../configure \
--with-num-cores="$NUM_PROC" \ --with-num-cores="$NUM_PROC" \
--disable-javac-server \ --disable-javac-server \
--disable-warnings-as-errors \ --disable-warnings-as-errors \
--with-boot-jdk-jvmargs=-XX:-UsePerfData
# Debug builds don't need same targets as release for # Debug builds don't need same targets as release for
# build speed-up # build speed-up
@ -1563,6 +1554,9 @@ require "copy_jdk_configs.lua"
%changelog %changelog
* Sat Jul 18 2020 jvmboy <hedongbo@huawei.com> - 1:11.0.8.10-0
- Update to 11.0.8+10 (GA)
* Thu Jun 9 2020 jdkboy <guoge1@huawei.com> - 1:11.0.7.10-5 * Thu Jun 9 2020 jdkboy <guoge1@huawei.com> - 1:11.0.7.10-5
- Version support fulljavaver.buildver - Version support fulljavaver.buildver
- Judge with_systemtap - Judge with_systemtap

View File

@ -1,27 +0,0 @@
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