!428 I7H5DO: Synchronize the 2306 code to the BiSheng JDK8 community

From: @kuenking111 
Reviewed-by: @stubCode 
Signed-off-by: @stubCode
This commit is contained in:
openeuler-ci-bot 2023-06-30 00:53:18 +00:00 committed by Gitee
commit 2f4a2ef46e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
54 changed files with 14968 additions and 1 deletions

View File

@ -0,0 +1,136 @@
Date: Tue, 30 May 2023 03:43:28 +0000
Subject: [PATCH 02/59] 8179498: attach in linux should be relative to
/proc/pid/root and namespace aware
Bug url: https://bugs.openjdk.org/browse/JDK-8179498
---
.../sun/tools/attach/LinuxVirtualMachine.java | 70 ++++++++++++++++---
1 file changed, 62 insertions(+), 8 deletions(-)
diff --git a/jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java b/jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java
index 20fdb5c0d..cc2ac0df2 100644
--- a/jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java
+++ b/jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java
@@ -32,6 +32,10 @@ import com.sun.tools.attach.spi.AttachProvider;
import java.io.InputStream;
import java.io.IOException;
import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.Files;
/*
* Linux implementation of HotSpotVirtualMachine
@@ -66,12 +70,15 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
throw new AttachNotSupportedException("Invalid process identifier");
}
+ // Try to resolve to the "inner most" pid namespace
+ int ns_pid = getNamespacePid(pid);
+
// Find the socket file. If not found then we attempt to start the
// attach mechanism in the target VM by sending it a QUIT signal.
// Then we attempt to find the socket file again.
- path = findSocketFile(pid);
+ path = findSocketFile(pid, ns_pid);
if (path == null) {
- File f = createAttachFile(pid);
+ File f = createAttachFile(pid, ns_pid);
try {
// On LinuxThreads each thread is a process and we don't have the
// pid of the VMThread which has SIGQUIT unblocked. To workaround
@@ -99,7 +106,7 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
try {
Thread.sleep(delay);
} catch (InterruptedException x) { }
- path = findSocketFile(pid);
+ path = findSocketFile(pid, ns_pid);
i++;
} while (i <= retries && path == null);
if (path == null) {
@@ -272,8 +279,12 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
}
// Return the socket file for the given process.
- private String findSocketFile(int pid) {
- File f = new File(tmpdir, ".java_pid" + pid);
+ private String findSocketFile(int pid, int ns_pid) {
+ // A process may not exist in the same mount namespace as the caller.
+ // Instead, attach relative to the target root filesystem as exposed by
+ // procfs regardless of namespaces.
+ String root = "/proc/" + pid + "/root/" + tmpdir;
+ File f = new File(root, ".java_pid" + ns_pid);
if (!f.exists()) {
return null;
}
@@ -284,14 +295,23 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
// if not already started. The client creates a .attach_pid<pid> file in the
// target VM's working directory (or temp directory), and the SIGQUIT handler
// checks for the file.
- private File createAttachFile(int pid) throws IOException {
- String fn = ".attach_pid" + pid;
+ private File createAttachFile(int pid, int ns_pid) throws IOException {
+ String fn = ".attach_pid" + ns_pid;
String path = "/proc/" + pid + "/cwd/" + fn;
File f = new File(path);
try {
f.createNewFile();
} catch (IOException x) {
- f = new File(tmpdir, fn);
+ String root;
+ if (pid != ns_pid) {
+ // A process may not exist in the same mount namespace as the caller.
+ // Instead, attach relative to the target root filesystem as exposed by
+ // procfs regardless of namespaces.
+ root = "/proc/" + pid + "/root/" + tmpdir;
+ } else {
+ root = tmpdir;
+ }
+ f = new File(root, fn);
f.createNewFile();
}
return f;
@@ -317,6 +337,40 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
}
+ // Return the inner most namespaced PID if there is one,
+ // otherwise return the original PID.
+ private int getNamespacePid(int pid) throws AttachNotSupportedException, IOException {
+ // Assuming a real procfs sits beneath, reading this doesn't block
+ // nor will it consume a lot of memory.
+ String statusFile = "/proc/" + pid + "/status";
+ File f = new File(statusFile);
+ if (!f.exists()) {
+ return pid; // Likely a bad pid, but this is properly handled later.
+ }
+
+ Path statusPath = Paths.get(statusFile);
+
+ try {
+ for (String line : Files.readAllLines(statusPath, StandardCharsets.UTF_8)) {
+ String[] parts = line.split(":");
+ if (parts.length == 2 && parts[0].trim().equals("NSpid")) {
+ parts = parts[1].trim().split("\\s+");
+ // The last entry represents the PID the JVM "thinks" it is.
+ // Even in non-namespaced pids these entries should be
+ // valid. You could refer to it as the inner most pid.
+ int ns_pid = Integer.parseInt(parts[parts.length - 1]);
+ return ns_pid;
+ }
+ }
+ // Old kernels may not have NSpid field (i.e. 3.10).
+ // Fallback to original pid in the event we cannot deduce.
+ return pid;
+ } catch (NumberFormatException | IOException x) {
+ throw new AttachNotSupportedException("Unable to parse namespace");
+ }
+ }
+
+
//-- native methods
static native boolean isLinuxThreads();
--
2.22.0

View File

@ -0,0 +1,348 @@
Date: Tue, 30 May 2023 15:42:59 +0800
Subject: [PATCH 03/59] 8187408: AbstractQueuedSynchronizer wait queue corrupted when thread awaits without holding the lock
Bug url: https://bugs.openjdk.org/browse/JDK-8187408
---
.../locks/AbstractQueuedLongSynchronizer.java | 20 +--
.../locks/AbstractQueuedSynchronizer.java | 52 +++---
jdk/test/java/util/Bug8187408/Bug8187408.java | 165 ++++++++++++++++++
3 files changed, 207 insertions(+), 30 deletions(-)
create mode 100644 jdk/test/java/util/Bug8187408/Bug8187408.java
diff --git a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
index 8699fc9b8..5adc39e17 100644
--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
+++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
@@ -64,11 +64,11 @@ public abstract class AbstractQueuedLongSynchronizer
private static final long serialVersionUID = 7373984972572414692L;
/*
- To keep sources in sync, the remainder of this source file is
- exactly cloned from AbstractQueuedSynchronizer, replacing class
- name and changing ints related with sync state to longs. Please
- keep it that way.
- */
+ * To keep sources in sync, the remainder of this source file is
+ * exactly cloned from AbstractQueuedSynchronizer, replacing class
+ * name and changing ints related with sync state to longs. Please
+ * keep it that way.
+ */
/**
* Creates a new {@code AbstractQueuedLongSynchronizer} instance
@@ -946,8 +946,7 @@ public abstract class AbstractQueuedLongSynchronizer
/**
* Returns {@code true} if synchronization is held exclusively with
* respect to the current (calling) thread. This method is invoked
- * upon each call to a non-waiting {@link ConditionObject} method.
- * (Waiting methods instead invoke {@link #release}.)
+ * upon each call to a {@link ConditionObject} method.
*
* <p>The default implementation throws {@link
* UnsupportedOperationException}. This method is invoked
@@ -1597,9 +1596,8 @@ public abstract class AbstractQueuedLongSynchronizer
}
/**
- * Condition implementation for a {@link
- * AbstractQueuedLongSynchronizer} serving as the basis of a {@link
- * Lock} implementation.
+ * Condition implementation for a {@link AbstractQueuedLongSynchronizer}
+ * serving as the basis of a {@link Lock} implementation.
*
* <p>Method documentation for this class describes mechanics,
* not behavioral specifications from the point of view of Lock
@@ -1632,6 +1630,8 @@ public abstract class AbstractQueuedLongSynchronizer
* @return its new wait node
*/
private Node addConditionWaiter() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
Node t = lastWaiter;
// If lastWaiter is cancelled, clean out.
if (t != null && t.waitStatus != Node.CONDITION) {
diff --git a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 9088e5894..0e2bcdfef 100644
--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -192,19 +192,13 @@ import sun.misc.Unsafe;
* represent the locked state. While a non-reentrant lock
* does not strictly require recording of the current owner
* thread, this class does so anyway to make usage easier to monitor.
- * It also supports conditions and exposes
- * one of the instrumentation methods:
+ * It also supports conditions and exposes some instrumentation methods:
*
* <pre> {@code
* class Mutex implements Lock, java.io.Serializable {
*
* // Our internal helper class
* private static class Sync extends AbstractQueuedSynchronizer {
- * // Reports whether in locked state
- * protected boolean isHeldExclusively() {
- * return getState() == 1;
- * }
- *
* // Acquires the lock if state is zero
* public boolean tryAcquire(int acquires) {
* assert acquires == 1; // Otherwise unused
@@ -218,14 +212,27 @@ import sun.misc.Unsafe;
* // Releases the lock by setting state to zero
* protected boolean tryRelease(int releases) {
* assert releases == 1; // Otherwise unused
- * if (getState() == 0) throw new IllegalMonitorStateException();
+ * if (!isHeldExclusively())
+ * throw new IllegalMonitorStateException();
* setExclusiveOwnerThread(null);
* setState(0);
* return true;
* }
*
+ * // Reports whether in locked state
+ * public boolean isLocked() {
+ * return getState() != 0;
+ * }
+ *
+ * public boolean isHeldExclusively() {
+ * // a data race, but safe due to out-of-thin-air guarantees
+ * return getExclusiveOwnerThread() == Thread.currentThread();
+ * }
+ *
* // Provides a Condition
- * Condition newCondition() { return new ConditionObject(); }
+ * public Condition newCondition() {
+ * return new ConditionObject();
+ * }
*
* // Deserializes properly
* private void readObject(ObjectInputStream s)
@@ -238,12 +245,17 @@ import sun.misc.Unsafe;
* // The sync object does all the hard work. We just forward to it.
* private final Sync sync = new Sync();
*
- * public void lock() { sync.acquire(1); }
- * public boolean tryLock() { return sync.tryAcquire(1); }
- * public void unlock() { sync.release(1); }
- * public Condition newCondition() { return sync.newCondition(); }
- * public boolean isLocked() { return sync.isHeldExclusively(); }
- * public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
+ * public void lock() { sync.acquire(1); }
+ * public boolean tryLock() { return sync.tryAcquire(1); }
+ * public void unlock() { sync.release(1); }
+ * public Condition newCondition() { return sync.newCondition(); }
+ * public boolean isLocked() { return sync.isLocked(); }
+ * public boolean isHeldByCurrentThread() {
+ * return sync.isHeldExclusively();
+ * }
+ * public boolean hasQueuedThreads() {
+ * return sync.hasQueuedThreads();
+ * }
* public void lockInterruptibly() throws InterruptedException {
* sync.acquireInterruptibly(1);
* }
@@ -1168,8 +1180,7 @@ public abstract class AbstractQueuedSynchronizer
/**
* Returns {@code true} if synchronization is held exclusively with
* respect to the current (calling) thread. This method is invoked
- * upon each call to a non-waiting {@link ConditionObject} method.
- * (Waiting methods instead invoke {@link #release}.)
+ * upon each call to a {@link ConditionObject} method.
*
* <p>The default implementation throws {@link
* UnsupportedOperationException}. This method is invoked
@@ -1819,9 +1830,8 @@ public abstract class AbstractQueuedSynchronizer
}
/**
- * Condition implementation for a {@link
- * AbstractQueuedSynchronizer} serving as the basis of a {@link
- * Lock} implementation.
+ * Condition implementation for a {@link AbstractQueuedSynchronizer}
+ * serving as the basis of a {@link Lock} implementation.
*
* <p>Method documentation for this class describes mechanics,
* not behavioral specifications from the point of view of Lock
@@ -1852,6 +1862,8 @@ public abstract class AbstractQueuedSynchronizer
* @return its new wait node
*/
private Node addConditionWaiter() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
Node t = lastWaiter;
// If lastWaiter is cancelled, clean out.
if (t != null && t.waitStatus != Node.CONDITION) {
diff --git a/jdk/test/java/util/Bug8187408/Bug8187408.java b/jdk/test/java/util/Bug8187408/Bug8187408.java
new file mode 100644
index 000000000..fee6c730d
--- /dev/null
+++ b/jdk/test/java/util/Bug8187408/Bug8187408.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug 8187408
+ * @summary AbstractQueuedSynchronizer wait queue corrupted when thread awaits without holding the lock
+ */
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class Bug8187408 {
+ static final long LONG_DELAY_MS = 10000L;
+
+ public static void main(String[] args) throws InterruptedException {
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ final AwaitMethod awaitMethod = randomAwaitMethod();
+ final int nThreads = rnd.nextInt(2, 10);
+ final ReentrantLock lock = new ReentrantLock();
+ final Condition cond = lock.newCondition();
+ final CountDownLatch done = new CountDownLatch(nThreads);
+ final ArrayList<Thread> threads = new ArrayList<>();
+
+ Runnable rogue = () -> {
+ while (done.getCount() > 0) {
+ try {
+ // call await without holding lock?!
+ await(cond, awaitMethod);
+ throw new AssertionError("should throw");
+ }
+ catch (IllegalMonitorStateException success) {}
+ catch (Throwable fail) { threadUnexpectedException(fail); }}};
+ Thread rogueThread = new Thread(rogue, "rogue");
+ threads.add(rogueThread);
+ rogueThread.start();
+
+ Runnable waiter = () -> {
+ lock.lock();
+ try {
+ done.countDown();
+ cond.await();
+ } catch (Throwable fail) {
+ threadUnexpectedException(fail);
+ } finally {
+ lock.unlock();
+ }};
+ for (int i = 0; i < nThreads; i++) {
+ Thread thread = new Thread(waiter, "waiter");
+ threads.add(thread);
+ thread.start();
+ }
+
+ assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+ lock.lock();
+ try {
+ assertEquals(nThreads, lock.getWaitQueueLength(cond));
+ } finally {
+ cond.signalAll();
+ lock.unlock();
+ }
+ for (Thread thread : threads) {
+ thread.join(LONG_DELAY_MS);
+ assertFalse(thread.isAlive());
+ }
+ }
+
+ private static void assertTrue(boolean expr) {
+ if (!expr)
+ throw new RuntimeException("assertion failed");
+ }
+
+ private static void assertFalse(boolean expr) {
+ if (expr)
+ throw new RuntimeException("assertion failed");
+ }
+
+ private static void assertEquals(int i, int j) {
+ if (i != j)
+ throw new AssertionError(i + " != " + j);
+ }
+
+ /**
+ * Records the given exception using {@link #threadRecordFailure},
+ * then rethrows the exception, wrapping it in an AssertionError
+ * if necessary.
+ */
+ private static void threadUnexpectedException(Throwable t) {
+ t.printStackTrace();
+ if (t instanceof RuntimeException)
+ throw (RuntimeException) t;
+ else if (t instanceof Error)
+ throw (Error) t;
+ else
+ throw new AssertionError("unexpected exception: " + t, t);
+ }
+
+ enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
+ private static AwaitMethod randomAwaitMethod() {
+ AwaitMethod[] awaitMethods = AwaitMethod.values();
+ return awaitMethods[ThreadLocalRandom.current().nextInt(awaitMethods.length)];
+ }
+
+ /**
+ * Returns a new Date instance representing a time at least
+ * delayMillis milliseconds in the future.
+ */
+ private static Date delayedDate(long delayMillis) {
+ // Add 1 because currentTimeMillis is known to round into the past.
+ return new Date(System.currentTimeMillis() + delayMillis + 1);
+ }
+
+ /**
+ * Awaits condition "indefinitely" using the specified AwaitMethod.
+ */
+ private static void await(Condition c, AwaitMethod awaitMethod)
+ throws InterruptedException {
+ long timeoutMillis = 2 * LONG_DELAY_MS;
+ switch (awaitMethod) {
+ case await:
+ c.await();
+ break;
+ case awaitTimed:
+ assertTrue(c.await(timeoutMillis, MILLISECONDS));
+ break;
+ case awaitNanos:
+ long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+ long nanosRemaining = c.awaitNanos(timeoutNanos);
+ assertTrue(nanosRemaining > timeoutNanos / 2);
+ assertTrue(nanosRemaining <= timeoutNanos);
+ break;
+ case awaitUntil:
+ assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+}
\ No newline at end of file
--
2.22.0

View File

@ -0,0 +1,985 @@
Date: Wed, 31 May 2023 03:55:21 +0000
Subject: [PATCH 04/59] 8193710: jcmd -l and jps commands do not list Java processes running in Docker containers
Bug url: https://bugs.openjdk.org/browse/JDK-8193710
---
hotspot/src/os/linux/vm/perfMemory_linux.cpp | 102 ++++++--
.../classes/sun/jvmstat/PlatformSupport.java | 114 +++++++++
.../sun/jvmstat/PlatformSupportImpl.java | 227 ++++++++++++++++++
.../protocol/local/LocalVmManager.java | 93 +++----
.../monitor/protocol/local/PerfDataFile.java | 179 ++++++++------
5 files changed, 582 insertions(+), 133 deletions(-)
create mode 100644 jdk/src/share/classes/sun/jvmstat/PlatformSupport.java
create mode 100644 jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java
diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
index 8293b7168..b45032edb 100644
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
@@ -147,11 +147,23 @@ static void save_memory_to_file(char* addr, size_t size) {
// return the user specific temporary directory name.
//
+// If containerized process, get dirname of
+// /proc/{vmid}/root/tmp/{PERFDATA_NAME_user}
+// otherwise /tmp/{PERFDATA_NAME_user}
+//
// the caller is expected to free the allocated memory.
//
-static char* get_user_tmp_dir(const char* user) {
+#define TMP_BUFFER_LEN (4+22)
+static char* get_user_tmp_dir(const char* user, int vmid, int nspid) {
+ char buffer[TMP_BUFFER_LEN];
+ char* tmpdir = (char *)os::get_temp_directory();
+ assert(strlen(tmpdir) == 4, "No longer using /tmp - update buffer size");
+
+ if (nspid != -1) {
+ jio_snprintf(buffer, TMP_BUFFER_LEN, "/proc/%d/root%s", vmid, tmpdir);
+ tmpdir = buffer;
+ }
- const char* tmpdir = os::get_temp_directory();
const char* perfdir = PERFDATA_NAME;
size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
@@ -500,7 +512,10 @@ static char* get_user_name(uid_t uid) {
//
// the caller is expected to free the allocated memory.
//
-static char* get_user_name_slow(int vmid, TRAPS) {
+// If nspid != -1, look in /proc/{vmid}/root/tmp for directories
+// containing nspid, otherwise just look for vmid in /tmp
+//
+static char* get_user_name_slow(int vmid, int nspid, TRAPS) {
// short circuit the directory search if the process doesn't even exist.
if (kill(vmid, 0) == OS_ERR) {
@@ -516,8 +531,19 @@ static char* get_user_name_slow(int vmid, TRAPS) {
// directory search
char* oldest_user = NULL;
time_t oldest_ctime = 0;
+ char buffer[TMP_BUFFER_LEN];
+ int searchpid;
+ char* tmpdirname = (char *)os::get_temp_directory();
+ assert(strlen(tmpdirname) == 4, "No longer using /tmp - update buffer size");
- const char* tmpdirname = os::get_temp_directory();
+ if (nspid == -1) {
+ searchpid = vmid;
+ }
+ else {
+ jio_snprintf(buffer, MAXPATHLEN, "/proc/%d/root%s", vmid, tmpdirname);
+ tmpdirname = buffer;
+ searchpid = nspid;
+ }
// open the temp directory
DIR* tmpdirp = os::opendir(tmpdirname);
@@ -528,7 +554,7 @@ static char* get_user_name_slow(int vmid, TRAPS) {
}
// for each entry in the directory that matches the pattern hsperfdata_*,
- // open the directory and check if the file for the given vmid exists.
+ // open the directory and check if the file for the given vmid or nspid exists.
// The file with the expected name and the latest creation date is used
// to determine the user name for the process id.
//
@@ -571,7 +597,7 @@ static char* get_user_name_slow(int vmid, TRAPS) {
errno = 0;
while ((udentry = os::readdir(subdirp)) != NULL) {
- if (filename_to_pid(udentry->d_name) == vmid) {
+ if (filename_to_pid(udentry->d_name) == searchpid) {
struct stat statbuf;
int result;
@@ -620,10 +646,51 @@ static char* get_user_name_slow(int vmid, TRAPS) {
return(oldest_user);
}
+// Determine if the vmid is the parent pid
+// for a child in a PID namespace.
+// return the namespace pid if so, otherwise -1
+static int get_namespace_pid(int vmid) {
+ char fname[24];
+ int retpid = -1;
+
+ snprintf(fname, sizeof(fname), "/proc/%d/status", vmid);
+ FILE *fp = fopen(fname, "r");
+
+ if (fp) {
+ int pid, nspid;
+ int ret;
+ while (!feof(fp)) {
+ ret = fscanf(fp, "NSpid: %d %d", &pid, &nspid);
+ if (ret == 1) {
+ break;
+ }
+ if (ret == 2) {
+ retpid = nspid;
+ break;
+ }
+ for (;;) {
+ int ch = fgetc(fp);
+ if (ch == EOF || ch == (int)'\n') break;
+ }
+ }
+ fclose(fp);
+ }
+ return retpid;
+}
+
// return the name of the user that owns the JVM indicated by the given vmid.
//
-static char* get_user_name(int vmid, TRAPS) {
- return get_user_name_slow(vmid, THREAD);
+static char* get_user_name(int vmid, int *nspid, TRAPS) {
+ char *result = get_user_name_slow(vmid, *nspid, THREAD);
+
+ // If we are examining a container process without PID namespaces enabled
+ // we need to use /proc/{pid}/root/tmp to find hsperfdata files.
+ if (result == NULL) {
+ result = get_user_name_slow(vmid, vmid, THREAD);
+ // Enable nspid logic going forward
+ if (result != NULL) *nspid = vmid;
+ }
+ return result;
}
// return the file name of the backing store file for the named
@@ -631,13 +698,15 @@ static char* get_user_name(int vmid, TRAPS) {
//
// the caller is expected to free the allocated memory.
//
-static char* get_sharedmem_filename(const char* dirname, int vmid) {
+static char* get_sharedmem_filename(const char* dirname, int vmid, int nspid) {
+
+ int pid = (nspid == -1) ? vmid : nspid;
// add 2 for the file separator and a null terminator.
size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
- snprintf(name, nbytes, "%s/%d", dirname, vmid);
+ snprintf(name, nbytes, "%s/%d", dirname, pid);
return name;
}
@@ -929,8 +998,8 @@ static char* mmap_create_shared(size_t size) {
if (user_name == NULL)
return NULL;
- char* dirname = get_user_tmp_dir(user_name);
- char* filename = get_sharedmem_filename(dirname, vmid);
+ char* dirname = get_user_tmp_dir(user_name, vmid, -1);
+ char* filename = get_sharedmem_filename(dirname, vmid, -1);
// get the short filename
char* short_filename = strrchr(filename, '/');
if (short_filename == NULL) {
@@ -1076,8 +1145,11 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
"Illegal access mode");
}
+ // determine if vmid is for a containerized process
+ int nspid = get_namespace_pid(vmid);
+
if (user == NULL || strlen(user) == 0) {
- luser = get_user_name(vmid, CHECK);
+ luser = get_user_name(vmid, &nspid, CHECK);
}
else {
luser = user;
@@ -1088,7 +1160,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
"Could not map vmid to user Name");
}
- char* dirname = get_user_tmp_dir(luser);
+ char* dirname = get_user_tmp_dir(luser, vmid, nspid);
// since we don't follow symbolic links when creating the backing
// store file, we don't follow them when attaching either.
@@ -1099,7 +1171,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
"Process not found");
}
- char* filename = get_sharedmem_filename(dirname, vmid);
+ char* filename = get_sharedmem_filename(dirname, vmid, nspid);
// copy heap memory to resource memory. the open_sharedmem_file
// method below need to use the filename, but could throw an
diff --git a/jdk/src/share/classes/sun/jvmstat/PlatformSupport.java b/jdk/src/share/classes/sun/jvmstat/PlatformSupport.java
new file mode 100644
index 000000000..84f3b2274
--- /dev/null
+++ b/jdk/src/share/classes/sun/jvmstat/PlatformSupport.java
@@ -0,0 +1,114 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package sun.jvmstat;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+import java.util.List;
+import sun.misc.VMSupport;
+
+/*
+ * Support routines handling temp directory locating
+ * and process ID extraction.
+ */
+public class PlatformSupport {
+ private static final String tmpDirName;
+ static {
+ /*
+ * For this to work, the target VM and this code need to use
+ * the same directory. Instead of guessing which directory the
+ * VM is using, we will ask.
+ */
+ String tmpdir = VMSupport.getVMTemporaryDirectory();
+
+ /*
+ * Assure that the string returned has a trailing File.separator
+ * character. This check was added because the Linux implementation
+ * changed such that the java.io.tmpdir string no longer terminates
+ * with a File.separator character.
+ */
+ if (tmpdir.lastIndexOf(File.separator) != (tmpdir.length()-1)) {
+ tmpdir = tmpdir + File.separator;
+ }
+ tmpDirName = tmpdir;
+ }
+
+ public static PlatformSupport getInstance() {
+ try {
+ Class<?> c = Class.forName("sun.jvmstat.PlatformSupportImpl");
+ @SuppressWarnings("unchecked")
+ Constructor<PlatformSupport> cntr = (Constructor<PlatformSupport>) c.getConstructor();
+ return cntr.newInstance();
+ } catch (ClassNotFoundException e) {
+ return new PlatformSupport();
+ } catch (ReflectiveOperationException e) {
+ throw new InternalError(e);
+ }
+ }
+
+ // package-private
+ PlatformSupport() {}
+
+ /*
+ * Return the OS specific temporary directory
+ */
+ public static String getTemporaryDirectory() {
+ return tmpDirName;
+ }
+
+ /*
+ * Return a list of the temporary directories that the VM uses
+ * for the attach and perf data files. This function returns
+ * the traditional temp directory in addition to any paths
+ * accessible by the host which map to temp directories used
+ * by containers. The container functionality is only currently
+ * supported on Linux platforms.
+ *
+ * It is important that this directory is well-known and the
+ * same for all VM instances. It cannot be affected by configuration
+ * variables such as java.io.tmpdir.
+ */
+ public List<String> getTemporaryDirectories(int vmid) {
+ // Add the default temporary directory only
+ return Collections.singletonList(tmpDirName);
+ }
+
+ /*
+ * Extract the host PID from a file path.
+ */
+ public int getLocalVmId(File file) throws NumberFormatException {
+ return Integer.parseInt(file.getName());
+ }
+
+
+ /*
+ * Return the inner most namespaced PID if there is one,
+ * otherwise return the original PID.
+ */
+ public int getNamespaceVmId(int pid) {
+ return pid;
+ }
+}
diff --git a/jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java b/jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java
new file mode 100644
index 000000000..4d1d718ab
--- /dev/null
+++ b/jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java
@@ -0,0 +1,227 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.jvmstat;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.Files;
+import java.nio.charset.*;
+
+/*
+ * Linux specific implementation of the PlatformSupport routines
+ * providing process ID and temp directory support for host and
+ * cgroup container processes.
+ */
+public class PlatformSupportImpl extends PlatformSupport {
+ private static final String containerTmpPath = "/root" + getTemporaryDirectory();
+ private static final String pidPatternStr = "^[0-9]+$";
+
+ /*
+ * Return the temporary directories that the VM uses for the attach
+ * and perf data files. This function returns the traditional
+ * /tmp directory in addition to paths within the /proc file system
+ * allowing access to container tmp directories such as /proc/{pid}/root/tmp.
+ *
+ * It is important that this directory is well-known and the
+ * same for all VM instances. It cannot be affected by configuration
+ * variables such as java.io.tmpdir.
+ *
+ * Implementation Details:
+ *
+ * Java processes that run in docker containers are typically running
+ * under cgroups with separate pid namespaces which means that pids
+ * within the container are different that the pid which is visible
+ * from the host. The container pids typically start with 1 and
+ * increase. The java process running in the container will use these
+ * pids when creating the hsperfdata files. In order to locate java
+ * processes that are running in containers, we take advantage of
+ * the Linux proc file system which maps the containers tmp directory
+ * to the hosts under /proc/{hostpid}/root/tmp. We use the /proc status
+ * file /proc/{hostpid}/status to determine the containers pid and
+ * then access the hsperfdata file. The status file contains an
+ * entry "NSPid:" which shows the mapping from the hostpid to the
+ * containers pid.
+ *
+ * Example:
+ *
+ * NSPid: 24345 11
+ *
+ * In this example process 24345 is visible from the host,
+ * is running under the PID namespace and has a container specific
+ * pid of 11.
+ *
+ * The search for Java processes is done by first looking in the
+ * traditional /tmp for host process hsperfdata files and then
+ * the search will container in every /proc/{pid}/root/tmp directory.
+ * There are of course added complications to this search that
+ * need to be taken into account.
+ *
+ * 1. duplication of tmp directories
+ *
+ * /proc/{hostpid}/root/tmp directories exist for many processes
+ * that are running on a Linux kernel that has cgroups enabled even
+ * if they are not running in a container. To avoid this duplication,
+ * we compare the inode of the /proc tmp directories to /tmp and
+ * skip these duplicated directories.
+ *
+ * 2. Containerized processes without PID namespaces being enabled.
+ *
+ * If a container is running a Java process without namespaces being
+ * enabled, an hsperfdata file will only be located at
+ * /proc/{hostpid}/root/tmp/{hostpid}. This is handled by
+ * checking the last component in the path for both the hostpid
+ * and potential namespacepids (if one exists).
+ */
+ public List<String> getTemporaryDirectories(int pid) {
+ FilenameFilter pidFilter;
+ Matcher pidMatcher;
+ Pattern pidPattern = Pattern.compile(pidPatternStr);
+ long tmpInode = 0;
+
+ File procdir = new File("/proc");
+
+ if (pid != 0) {
+ pidPattern = Pattern.compile(Integer.toString(pid));
+ }
+ else {
+ pidPattern = Pattern.compile(pidPatternStr);
+ }
+ pidMatcher = pidPattern.matcher("");
+
+ // Add the default temporary directory first
+ List<String> v = new ArrayList<>();
+ v.add(getTemporaryDirectory());
+
+ try {
+ File f = new File(getTemporaryDirectory());
+ tmpInode = (Long)Files.getAttribute(f.toPath(), "unix:ino");
+ }
+ catch (IOException e) {}
+
+ pidFilter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (!dir.isDirectory())
+ return false;
+ pidMatcher.reset(name);
+ return pidMatcher.matches();
+ }
+ };
+
+ File[] dirs = procdir.listFiles(pidFilter);
+
+ // Add all unique /proc/{pid}/root/tmp dirs that are not mapped to /tmp
+ for (File dir : dirs) {
+ String containerTmpDir = dir.getAbsolutePath() + containerTmpPath;
+ File containerFile = new File(containerTmpDir);
+
+ try {
+ long procInode = (Long)Files.getAttribute(containerFile.toPath(), "unix:ino");
+ if (containerFile.exists() && containerFile.isDirectory() &&
+ containerFile.canRead() && procInode != tmpInode) {
+ v.add(containerTmpDir);
+ }
+ }
+ catch (IOException e) {}
+ }
+
+ return v;
+ }
+
+
+ /*
+ * Extract either the host PID or the NameSpace PID
+ * from a file path.
+ *
+ * File path should be in 1 of these 2 forms:
+ *
+ * /proc/{pid}/root/tmp/hsperfdata_{user}/{nspid}
+ * or
+ * /tmp/hsperfdata_{user}/{pid}
+ *
+ * In either case we want to return {pid} and NOT {nspid}
+ *
+ * This function filters out host pids which do not have
+ * associated hsperfdata files. This is due to the fact that
+ * getTemporaryDirectories will return /proc/{pid}/root/tmp
+ * paths for all container processes whether they are java
+ * processes or not causing duplicate matches.
+ */
+ public int getLocalVmId(File file) throws NumberFormatException {
+ String p = file.getAbsolutePath();
+ String s[] = p.split("\\/");
+
+ // Determine if this file is from a container
+ if (s.length == 7 && s[1].equals("proc")) {
+ int hostpid = Integer.parseInt(s[2]);
+ int nspid = Integer.parseInt(s[6]);
+ if (nspid == hostpid || nspid == getNamespaceVmId(hostpid)) {
+ return hostpid;
+ }
+ else {
+ return -1;
+ }
+ }
+ else {
+ return Integer.parseInt(file.getName());
+ }
+ }
+
+
+ /*
+ * Return the inner most namespaced PID if there is one,
+ * otherwise return the original PID.
+ */
+ public int getNamespaceVmId(int pid) {
+ // Assuming a real procfs sits beneath, reading this doesn't block
+ // nor will it consume a lot of memory.
+ Path statusPath = Paths.get("/proc", Integer.toString(pid), "status");
+ if (Files.notExists(statusPath)) {
+ return pid; // Likely a bad pid, but this is properly handled later.
+ }
+
+ try {
+ for (String line : Files.readAllLines(statusPath, StandardCharsets.UTF_8)) {
+ String[] parts = line.split(":");
+ if (parts.length == 2 && parts[0].trim().equals("NSpid")) {
+ parts = parts[1].trim().split("\\s+");
+ // The last entry represents the PID the JVM "thinks" it is.
+ // Even in non-namespaced pids these entries should be
+ // valid. You could refer to it as the inner most pid.
+ int ns_pid = Integer.parseInt(parts[parts.length - 1]);
+ return ns_pid;
+ }
+ }
+ // Old kernels may not have NSpid field (i.e. 3.10).
+ // Fallback to original pid in the event we cannot deduce.
+ return pid;
+ } catch (NumberFormatException | IOException x) {
+ return pid;
+ }
+ }
+}
diff --git a/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java b/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java
index fde75fb2d..35d25700d 100644
--- a/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java
+++ b/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -45,7 +45,7 @@ import java.io.*;
*/
public class LocalVmManager {
private String userName; // user name for monitored jvm
- private File tmpdir;
+ private List<String> tmpdirs;
private Pattern userPattern;
private Matcher userMatcher;
private FilenameFilter userFilter;
@@ -77,8 +77,9 @@ public class LocalVmManager {
public LocalVmManager(String user) {
this.userName = user;
+
if (userName == null) {
- tmpdir = new File(PerfDataFile.getTempDirectory());
+ tmpdirs = PerfDataFile.getTempDirectories(null, 0);
userPattern = Pattern.compile(PerfDataFile.userDirNamePattern);
userMatcher = userPattern.matcher("");
@@ -89,7 +90,7 @@ public class LocalVmManager {
}
};
} else {
- tmpdir = new File(PerfDataFile.getTempDirectory(userName));
+ tmpdirs = PerfDataFile.getTempDirectories(userName, 0);
}
filePattern = Pattern.compile(PerfDataFile.fileNamePattern);
@@ -134,65 +135,73 @@ public class LocalVmManager {
*/
Set<Integer> jvmSet = new HashSet<Integer>();
- if (! tmpdir.isDirectory()) {
- return jvmSet;
- }
+ for (String dir : tmpdirs) {
+ File tmpdir = new File(dir);
+ if (! tmpdir.isDirectory()) {
+ continue;
+ }
- if (userName == null) {
- /*
- * get a list of all of the user temporary directories and
- * iterate over the list to find any files within those directories.
- */
- File[] dirs = tmpdir.listFiles(userFilter);
-
- for (int i = 0 ; i < dirs.length; i ++) {
- if (!dirs[i].isDirectory()) {
- continue;
+ if (userName == null) {
+ /*
+ * get a list of all of the user temporary directories and
+ * iterate over the list to find any files within those directories.
+ */
+ File[] dirs = tmpdir.listFiles(userFilter);
+ for (int i = 0 ; i < dirs.length; i ++) {
+ if (!dirs[i].isDirectory()) {
+ continue;
+ }
+
+ // get a list of files from the directory
+ File[] files = dirs[i].listFiles(fileFilter);
+ if (files != null) {
+ for (int j = 0; j < files.length; j++) {
+ if (files[j].isFile() && files[j].canRead()) {
+ int vmid = PerfDataFile.getLocalVmId(files[j]);
+ if (vmid != -1) {
+ jvmSet.add(vmid);
+ }
+ }
+ }
+ }
}
+ } else {
+ /*
+ * Check if the user directory can be accessed. Any of these
+ * conditions may have asynchronously changed between subsequent
+ * calls to this method.
+ */
- // get a list of files from the directory
- File[] files = dirs[i].listFiles(fileFilter);
+ // get the list of files from the specified user directory
+ File[] files = tmpdir.listFiles(fileFilter);
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (files[j].isFile() && files[j].canRead()) {
- jvmSet.add(new Integer(
- PerfDataFile.getLocalVmId(files[j])));
+ int vmid = PerfDataFile.getLocalVmId(files[j]);
+ if (vmid != -1) {
+ jvmSet.add(vmid);
+ }
}
}
}
}
- } else {
- /*
- * Check if the user directory can be accessed. Any of these
- * conditions may have asynchronously changed between subsequent
- * calls to this method.
- */
- // get the list of files from the specified user directory
- File[] files = tmpdir.listFiles(fileFilter);
+ // look for any 1.4.1 files
+ File[] files = tmpdir.listFiles(tmpFileFilter);
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (files[j].isFile() && files[j].canRead()) {
- jvmSet.add(new Integer(
- PerfDataFile.getLocalVmId(files[j])));
+ int vmid = PerfDataFile.getLocalVmId(files[j]);
+ if (vmid != -1) {
+ jvmSet.add(vmid);
+ }
}
}
}
}
- // look for any 1.4.1 files
- File[] files = tmpdir.listFiles(tmpFileFilter);
- if (files != null) {
- for (int j = 0; j < files.length; j++) {
- if (files[j].isFile() && files[j].canRead()) {
- jvmSet.add(new Integer(
- PerfDataFile.getLocalVmId(files[j])));
- }
- }
- }
-
return jvmSet;
}
}
diff --git a/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java b/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java
index 62c64795b..26045ac5e 100644
--- a/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java
+++ b/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -26,7 +26,11 @@
package sun.jvmstat.perfdata.monitor.protocol.local;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
import java.io.FilenameFilter;
+import sun.jvmstat.PlatformSupport;
/**
* Class to provide translations from the local Vm Identifier
@@ -44,11 +48,6 @@ import java.io.FilenameFilter;
public class PerfDataFile {
private PerfDataFile() { };
- /**
- * The name of the of the system dependent temporary directory
- */
- public static final String tmpDirName;
-
/**
* The file name prefix for PerfData shared memory files.
* <p>
@@ -79,6 +78,12 @@ public class PerfDataFile {
"^hsperfdata_[0-9]+(_[1-2]+)?$";
+ /**
+ * Platform Specific methods for looking up temporary directories
+ * and process IDs.
+ */
+ private static final PlatformSupport platSupport = PlatformSupport.getInstance();
+
/**
* Get a File object for the instrumentation backing store file
* for the JVM identified by the given local Vm Identifier.
@@ -93,7 +98,7 @@ public class PerfDataFile {
* @return File - a File object to the backing store file for the named
* shared memory region of the target JVM.
* @see java.io.File
- * @see #getTempDirectory()
+ * @see #getTempDirectories()
*/
public static File getFile(int lvmid) {
if (lvmid == 0) {
@@ -106,56 +111,65 @@ public class PerfDataFile {
return null;
}
- /*
- * iterate over all files in all directories in tmpDirName that
- * match the file name patterns.
- */
- File tmpDir = new File(tmpDirName);
- String[] files = tmpDir.list(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- if (!name.startsWith(dirNamePrefix)) {
- return false;
- }
- File candidate = new File(dir, name);
- return ((candidate.isDirectory() || candidate.isFile())
- && candidate.canRead());
- }
- });
-
- long newestTime = 0;
+ List<String> tmpDirs = getTempDirectories(null, lvmid);
File newest = null;
- for (int i = 0; i < files.length; i++) {
- File f = new File(tmpDirName + files[i]);
- File candidate = null;
+ for (String dir : tmpDirs) {
+ /*
+ * iterate over all files in all directories in this tmpDir that
+ * match the file name patterns.
+ */
+ File tmpDir = new File(dir);
+ String[] files = tmpDir.list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (!name.startsWith(dirNamePrefix)) {
+ return false;
+ }
+ File candidate = new File(dir, name);
+ return ((candidate.isDirectory() || candidate.isFile())
+ && candidate.canRead());
+ }
+ });
- if (f.exists() && f.isDirectory()) {
- /*
- * found a directory matching the name patterns. This
- * is a 1.4.2 hsperfdata_<user> directory. Check for
- * file named <lvmid> in that directory
- */
- String name = Integer.toString(lvmid);
- candidate = new File(f.getName(), name);
+ long newestTime = 0;
- } else if (f.exists() && f.isFile()) {
- /*
- * found a file matching the name patterns. This
- * is a 1.4.1 hsperfdata_<lvmid> file.
- */
- candidate = f;
+ for (String file : files) {
+ File f = new File(dir + file);
+ File candidate = null;
- } else {
- // unexpected - let conditional below filter this one out
- candidate = f;
- }
+ if (f.exists() && f.isDirectory()) {
+ /*
+ * found a directory matching the name patterns. This
+ * is a 1.4.2 hsperfdata_<user> directory. Check for
+ * file named <lvmid> in that directory
+ */
+ String name = f.getAbsolutePath() + File.separator + lvmid;
+ candidate = new File(name);
+ // Try NameSpace Id if Host Id doesn't exist.
+ if (!candidate.exists()) {
+ name = f.getAbsolutePath() + File.separator +
+ platSupport.getNamespaceVmId(lvmid);
+ candidate = new File(name);
+ }
+ } else if (f.exists() && f.isFile()) {
+ /*
+ * found a file matching the name patterns. This
+ * is a 1.4.1 hsperfdata_<lvmid> file.
+ */
+ candidate = f;
- if (candidate.exists() && candidate.isFile()
- && candidate.canRead()) {
- long modTime = candidate.lastModified();
- if (modTime >= newestTime) {
- newestTime = modTime;
- newest = candidate;
+ } else {
+ // unexpected - let conditional below filter this one out
+ candidate = f;
+ }
+
+ if (candidate.exists() && candidate.isFile()
+ && candidate.canRead()) {
+ long modTime = candidate.lastModified();
+ if (modTime >= newestTime) {
+ newestTime = modTime;
+ newest = candidate;
+ }
}
}
}
@@ -176,7 +190,7 @@ public class PerfDataFile {
* @return File - a File object to the backing store file for the named
* shared memory region of the target JVM.
* @see java.io.File
- * @see #getTempDirectory()
+ * @see #getTempDirectories()
*/
public static File getFile(String user, int lvmid) {
if (lvmid == 0) {
@@ -190,11 +204,22 @@ public class PerfDataFile {
}
// first try for 1.4.2 and later JVMs
- String basename = getTempDirectory(user) + Integer.toString(lvmid);
- File f = new File(basename);
+ List<String> tmpDirs = getTempDirectories(user, lvmid);
+ String basename;
+ File f;
- if (f.exists() && f.isFile() && f.canRead()) {
- return f;
+ for (String dir : tmpDirs) {
+ basename = dir + lvmid;
+ f = new File(basename);
+ if (f.exists() && f.isFile() && f.canRead()) {
+ return f;
+ }
+ // Try NameSpace Id if Host Id doesn't exist.
+ basename = dir + platSupport.getNamespaceVmId(lvmid);
+ f = new File(basename);
+ if (f.exists() && f.isFile() && f.canRead()) {
+ return f;
+ }
}
// No hit on 1.4.2 JVMs, try 1.4.1 files
@@ -235,7 +260,7 @@ public class PerfDataFile {
public static int getLocalVmId(File file) {
try {
// try 1.4.2 and later format first
- return Integer.parseInt(file.getName());
+ return(platSupport.getLocalVmId(file));
} catch (NumberFormatException e) { }
// now try the 1.4.1 format
@@ -266,7 +291,7 @@ public class PerfDataFile {
* @return String - the name of the temporary directory.
*/
public static String getTempDirectory() {
- return tmpDirName;
+ return PlatformSupport.getTemporaryDirectory();
}
/**
@@ -282,26 +307,28 @@ public class PerfDataFile {
* @return String - the name of the temporary directory.
*/
public static String getTempDirectory(String user) {
- return tmpDirName + dirNamePrefix + user + File.separator;
+ return getTempDirectory() + dirNamePrefix + user + File.separator;
}
- static {
- /*
- * For this to work, the target VM and this code need to use
- * the same directory. Instead of guessing which directory the
- * VM is using, we will ask.
- */
- String tmpdir = sun.misc.VMSupport.getVMTemporaryDirectory();
-
- /*
- * Assure that the string returned has a trailing File.separator
- * character. This check was added because the Linux implementation
- * changed such that the java.io.tmpdir string no longer terminates
- * with a File.separator character.
- */
- if (tmpdir.lastIndexOf(File.separator) != (tmpdir.length()-1)) {
- tmpdir = tmpdir + File.separator;
+ /**
+ * Return the names of the temporary directories being searched for
+ * HotSpot PerfData backing store files.
+ * <p>
+ * This method returns the traditional host temp directory but also
+ * includes a list of temp directories used by containers.
+ *
+ * @return List<String> - A List of temporary directories to search.
+ */
+ public static List<String> getTempDirectories(String userName, int vmid) {
+ List<String> list = platSupport.getTemporaryDirectories(vmid);
+ if (userName == null) {
+ return list;
}
- tmpDirName = tmpdir;
+
+ List<String> nameList = list.stream()
+ .map(name -> name + dirNamePrefix + userName + File.separator)
+ .collect(Collectors.toList());
+
+ return nameList;
}
}
--
2.22.0

View File

@ -0,0 +1,57 @@
Date: Wed, 31 May 2023 09:22:26 +0000
Subject: [PATCH 05/59] 8196743: jstatd doesn't see new Java processes inside Docker container
Bug url: https://bugs.openjdk.org/browse/JDK-8196743
---
.../perfdata/monitor/protocol/local/LocalVmManager.java | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java b/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java
index 35d25700d..4be281f65 100644
--- a/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java
+++ b/jdk/src/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2021, 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
@@ -45,7 +45,6 @@ import java.io.*;
*/
public class LocalVmManager {
private String userName; // user name for monitored jvm
- private List<String> tmpdirs;
private Pattern userPattern;
private Matcher userMatcher;
private FilenameFilter userFilter;
@@ -77,9 +76,7 @@ public class LocalVmManager {
public LocalVmManager(String user) {
this.userName = user;
-
if (userName == null) {
- tmpdirs = PerfDataFile.getTempDirectories(null, 0);
userPattern = Pattern.compile(PerfDataFile.userDirNamePattern);
userMatcher = userPattern.matcher("");
@@ -89,8 +86,6 @@ public class LocalVmManager {
return userMatcher.lookingAt();
}
};
- } else {
- tmpdirs = PerfDataFile.getTempDirectories(userName, 0);
}
filePattern = Pattern.compile(PerfDataFile.fileNamePattern);
@@ -134,6 +129,7 @@ public class LocalVmManager {
* we'd see strange file names being matched by the matcher.
*/
Set<Integer> jvmSet = new HashSet<Integer>();
+ List<String> tmpdirs = PerfDataFile.getTempDirectories(userName, 0);
for (String dir : tmpdirs) {
File tmpdir = new File(dir);
--
2.22.0

View File

@ -0,0 +1,113 @@
Date: Wed, 31 May 2023 09:34:28 +0000
Subject: [PATCH 06/59] 8284330: jcmd may not be able to find processes in the container
Bug url: https://bugs.openjdk.org/browse/JDK-8284330
---
.../sun/jvmstat/PlatformSupportImpl.java | 57 ++++++++++++-------
1 file changed, 37 insertions(+), 20 deletions(-)
diff --git a/jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java b/jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java
index 4d1d718ab..38da80cc7 100644
--- a/jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java
+++ b/jdk/src/share/classes/sun/jvmstat/PlatformSupportImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2022, 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
@@ -42,6 +42,32 @@ public class PlatformSupportImpl extends PlatformSupport {
private static final String containerTmpPath = "/root" + getTemporaryDirectory();
private static final String pidPatternStr = "^[0-9]+$";
+ private long tmpInode;
+ private long tmpDev;
+
+ public PlatformSupportImpl() {
+ super();
+ try {
+ File f = new File(getTemporaryDirectory());
+ Path tmpPath = f.toPath();
+ tmpInode = (Long)Files.getAttribute(tmpPath, "unix:ino");
+ tmpDev = (Long)Files.getAttribute(tmpPath, "unix:dev");
+ } catch (IOException e) {
+ tmpInode = -1L;
+ tmpDev = -1L;
+ }
+ }
+
+ private boolean tempDirectoryEquals(Path p) {
+ try {
+ long ino = (Long)Files.getAttribute(p, "unix:ino");
+ long dev = (Long)Files.getAttribute(p, "unix:dev");
+ return (ino == tmpInode) && (dev == tmpDev);
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
/*
* Return the temporary directories that the VM uses for the attach
* and perf data files. This function returns the traditional
@@ -84,11 +110,12 @@ public class PlatformSupportImpl extends PlatformSupport {
*
* 1. duplication of tmp directories
*
- * /proc/{hostpid}/root/tmp directories exist for many processes
- * that are running on a Linux kernel that has cgroups enabled even
- * if they are not running in a container. To avoid this duplication,
- * we compare the inode of the /proc tmp directories to /tmp and
- * skip these duplicated directories.
+ * When cgroups is enabled, the directory /proc/{pid}/root/tmp may
+ * exist even if the given pid is not running inside a container. In
+ * this case, this directory is usually the same as /tmp and should
+ * be skipped, or else we would get duplicated hsperfdata files.
+ * This case can be detected if the inode and device id of
+ * /proc/{pid}/root/tmp are the same as /tmp.
*
* 2. Containerized processes without PID namespaces being enabled.
*
@@ -102,7 +129,6 @@ public class PlatformSupportImpl extends PlatformSupport {
FilenameFilter pidFilter;
Matcher pidMatcher;
Pattern pidPattern = Pattern.compile(pidPatternStr);
- long tmpInode = 0;
File procdir = new File("/proc");
@@ -118,12 +144,6 @@ public class PlatformSupportImpl extends PlatformSupport {
List<String> v = new ArrayList<>();
v.add(getTemporaryDirectory());
- try {
- File f = new File(getTemporaryDirectory());
- tmpInode = (Long)Files.getAttribute(f.toPath(), "unix:ino");
- }
- catch (IOException e) {}
-
pidFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (!dir.isDirectory())
@@ -140,14 +160,11 @@ public class PlatformSupportImpl extends PlatformSupport {
String containerTmpDir = dir.getAbsolutePath() + containerTmpPath;
File containerFile = new File(containerTmpDir);
- try {
- long procInode = (Long)Files.getAttribute(containerFile.toPath(), "unix:ino");
- if (containerFile.exists() && containerFile.isDirectory() &&
- containerFile.canRead() && procInode != tmpInode) {
- v.add(containerTmpDir);
- }
+ if (containerFile.exists() && containerFile.isDirectory() &&
+ containerFile.canRead() &&
+ !tempDirectoryEquals(containerFile.toPath())) {
+ v.add(containerTmpDir);
}
- catch (IOException e) {}
}
return v;
--
2.22.0

View File

@ -0,0 +1,146 @@
Date: Mon, 5 Jun 2023 20:12:44 +0800
Subject: [PATCH 07/59] 8241670: Enhance heap region size ergonomics to improve OOTB performance
---
.../g1/g1CollectorPolicy.cpp | 3 +-
.../vm/gc_implementation/g1/heapRegion.cpp | 29 ++++++++-----------
.../vm/gc_implementation/g1/heapRegion.hpp | 3 +-
.../gc_implementation/g1/heapRegionBounds.hpp | 3 +-
.../gc/arguments/TestG1HeapRegionSize.java | 3 +-
5 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index 05ce59987..0acdd2b69 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -184,7 +185,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
// the region size on the heap size, but the heap size should be
// aligned with the region size. To get around this we use the
// unaligned values for the heap.
- HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize);
+ HeapRegion::setup_heap_region_size(MaxHeapSize);
HeapRegionRemSet::setup_remset_size();
G1ErgoVerbose::initialize();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
index 87cc73bee..28b21a9be 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -107,29 +108,23 @@ size_t HeapRegion::max_region_size() {
return HeapRegionBounds::max_size();
}
-void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
- uintx region_size = G1HeapRegionSize;
- if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
- size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
- region_size = MAX2(average_heap_size / HeapRegionBounds::target_number(),
+void HeapRegion::setup_heap_region_size(size_t max_heap_size) {
+ uintx region_size = G1HeapRegionSize;
+ // G1HeapRegionSize = 0 means decide ergonomically.
+ if (region_size == 0) {
+ region_size = MAX2(max_heap_size / HeapRegionBounds::target_number(),
(uintx) HeapRegionBounds::min_size());
}
- int region_size_log = log2_long((jlong) region_size);
- // Recalculate the region size to make sure it's a power of
- // 2. This means that region_size is the largest power of 2 that's
- // <= what we've calculated so far.
- region_size = ((uintx)1 << region_size_log);
+ // Make sure region size is a power of 2. Rounding up since this
+ // is beneficial in most cases.
+ region_size = is_power_of_2(region_size) ? region_size : (size_t)1 << (log2_intptr(region_size) + 1);
// Now make sure that we don't go over or under our limits.
- if (region_size < HeapRegionBounds::min_size()) {
- region_size = HeapRegionBounds::min_size();
- } else if (region_size > HeapRegionBounds::max_size()) {
- region_size = HeapRegionBounds::max_size();
- }
+ region_size = MIN2(MAX2(region_size, HeapRegionBounds::min_size()), HeapRegionBounds::max_size());
- // And recalculate the log.
- region_size_log = log2_long((jlong) region_size);
+ // Calculate the log for the region size.
+ int region_size_log = exact_log2_long((jlong)region_size);
// Now, set up the globals.
guarantee(LogOfHRGrainBytes == 0, "we should only set it once");
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
index 5d2415e84..4e0afbac1 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -333,7 +334,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
// CardsPerRegion). All those fields are considered constant
// throughout the JVM's execution, therefore they should only be set
// up once during initialization time.
- static void setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size);
+ static void setup_heap_region_size(size_t max_heap_size);
// All allocated blocks are occupied by objects in a HeapRegion
bool block_is_obj(const HeapWord* p) const;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp
index 1da7f24c1..c76dead88 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +41,7 @@ private:
static const size_t MAX_REGION_SIZE = 32 * 1024 * 1024;
// The automatic region size calculation will try to have around this
- // many regions in the heap (based on the min heap size).
+ // many regions in the heap.
static const size_t TARGET_REGION_NUMBER = 2048;
public:
diff --git a/hotspot/test/gc/arguments/TestG1HeapRegionSize.java b/hotspot/test/gc/arguments/TestG1HeapRegionSize.java
index 0442d2c61..a9b5fa0cb 100644
--- a/hotspot/test/gc/arguments/TestG1HeapRegionSize.java
+++ b/hotspot/test/gc/arguments/TestG1HeapRegionSize.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +29,7 @@
* @summary Verify that the flag G1HeapRegionSize is updated properly
* @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576
* @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152
- * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 4194304
* @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432
*/
--
2.22.0

View File

@ -0,0 +1,60 @@
Date: Mon, 5 Jun 2023 20:26:02 +0800
Subject: 8223162: Improve ergonomics for Sparse PRT entry sizing
---
.../share/vm/gc_implementation/g1/heapRegionRemSet.cpp | 8 ++++----
.../share/vm/gc_implementation/g1/heapRegionRemSet.hpp | 1 +
hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp | 4 +---
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
index 8167d2b09..9e9391ba6 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
@@ -868,12 +868,12 @@ HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
}
void HeapRegionRemSet::setup_remset_size() {
- // Setup sparse and fine-grain tables sizes.
- // table_size = base * (log(region_size / 1M) + 1)
const int LOG_M = 20;
- int region_size_log_mb = MAX2(HeapRegion::LogOfHRGrainBytes - LOG_M, 0);
+ guarantee(HeapRegion::LogOfHRGrainBytes >= LOG_M, err_msg("Code assumes the region size >= 1M, but is " SIZE_FORMAT "B", HeapRegion::GrainBytes));
+
+ int region_size_log_mb = HeapRegion::LogOfHRGrainBytes - LOG_M;
if (FLAG_IS_DEFAULT(G1RSetSparseRegionEntries)) {
- G1RSetSparseRegionEntries = G1RSetSparseRegionEntriesBase * (region_size_log_mb + 1);
+ G1RSetSparseRegionEntries = G1RSetSparseRegionEntriesBase * ((size_t)1 << (region_size_log_mb + 1));
}
if (FLAG_IS_DEFAULT(G1RSetRegionEntries)) {
G1RSetRegionEntries = G1RSetRegionEntriesBase * (region_size_log_mb + 1);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
index 77751b4a9..6659dc550 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
@@ -271,6 +271,7 @@ public:
HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr);
static uint num_par_rem_sets();
+ // Setup sparse and fine-grain tables sizes.
static void setup_remset_size();
HeapRegion* hr() const {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp
index 17bd4a145..3d2de1a95 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp
@@ -218,9 +218,7 @@ class SparsePRT VALUE_OBJ_CLASS_SPEC {
HeapRegion* _hr;
- enum SomeAdditionalPrivateConstants {
- InitialCapacity = 16
- };
+ static const size_t InitialCapacity = 8;
void expand();
--
2.22.0

View File

@ -0,0 +1,165 @@
Date: Mon, 5 Jun 2023 20:27:38 +0800
Subject: 8262316: Reducing locks in RSA Blinding
Bug url: https://bugs.openjdk.org/browse/JDK-8262316
---
.../classes/sun/security/rsa/RSACore.java | 101 +++++++++++-------
1 file changed, 60 insertions(+), 41 deletions(-)
diff --git a/jdk/src/share/classes/sun/security/rsa/RSACore.java b/jdk/src/share/classes/sun/security/rsa/RSACore.java
index 9809639a0..ae187b5a5 100644
--- a/jdk/src/share/classes/sun/security/rsa/RSACore.java
+++ b/jdk/src/share/classes/sun/security/rsa/RSACore.java
@@ -25,20 +25,26 @@
package sun.security.rsa;
-import java.math.BigInteger;
-import java.util.*;
-
-import java.security.SecureRandom;
-import java.security.interfaces.*;
+import sun.security.jca.JCAUtil;
import javax.crypto.BadPaddingException;
-import sun.security.jca.JCAUtil;
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.locks.ReentrantLock;
/**
* Core of the RSA implementation. Has code to perform public and private key
* RSA operations (with and without CRT for private key ops). Private CRT ops
- * also support blinding to twart timing attacks.
+ * also support blinding to thwart timing attacks.
*
* The code in this class only does the core RSA operation. Padding and
* unpadding must be done externally.
@@ -53,11 +59,14 @@ public final class RSACore {
// globally enable/disable use of blinding
private final static boolean ENABLE_BLINDING = true;
- // cache for blinding parameters. Map<BigInteger, BlindingParameters>
- // use a weak hashmap so that cached values are automatically cleared
- // when the modulus is GC'ed
- private final static Map<BigInteger, BlindingParameters>
+ // cache for blinding parameters. Map<BigInteger,
+ // ConcurrentLinkedQueue<BlindingParameters>> use a weak hashmap so that,
+ // cached values are automatically cleared when the modulus is GC'ed.
+ // Multiple BlindingParameters can be queued during times of heavy load,
+ // like performance testing.
+ private static final Map<BigInteger, ConcurrentLinkedQueue<BlindingParameters>>
blindingCache = new WeakHashMap<>();
+ private static final ReentrantLock lock = new ReentrantLock();
private RSACore() {
// empty
@@ -402,56 +411,66 @@ public final class RSACore {
if ((this.e != null && this.e.equals(e)) ||
(this.d != null && this.d.equals(d))) {
- BlindingRandomPair brp = null;
- synchronized (this) {
- if (!u.equals(BigInteger.ZERO) &&
- !v.equals(BigInteger.ZERO)) {
-
- brp = new BlindingRandomPair(u, v);
- if (u.compareTo(BigInteger.ONE) <= 0 ||
- v.compareTo(BigInteger.ONE) <= 0) {
-
- // need to reset the random pair next time
- u = BigInteger.ZERO;
- v = BigInteger.ZERO;
- } else {
- u = u.modPow(BIG_TWO, n);
- v = v.modPow(BIG_TWO, n);
- }
- } // Otherwise, need to reset the random pair.
+ BlindingRandomPair brp = new BlindingRandomPair(u, v);
+ if (u.compareTo(BigInteger.ONE) <= 0 ||
+ v.compareTo(BigInteger.ONE) <= 0) {
+ // Reset so the parameters will be not queued later
+ u = BigInteger.ZERO;
+ v = BigInteger.ZERO;
+ } else {
+ u = u.modPow(BIG_TWO, n);
+ v = v.modPow(BIG_TWO, n);
}
return brp;
}
return null;
}
+
+ // Check if reusable, return true if both u & v are not zero.
+ boolean isReusable() {
+ return !u.equals(BigInteger.ZERO) && !v.equals(BigInteger.ZERO);
+ }
}
private static BlindingRandomPair getBlindingRandomPair(
BigInteger e, BigInteger d, BigInteger n) {
- BlindingParameters bps = null;
- synchronized (blindingCache) {
- bps = blindingCache.get(n);
+ ConcurrentLinkedQueue<BlindingParameters> queue;
+
+ // Get queue from map, if there is none then create one
+ lock.lock();
+ try {
+ queue = blindingCache.computeIfAbsent(n,
+ ignored -> new ConcurrentLinkedQueue<>());
+ } finally {
+ lock.unlock();
}
+ BlindingParameters bps = queue.poll();
if (bps == null) {
bps = new BlindingParameters(e, d, n);
- synchronized (blindingCache) {
- blindingCache.putIfAbsent(n, bps);
- }
}
+ BlindingRandomPair brp = null;
- BlindingRandomPair brp = bps.getBlindingRandomPair(e, d, n);
- if (brp == null) {
- // need to reset the blinding parameters
- bps = new BlindingParameters(e, d, n);
- synchronized (blindingCache) {
- blindingCache.replace(n, bps);
- }
+ // Loops to get a valid pair, going through the queue or create a new
+ // parameters if needed.
+ while (brp == null) {
brp = bps.getBlindingRandomPair(e, d, n);
+ if (brp == null) {
+ // need to reset the blinding parameters, first check for
+ // another in the queue.
+ bps = queue.poll();
+ if (bps == null) {
+ bps = new BlindingParameters(e, d, n);
+ }
+ }
}
+ // If this parameters are still usable, put them back into the queue.
+ if (bps.isReusable()) {
+ queue.add(bps);
+ }
return brp;
}
--
2.22.0

View File

@ -0,0 +1,26 @@
Date: Mon, 5 Jun 2023 20:31:43 +0800
Subject: 8283994: Make Xerces DatatypeException stackless
Bug url: https://bugs.openjdk.org/browse/JDK-8283994
---
.../apache/xerces/internal/impl/dv/DatatypeException.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java
index 17efe6aa0..9a428649a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java
@@ -107,4 +107,10 @@ public class DatatypeException extends Exception {
return msg;
}
+
+ @Override
+ public Throwable fillInStackTrace() {
+ // This is an internal exception; the stack trace is irrelevant.
+ return this;
+ }
}
--
2.22.0

View File

@ -0,0 +1,51 @@
Date: Mon, 5 Jun 2023 20:35:04 +0800
Subject: Optimizing ObjectInputStream by FreqInlineSize
---
hotspot/src/share/vm/opto/bytecodeInfo.cpp | 2 +-
.../share/classes/java/io/ObjectInputStream.java | 2 +-
.../share/classes/java/io/ObjectOutputStream.java | 2 +-
4 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
index 4fa8e12f1..f9191ec06 100644
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
@@ -171,7 +171,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
is_unboxing_method(callee_method, C) ||
is_init_with_ea(callee_method, caller_method, C)) {
- max_inline_size = C->freq_inline_size();
+ max_inline_size = (int)FreqInlineSize;
if (size <= max_inline_size && TraceFrequencyInlining) {
CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count);
diff --git a/jdk/src/share/classes/java/io/ObjectInputStream.java b/jdk/src/share/classes/java/io/ObjectInputStream.java
index 85e3958b4..6a7280eab 100644
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java
@@ -387,7 +387,7 @@ public class ObjectInputStream
/**
* value of "useFastSerializer" property
*/
- private static final boolean defaultFastSerializer = UNSAFE.getUseFastSerializer();
+ private final boolean defaultFastSerializer = UNSAFE.getUseFastSerializer();
/**
* true or false for open FastSerilizer
diff --git a/jdk/src/share/classes/java/io/ObjectOutputStream.java b/jdk/src/share/classes/java/io/ObjectOutputStream.java
index 23c1fff59..328f47589 100644
--- a/jdk/src/share/classes/java/io/ObjectOutputStream.java
+++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java
@@ -240,7 +240,7 @@ public class ObjectOutputStream
* Value of "UseFastSerializer" property. The fastSerializer is turned
* on when it is true.
*/
- private static final boolean useFastSerializer = UNSAFE.getUseFastSerializer();
+ private final boolean useFastSerializer = UNSAFE.getUseFastSerializer();
/**
* value of "printFastSerializer" property,
--
2.22.0

View File

@ -0,0 +1,30 @@
Date: Mon, 5 Jun 2023 20:37:13 +0800
Subject: [PATCH 12/59] 8301187: Memory leaks in OopMapCache
Bug url: https://bugs.openjdk.org/browse/JDK-8301187
---
hotspot/src/share/vm/interpreter/oopMapCache.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp
index 528906267..bd7d4f100 100644
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp
@@ -561,6 +561,7 @@ void OopMapCache::lookup(methodHandle method,
// at this time. We give the caller of lookup() a copy of the
// interesting info via parameter entry_for, but we don't add it to
// the cache. See the gory details in Method*.cpp.
+ tmp->flush();
FREE_C_HEAP_OBJ(tmp, mtClass);
return;
}
@@ -635,5 +636,6 @@ void OopMapCache::compute_one_oop_map(methodHandle method, int bci, InterpreterO
tmp->initialize();
tmp->fill(method, bci);
entry->resource_copy(tmp);
+ tmp->flush();
FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp, mtInternal);
}
--
2.22.0

View File

@ -0,0 +1,28 @@
Date: Mon, 5 Jun 2023 20:39:01 +0800
Subject: [PATCH 13/59] 8287349: AArch64: Merge LDR instructions to improve C1 OSR performance
Bug url: https://bugs.openjdk.org/browse/JDK-8287349
---
hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
index 528eeae32..22dfd1008 100644
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
@@ -292,10 +292,9 @@ void LIR_Assembler::osr_entry() {
__ bind(L);
}
#endif
- __ ldr(r19, Address(OSR_buf, slot_offset + 0));
+ __ ldp(r19, r20, Address(OSR_buf, slot_offset));
__ str(r19, frame_map()->address_for_monitor_lock(i));
- __ ldr(r19, Address(OSR_buf, slot_offset + 1*BytesPerWord));
- __ str(r19, frame_map()->address_for_monitor_object(i));
+ __ str(r20, frame_map()->address_for_monitor_object(i));
}
}
}
--
2.22.0

View File

@ -0,0 +1,382 @@
Date: Mon, 5 Jun 2023 20:43:22 +0800
Subject: [PATCH 14/59] 8280511: AArch64: Combine shift and negate to a single instruction
Bug url: https://bugs.openjdk.org/browse/JDK-8280511
---
hotspot/src/cpu/aarch64/vm/aarch64.ad | 102 ++++++++++
hotspot/src/cpu/aarch64/vm/aarch64_ad.m4 | 25 +++
hotspot/test/compiler/codegen/ShiftTest.java | 199 +++++++++++++++++++
3 files changed, 326 insertions(+)
create mode 100644 hotspot/test/compiler/codegen/ShiftTest.java
diff --git a/hotspot/src/cpu/aarch64/vm/aarch64.ad b/hotspot/src/cpu/aarch64/vm/aarch64.ad
index 511ce913e..d73d5d457 100644
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad
@@ -9818,6 +9818,108 @@ instruct regI_not_reg(iRegINoSp dst,
ins_pipe(ialu_reg);
%}
+// This pattern is automatically generated from aarch64_ad.m4
+// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
+instruct NegI_reg_URShift_reg(iRegINoSp dst,
+ immI0 zero, iRegIorL2I src1, immI src2) %{
+ match(Set dst (SubI zero (URShiftI src1 src2)));
+
+ ins_cost(1.9 * INSN_COST);
+ format %{ "negw $dst, $src1, LSR $src2" %}
+
+ ins_encode %{
+ __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
+ Assembler::LSR, $src2$$constant & 0x1f);
+ %}
+
+ ins_pipe(ialu_reg_shift);
+%}
+
+// This pattern is automatically generated from aarch64_ad.m4
+// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
+instruct NegI_reg_RShift_reg(iRegINoSp dst,
+ immI0 zero, iRegIorL2I src1, immI src2) %{
+ match(Set dst (SubI zero (RShiftI src1 src2)));
+
+ ins_cost(1.9 * INSN_COST);
+ format %{ "negw $dst, $src1, ASR $src2" %}
+
+ ins_encode %{
+ __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
+ Assembler::ASR, $src2$$constant & 0x1f);
+ %}
+
+ ins_pipe(ialu_reg_shift);
+%}
+
+// This pattern is automatically generated from aarch64_ad.m4
+// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
+instruct NegI_reg_LShift_reg(iRegINoSp dst,
+ immI0 zero, iRegIorL2I src1, immI src2) %{
+ match(Set dst (SubI zero (LShiftI src1 src2)));
+
+ ins_cost(1.9 * INSN_COST);
+ format %{ "negw $dst, $src1, LSL $src2" %}
+
+ ins_encode %{
+ __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
+ Assembler::LSL, $src2$$constant & 0x1f);
+ %}
+
+ ins_pipe(ialu_reg_shift);
+%}
+
+// This pattern is automatically generated from aarch64_ad.m4
+// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
+instruct NegL_reg_URShift_reg(iRegLNoSp dst,
+ immL0 zero, iRegL src1, immI src2) %{
+ match(Set dst (SubL zero (URShiftL src1 src2)));
+
+ ins_cost(1.9 * INSN_COST);
+ format %{ "neg $dst, $src1, LSR $src2" %}
+
+ ins_encode %{
+ __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
+ Assembler::LSR, $src2$$constant & 0x3f);
+ %}
+
+ ins_pipe(ialu_reg_shift);
+%}
+
+// This pattern is automatically generated from aarch64_ad.m4
+// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
+instruct NegL_reg_RShift_reg(iRegLNoSp dst,
+ immL0 zero, iRegL src1, immI src2) %{
+ match(Set dst (SubL zero (RShiftL src1 src2)));
+
+ ins_cost(1.9 * INSN_COST);
+ format %{ "neg $dst, $src1, ASR $src2" %}
+
+ ins_encode %{
+ __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
+ Assembler::ASR, $src2$$constant & 0x3f);
+ %}
+
+ ins_pipe(ialu_reg_shift);
+%}
+
+// This pattern is automatically generated from aarch64_ad.m4
+// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
+instruct NegL_reg_LShift_reg(iRegLNoSp dst,
+ immL0 zero, iRegL src1, immI src2) %{
+ match(Set dst (SubL zero (LShiftL src1 src2)));
+
+ ins_cost(1.9 * INSN_COST);
+ format %{ "neg $dst, $src1, LSL $src2" %}
+
+ ins_encode %{
+ __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
+ Assembler::LSL, $src2$$constant & 0x3f);
+ %}
+
+ ins_pipe(ialu_reg_shift);
+%}
+
instruct AndI_reg_not_reg(iRegINoSp dst,
iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1,
rFlagsReg cr) %{
diff --git a/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4 b/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4
index 9fb793023..6ec8fde08 100644
--- a/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4
+++ b/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4
@@ -47,6 +47,24 @@ instruct $2$1_reg_$4_reg(iReg$1NoSp dst,
ins_pipe(ialu_reg_reg_shift);
%}')dnl
+define(`NEG_SHIFT_INSN',
+`// This pattern is automatically generated from aarch64_ad.m4
+// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
+instruct Neg$1_reg_$2_reg(iReg$1NoSp dst,
+ imm$1`0' zero, iReg$1`'ORL2I($1) src1, immI src2) %{
+ match(Set dst (Sub$1 zero ($2$1 src1 src2)));
+
+ ins_cost(1.9 * INSN_COST);
+ format %{ "ifelse($1, I, negw, neg) $dst, $src1, $3 $src2" %}
+
+ ins_encode %{
+ __ ifelse($1, I, negw, neg)(as_Register($dst$$reg), as_Register($src1$$reg),
+ Assembler::$3, $src2$$constant & ifelse($1,I,0x1f,0x3f));
+ %}
+
+ ins_pipe(ialu_reg_shift);
+%}
+')dnl
define(`BASE_INVERTED_INSN',
`
instruct $2$1_reg_not_reg(iReg$1NoSp dst,
@@ -110,6 +128,11 @@ define(`NOT_INSN',
ins_pipe(ialu_reg);
%}')dnl
dnl
+define(`BOTH_NEG_SHIFT_INSNS',
+`NEG_SHIFT_INSN($1, URShift, LSR)
+NEG_SHIFT_INSN($1, RShift, ASR)
+NEG_SHIFT_INSN($1, LShift, LSL)')dnl
+dnl
define(`BOTH_SHIFT_INSNS',
`BASE_SHIFT_INSN(I, $1, ifelse($2,andr,andw,$2w), $3, $4)
BASE_SHIFT_INSN(L, $1, $2, $3, $4)')dnl
@@ -134,6 +157,8 @@ BOTH_INVERTED_SHIFT_INSNS($1, $2, LShift, LSL)')dnl
dnl
NOT_INSN(L, eon)
NOT_INSN(I, eonw)
+BOTH_NEG_SHIFT_INSNS(I)
+BOTH_NEG_SHIFT_INSNS(L)
BOTH_INVERTED_INSNS(And, bic)
BOTH_INVERTED_INSNS(Or, orn)
BOTH_INVERTED_INSNS(Xor, eon)
diff --git a/hotspot/test/compiler/codegen/ShiftTest.java b/hotspot/test/compiler/codegen/ShiftTest.java
new file mode 100644
index 000000000..45d192341
--- /dev/null
+++ b/hotspot/test/compiler/codegen/ShiftTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4093292 8280511
+ * @summary Test for correct code generation by the JIT
+ * @library /testlibrary
+ * @run main compiler.codegen.ShiftTest
+ * @run main/othervm -XX:-TieredCompilation compiler.codegen.ShiftTest
+ */
+
+package compiler.codegen;
+import com.oracle.java.testlibrary.Asserts;
+
+public class ShiftTest {
+ static final int w = 32;
+
+ private static void doTest(long ct) throws Exception {
+ int S22 = 0xc46cf7c2;
+ int S23 = 0xcfda9162;
+ int S24 = 0xd029aa4c;
+ int S25 = 0x17cf1801;
+ int A = (int)(ct & 0xffffffffL);
+ int B = (int)(ct >>> 32);
+ int x, y;
+ x = B - S25;
+ y = A & (w-1);
+ B = ((x >>> y) | (x << (w-y))) ^ A;
+ x = A - S24;
+ y = B & (w-1);
+ A = ((x >>> y) | (x << (w-y))) ^ B;
+ x = B - S23;
+ y = A & (w-1);
+ B = ((x >>> y) | (x << (w-y))) ^ A;
+ x = A - S22;
+ y = B & (w-1);
+ A = ((x >>> y) | (x << (w-y))) ^ B;
+ String astr = Integer.toHexString(A);
+ String bstr = Integer.toHexString(B);
+ System.err.println("A = " + astr + " B = " + bstr);
+ if ((!astr.equals("dcb38144")) ||
+ (!bstr.equals("1916de73"))) {
+ throw new RuntimeException("Unexpected shift results!");
+ }
+ System.err.println("Test passed");
+ }
+
+ private static int[] ispecial = {
+ 0, Integer.MAX_VALUE, -Integer.MAX_VALUE, Integer.MIN_VALUE, -42, 42, -1, 1
+ };
+
+ private static long[] lspecial = {
+ 0, Long.MAX_VALUE, -Long.MAX_VALUE, Long.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE, Integer.MIN_VALUE, -42, 42, -1, 1
+ };
+
+ private static int[] ispecial_LeftShift_expected = {
+ 0, 32, -32, 0, 1344, -1344, 32, -32
+ };
+
+ private static int[] ispecial_UnsignedRightShift_expected = {
+ 0, -33554431, -33554432, -33554432 ,-67108863, 0, -67108863, 0
+ };
+
+ private static int[] ispecial_SignedRightShift_expected = {
+ 0, -16777215, 16777216, 16777216, 1, 0, 1, 0
+ };
+
+ private static int[] ispecial_LeftShiftCorner_expected = {
+ 0, -2147483647, 2147483647, -2147483648, 42, -42, 1, -1
+ };
+
+ private static int[] ispecial_UnsignedRightShiftCorner_expected = {
+ 0, -1073741823, -1073741824, -1073741824, -2147483627, -21, -2147483647, 0
+ };
+
+ private static int[] ispecial_SignedRightShiftCorner_expected = {
+ 0, -536870911, 536870912, 536870912, 11, -10, 1, 0
+ };
+
+ private static long[] lspecial_LeftShift_expected = {
+ 0, 256, -256, 0, -549755813632L, 549755813632L, 549755813888L, 10752, -10752, 256, -256
+ };
+
+ private static long[] lspecial_UnsignedRightShift_expected = {
+ 0, -18014398509481983L, -18014398509481984L, -18014398509481984L, -4194303, -36028797014769664L, -36028797014769664L, -36028797018963967L, 0, -36028797018963967L, 0
+ };
+
+ private static long[] lspecial_SignedRightShift_expected = {
+ 0, -9007199254740991L, 9007199254740992L, 9007199254740992L, -2097151, 2097152, 2097152, 1, 0, 1, 0
+ };
+
+ private static long[] lspecial_LeftShiftCorner_expected = {
+ 0, -9223372036854775807L, 9223372036854775807L, -9223372036854775808L, -2147483647, 2147483647, 2147483648L, 42, -42, 1, -1
+ };
+
+ private static long[] lspecial_UnsignedRightShiftCorner_expected = {
+ 0, -4611686018427387903L, -4611686018427387904L, -4611686018427387904L, -1073741823, -9223372035781033984L, -9223372035781033984L, -9223372036854775787L, -21, -9223372036854775807L, 0
+ };
+
+ private static long[] lspecial_SignedRightShiftCorner_expected = {
+ 0, -2305843009213693951L, 2305843009213693952L, 2305843009213693952L, -536870911, 536870912, 536870912, 11, -10, 1, 0
+ };
+
+ private static int negLeftShiftInt(int input) {
+ return -(input << 5);
+ }
+
+ private static int negUnsignedRightShiftInt(int input) {
+ return -(input >>> 6);
+ }
+
+ private static int negSignedRightShiftInt(int input) {
+ return -(input >> 7);
+ }
+
+ private static int negLeftShiftICorner(int input) {
+ return -(input << 32);
+ }
+
+ private static int negUnsignedRightShiftICorner(int input) {
+ return -(input >>> 33);
+ }
+
+ private static int negSignedRightShiftICorner(int input) {
+ return -(input >> 34);
+ }
+
+ private static long negLeftShiftLong(long input) {
+ return -(input << 8);
+ }
+
+ private static long negUnsignedRightShiftLong(long input) {
+ return -(input >>> 9);
+ }
+
+ private static long negSignedRightShiftLong(long input) {
+ return -(input >> 10);
+ }
+
+ private static long negLeftShiftLCorner(long input) {
+ return -(input << 64);
+ }
+
+ private static long negUnsignedRightShiftLCorner(long input) {
+ return -(input >>> 65);
+ }
+
+ private static long negSignedRightShiftLCorner(long input) {
+ return -(input >> 66);
+ }
+
+ private static void testNegShift() {
+ for (int i = 0; i < 20_000; i++) {
+ for (int j = 0; j < ispecial.length; j++) {
+ Asserts.assertEquals(negLeftShiftInt(ispecial[j]), ispecial_LeftShift_expected[j]);
+ Asserts.assertEquals(negUnsignedRightShiftInt(ispecial[j]), ispecial_UnsignedRightShift_expected[j]);
+ Asserts.assertEquals(negSignedRightShiftInt(ispecial[j]), ispecial_SignedRightShift_expected[j]);
+ Asserts.assertEquals(negLeftShiftICorner(ispecial[j]), ispecial_LeftShiftCorner_expected[j]);
+ Asserts.assertEquals(negUnsignedRightShiftICorner(ispecial[j]), ispecial_UnsignedRightShiftCorner_expected[j]);
+ Asserts.assertEquals(negSignedRightShiftICorner(ispecial[j]), ispecial_SignedRightShiftCorner_expected[j]);
+ }
+ for (int j = 0; j < lspecial.length; j++) {
+ Asserts.assertEquals(negLeftShiftLong(lspecial[j]), lspecial_LeftShift_expected[j]);
+ Asserts.assertEquals(negUnsignedRightShiftLong(lspecial[j]), lspecial_UnsignedRightShift_expected[j]);
+ Asserts.assertEquals(negSignedRightShiftLong(lspecial[j]), lspecial_SignedRightShift_expected[j]);
+ Asserts.assertEquals(negLeftShiftLCorner(lspecial[j]), lspecial_LeftShiftCorner_expected[j]);
+ Asserts.assertEquals(negUnsignedRightShiftLCorner(lspecial[j]), lspecial_UnsignedRightShiftCorner_expected[j]);
+ Asserts.assertEquals(negSignedRightShiftLCorner(lspecial[j]), lspecial_SignedRightShiftCorner_expected[j]);
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ doTest(0x496def29b74be041L);
+ testNegShift();
+ }
+}
--
2.22.0

View File

@ -0,0 +1,34 @@
Date: Tue, 6 Jun 2023 02:06:23 +0000
Subject: [PATCH 15/59] 6605915: jinfo -flag <flag name> functionality doesn't work with core files
Bug url: https://bugs.openjdk.org/browse/JDK-6605915
---
jdk/src/share/classes/sun/tools/jinfo/JInfo.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java
index 7c817ba86..d5adc3537 100644
--- a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java
+++ b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java
@@ -196,15 +196,17 @@ public class JInfo {
if (usageSA) {
System.err.println(" jinfo [option] <pid>");
System.err.println(" (to connect to running process)");
- System.err.println(" jinfo [option] <executable <core>");
+ System.err.println(" jinfo [option] <executable> <core>");
System.err.println(" (to connect to a core file)");
System.err.println(" jinfo [option] [server_id@]<remote server IP or hostname>");
System.err.println(" (to connect to remote debug server)");
System.err.println("");
System.err.println("where <option> is one of:");
+ System.err.println(" for running processes:");
System.err.println(" -flag <name> to print the value of the named VM flag");
System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag");
System.err.println(" -flag <name>=<value> to set the named VM flag to the given value");
+ System.err.println(" for running processes and core files:");
System.err.println(" -flags to print VM flags");
System.err.println(" -sysprops to print Java system properties");
System.err.println(" <no option> to print both of the above");
--
2.22.0

View File

@ -0,0 +1,313 @@
Date: Tue, 6 Jun 2023 03:31:04 +0000
Subject: [PATCH 16/59] 8036599: Use Diagnostic Commands instead of SA by default in jinfo
Bug url: https://bugs.openjdk.org/browse/JDK-8036599
---
.../share/classes/sun/tools/jinfo/JInfo.java | 144 ++++++++++++------
jdk/test/sun/tools/jinfo/Basic.sh | 26 +++-
2 files changed, 121 insertions(+), 49 deletions(-)
diff --git a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java
index d5adc3537..0c1d6a1e6 100644
--- a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java
+++ b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java
@@ -26,18 +26,18 @@
package sun.tools.jinfo;
import java.lang.reflect.Method;
+import java.util.Arrays;
import java.io.IOException;
import java.io.InputStream;
import com.sun.tools.attach.VirtualMachine;
+
import sun.tools.attach.HotSpotVirtualMachine;
/*
* This class is the main class for the JInfo utility. It parses its arguments
* and decides if the command should be satisfied using the VM attach mechanism
- * or an SA tool. At this time the only option that uses the VM attach
- * mechanism is the -flag option to set or print a command line option of a
- * running application. All other options are mapped to SA tools.
+ * or an SA tool.
*/
public class JInfo {
@@ -46,62 +46,95 @@ public class JInfo {
usage(1); // no arguments
}
- boolean useSA = true;
- String arg1 = args[0];
- if (arg1.startsWith("-")) {
- if (arg1.equals("-flags") ||
- arg1.equals("-sysprops")) {
- // SA JInfo needs <pid> or <server> or
- // (<executable> and <code file>). So, total
- // argument count including option has to 2 or 3.
- if (args.length != 2 && args.length != 3) {
- usage(1);
- }
- } else if (arg1.equals("-flag")) {
- // do not use SA, use attach-on-demand
- useSA = false;
- } else {
- // unknown option or -h or -help, print help
- int exit;
- if (arg1.equals("-help") || arg1.equals("-h")) {
- exit = 0;
- } else {
- exit = 1;
+ // First determine if we should launch SA or not
+ boolean useSA = false;
+ if (args[0].equals("-F")) {
+ // delete the -F
+ args = Arrays.copyOfRange(args, 1, args.length);
+ useSA = true;
+ } else if (args[0].equals("-flags")
+ || args[0].equals("-sysprops"))
+ {
+ if (args.length == 2) {
+ if (!args[1].matches("[0-9]+")) {
+ // If args[1] doesn't parse to a number then
+ // it must be the SA debug server
+ // (otherwise it is the pid)
+ useSA = true;
}
- usage(exit);
}
+ if (args.length == 3) {
+ // arguments include an executable and a core file
+ useSA = true;
+ }
+ } else if (!args[0].startsWith("-")) {
+ if (args.length == 2) {
+ // the only arguments are an executable and a core file
+ useSA = true;
+ }
+ } else if (args[0].equals("-h")
+ || args[0].equals("-help")) {
+ usage(0);
}
if (useSA) {
+ // invoke SA which does it's own argument parsing
runTool(args);
} else {
- if (args.length == 3) {
- String pid = args[2];
+ // Now we can parse arguments for the non-SA case
+ String pid = null;
+
+ switch(args[0]) {
+ case "-flag":
+ if (args.length != 3) {
+ usage(1);
+ }
String option = args[1];
+ pid = args[2];
flag(pid, option);
- } else {
- int exit;
- if (arg1.equals("-help") || arg1.equals("-h")) {
- exit = 0;
- } else {
- exit = 1;
+ break;
+ case "-flags":
+ if (args.length != 2) {
+ usage(1);
+ }
+ pid = args[1];
+ flags(pid);
+ break;
+ case "-sysprops":
+ if (args.length != 2) {
+ usage(1);
}
- usage(exit);
+ pid = args[1];
+ sysprops(pid);
+ break;
+ case "-help":
+ case "-h":
+ usage(0);
+ default:
+ if (args.length == 1) {
+ // no flags specified, we do -sysprops and -flags
+ pid = args[0];
+ sysprops(pid);
+ System.out.println();
+ flags(pid);
+ } else {
+ usage(1);
+ }
}
}
}
- // Invoke SA tool with the given arguments
+ // Invoke SA tool with the given arguments
private static void runTool(String args[]) throws Exception {
String tool = "sun.jvm.hotspot.tools.JInfo";
- // Tool not available on this platform.
+ // Tool not available on this platform.
Class<?> c = loadClass(tool);
if (c == null) {
usage(1);
}
// invoke the main method with the arguments
- Class[] argTypes = { String[].class } ;
+ Class<?>[] argTypes = { String[].class } ;
Method m = c.getDeclaredMethod("main", argTypes);
Object[] invokeArgs = { args };
@@ -111,7 +144,7 @@ public class JInfo {
// loads the given class using the system class loader
private static Class<?> loadClass(String name) {
//
- // We specify the system clas loader so as to cater for development
+ // We specify the system class loader so as to cater for development
// environments where this class is on the boot class path but sa-jdi.jar
// is on the system class path. Once the JDK is deployed then both
// tools.jar and sa-jdi.jar are on the system class path.
@@ -124,28 +157,28 @@ public class JInfo {
}
private static void flag(String pid, String option) throws IOException {
- VirtualMachine vm = attach(pid);
+ HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid);
String flag;
InputStream in;
int index = option.indexOf('=');
if (index != -1) {
flag = option.substring(0, index);
String value = option.substring(index + 1);
- in = ((HotSpotVirtualMachine)vm).setFlag(flag, value);
+ in = vm.setFlag(flag, value);
} else {
char c = option.charAt(0);
switch (c) {
case '+':
flag = option.substring(1);
- in = ((HotSpotVirtualMachine)vm).setFlag(flag, "1");
+ in = vm.setFlag(flag, "1");
break;
case '-':
flag = option.substring(1);
- in = ((HotSpotVirtualMachine)vm).setFlag(flag, "0");
+ in = vm.setFlag(flag, "0");
break;
default:
flag = option;
- in = ((HotSpotVirtualMachine)vm).printFlag(flag);
+ in = vm.printFlag(flag);
break;
}
}
@@ -153,6 +186,20 @@ public class JInfo {
drain(vm, in);
}
+ private static void flags(String pid) throws IOException {
+ HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid);
+ InputStream in = vm.executeJCmd("VM.flags");
+ System.out.println("VM Flags:");
+ drain(vm, in);
+ }
+
+ private static void sysprops(String pid) throws IOException {
+ HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid);
+ InputStream in = vm.executeJCmd("VM.system_properties");
+ System.out.println("Java System Properties:");
+ drain(vm, in);
+ }
+
// Attach to <pid>, exiting if we fail to attach
private static VirtualMachine attach(String pid) {
try {
@@ -195,7 +242,9 @@ public class JInfo {
System.err.println("Usage:");
if (usageSA) {
System.err.println(" jinfo [option] <pid>");
- System.err.println(" (to connect to running process)");
+ System.err.println(" (to connect to a running process)");
+ System.err.println(" jinfo -F [option] <pid>");
+ System.err.println(" (to connect to a hung process)");
System.err.println(" jinfo [option] <executable> <core>");
System.err.println(" (to connect to a core file)");
System.err.println(" jinfo [option] [server_id@]<remote server IP or hostname>");
@@ -206,10 +255,10 @@ public class JInfo {
System.err.println(" -flag <name> to print the value of the named VM flag");
System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag");
System.err.println(" -flag <name>=<value> to set the named VM flag to the given value");
- System.err.println(" for running processes and core files:");
+ System.err.println(" for running or hung processes and core files:");
System.err.println(" -flags to print VM flags");
System.err.println(" -sysprops to print Java system properties");
- System.err.println(" <no option> to print both of the above");
+ System.err.println(" <no option> to print both VM flags and system properties");
System.err.println(" -h | -help to print this help message");
} else {
System.err.println(" jinfo <option> <pid>");
@@ -219,6 +268,9 @@ public class JInfo {
System.err.println(" -flag <name> to print the value of the named VM flag");
System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag");
System.err.println(" -flag <name>=<value> to set the named VM flag to the given value");
+ System.err.println(" -flags to print VM flags");
+ System.err.println(" -sysprops to print Java system properties");
+ System.err.println(" <no option> to print both VM flags and system properties");
System.err.println(" -h | -help to print this help message");
}
diff --git a/jdk/test/sun/tools/jinfo/Basic.sh b/jdk/test/sun/tools/jinfo/Basic.sh
index 5905c83d0..8d4b01238 100644
--- a/jdk/test/sun/tools/jinfo/Basic.sh
+++ b/jdk/test/sun/tools/jinfo/Basic.sh
@@ -61,19 +61,39 @@ fi
if [ $runSA = true ]; then
# -sysprops option
- ${JINFO} -J-XX:+UsePerfData -sysprops $appJavaPid
+ ${JINFO} -J-XX:+UsePerfData -F -sysprops $appJavaPid
if [ $? != 0 ]; then failed=1; fi
# -flags option
- ${JINFO} -J-XX:+UsePerfData -flags $appJavaPid
+ ${JINFO} -J-XX:+UsePerfData -F -flags $appJavaPid
if [ $? != 0 ]; then failed=1; fi
# no option
- ${JINFO} -J-XX:+UsePerfData $appJavaPid
+ ${JINFO} -J-XX:+UsePerfData -F $appJavaPid
if [ $? != 0 ]; then failed=1; fi
+ # -flag option
+ ${JINFO} -J-XX:+UsePerfData -F -flag +PrintGC $appJavaPid
+ if [ $? != 0 ]; then failed=1; fi
+
+ ${JINFO} -J-XX:+UsePerfData -F -flag -PrintGC $appJavaPid
+ if [ $? != 0 ]; then failed=1; fi
+
+ ${JINFO} -J-XX:+UsePerfData -F -flag PrintGC $appJavaPid
+ if [ $? != 0 ]; then failed=1; fi
fi
+# -sysprops option
+${JINFO} -J-XX:+UsePerfData -sysprops $appJavaPid
+if [ $? != 0 ]; then failed=1; fi
+
+# -flags option
+${JINFO} -J-XX:+UsePerfData -flags $appJavaPid
+if [ $? != 0 ]; then failed=1; fi
+
+# no option
+${JINFO} -J-XX:+UsePerfData $appJavaPid
+if [ $? != 0 ]; then failed=1; fi
# -flag option
${JINFO} -J-XX:+UsePerfData -flag +PrintGC $appJavaPid
--
2.22.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,730 @@
Date: Mon, 5 Jun 2023 20:33:14 +0800
Subject: [PATCH 19/59] 8040213: C2 does not put all modified nodes on IGVN worklist
Bug url: https://bugs.openjdk.org/browse/JDK-8040213
---
hotspot/src/share/vm/opto/cfgnode.cpp | 7 +++-
hotspot/src/share/vm/opto/compile.cpp | 31 +++++++++++++---
hotspot/src/share/vm/opto/compile.hpp | 6 ++++
hotspot/src/share/vm/opto/divnode.cpp | 10 ++++--
hotspot/src/share/vm/opto/loopPredicate.cpp | 9 ++---
hotspot/src/share/vm/opto/loopTransform.cpp | 27 +++++---------
hotspot/src/share/vm/opto/loopnode.cpp | 23 ++++++------
hotspot/src/share/vm/opto/loopopts.cpp | 2 +-
hotspot/src/share/vm/opto/macro.cpp | 2 ++
hotspot/src/share/vm/opto/memnode.cpp | 10 ++++--
hotspot/src/share/vm/opto/node.cpp | 4 +++
hotspot/src/share/vm/opto/node.hpp | 2 ++
hotspot/src/share/vm/opto/phaseX.cpp | 39 +++++++++++++++++----
hotspot/src/share/vm/opto/rootnode.cpp | 4 ++-
14 files changed, 123 insertions(+), 53 deletions(-)
diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp
index 82fc957d5..752b603e8 100644
--- a/hotspot/src/share/vm/opto/cfgnode.cpp
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp
@@ -105,6 +105,7 @@ static Node *merge_region(RegionNode *region, PhaseGVN *phase) {
rreq++; // One more input to Region
} // Found a region to merge into Region
+ igvn->_worklist.push(r);
// Clobber pointer to the now dead 'r'
region->set_req(i, phase->C->top());
}
@@ -446,6 +447,7 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Remove TOP or NULL input paths. If only 1 input path remains, this Region
// degrades to a copy.
bool add_to_worklist = false;
+ bool modified = false;
int cnt = 0; // Count of values merging
DEBUG_ONLY( int cnt_orig = req(); ) // Save original inputs count
int del_it = 0; // The last input path we delete
@@ -456,6 +458,7 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Remove useless control copy inputs
if( n->is_Region() && n->as_Region()->is_copy() ) {
set_req(i, n->nonnull_req());
+ modified = true;
i--;
continue;
}
@@ -463,12 +466,14 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *call = n->in(0);
if (call->is_Call() && call->as_Call()->entry_point() == OptoRuntime::rethrow_stub()) {
set_req(i, call->in(0));
+ modified = true;
i--;
continue;
}
}
if( phase->type(n) == Type::TOP ) {
set_req(i, NULL); // Ignore TOP inputs
+ modified = true;
i--;
continue;
}
@@ -688,7 +693,7 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
}
- return NULL;
+ return modified ? this : NULL;
}
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index 4a32e8a9f..f55437eb3 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -1071,6 +1071,7 @@ void Compile::Init(int aliaslevel) {
_node_note_array = NULL;
_default_node_notes = NULL;
+ DEBUG_ONLY( _modified_nodes = NULL; ) // Used in Optimize()
_immutable_memory = NULL; // filled in at first inquiry
@@ -1283,6 +1284,19 @@ void Compile::print_missing_nodes() {
}
}
}
+
+void Compile::record_modified_node(Node* n) const {
+ if (_modified_nodes != NULL && !_inlining_incrementally &&
+ n->outcnt() != 0 && !n->is_Con()) {
+ _modified_nodes->push(n);
+ }
+}
+
+void Compile::remove_modified_node(Node* n) const {
+ if (_modified_nodes != NULL) {
+ _modified_nodes->remove(n);
+ }
+}
#endif
#ifndef PRODUCT
@@ -2123,6 +2137,9 @@ void Compile::Optimize() {
// Iterative Global Value Numbering, including ideal transforms
// Initialize IterGVN with types and values from parse-time GVN
PhaseIterGVN igvn(initial_gvn());
+#ifdef ASSERT
+ _modified_nodes = new (comp_arena()) Unique_Node_List(comp_arena());
+#endif
{
NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); )
igvn.optimize();
@@ -2308,7 +2325,7 @@ void Compile::Optimize() {
return;
}
}
-
+ DEBUG_ONLY( _modified_nodes = NULL; )
} // (End scope of igvn; run destructor if necessary for asserts.)
dump_inlining();
@@ -4059,6 +4076,7 @@ void Compile::cleanup_expensive_nodes(PhaseIterGVN &igvn) {
int j = 0;
int identical = 0;
int i = 0;
+ bool modified = false;
for (; i < _expensive_nodes->length()-1; i++) {
assert(j <= i, "can't write beyond current index");
if (_expensive_nodes->at(i)->Opcode() == _expensive_nodes->at(i+1)->Opcode()) {
@@ -4071,20 +4089,23 @@ void Compile::cleanup_expensive_nodes(PhaseIterGVN &igvn) {
identical = 0;
} else {
Node* n = _expensive_nodes->at(i);
- igvn.hash_delete(n);
- n->set_req(0, NULL);
+ igvn.replace_input_of(n, 0, NULL);
igvn.hash_insert(n);
+ modified = true;
}
}
if (identical > 0) {
_expensive_nodes->at_put(j++, _expensive_nodes->at(i));
} else if (_expensive_nodes->length() >= 1) {
Node* n = _expensive_nodes->at(i);
- igvn.hash_delete(n);
- n->set_req(0, NULL);
+ igvn.replace_input_of(n, 0, NULL);
igvn.hash_insert(n);
+ modified = true;
}
_expensive_nodes->trunc_to(j);
+ if (modified) {
+ igvn.optimize();
+ }
}
void Compile::add_expensive_node(Node * n) {
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index fb12b6874..20d8324ff 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -358,6 +358,7 @@ class Compile : public Phase {
VectorSet _dead_node_list; // Set of dead nodes
uint _dead_node_count; // Number of dead nodes; VectorSet::Size() is O(N).
// So use this to keep count and make the call O(1).
+ DEBUG_ONLY( Unique_Node_List* _modified_nodes; ) // List of nodes which inputs were modified
debug_only(static int _debug_idx;) // Monotonic counter (not reset), use -XX:BreakAtNode=<idx>
Arena _node_arena; // Arena for new-space Nodes
Arena _old_arena; // Arena for old-space Nodes, lifetime during xform
@@ -795,6 +796,11 @@ class Compile : public Phase {
void print_missing_nodes();
#endif
+ // Record modified nodes to check that they are put on IGVN worklist
+ void record_modified_node(Node* /* n */) const NOT_DEBUG_RETURN;
+ void remove_modified_node(Node* /* n */) const NOT_DEBUG_RETURN;
+ DEBUG_ONLY( Unique_Node_List* modified_nodes() const { return _modified_nodes; } )
+
// Constant table
ConstantTable& constant_table() { return _constant_table; }
diff --git a/hotspot/src/share/vm/opto/divnode.cpp b/hotspot/src/share/vm/opto/divnode.cpp
index e1a8ad558..6a893ff3a 100644
--- a/hotspot/src/share/vm/opto/divnode.cpp
+++ b/hotspot/src/share/vm/opto/divnode.cpp
@@ -477,7 +477,10 @@ Node *DivINode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (i == 0) return NULL; // Dividing by zero constant does not idealize
- set_req(0,NULL); // Dividing by a not-zero constant; no faulting
+ if (in(0) != NULL) {
+ phase->igvn_rehash_node_delayed(this);
+ set_req(0, NULL); // Dividing by a not-zero constant; no faulting
+ }
// Dividing by MININT does not optimize as a power-of-2 shift.
if( i == min_jint ) return NULL;
@@ -576,7 +579,10 @@ Node *DivLNode::Ideal( PhaseGVN *phase, bool can_reshape) {
if (l == 0) return NULL; // Dividing by zero constant does not idealize
- set_req(0,NULL); // Dividing by a not-zero constant; no faulting
+ if (in(0) != NULL) {
+ phase->igvn_rehash_node_delayed(this);
+ set_req(0, NULL); // Dividing by a not-zero constant; no faulting
+ }
// Dividing by MINLONG does not optimize as a power-of-2 shift.
if( l == min_jlong ) return NULL;
diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp
index c54f10358..a21702e98 100644
--- a/hotspot/src/share/vm/opto/loopPredicate.cpp
+++ b/hotspot/src/share/vm/opto/loopPredicate.cpp
@@ -106,8 +106,7 @@ ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node*
rgn = new (C) RegionNode(1);
rgn->add_req(uncommon_proj);
register_control(rgn, loop, uncommon_proj);
- _igvn.hash_delete(call);
- call->set_req(0, rgn);
+ _igvn.replace_input_of(call, 0, rgn);
// When called from beautify_loops() idom is not constructed yet.
if (_idom != NULL) {
set_idom(call, rgn, dom_depth(rgn));
@@ -165,8 +164,7 @@ ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node*
if (new_entry == NULL) {
// Attach if_cont to iff
- _igvn.hash_delete(iff);
- iff->set_req(0, if_cont);
+ _igvn.replace_input_of(iff, 0, if_cont);
if (_idom != NULL) {
set_idom(iff, if_cont, dom_depth(iff));
}
@@ -193,8 +191,7 @@ ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* n
rgn = new (C) RegionNode(1);
register_new_node_with_optimizer(rgn);
rgn->add_req(uncommon_proj);
- hash_delete(call);
- call->set_req(0, rgn);
+ replace_input_of(call, 0, rgn);
} else {
// Find region's edge corresponding to uncommon_proj
for (; proj_index < rgn->req(); proj_index++)
diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp
index 7b3f3abe8..414edc26b 100644
--- a/hotspot/src/share/vm/opto/loopTransform.cpp
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp
@@ -934,15 +934,13 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
if( bol->outcnt() != 1 ) {
bol = bol->clone();
register_new_node(bol,main_end->in(CountedLoopEndNode::TestControl));
- _igvn.hash_delete(main_end);
- main_end->set_req(CountedLoopEndNode::TestValue, bol);
+ _igvn.replace_input_of(main_end, CountedLoopEndNode::TestValue, bol);
}
// Need only 1 user of 'cmp' because I will be hacking the loop bounds.
if( cmp->outcnt() != 1 ) {
cmp = cmp->clone();
register_new_node(cmp,main_end->in(CountedLoopEndNode::TestControl));
- _igvn.hash_delete(bol);
- bol->set_req(1, cmp);
+ _igvn.replace_input_of(bol, 1, cmp);
}
//------------------------------
@@ -1146,8 +1144,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
Node* pre_bol = pre_end->in(CountedLoopEndNode::TestValue)->as_Bool();
BoolNode* new_bol0 = new (C) BoolNode(pre_bol->in(1), new_test);
register_new_node( new_bol0, pre_head->in(0) );
- _igvn.hash_delete(pre_end);
- pre_end->set_req(CountedLoopEndNode::TestValue, new_bol0);
+ _igvn.replace_input_of(pre_end, CountedLoopEndNode::TestValue, new_bol0);
// Modify main loop guard condition
assert(min_iff->in(CountedLoopEndNode::TestValue) == min_bol, "guard okay");
BoolNode* new_bol1 = new (C) BoolNode(min_bol->in(1), new_test);
@@ -1158,8 +1155,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
BoolNode* main_bol = main_end->in(CountedLoopEndNode::TestValue)->as_Bool();
BoolNode* new_bol2 = new (C) BoolNode(main_bol->in(1), new_test);
register_new_node( new_bol2, main_end->in(CountedLoopEndNode::TestControl) );
- _igvn.hash_delete(main_end);
- main_end->set_req(CountedLoopEndNode::TestValue, new_bol2);
+ _igvn.replace_input_of(main_end, CountedLoopEndNode::TestValue, new_bol2);
}
// Flag main loop
@@ -1368,8 +1364,7 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
Node* bol2 = loop_end->in(1)->clone();
bol2->set_req(1, cmp2);
register_new_node(bol2, ctrl2);
- _igvn.hash_delete(loop_end);
- loop_end->set_req(1, bol2);
+ _igvn.replace_input_of(loop_end, 1, bol2);
}
// Step 3: Find the min-trip test guaranteed before a 'main' loop.
// Make it a 1-trip test (means at least 2 trips).
@@ -1378,8 +1373,7 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
// can edit it's inputs directly. Hammer in the new limit for the
// minimum-trip guard.
assert(opaq->outcnt() == 1, "");
- _igvn.hash_delete(opaq);
- opaq->set_req(1, new_limit);
+ _igvn.replace_input_of(opaq, 1, new_limit);
}
// Adjust max trip count. The trip count is intentionally rounded
@@ -1429,8 +1423,7 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
register_new_node( cmp2, ctrl2 );
Node *bol2 = new (C) BoolNode( cmp2, loop_end->test_trip() );
register_new_node( bol2, ctrl2 );
- _igvn.hash_delete(loop_end);
- loop_end->set_req(CountedLoopEndNode::TestValue, bol2);
+ _igvn.replace_input_of(loop_end, CountedLoopEndNode::TestValue, bol2);
// Step 3: Find the min-trip test guaranteed before a 'main' loop.
// Make it a 1-trip test (means at least 2 trips).
@@ -1978,8 +1971,7 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
: (Node*)new (C) MaxINode(pre_limit, orig_limit);
register_new_node(pre_limit, pre_ctrl);
}
- _igvn.hash_delete(pre_opaq);
- pre_opaq->set_req(1, pre_limit);
+ _igvn.replace_input_of(pre_opaq, 1, pre_limit);
// Note:: we are making the main loop limit no longer precise;
// need to round up based on stride.
@@ -2008,10 +2000,9 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
Node *main_bol = main_cle->in(1);
// Hacking loop bounds; need private copies of exit test
if( main_bol->outcnt() > 1 ) {// BoolNode shared?
- _igvn.hash_delete(main_cle);
main_bol = main_bol->clone();// Clone a private BoolNode
register_new_node( main_bol, main_cle->in(0) );
- main_cle->set_req(1,main_bol);
+ _igvn.replace_input_of(main_cle, 1, main_bol);
}
Node *main_cmp = main_bol->in(1);
if( main_cmp->outcnt() > 1 ) { // CmpNode shared?
diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp
index d8143821b..1b7c768df 100644
--- a/hotspot/src/share/vm/opto/loopnode.cpp
+++ b/hotspot/src/share/vm/opto/loopnode.cpp
@@ -132,7 +132,7 @@ Node *PhaseIdealLoop::get_early_ctrl( Node *n ) {
// Return earliest legal location
assert(early == find_non_split_ctrl(early), "unexpected early control");
- if (n->is_expensive()) {
+ if (n->is_expensive() && !_verify_only && !_verify_me) {
assert(n->in(0), "should have control input");
early = get_early_ctrl_for_expensive(n, early);
}
@@ -225,8 +225,7 @@ Node *PhaseIdealLoop::get_early_ctrl_for_expensive(Node *n, Node* earliest) {
}
if (ctl != n->in(0)) {
- _igvn.hash_delete(n);
- n->set_req(0, ctl);
+ _igvn.replace_input_of(n, 0, ctl);
_igvn.hash_insert(n);
}
@@ -541,8 +540,7 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
assert(check_iff->in(1)->Opcode() == Op_Conv2B &&
check_iff->in(1)->in(1)->Opcode() == Op_Opaque1, "");
Node* opq = check_iff->in(1)->in(1);
- _igvn.hash_delete(opq);
- opq->set_req(1, bol);
+ _igvn.replace_input_of(opq, 1, bol);
// Update ctrl.
set_ctrl(opq, check_iff->in(0));
set_ctrl(check_iff->in(1), check_iff->in(0));
@@ -712,7 +710,7 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
incr->set_req(2,stride);
incr = _igvn.register_new_node_with_optimizer(incr);
set_early_ctrl( incr );
- _igvn.hash_delete(phi);
+ _igvn.rehash_node_delayed(phi);
phi->set_req_X( LoopNode::LoopBackControl, incr, &_igvn );
// If phi type is more restrictive than Int, raise to
@@ -765,8 +763,8 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
iffalse = iff2;
iftrue = ift2;
} else {
- _igvn.hash_delete(iffalse);
- _igvn.hash_delete(iftrue);
+ _igvn.rehash_node_delayed(iffalse);
+ _igvn.rehash_node_delayed(iftrue);
iffalse->set_req_X( 0, le, &_igvn );
iftrue ->set_req_X( 0, le, &_igvn );
}
@@ -1282,6 +1280,7 @@ void IdealLoopTree::split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt ) {
_head->del_req(i);
}
}
+ igvn.rehash_node_delayed(_head);
// Transform landing pad
igvn.register_new_node_with_optimizer(landing_pad, _head);
// Insert landing pad into the header
@@ -1422,7 +1421,7 @@ void IdealLoopTree::merge_many_backedges( PhaseIdealLoop *phase ) {
igvn.register_new_node_with_optimizer(r, _head);
// Plug region into end of loop _head, followed by hot_tail
while( _head->req() > 3 ) _head->del_req( _head->req()-1 );
- _head->set_req(2, r);
+ igvn.replace_input_of(_head, 2, r);
if( hot_idx ) _head->add_req(hot_tail);
// Split all the Phis up between '_head' loop and the Region 'r'
@@ -1444,7 +1443,7 @@ void IdealLoopTree::merge_many_backedges( PhaseIdealLoop *phase ) {
igvn.register_new_node_with_optimizer(phi, n);
// Add the merge phi to the old Phi
while( n->req() > 3 ) n->del_req( n->req()-1 );
- n->set_req(2, phi);
+ igvn.replace_input_of(n, 2, phi);
if( hot_idx ) n->add_req(hot_phi);
}
}
@@ -1520,13 +1519,14 @@ bool IdealLoopTree::beautify_loops( PhaseIdealLoop *phase ) {
if( fall_in_cnt > 1 ) {
// Since I am just swapping inputs I do not need to update def-use info
Node *tmp = _head->in(1);
+ igvn.rehash_node_delayed(_head);
_head->set_req( 1, _head->in(fall_in_cnt) );
_head->set_req( fall_in_cnt, tmp );
// Swap also all Phis
for (DUIterator_Fast imax, i = _head->fast_outs(imax); i < imax; i++) {
Node* phi = _head->fast_out(i);
if( phi->is_Phi() ) {
- igvn.hash_delete(phi); // Yank from hash before hacking edges
+ igvn.rehash_node_delayed(phi); // Yank from hash before hacking edges
tmp = phi->in(1);
phi->set_req( 1, phi->in(fall_in_cnt) );
phi->set_req( fall_in_cnt, tmp );
@@ -2970,6 +2970,7 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
uint k = 0; // Probably cfg->in(0)
while( cfg->in(k) != m ) k++; // But check incase cfg is a Region
cfg->set_req( k, if_t ); // Now point to NeverBranch
+ _igvn._worklist.push(cfg);
// Now create the never-taken loop exit
Node *if_f = new (C) CProjNode( iff, 1 );
diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp
index 28bfcb75b..006b1a203 100644
--- a/hotspot/src/share/vm/opto/loopopts.cpp
+++ b/hotspot/src/share/vm/opto/loopopts.cpp
@@ -2825,7 +2825,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
new_head->set_unswitch_count(head->unswitch_count()); // Preserve
_igvn.register_new_node_with_optimizer(new_head);
assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled");
- first_not_peeled->set_req(0, new_head);
+ _igvn.replace_input_of(first_not_peeled, 0, new_head);
set_loop(new_head, loop);
loop->_body.push(new_head);
not_peel.set(new_head->_idx);
diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp
index bd8b528e1..86c5b7aa0 100644
--- a/hotspot/src/share/vm/opto/macro.cpp
+++ b/hotspot/src/share/vm/opto/macro.cpp
@@ -853,6 +853,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
int start = jvms->debug_start();
int end = jvms->debug_end();
sfpt->replace_edges_in_range(res, sobj, start, end);
+ _igvn._worklist.push(sfpt);
safepoints_done.append_if_missing(sfpt); // keep it for rollback
}
return true;
@@ -1793,6 +1794,7 @@ Node* PhaseMacroExpand::prefetch_allocation(Node* i_o, Node*& needgc_false,
Node *pf_region = new (C) RegionNode(3);
Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY,
TypeRawPtr::BOTTOM );
+ transform_later(pf_region);
// Generate several prefetch instructions.
uint lines = (length != NULL) ? AllocatePrefetchLines : AllocateInstancePrefetchLines;
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
index 8d62fcc7e..db867c95a 100644
--- a/hotspot/src/share/vm/opto/memnode.cpp
+++ b/hotspot/src/share/vm/opto/memnode.cpp
@@ -1521,6 +1521,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* ctrl = in(MemNode::Control);
Node* address = in(MemNode::Address);
+ bool progress = false;
bool addr_mark = ((phase->type(address)->isa_oopptr() || phase->type(address)->isa_narrowoop()) &&
phase->type(address)->is_ptr()->offset() == oopDesc::mark_offset_in_bytes());
@@ -1532,6 +1533,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
!addr_mark ) {
ctrl = ctrl->in(0);
set_req(MemNode::Control,ctrl);
+ progress = true;
}
intptr_t ignore = 0;
@@ -1545,6 +1547,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
&& all_controls_dominate(base, phase->C->start())) {
// A method-invariant, non-null address (constant or 'this' argument).
set_req(MemNode::Control, NULL);
+ progress = true;
}
}
@@ -1605,7 +1608,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
}
- return NULL; // No further progress
+ return progress ? this : NULL;
}
// Helper to recognize certain Klass fields which are invariant across
@@ -3151,6 +3154,7 @@ Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
return NULL;
}
+ bool progress = false;
// Eliminate volatile MemBars for scalar replaced objects.
if (can_reshape && req() == (Precedent+1)) {
bool eliminate = false;
@@ -3173,6 +3177,7 @@ Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
phase->is_IterGVN()->_worklist.push(my_mem); // remove dead node later
my_mem = NULL;
}
+ progress = true;
}
if (my_mem != NULL && my_mem->is_Mem()) {
const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
@@ -3203,7 +3208,7 @@ Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) {
return new (phase->C) ConINode(TypeInt::ZERO);
}
}
- return NULL;
+ return progress ? this : NULL;
}
//------------------------------Value------------------------------------------
@@ -3840,6 +3845,7 @@ Node* InitializeNode::capture_store(StoreNode* st, intptr_t start,
// if it redundantly stored the same value (or zero to fresh memory).
// In any case, wire it in:
+ phase->igvn_rehash_node_delayed(this);
set_req(i, new_st);
// The caller may now kill the old guy.
diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp
index 7ea783e54..2e7a74b83 100644
--- a/hotspot/src/share/vm/opto/node.cpp
+++ b/hotspot/src/share/vm/opto/node.cpp
@@ -675,6 +675,7 @@ void Node::destruct() {
*(address*)this = badAddress; // smash the C++ vtbl, probably
_in = _out = (Node**) badAddress;
_max = _cnt = _outmax = _outcnt = 0;
+ compile->remove_modified_node(this);
#endif
}
@@ -821,6 +822,7 @@ void Node::del_req( uint idx ) {
_in[idx] = in(--_cnt); // Compact the array
// Avoid spec violation: Gap in prec edges.
close_prec_gap_at(_cnt);
+ Compile::current()->record_modified_node(this);
}
//------------------------------del_req_ordered--------------------------------
@@ -837,6 +839,7 @@ void Node::del_req_ordered( uint idx ) {
}
// Avoid spec violation: Gap in prec edges.
close_prec_gap_at(_cnt);
+ Compile::current()->record_modified_node(this);
}
//------------------------------ins_req----------------------------------------
@@ -1376,6 +1379,7 @@ static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
// Done with outputs.
igvn->hash_delete(dead);
igvn->_worklist.remove(dead);
+ igvn->C->remove_modified_node(dead);
igvn->set_type(dead, Type::TOP);
if (dead->is_macro()) {
igvn->C->remove_macro_node(dead);
diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp
index f0a6ee061..0a4b94acc 100644
--- a/hotspot/src/share/vm/opto/node.hpp
+++ b/hotspot/src/share/vm/opto/node.hpp
@@ -409,6 +409,7 @@ protected:
if (*p != NULL) (*p)->del_out((Node *)this);
(*p) = n;
if (n != NULL) n->add_out((Node *)this);
+ Compile::current()->record_modified_node(this);
}
// Light version of set_req() to init inputs after node creation.
void init_req( uint i, Node *n ) {
@@ -420,6 +421,7 @@ protected:
assert( _in[i] == NULL, "sanity");
_in[i] = n;
if (n != NULL) n->add_out((Node *)this);
+ Compile::current()->record_modified_node(this);
}
// Find first occurrence of n among my edges:
int find_edge(Node* n);
diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp
index ae1031d31..67c06317b 100644
--- a/hotspot/src/share/vm/opto/phaseX.cpp
+++ b/hotspot/src/share/vm/opto/phaseX.cpp
@@ -950,6 +950,17 @@ void PhaseIterGVN::optimize() {
for ( int i = 0; i < _verify_window_size; i++ ) {
_verify_window[i] = NULL;
}
+#ifdef ASSERT
+ // Verify that all modified nodes are on _worklist
+ Unique_Node_List* modified_list = C->modified_nodes();
+ while (modified_list != NULL && modified_list->size()) {
+ Node* n = modified_list->pop();
+ if (n->outcnt() != 0 && !n->is_Con() && !_worklist.member(n)) {
+ n->dump();
+ assert(false, "modified node is not on IGVN._worklist");
+ }
+ }
+#endif
}
#endif
@@ -1048,6 +1059,17 @@ void PhaseIterGVN::optimize() {
}
#ifndef PRODUCT
+#ifdef ASSERT
+ // Verify nodes with changed inputs.
+ Unique_Node_List* modified_list = C->modified_nodes();
+ while (modified_list != NULL && modified_list->size()) {
+ Node* n = modified_list->pop();
+ if (n->outcnt() != 0 && !n->is_Con()) { // skip dead and Con nodes
+ n->dump();
+ assert(false, "modified node was not processed by IGVN.transform_old()");
+ }
+ }
+#endif
C->verify_graph_edges();
if( VerifyOpto && allow_progress() ) {
// Must turn off allow_progress to enable assert and break recursion
@@ -1075,6 +1097,13 @@ void PhaseIterGVN::optimize() {
tty->print_cr("VerifyIterativeGVN: %d transforms, %d full verify passes",
(int) _verify_counter, (int) _verify_full_passes);
}
+#ifdef ASSERT
+ while (modified_list->size()) {
+ Node* n = modified_list->pop();
+ n->dump();
+ assert(false, "VerifyIterativeGVN: new modified node was added");
+ }
+#endif
#endif
}
@@ -1123,6 +1152,7 @@ Node *PhaseIterGVN::transform_old( Node *n ) {
Node *k = n;
DEBUG_ONLY(dead_loop_check(k);)
DEBUG_ONLY(bool is_new = (k->outcnt() == 0);)
+ C->remove_modified_node(k);
Node *i = k->Ideal(this, /*can_reshape=*/true);
assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes");
#ifndef PRODUCT
@@ -1163,6 +1193,7 @@ Node *PhaseIterGVN::transform_old( Node *n ) {
DEBUG_ONLY(dead_loop_check(k);)
// Try idealizing again
DEBUG_ONLY(is_new = (k->outcnt() == 0);)
+ C->remove_modified_node(k);
i = k->Ideal(this, /*can_reshape=*/true);
assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes");
#ifndef PRODUCT
@@ -1316,6 +1347,7 @@ void PhaseIterGVN::remove_globally_dead_node( Node *dead ) {
_stack.pop();
// Remove dead node from iterative worklist
_worklist.remove(dead);
+ C->remove_modified_node(dead);
// Constant node that has no out-edges and has only one in-edge from
// root is usually dead. However, sometimes reshaping walk makes
// it reachable by adding use edges. So, we will NOT count Con nodes
@@ -1352,7 +1384,7 @@ void PhaseIterGVN::subsume_node( Node *old, Node *nn ) {
for (DUIterator_Last imin, i = old->last_outs(imin); i >= imin; ) {
Node* use = old->last_out(i); // for each use...
// use might need re-hashing (but it won't if it's a new node)
- bool is_in_table = _table.hash_delete( use );
+ rehash_node_delayed(use);
// Update use-def info as well
// We remove all occurrences of old within use->in,
// so as to avoid rehashing any node more than once.
@@ -1364,11 +1396,6 @@ void PhaseIterGVN::subsume_node( Node *old, Node *nn ) {
++num_edges;
}
}
- // Insert into GVN hash table if unique
- // If a duplicate, 'use' will be cleaned up when pulled off worklist
- if( is_in_table ) {
- hash_find_insert(use);
- }
i -= num_edges; // we deleted 1 or more copies of this edge
}
diff --git a/hotspot/src/share/vm/opto/rootnode.cpp b/hotspot/src/share/vm/opto/rootnode.cpp
index 56775ed7e..4cf51528d 100644
--- a/hotspot/src/share/vm/opto/rootnode.cpp
+++ b/hotspot/src/share/vm/opto/rootnode.cpp
@@ -35,10 +35,12 @@
//------------------------------Ideal------------------------------------------
// Remove dead inputs
Node *RootNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+ bool modified = false;
for( uint i = 1; i < req(); i++ ) { // For all inputs
// Check for and remove dead inputs
if( phase->type(in(i)) == Type::TOP ) {
del_req(i--); // Delete TOP inputs
+ modified = true;
}
}
@@ -56,7 +58,7 @@ Node *RootNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// If we want to get the rest of the win later, we should pattern match
// simple recursive call trees to closed-form solutions.
- return NULL; // No further opportunities exposed
+ return modified ? this : NULL;
}
//=============================================================================
--
2.22.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
Date: Thu, 8 Jun 2023 20:36:17 +0800
Subject: fix TestMD5Intrinsics.java and TestMD5MultiBlockIntrinsics.java crash
---
hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
index f963cd2f8..e153e3f36 100644
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
@@ -33,7 +33,7 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _
enum platform_dependent_constants {
code_size1 = 19000, // simply increase if too small (assembler will crash if too small)
- code_size2 = 27000 // simply increase if too small (assembler will crash if too small)
+ code_size2 = 28000 // simply increase if too small (assembler will crash if too small)
};
class x86 {
--
2.22.0

View File

@ -0,0 +1,29 @@
Date: Thu, 8 Jun 2023 20:38:26 +0800
Subject: 8198510: Enable UseDynamicNumberOfGCThreads by default
Bug url: https://bugs.openjdk.org/browse/JDK-8198510
---
hotspot/src/share/vm/runtime/globals.hpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index ac9165031..bdc49332a 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -1504,9 +1504,10 @@ class CommandLineFlags {
product(uintx, ParallelGCThreads, 0, \
"Number of parallel threads parallel gc will use") \
\
- product(bool, UseDynamicNumberOfGCThreads, false, \
- "Dynamically choose the number of parallel threads " \
- "parallel gc will use") \
+ product(bool, UseDynamicNumberOfGCThreads, true, \
+ "Dynamically choose the number of threads up to a maximum of " \
+ "ParallelGCThreads parallel collectors will use for garbage " \
+ "collection work") \
\
diagnostic(bool, ForceDynamicNumberOfGCThreads, false, \
"Force dynamic selection of the number of " \
--
2.22.0

View File

@ -0,0 +1,24 @@
Date: Thu, 8 Jun 2023 20:39:32 +0800
Subject: [PATCH 23/59] 8180421: Change default value of BiasedLockingStartupDelay to 0
Bug url: https://bugs.openjdk.org/browse/JDK-8180421
---
hotspot/src/share/vm/runtime/globals.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index ac9165031..9a0a6868c 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -1328,7 +1328,7 @@ class CommandLineFlags {
product(bool, UseBiasedLocking, true, \
"Enable biased locking in JVM") \
\
- product(intx, BiasedLockingStartupDelay, 4000, \
+ product(intx, BiasedLockingStartupDelay, 0, \
"Number of milliseconds to wait before enabling biased locking") \
\
diagnostic(bool, PrintBiasedLockingStatistics, false, \
--
2.22.0

View File

@ -0,0 +1,23 @@
Date: Thu, 8 Jun 2023 20:40:47 +0800
Subject: Fix the trim crash caused by incorrect assert in fastdebug version
Bug url: https://codehub-y.huawei.com/huaweijdk/jdk8u-dev/issues/4117
---
.../src/share/vm/gc_implementation/shared/gcTrimNativeHeap.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTrimNativeHeap.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTrimNativeHeap.cpp
index b9bac5601..4350d7a03 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/gcTrimNativeHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrimNativeHeap.cpp
@@ -218,7 +218,6 @@ bool GCTrimNative::should_trim(bool ignore_delay) {
void GCTrimNative::execute_trim() {
if (GCTrimNativeHeap) {
- assert(!_async_mode, "Only call for non-async mode");
do_trim();
_next_trim_not_before = os::elapsedTime() + GCTrimNativeHeapInterval;
}
--
2.22.0

View File

@ -0,0 +1,35 @@
Date: Thu, 8 Jun 2023 20:42:07 +0800
Subject: 8220166: Performance regression in deserialization
Bug url: https://bugs.openjdk.org/browse/JDK-8220166
---
jdk/src/share/classes/sun/misc/ObjectInputFilter.java | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/jdk/src/share/classes/sun/misc/ObjectInputFilter.java b/jdk/src/share/classes/sun/misc/ObjectInputFilter.java
index af21c7400..eb75755fb 100644
--- a/jdk/src/share/classes/sun/misc/ObjectInputFilter.java
+++ b/jdk/src/share/classes/sun/misc/ObjectInputFilter.java
@@ -270,7 +270,7 @@ public interface ObjectInputFilter {
/**
* Current configured filter.
*/
- private static ObjectInputFilter serialFilter = configuredFilter;
+ private static volatile ObjectInputFilter serialFilter = configuredFilter;
/**
* Get the filter for classes being deserialized on the ObjectInputStream.
@@ -304,9 +304,7 @@ public interface ObjectInputFilter {
* @return the process-wide serialization filter or {@code null} if not configured
*/
public static ObjectInputFilter getSerialFilter() {
- synchronized (serialFilterLock) {
- return serialFilter;
- }
+ return serialFilter;
}
/**
--
2.22.0

View File

@ -0,0 +1,364 @@
Date: Thu, 8 Jun 2023 20:43:33 +0800
Subject: 8072070: Improve interpreter stack banging
Bug url: https://bugs.openjdk.org/browse/JDK-8072070
---
.../vm/templateInterpreter_aarch64.cpp | 49 +++++++++++---
.../cpu/ppc/vm/templateInterpreter_ppc.cpp | 20 ++++++
.../sparc/vm/templateInterpreter_sparc.cpp | 22 +++++++
.../cpu/x86/vm/templateInterpreter_x86.cpp | 64 +++++++++++++++++++
.../src/share/vm/interpreter/interpreter.cpp | 25 +-------
hotspot/src/share/vm/runtime/os.cpp | 7 +-
hotspot/src/share/vm/runtime/thread.cpp | 4 +-
hotspot/src/share/vm/runtime/thread.hpp | 20 ++++++
8 files changed, 174 insertions(+), 37 deletions(-)
diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
index f356fbf81..a5a91e5f3 100644
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
@@ -1087,17 +1087,46 @@ address InterpreterGenerator::generate_Dgemv_dgemv_entry() {
}
void InterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
- // Bang each page in the shadow zone. We can't assume it's been done for
- // an interpreter frame with greater than a page of locals, so each page
- // needs to be checked. Only true for non-native.
- if (UseStackBanging) {
- const int start_page = native_call ? StackShadowPages : 1;
- const int page_size = os::vm_page_size();
- for (int pages = start_page; pages <= StackShadowPages ; pages++) {
- __ sub(rscratch2, sp, pages*page_size);
- __ str(zr, Address(rscratch2));
- }
+ // See more discussion in stackOverflow.hpp.
+
+ const int shadow_zone_size = (int)(JavaThread::stack_shadow_zone_size());
+ const int page_size = os::vm_page_size();
+ const int n_shadow_pages = shadow_zone_size / page_size;
+
+#ifdef ASSERT
+ Label L_good_limit;
+ __ ldr(rscratch1, Address(rthread, JavaThread::shadow_zone_safe_limit_offset()));
+ __ cbnz(rscratch1, L_good_limit);
+ __ stop("shadow zone safe limit is not initialized");
+ __ bind(L_good_limit);
+
+ Label L_good_watermark;
+ __ ldr(rscratch1, Address(rthread, JavaThread::shadow_zone_growth_watermark_offset()));
+ __ cbnz(rscratch1, L_good_watermark);
+ __ stop("shadow zone growth watermark is not initialized");
+ __ bind(L_good_watermark);
+#endif
+
+ Label L_done;
+
+ __ ldr(rscratch1, Address(rthread, JavaThread::shadow_zone_growth_watermark_offset()));
+ __ cmp(sp, rscratch1);
+ __ br(Assembler::HI, L_done);
+
+ for (int p = 1; p <= n_shadow_pages; p++) {
+ __ sub(rscratch2, sp, p*page_size);
+ __ str(zr, Address(rscratch2));
}
+
+ // Record the new watermark, but only if the update is above the safe limit.
+ // Otherwise, the next time around the check above would pass the safe limit.
+ __ ldr(rscratch1, Address(rthread, JavaThread::shadow_zone_safe_limit_offset()));
+ __ cmp(sp, rscratch1);
+ __ br(Assembler::LS, L_done);
+ __ mov(rscratch1, sp);
+ __ str(rscratch1, Address(rthread, JavaThread::shadow_zone_growth_watermark_offset()));
+
+ __ bind(L_done);
}
diff --git a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp
index 42dd8f2a9..0fb934166 100644
--- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp
@@ -2030,5 +2030,25 @@ void TemplateInterpreterGenerator::stop_interpreter_at() {
__ bind(L);
}
+void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
+ // Quick & dirty stack overflow checking: bang the stack & handle trap.
+ // Note that we do the banging after the frame is setup, since the exception
+ // handling code expects to find a valid interpreter frame on the stack.
+ // Doing the banging earlier fails if the caller frame is not an interpreter
+ // frame.
+ // (Also, the exception throwing code expects to unlock any synchronized
+ // method receiever, so do the banging after locking the receiver.)
+
+ // Bang each page in the shadow zone. We can't assume it's been done for
+ // an interpreter frame with greater than a page of locals, so each page
+ // needs to be checked. Only true for non-native.
+ if (UseStackBanging) {
+ const int start_page = native_call ? StackShadowPages : 1;
+ const int page_size = os::vm_page_size();
+ for (int pages = start_page; pages <= StackShadowPages ; pages++) {
+ __ bang_stack_with_offset(pages*page_size);
+ }
+ }
+}
#endif // !PRODUCT
#endif // !CC_INTERP
diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index 83d40496c..540f9b287 100644
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -2113,5 +2113,27 @@ void TemplateInterpreterGenerator::stop_interpreter_at() {
__ cmp(G3_scratch, G4_scratch);
__ breakpoint_trap(Assembler::equal, Assembler::icc);
}
+
+void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
+ // Quick & dirty stack overflow checking: bang the stack & handle trap.
+ // Note that we do the banging after the frame is setup, since the exception
+ // handling code expects to find a valid interpreter frame on the stack.
+ // Doing the banging earlier fails if the caller frame is not an interpreter
+ // frame.
+ // (Also, the exception throwing code expects to unlock any synchronized
+ // method receiever, so do the banging after locking the receiver.)
+
+ // Bang each page in the shadow zone. We can't assume it's been done for
+ // an interpreter frame with greater than a page of locals, so each page
+ // needs to be checked. Only true for non-native.
+ if (UseStackBanging) {
+ const int start_page = native_call ? StackShadowPages : 1;
+ const int page_size = os::vm_page_size();
+ for (int pages = start_page; pages <= StackShadowPages ; pages++) {
+ __ bang_stack_with_offset(pages*page_size);
+ }
+ }
+}
+
#endif // not PRODUCT
#endif // !CC_INTERP
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp
index e470aa62d..fda2908c3 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp
@@ -29,6 +29,8 @@
#ifndef CC_INTERP
+# define __ _masm->
+
// asm based interpreter deoptimization helpers
int AbstractInterpreter::size_activation(int max_stack,
int temps,
@@ -121,4 +123,66 @@ void AbstractInterpreter::layout_activation(Method* method,
method->constants()->cache();
}
+void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
+ // See more discussion in stackOverflow.hpp.
+
+ // Note that we do the banging after the frame is setup, since the exception
+ // handling code expects to find a valid interpreter frame on the stack.
+ // Doing the banging earlier fails if the caller frame is not an interpreter
+ // frame.
+ // (Also, the exception throwing code expects to unlock any synchronized
+ // method receiver, so do the banging after locking the receiver.)
+
+ const int shadow_zone_size = (int)(JavaThread::stack_shadow_zone_size());
+ const int page_size = os::vm_page_size();
+ const int n_shadow_pages = shadow_zone_size / page_size;
+
+ const Register thread = NOT_LP64(rsi) LP64_ONLY(r15_thread);
+ #ifndef _LP64
+ __ push(thread);
+ __ get_thread(thread);
+#endif
+
+#ifdef ASSERT
+ Label L_good_limit;
+ __ cmpptr(Address(thread, JavaThread::shadow_zone_safe_limit_offset()), (int32_t)NULL_WORD);
+ __ jcc(Assembler::notEqual, L_good_limit);
+ __ stop("shadow zone safe limit is not initialized");
+ __ bind(L_good_limit);
+
+ Label L_good_watermark;
+ __ cmpptr(Address(thread, JavaThread::shadow_zone_growth_watermark_offset()), (int32_t)NULL_WORD);
+ __ jcc(Assembler::notEqual, L_good_watermark);
+ __ stop("shadow zone growth watermark is not initialized");
+ __ bind(L_good_watermark);
+#endif
+
+ Label L_done;
+
+ __ cmpptr(rsp, Address(thread, JavaThread::shadow_zone_growth_watermark_offset()));
+ __ jcc(Assembler::above, L_done);
+
+ for (int p = 1; p <= n_shadow_pages; p++) {
+ __ bang_stack_with_offset(p*page_size);
+ }
+
+ // Record a new watermark, unless the update is above the safe limit.
+ // Otherwise, the next time around a check above would pass the safe limit.
+ __ cmpptr(rsp, Address(thread, JavaThread::shadow_zone_safe_limit_offset()));
+ __ jccb(Assembler::belowEqual, L_done);
+#ifdef _LP64
+ __ movptr(rscratch1, rsp);
+ __ andptr(rscratch1, ~(page_size - 1));
+ __ movptr(Address(thread, JavaThread::shadow_zone_growth_watermark_offset()), rscratch1);
+#else
+ __ movptr(Address(thread, JavaThread::shadow_zone_growth_watermark_offset()), rsp);
+#endif
+
+ __ bind(L_done);
+
+#ifndef _LP64
+ __ pop(thread);
+#endif
+}
+
#endif // CC_INTERP
diff --git a/hotspot/src/share/vm/interpreter/interpreter.cpp b/hotspot/src/share/vm/interpreter/interpreter.cpp
index bfcb1bea2..d5d94f34c 100644
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp
@@ -44,7 +44,9 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/timer.hpp"
-
+#include "runtime/vframeArray.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
# define __ _masm->
@@ -474,27 +476,6 @@ bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) {
}
}
-void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
- // Quick & dirty stack overflow checking: bang the stack & handle trap.
- // Note that we do the banging after the frame is setup, since the exception
- // handling code expects to find a valid interpreter frame on the stack.
- // Doing the banging earlier fails if the caller frame is not an interpreter
- // frame.
- // (Also, the exception throwing code expects to unlock any synchronized
- // method receiever, so do the banging after locking the receiver.)
-
- // Bang each page in the shadow zone. We can't assume it's been done for
- // an interpreter frame with greater than a page of locals, so each page
- // needs to be checked. Only true for non-native.
- if (UseStackBanging) {
- const int start_page = native_call ? StackShadowPages : 1;
- const int page_size = os::vm_page_size();
- for (int pages = start_page; pages <= StackShadowPages ; pages++) {
- __ bang_stack_with_offset(pages*page_size);
- }
- }
-}
-
void AbstractInterpreterGenerator::initialize_method_handle_entries() {
// method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index b4f83a3cb..84841b76e 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -1371,11 +1371,10 @@ bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) {
// respectively.
const int framesize_in_bytes =
Interpreter::size_top_interpreter_activation(method()) * wordSize;
- int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages)
- * vm_page_size()) + framesize_in_bytes;
+
// The very lower end of the stack
- address stack_limit = thread->stack_base() - thread->stack_size();
- return (sp > (stack_limit + reserved_area));
+ address stack_limit = ((JavaThread*)thread)->shadow_zone_safe_limit();
+ return (sp > (stack_limit + framesize_in_bytes));
}
size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
index d111aff96..2be226463 100644
--- a/hotspot/src/share/vm/runtime/thread.cpp
+++ b/hotspot/src/share/vm/runtime/thread.cpp
@@ -326,7 +326,7 @@ void Thread::record_stack_base_and_size() {
set_stack_base(os::current_stack_base());
set_stack_size(os::current_stack_size());
if (is_Java_thread()) {
- ((JavaThread*) this)->set_stack_overflow_limit();
+ ((JavaThread*) this)->set_shadow_zone_limits();
}
// CR 7190089: on Solaris, primordial thread's stack is adjusted
// in initialize_thread(). Without the adjustment, stack size is
@@ -1488,6 +1488,8 @@ void JavaThread::initialize() {
_suspend_equivalent = false;
_in_deopt_handler = 0;
_doing_unsafe_access = false;
+ _shadow_zone_safe_limit = NULL;
+ _shadow_zone_growth_watermark = NULL;
_stack_guard_state = stack_guard_unused;
(void)const_cast<oop&>(_exception_oop = oop(NULL));
_exception_pc = 0;
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
index 0e126964d..f1f0cdc58 100644
--- a/hotspot/src/share/vm/runtime/thread.hpp
+++ b/hotspot/src/share/vm/runtime/thread.hpp
@@ -561,6 +561,7 @@ protected:
void set_stack_base(address base) { _stack_base = base; }
size_t stack_size() const { return _stack_size; }
void set_stack_size(size_t size) { _stack_size = size; }
+ address stack_end() const { return stack_base() - stack_size(); }
void record_stack_base_and_size();
bool on_local_stack(address adr) const {
@@ -925,6 +926,9 @@ class JavaThread: public Thread {
// We load it from here to simplify the stack overflow check in assembly.
address _stack_overflow_limit;
+ address _shadow_zone_safe_limit;
+ address _shadow_zone_growth_watermark;
+
// Compiler exception handling (NOTE: The _exception_oop is *NOT* the same as _pending_exception. It is
// used to temp. parsing values into and out of the runtime system during exception handling for compiled
// code)
@@ -1313,6 +1317,14 @@ class JavaThread: public Thread {
bool in_stack_red_zone(address a)
{ return (a <= stack_red_zone_base()) && (a >= (address)((intptr_t)stack_base() - stack_size())); }
+ static size_t stack_shadow_zone_size()
+ { return StackShadowPages * os::vm_page_size(); }
+
+ address shadow_zone_safe_limit() const {
+ assert(_shadow_zone_safe_limit != NULL, "Don't call this before the field is initialized.");
+ return _shadow_zone_safe_limit;
+ }
+
void create_stack_guard_pages();
void remove_stack_guard_pages();
@@ -1344,6 +1356,12 @@ class JavaThread: public Thread {
StackRedPages) * os::vm_page_size());
}
+ void set_shadow_zone_limits() {
+ _shadow_zone_safe_limit =
+ Thread::stack_end() + JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size() + JavaThread::stack_shadow_zone_size();
+ _shadow_zone_growth_watermark = JavaThread::stack_base();
+ }
+
// Misc. accessors/mutators
void set_do_not_unlock(void) { _do_not_unlock_if_synchronized = true; }
void clr_do_not_unlock(void) { _do_not_unlock_if_synchronized = false; }
@@ -1381,6 +1399,8 @@ class JavaThread: public Thread {
static ByteSize stack_overflow_limit_offset() { return byte_offset_of(JavaThread, _stack_overflow_limit); }
static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); }
static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); }
+ static ByteSize shadow_zone_safe_limit_offset() { return byte_offset_of(JavaThread, _shadow_zone_safe_limit);}
+ static ByteSize shadow_zone_growth_watermark_offset() { return byte_offset_of(JavaThread, _shadow_zone_growth_watermark);}
static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); }
static ByteSize do_not_unlock_if_synchronized_offset() { return byte_offset_of(JavaThread, _do_not_unlock_if_synchronized); }
--
2.22.0

View File

@ -0,0 +1,31 @@
Date: Thu, 8 Jun 2023 20:44:16 +0800
Subject: [PATCH 27/59] 8193386: CompressedClassSize too large with MaxMetaspace
Bug url: https://bugs.openjdk.org/browse/JDK-8193386
---
hotspot/src/share/vm/memory/metaspace.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index 4a3f2a9ab..cc5bd4544 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -3572,7 +3572,6 @@ void Metaspace::ergo_initialize() {
MaxMetaspaceExpansion = align_size_down_bounded(MaxMetaspaceExpansion, _commit_alignment);
CompressedClassSpaceSize = align_size_down_bounded(CompressedClassSpaceSize, _reserve_alignment);
- set_compressed_class_space_size(CompressedClassSpaceSize);
// Initial virtual space size will be calculated at global_initialize()
uintx min_metaspace_sz =
@@ -3591,6 +3590,7 @@ void Metaspace::ergo_initialize() {
min_metaspace_sz);
}
+ set_compressed_class_space_size(CompressedClassSpaceSize);
}
void Metaspace::global_initialize() {
--
2.22.0

View File

@ -0,0 +1,41 @@
Date: Thu, 8 Jun 2023 20:44:34 +0800
Subject: Display more information about the codedump file path
---
hotspot/src/os/posix/vm/os_posix.cpp | 6 +++++-
hotspot/src/share/vm/utilities/vmError.cpp | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp
index 678a1059f..ae187eb0f 100644
--- a/hotspot/src/os/posix/vm/os_posix.cpp
+++ b/hotspot/src/os/posix/vm/os_posix.cpp
@@ -61,7 +61,11 @@ void os::check_dump_limit(char* buffer, size_t bufferSize) {
} else {
switch(rlim.rlim_cur) {
case RLIM_INFINITY:
- jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d", current_process_id());
+ jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d\
+ \n# or /var/lib/systemd/coredump/* (process core dumps by systemd-coredump)\
+ \n# or /var/lib/apport/coredump/* (process core dumps by apport)\
+ \n# or /var/spool/abrt/* (process core dumps by abrt-hook-ccpp)\
+ \n# or other name defined in /proc/sys/kernel/core_pattern", current_process_id());
success = true;
break;
case 0:
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index 56ae50fe5..d6d11b5ee 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -535,7 +535,7 @@ void VMError::report(outputStream* st) {
st->print("# ");
if (CreateCoredumpOnCrash) {
if (coredump_status) {
- st->print("Core dump will be written. %s", coredump_message);
+ st->print("Core dump will be written, saved as:\n# %s", coredump_message);
} else {
st->print("No core dump will be written. %s", coredump_message);
}
--
2.22.0

View File

@ -0,0 +1,26 @@
Date: Thu, 8 Jun 2023 20:46:33 +0800
Subject: [PATCH 29/59] 8211845: A new switch to control verbosity of hs-err files
Bug url: https://bugs.openjdk.org/browse/JDK-8211845
---
hotspot/src/share/vm/runtime/globals.hpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index ac9165031..013379f5a 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -2745,6 +2745,10 @@ class CommandLineFlags {
"If an error occurs, save the error data to this file " \
"[default: ./hs_err_pid%p.log] (%p replaced with pid)") \
\
+ product(bool, ExtensiveErrorReports, \
+ PRODUCT_ONLY(false) NOT_PRODUCT(true), \
+ "Error reports are more extensive.") \
+ \
product(bool, DisplayVMOutputToStderr, false, \
"If DisplayVMOutput is true, display all VM output to stderr") \
\
--
2.22.0

View File

@ -0,0 +1,50 @@
Date: Thu, 8 Jun 2023 20:49:01 +0800
Subject: [PATCH 30/59] add more specific possible reasons in hs_error log when OOM
---
hotspot/src/share/vm/utilities/vmError.cpp | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index 56ae50fe5..351c21200 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -312,6 +312,7 @@ void VMError::print_stack_trace(outputStream* st, JavaThread* jt,
static void print_oom_reasons(outputStream* st) {
st->print_cr("# Possible reasons:");
st->print_cr("# The system is out of physical RAM or swap space");
+ st->print_cr("# There are unreasonable system configurations which limit the available memory and the number of threads the process can create");
if (UseCompressedOops) {
st->print_cr("# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap");
}
@@ -322,6 +323,27 @@ static void print_oom_reasons(outputStream* st) {
st->print_cr("# Reduce memory load on the system");
st->print_cr("# Increase physical memory or swap space");
st->print_cr("# Check if swap backing store is full");
+ st->print_cr("# Check the memory info part of the hs_error log file to see if there is enough available memory");
+ st->print_cr("# Check the operating system log to confirm whether there is an OOM error message");
+#if defined(LINUX)
+ st->print_cr("# In linux, please use \"grep 'Out of memory' /var/log/messages\" or ");
+ st->print_cr("# \"dmesg | egrep -i 'killed process'\" to find the OOM error messages");
+#endif
+ st->print_cr("# Check the relevant operating system configurations associating with memory allocation");
+#if defined(LINUX)
+ st->print_cr("# In linux, please check the following configurations:");
+ st->print_cr("# 1) /proc/sys/vm/min_free_kbytes. This is used to force the Linux VM to keep a minimum number");
+ st->print_cr("# of kilobytes free. If a large value is set, it will leave little memory for JVM to use.");
+ st->print_cr("# 2) vm.overcommit_memory. If 2 is set, overcommit is prohibited and JVM may not get enough memory.");
+ st->print_cr("# 3) /proc/sys/vm/max_map_count. This file contains the maximum number of memory map areas a process may have.");
+ st->print_cr("# Memory map areas are used as a side-effect of calling malloc, directly by mmap, mprotect, and madvise,");
+ st->print_cr("# and also when loading shared libraries, so max_map_count should not be too small. Please compare the number of mappings");
+ st->print_cr("# in the dynamic libraries part of the hs_error log with this value to see if it is the cause of the OOM error.");
+ st->print_cr("# 4) configurations in limits.conf. Please check data, rss and as which limit the maximum memory size JVM can use");
+ st->print_cr("# and nproc which influences the maximum number of threads JVM can create.");
+ st->print_cr("# 5) Other configurations that may cause a thread creation failure. Please check /proc/sys/kernel/threads-max,");
+ st->print_cr("# /proc/sys/kernel/pid_max and TasksMax in systemd service file and make sure they are not too small.");
+#endif
if (LogBytesPerWord == 2) {
st->print_cr("# Use 64 bit Java on a 64 bit OS");
}
--
2.22.0

View File

@ -0,0 +1,113 @@
Date: Thu, 8 Jun 2023 21:01:37 +0800
Subject: [PATCH 31/59] 8187653: Lock in CoderResult.Cache becomes performance bottleneck
Bug url: https://bugs.openjdk.org/browse/JDK-8187653
---
.../classes/java/nio/charset/CoderResult.java | 38 ++++++++++++++-----
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/jdk/src/share/classes/java/nio/charset/CoderResult.java b/jdk/src/share/classes/java/nio/charset/CoderResult.java
index d087c9799..c93fb198e 100644
--- a/jdk/src/share/classes/java/nio/charset/CoderResult.java
+++ b/jdk/src/share/classes/java/nio/charset/CoderResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -27,9 +27,8 @@ package java.nio.charset;
import java.lang.ref.WeakReference;
import java.nio.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
-import java.util.HashMap;
-
/**
* A description of the result state of a coder.
@@ -197,14 +196,12 @@ public class CoderResult {
protected abstract CoderResult create(int len);
- private synchronized CoderResult get(int len) {
- if (len <= 0)
- throw new IllegalArgumentException("Non-positive length");
+ private CoderResult get(int len) {
Integer k = new Integer(len);
WeakReference<CoderResult> w;
CoderResult e = null;
if (cache == null) {
- cache = new HashMap<Integer,WeakReference<CoderResult>>();
+ cache = new ConcurrentHashMap<Integer,WeakReference<CoderResult>>();
} else if ((w = cache.get(k)) != null) {
e = w.get();
}
@@ -214,15 +211,21 @@ public class CoderResult {
}
return e;
}
-
}
- private static Cache malformedCache
+ private static final Cache malformedCache
= new Cache() {
public CoderResult create(int len) {
return new CoderResult(CR_MALFORMED, len);
}};
+ private static final CoderResult[] malformed4 = new CoderResult[] {
+ new CoderResult(CR_MALFORMED, 1),
+ new CoderResult(CR_MALFORMED, 2),
+ new CoderResult(CR_MALFORMED, 3),
+ new CoderResult(CR_MALFORMED, 4)
+ };
+
/**
* Static factory method that returns the unique object describing a
* malformed-input error of the given length.
@@ -233,15 +236,26 @@ public class CoderResult {
* @return The requested coder-result object
*/
public static CoderResult malformedForLength(int length) {
+ if (length <= 0)
+ throw new IllegalArgumentException("Non-positive length");
+ if (length <= 4)
+ return malformed4[length - 1];
return malformedCache.get(length);
}
- private static Cache unmappableCache
+ private static final Cache unmappableCache
= new Cache() {
public CoderResult create(int len) {
return new CoderResult(CR_UNMAPPABLE, len);
}};
+ private static final CoderResult[] unmappable4 = new CoderResult[] {
+ new CoderResult(CR_UNMAPPABLE, 1),
+ new CoderResult(CR_UNMAPPABLE, 2),
+ new CoderResult(CR_UNMAPPABLE, 3),
+ new CoderResult(CR_UNMAPPABLE, 4)
+ };
+
/**
* Static factory method that returns the unique result object describing
* an unmappable-character error of the given length.
@@ -252,6 +266,10 @@ public class CoderResult {
* @return The requested coder-result object
*/
public static CoderResult unmappableForLength(int length) {
+ if (length <= 0)
+ throw new IllegalArgumentException("Non-positive length");
+ if (length <= 4)
+ return unmappable4[length - 1];
return unmappableCache.get(length);
}
--
2.22.0

View File

@ -0,0 +1,58 @@
Date: Fri, 9 Jun 2023 09:04:38 +0800
Subject: 8299158: Improve MD5 intrinsic on AArch64
Bug url: https://bugs.openjdk.org/browse/JDK-8299158
---
.../src/cpu/aarch64/vm/stubGenerator_aarch64.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
index a3f93204e..565fe559c 100644
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
@@ -3218,19 +3218,19 @@ class StubGenerator: public StubCodeGenerator {
__ addw(rscratch4, r1, rscratch2); \
__ ldrw(rscratch1, Address(buf, k*4)); \
__ eorw(rscratch3, rscratch3, r4); \
- __ addw(rscratch3, rscratch3, rscratch1); \
+ __ addw(rscratch4, rscratch4, rscratch1); \
__ addw(rscratch3, rscratch3, rscratch4); \
__ rorw(rscratch2, rscratch3, 32 - s); \
__ addw(r1, rscratch2, r2);
#define GG(r1, r2, r3, r4, k, s, t) \
- __ eorw(rscratch2, r2, r3); \
+ __ andw(rscratch3, r2, r4); \
+ __ bicw(rscratch4, r3, r4); \
__ ldrw(rscratch1, Address(buf, k*4)); \
- __ andw(rscratch3, rscratch2, r4); \
__ movw(rscratch2, t); \
- __ eorw(rscratch3, rscratch3, r3); \
+ __ orrw(rscratch3, rscratch3, rscratch4); \
__ addw(rscratch4, r1, rscratch2); \
- __ addw(rscratch3, rscratch3, rscratch1); \
+ __ addw(rscratch4, rscratch4, rscratch1); \
__ addw(rscratch3, rscratch3, rscratch4); \
__ rorw(rscratch2, rscratch3, 32 - s); \
__ addw(r1, rscratch2, r2);
@@ -3241,7 +3241,7 @@ class StubGenerator: public StubCodeGenerator {
__ addw(rscratch4, r1, rscratch2); \
__ ldrw(rscratch1, Address(buf, k*4)); \
__ eorw(rscratch3, rscratch3, r2); \
- __ addw(rscratch3, rscratch3, rscratch1); \
+ __ addw(rscratch4, rscratch4, rscratch1); \
__ addw(rscratch3, rscratch3, rscratch4); \
__ rorw(rscratch2, rscratch3, 32 - s); \
__ addw(r1, rscratch2, r2);
@@ -3252,7 +3252,7 @@ class StubGenerator: public StubCodeGenerator {
__ addw(rscratch4, r1, rscratch3); \
__ ldrw(rscratch1, Address(buf, k*4)); \
__ eorw(rscratch3, rscratch2, r3); \
- __ addw(rscratch3, rscratch3, rscratch1); \
+ __ addw(rscratch4, rscratch4, rscratch1); \
__ addw(rscratch3, rscratch3, rscratch4); \
__ rorw(rscratch2, rscratch3, 32 - s); \
__ addw(r1, rscratch2, r2);
--
2.22.0

View File

@ -0,0 +1,97 @@
Date: Thu, 8 Jun 2023 20:47:32 +0800
Subject: [PATCH 33/59] 8211326: add OS user related information to hs_err file
Bug url: https://bugs.openjdk.org/browse/JDK-8211326
---
hotspot/src/os/posix/vm/os_posix.cpp | 33 ++++++++++++++++++++++
hotspot/src/os/posix/vm/os_posix.hpp | 3 ++
hotspot/src/share/vm/utilities/vmError.cpp | 8 ++++++
3 files changed, 44 insertions(+)
diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp
index 678a1059f..189c8b411 100644
--- a/hotspot/src/os/posix/vm/os_posix.cpp
+++ b/hotspot/src/os/posix/vm/os_posix.cpp
@@ -33,6 +33,8 @@
#include <unistd.h>
#include <sys/resource.h>
#include <sys/utsname.h>
+#include <grp.h>
+#include <pwd.h>
#include <pthread.h>
#include <signal.h>
@@ -233,6 +235,37 @@ void os::Posix::print_uname_info(outputStream* st) {
st->cr();
}
+void os::Posix::print_umask(outputStream* st, mode_t umsk) {
+ st->print((umsk & S_IRUSR) ? "r" : "-");
+ st->print((umsk & S_IWUSR) ? "w" : "-");
+ st->print((umsk & S_IXUSR) ? "x" : "-");
+ st->print((umsk & S_IRGRP) ? "r" : "-");
+ st->print((umsk & S_IWGRP) ? "w" : "-");
+ st->print((umsk & S_IXGRP) ? "x" : "-");
+ st->print((umsk & S_IROTH) ? "r" : "-");
+ st->print((umsk & S_IWOTH) ? "w" : "-");
+ st->print((umsk & S_IXOTH) ? "x" : "-");
+}
+
+void os::Posix::print_user_info(outputStream* st) {
+ unsigned id = (unsigned) ::getuid();
+ st->print("uid : %u ", id);
+ id = (unsigned) ::geteuid();
+ st->print("euid : %u ", id);
+ id = (unsigned) ::getgid();
+ st->print("gid : %u ", id);
+ id = (unsigned) ::getegid();
+ st->print_cr("egid : %u", id);
+ st->cr();
+
+ mode_t umsk = ::umask(0);
+ (void)::umask(umsk);
+ st->print("umask: %04o (", (unsigned) umsk);
+ print_umask(st, umsk);
+ st->print_cr(")");
+ st->cr();
+}
+
bool os::has_allocatable_memory_limit(julong* limit) {
struct rlimit rlim;
int getrlimit_res = getrlimit(RLIMIT_AS, &rlim);
diff --git a/hotspot/src/os/posix/vm/os_posix.hpp b/hotspot/src/os/posix/vm/os_posix.hpp
index d3e55d020..0d29bfbaf 100644
--- a/hotspot/src/os/posix/vm/os_posix.hpp
+++ b/hotspot/src/os/posix/vm/os_posix.hpp
@@ -69,6 +69,9 @@ public:
// effective gid, or if given uid is root.
static bool matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid);
+ static void print_umask(outputStream* st, mode_t umsk);
+
+ static void print_user_info(outputStream* st);
};
/*
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index 351c21200..44562fe36 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -713,6 +713,14 @@ void VMError::report(outputStream* st) {
st->cr();
}
+#ifndef _WIN32
+ STEP(165, "(printing user info)" )
+
+ if (ExtensiveErrorReports && _verbose) {
+ os::Posix::print_user_info(st);
+ }
+#endif
+
STEP(170, "(printing all threads)" )
// all threads
--
2.22.0

View File

@ -0,0 +1,444 @@
Date: Fri, 9 Jun 2023 09:23:12 +0800
Subject: 8250902:Implement MD5 Intrinsics on x64
Bug url: https://bugs.openjdk.org/browse/JDK-8250902
---
hotspot/src/cpu/x86/vm/assembler_x86.cpp | 10 ++
hotspot/src/cpu/x86/vm/assembler_x86.hpp | 2 +
hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 153 ++++++++++++++++++
hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp | 3 +
.../src/cpu/x86/vm/stubGenerator_x86_32.cpp | 44 +++++
.../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 42 +++++
hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 5 -
hotspot/src/share/vm/asm/assembler.hpp | 3 +
hotspot/src/share/vm/asm/codeBuffer.hpp | 13 ++
.../intrinsics/IntrinsicAvailableTest.java | 2 +-
.../GenericTestCaseForUnsupportedX86CPU.java | 6 +-
11 files changed, 276 insertions(+), 7 deletions(-)
diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp
index ddc1acfd8..c0ae3d32a 100644
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp
@@ -2808,6 +2808,16 @@ void Assembler::ret(int imm16) {
}
}
+void Assembler::roll(Register dst, int imm8) {
+ assert(isShiftCount(imm8 >> 1), "illegal shift count");
+ int encode = prefix_and_encode(dst->encoding());
+ if (imm8 == 1) {
+ emit_int16((unsigned char)0xD1, (0xC0 | encode));
+ } else {
+ emit_int24((unsigned char)0xC1, (0xc0 | encode), imm8);
+ }
+}
+
void Assembler::sahf() {
#ifdef _LP64
// Not supported in 64bit mode
diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp
index c2e70bc2a..1695d7969 100644
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp
@@ -1574,6 +1574,8 @@ private:
void ret(int imm16);
+ void roll(Register dst, int imm8);
+
#ifdef _LP64
void rorq(Register dst, int imm8);
void rorxq(Register dst, Register src, int imm8);
diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
index 1b09514c9..3aca9a30d 100644
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
@@ -8577,3 +8577,156 @@ SkipIfEqual::SkipIfEqual(
SkipIfEqual::~SkipIfEqual() {
_masm->bind(_label);
}
+
+void MacroAssembler::fast_md5(Register buf, Address state, Address ofs, Address limit, bool multi_block) {
+
+ Label start, done_hash, loop0;
+
+ bind(start);
+
+ bind(loop0);
+
+ // Save hash values for addition after rounds
+ movptr(rdi, state);
+ movl(rax, Address(rdi, 0));
+ movl(rbx, Address(rdi, 4));
+ movl(rcx, Address(rdi, 8));
+ movl(rdx, Address(rdi, 12));
+
+#define FF(r1, r2, r3, r4, k, s, t) \
+ movl(rsi, r3); \
+ addl(r1, Address(buf, k*4)); \
+ xorl(rsi, r4); \
+ andl(rsi, r2); \
+ xorl(rsi, r4); \
+ leal(r1, Address(r1, rsi, Address::times_1, t)); \
+ roll(r1, s); \
+ addl(r1, r2);
+
+#define GG(r1, r2, r3, r4, k, s, t) \
+ movl(rsi, r4); \
+ movl(rdi, r4); \
+ addl(r1, Address(buf, k*4)); \
+ notl(rsi); \
+ andl(rdi, r2); \
+ andl(rsi, r3); \
+ orl(rsi, rdi); \
+ leal(r1, Address(r1, rsi, Address::times_1, t)); \
+ roll(r1, s); \
+ addl(r1, r2);
+
+#define HH(r1, r2, r3, r4, k, s, t) \
+ movl(rsi, r3); \
+ addl(r1, Address(buf, k*4)); \
+ xorl(rsi, r4); \
+ xorl(rsi, r2); \
+ leal(r1, Address(r1, rsi, Address::times_1, t)); \
+ roll(r1, s); \
+ addl(r1, r2);
+
+#define II(r1, r2, r3, r4, k, s, t) \
+ movl(rsi, r4); \
+ notl(rsi); \
+ addl(r1, Address(buf, k*4)); \
+ orl(rsi, r2); \
+ xorl(rsi, r3); \
+ leal(r1, Address(r1, rsi, Address::times_1, t)); \
+ roll(r1, s); \
+ addl(r1, r2);
+
+ // Round 1
+ FF(rax, rbx, rcx, rdx, 0, 7, 0xd76aa478)
+ FF(rdx, rax, rbx, rcx, 1, 12, 0xe8c7b756)
+ FF(rcx, rdx, rax, rbx, 2, 17, 0x242070db)
+ FF(rbx, rcx, rdx, rax, 3, 22, 0xc1bdceee)
+ FF(rax, rbx, rcx, rdx, 4, 7, 0xf57c0faf)
+ FF(rdx, rax, rbx, rcx, 5, 12, 0x4787c62a)
+ FF(rcx, rdx, rax, rbx, 6, 17, 0xa8304613)
+ FF(rbx, rcx, rdx, rax, 7, 22, 0xfd469501)
+ FF(rax, rbx, rcx, rdx, 8, 7, 0x698098d8)
+ FF(rdx, rax, rbx, rcx, 9, 12, 0x8b44f7af)
+ FF(rcx, rdx, rax, rbx, 10, 17, 0xffff5bb1)
+ FF(rbx, rcx, rdx, rax, 11, 22, 0x895cd7be)
+ FF(rax, rbx, rcx, rdx, 12, 7, 0x6b901122)
+ FF(rdx, rax, rbx, rcx, 13, 12, 0xfd987193)
+ FF(rcx, rdx, rax, rbx, 14, 17, 0xa679438e)
+ FF(rbx, rcx, rdx, rax, 15, 22, 0x49b40821)
+
+ // Round 2
+ GG(rax, rbx, rcx, rdx, 1, 5, 0xf61e2562)
+ GG(rdx, rax, rbx, rcx, 6, 9, 0xc040b340)
+ GG(rcx, rdx, rax, rbx, 11, 14, 0x265e5a51)
+ GG(rbx, rcx, rdx, rax, 0, 20, 0xe9b6c7aa)
+ GG(rax, rbx, rcx, rdx, 5, 5, 0xd62f105d)
+ GG(rdx, rax, rbx, rcx, 10, 9, 0x02441453)
+ GG(rcx, rdx, rax, rbx, 15, 14, 0xd8a1e681)
+ GG(rbx, rcx, rdx, rax, 4, 20, 0xe7d3fbc8)
+ GG(rax, rbx, rcx, rdx, 9, 5, 0x21e1cde6)
+ GG(rdx, rax, rbx, rcx, 14, 9, 0xc33707d6)
+ GG(rcx, rdx, rax, rbx, 3, 14, 0xf4d50d87)
+ GG(rbx, rcx, rdx, rax, 8, 20, 0x455a14ed)
+ GG(rax, rbx, rcx, rdx, 13, 5, 0xa9e3e905)
+ GG(rdx, rax, rbx, rcx, 2, 9, 0xfcefa3f8)
+ GG(rcx, rdx, rax, rbx, 7, 14, 0x676f02d9)
+ GG(rbx, rcx, rdx, rax, 12, 20, 0x8d2a4c8a)
+
+ // Round 3
+ HH(rax, rbx, rcx, rdx, 5, 4, 0xfffa3942)
+ HH(rdx, rax, rbx, rcx, 8, 11, 0x8771f681)
+ HH(rcx, rdx, rax, rbx, 11, 16, 0x6d9d6122)
+ HH(rbx, rcx, rdx, rax, 14, 23, 0xfde5380c)
+ HH(rax, rbx, rcx, rdx, 1, 4, 0xa4beea44)
+ HH(rdx, rax, rbx, rcx, 4, 11, 0x4bdecfa9)
+ HH(rcx, rdx, rax, rbx, 7, 16, 0xf6bb4b60)
+ HH(rbx, rcx, rdx, rax, 10, 23, 0xbebfbc70)
+ HH(rax, rbx, rcx, rdx, 13, 4, 0x289b7ec6)
+ HH(rdx, rax, rbx, rcx, 0, 11, 0xeaa127fa)
+ HH(rcx, rdx, rax, rbx, 3, 16, 0xd4ef3085)
+ HH(rbx, rcx, rdx, rax, 6, 23, 0x04881d05)
+ HH(rax, rbx, rcx, rdx, 9, 4, 0xd9d4d039)
+ HH(rdx, rax, rbx, rcx, 12, 11, 0xe6db99e5)
+ HH(rcx, rdx, rax, rbx, 15, 16, 0x1fa27cf8)
+ HH(rbx, rcx, rdx, rax, 2, 23, 0xc4ac5665)
+
+ // Round 4
+ II(rax, rbx, rcx, rdx, 0, 6, 0xf4292244)
+ II(rdx, rax, rbx, rcx, 7, 10, 0x432aff97)
+ II(rcx, rdx, rax, rbx, 14, 15, 0xab9423a7)
+ II(rbx, rcx, rdx, rax, 5, 21, 0xfc93a039)
+ II(rax, rbx, rcx, rdx, 12, 6, 0x655b59c3)
+ II(rdx, rax, rbx, rcx, 3, 10, 0x8f0ccc92)
+ II(rcx, rdx, rax, rbx, 10, 15, 0xffeff47d)
+ II(rbx, rcx, rdx, rax, 1, 21, 0x85845dd1)
+ II(rax, rbx, rcx, rdx, 8, 6, 0x6fa87e4f)
+ II(rdx, rax, rbx, rcx, 15, 10, 0xfe2ce6e0)
+ II(rcx, rdx, rax, rbx, 6, 15, 0xa3014314)
+ II(rbx, rcx, rdx, rax, 13, 21, 0x4e0811a1)
+ II(rax, rbx, rcx, rdx, 4, 6, 0xf7537e82)
+ II(rdx, rax, rbx, rcx, 11, 10, 0xbd3af235)
+ II(rcx, rdx, rax, rbx, 2, 15, 0x2ad7d2bb)
+ II(rbx, rcx, rdx, rax, 9, 21, 0xeb86d391)
+
+#undef FF
+#undef GG
+#undef HH
+#undef II
+
+ // write hash values back in the correct order
+ movptr(rdi, state);
+ addl(Address(rdi, 0), rax);
+ addl(Address(rdi, 4), rbx);
+ addl(Address(rdi, 8), rcx);
+ addl(Address(rdi, 12), rdx);
+
+ if (multi_block) {
+ // increment data pointer and loop if more to process
+ addptr(buf, 64);
+ addl(ofs, 64);
+ movl(rsi, ofs);
+ cmpl(rsi, limit);
+ jcc(Assembler::belowEqual, loop0);
+ movptr(rax, rsi); //return ofs
+ }
+
+ bind(done_hash);
+}
diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
index e94fdd7d7..c18645f18 100644
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
@@ -907,6 +907,9 @@ class MacroAssembler: public Assembler {
// computes pow(x,y). Fallback to runtime call included.
void pow_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(false, num_fpu_regs_in_use); }
+ void fast_md5(Register buf, Address state, Address ofs, Address limit,
+ bool multi_block);
+
private:
// call runtime as a fallback for trig functions and pow/exp.
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
index f555f3326..b4e3f2914 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
@@ -3057,6 +3057,45 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
+ // ofs and limit are use for multi-block byte array.
+ // int com.sun.security.provider.MD5.implCompress(byte[] b, int ofs)
+ address generate_md5_implCompress(bool multi_block, const char *name) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", name);
+ address start = __ pc();
+
+ const Register buf_param = rbp;
+ const Address state_param(rsp, 0 * wordSize);
+ const Address ofs_param (rsp, 1 * wordSize);
+ const Address limit_param(rsp, 2 * wordSize);
+
+ __ enter();
+ __ push(rbx);
+ __ push(rdi);
+ __ push(rsi);
+ __ push(rbp);
+ __ subptr(rsp, 3 * wordSize);
+
+ __ movptr(rsi, Address(rbp, 8 + 4));
+ __ movptr(state_param, rsi);
+ if (multi_block) {
+ __ movptr(rsi, Address(rbp, 8 + 8));
+ __ movptr(ofs_param, rsi);
+ __ movptr(rsi, Address(rbp, 8 + 12));
+ __ movptr(limit_param, rsi);
+ }
+ __ movptr(buf_param, Address(rbp, 8 + 0)); // do it last because it override rbp
+ __ fast_md5(buf_param, state_param, ofs_param, limit_param, multi_block);
+
+ __ addptr(rsp, 3 * wordSize);
+ __ pop(rbp);
+ __ pop(rsi);
+ __ pop(rdi);
+ __ pop(rbx);
+ __ leave();
+ __ ret(0);
+ return start;
+ }
// byte swap x86 long
address generate_ghash_long_swap_mask() {
@@ -3525,6 +3564,11 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt_Parallel();
}
+ if (UseMD5Intrinsics) {
+ StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress");
+ StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB");
+ }
+
// Generate GHASH intrinsics code
if (UseGHASHIntrinsics) {
StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask();
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
index 254f63392..f6511b273 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
@@ -3660,6 +3660,43 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
+ // ofs and limit are use for multi-block byte array.
+ // int com.sun.security.provider.MD5.implCompress(byte[] b, int ofs)
+ address generate_md5_implCompress(bool multi_block, const char *name) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", name);
+ address start = __ pc();
+
+ const Register buf_param = r15;
+ const Address state_param(rsp, 0 * wordSize);
+ const Address ofs_param (rsp, 1 * wordSize );
+ const Address limit_param(rsp, 1 * wordSize + 4);
+
+ __ enter();
+ __ push(rbx);
+ __ push(rdi);
+ __ push(rsi);
+ __ push(r15);
+ __ subptr(rsp, 2 * wordSize);
+
+ __ movptr(buf_param, c_rarg0);
+ __ movptr(state_param, c_rarg1);
+ if (multi_block) {
+ __ movl(ofs_param, c_rarg2);
+ __ movl(limit_param, c_rarg3);
+ }
+ __ fast_md5(buf_param, state_param, ofs_param, limit_param, multi_block);
+
+ __ addptr(rsp, 2 * wordSize);
+ __ pop(r15);
+ __ pop(rsi);
+ __ pop(rdi);
+ __ pop(rbx);
+ __ leave();
+ __ ret(0);
+ return start;
+ }
+
// This is a version of CTR/AES crypt which does 6 blocks in a loop at a time
// to hide instruction latency
//
@@ -4584,6 +4621,11 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt_Parallel();
}
+ if (UseMD5Intrinsics) {
+ StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress");
+ StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB");
+ }
+
// Generate GHASH intrinsics code
if (UseGHASHIntrinsics) {
StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask();
diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
index 41f827364..ce3037d76 100644
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
@@ -669,11 +669,6 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseF2jBLASIntrinsics, false);
}
- if (UseMD5Intrinsics) {
- warning("MD5 intrinsics are not available on this CPU");
- FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
- }
-
// Adjust RTM (Restricted Transactional Memory) flags
if (!supports_rtm() && UseRTMLocking) {
// Can't continue because UseRTMLocking affects UseBiasedLocking flag
diff --git a/hotspot/src/share/vm/asm/assembler.hpp b/hotspot/src/share/vm/asm/assembler.hpp
index d4d31d47e..823653d55 100644
--- a/hotspot/src/share/vm/asm/assembler.hpp
+++ b/hotspot/src/share/vm/asm/assembler.hpp
@@ -287,6 +287,9 @@ class AbstractAssembler : public ResourceObj {
void emit_int8( int8_t x) { code_section()->emit_int8( x); }
void emit_int16( int16_t x) { code_section()->emit_int16( x); }
+ void emit_int16( uint8_t x1, uint8_t x2) { code_section()->emit_int16(x1, x2); }
+
+ void emit_int24( uint8_t x1, uint8_t x2, uint8_t x3) { code_section()->emit_int24(x1, x2, x3); }
void emit_int32( int32_t x) { code_section()->emit_int32( x); }
void emit_int64( int64_t x) { code_section()->emit_int64( x); }
diff --git a/hotspot/src/share/vm/asm/codeBuffer.hpp b/hotspot/src/share/vm/asm/codeBuffer.hpp
index a89f2c18b..32c2f717a 100644
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp
@@ -195,6 +195,19 @@ class CodeSection VALUE_OBJ_CLASS_SPEC {
// Code emission
void emit_int8 ( int8_t x) { *((int8_t*) end()) = x; set_end(end() + sizeof(int8_t)); }
void emit_int16( int16_t x) { *((int16_t*) end()) = x; set_end(end() + sizeof(int16_t)); }
+ void emit_int16(uint8_t x1, uint8_t x2) {
+ address curr = end();
+ *((uint8_t*) curr++) = x1;
+ *((uint8_t*) curr++) = x2;
+ set_end(curr);
+ }
+ void emit_int24(uint8_t x1, uint8_t x2, uint8_t x3) {
+ address curr = end();
+ *((uint8_t*) curr++) = x1;
+ *((uint8_t*) curr++) = x2;
+ *((uint8_t*) curr++) = x3;
+ set_end(curr);
+ }
void emit_int32( int32_t x) { *((int32_t*) end()) = x; set_end(end() + sizeof(int32_t)); }
void emit_int64( int64_t x) { *((int64_t*) end()) = x; set_end(end() + sizeof(int64_t)); }
diff --git a/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java b/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java
index 1a5475403..b52c6f523 100644
--- a/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java
+++ b/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java
@@ -26,7 +26,7 @@ import java.util.Objects;
/*
* @test
* @bug 8130832
- * @library /testlibrary /../../test/lib /compiler/whitebox /compiler/testlibrary
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox /compiler/testlibrary
* @build IntrinsicAvailableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
diff --git a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java
index 8a8dde4ad..a916ac746 100644
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java
@@ -24,7 +24,9 @@
import com.oracle.java.testlibrary.ExitCode;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
/**
* Generic test case for SHA-related options targeted to X86 CPUs that don't
@@ -33,7 +35,9 @@ import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
public class GenericTestCaseForUnsupportedX86CPU
extends DigestOptionsBase.TestCase {
public GenericTestCaseForUnsupportedX86CPU(String optionName) {
- super(optionName, new OrPredicate(Platform::isX64, Platform::isX86));
+ super(optionName, new AndPredicate(new OrPredicate(Platform::isX64, Platform::isX86),
+ new NotPredicate(DigestOptionsBase.getPredicateForOption(
+ optionName))));
}
@Override
--
2.22.0

View File

@ -0,0 +1,177 @@
Date: Fri, 9 Jun 2023 09:31:14 +0800
Subject: 8210821: Support dns_canonicalize_hostname in krb5.conf
Bug url: https://bugs.openjdk.org/browse/JDK-8210821
---
.../sun/security/krb5/PrincipalName.java | 47 ++++++-----
.../krb5/auto/DnsCanonicalizeHostname.java | 81 +++++++++++++++++++
.../krb5/auto/dns_canonicalize_hostname.hosts | 8 ++
3 files changed, 118 insertions(+), 18 deletions(-)
create mode 100644 jdk/test/sun/security/krb5/auto/DnsCanonicalizeHostname.java
create mode 100644 jdk/test/sun/security/krb5/auto/dns_canonicalize_hostname.hosts
diff --git a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
index e2dadb326..c1dc762ac 100644
--- a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
+++ b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
@@ -411,26 +411,37 @@ public class PrincipalName implements Cloneable {
case KRB_NT_SRV_HST:
if (nameParts.length >= 2) {
String hostName = nameParts[1];
+ Boolean option;
try {
- // RFC4120 does not recommend canonicalizing a hostname.
- // However, for compatibility reason, we will try
- // canonicalize it and see if the output looks better.
-
- String canonicalized = (InetAddress.getByName(hostName)).
- getCanonicalHostName();
-
- // Looks if canonicalized is a longer format of hostName,
- // we accept cases like
- // bunny -> bunny.rabbit.hole
- if (canonicalized.toLowerCase(Locale.ENGLISH).startsWith(
- hostName.toLowerCase(Locale.ENGLISH)+".")) {
- hostName = canonicalized;
- }
- } catch (UnknownHostException | SecurityException e) {
- // not canonicalized or no permission to do so, use old
+ // If true, try canonicalizing and accept it if it starts
+ // with the short name. Otherwise, never. Default true.
+ option = Config.getInstance().getBooleanObject(
+ "libdefaults", "dns_canonicalize_hostname");
+ } catch (KrbException e) {
+ option = null;
}
- if (hostName.endsWith(".")) {
- hostName = hostName.substring(0, hostName.length() - 1);
+ if (option != Boolean.FALSE) {
+ try {
+ // RFC4120 does not recommend canonicalizing a hostname.
+ // However, for compatibility reason, we will try
+ // canonicalizing it and see if the output looks better.
+
+ String canonicalized = (InetAddress.getByName(hostName)).
+ getCanonicalHostName();
+
+ // Looks if canonicalized is a longer format of hostName,
+ // we accept cases like
+ // bunny -> bunny.rabbit.hole
+ if (canonicalized.toLowerCase(Locale.ENGLISH).startsWith(
+ hostName.toLowerCase(Locale.ENGLISH) + ".")) {
+ hostName = canonicalized;
+ }
+ } catch (UnknownHostException | SecurityException e) {
+ // not canonicalized or no permission to do so, use old
+ }
+ if (hostName.endsWith(".")) {
+ hostName = hostName.substring(0, hostName.length() - 1);
+ }
}
nameParts[1] = hostName.toLowerCase(Locale.ENGLISH);
}
diff --git a/jdk/test/sun/security/krb5/auto/DnsCanonicalizeHostname.java b/jdk/test/sun/security/krb5/auto/DnsCanonicalizeHostname.java
new file mode 100644
index 000000000..7b33d4b91
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/DnsCanonicalizeHostname.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.testlibrary.Asserts;
+import sun.security.krb5.PrincipalName;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+/*
+ * @test
+ * @bug 8210821
+ * @summary Support dns_canonicalize_hostname in krb5.conf
+ * @library /lib/testlibrary
+ * /lib
+ * @compile -XDignore.symbol.file DnsCanonicalizeHostname.java
+ * @run main jdk.test.lib.FileInstaller dns_canonicalize_hostname.hosts hosts
+ * @run main/othervm -Djdk.net.hosts.file=hosts DnsCanonicalizeHostname false
+ */
+public class DnsCanonicalizeHostname {
+
+ // In dns_canonicalize_hostname.hosts, all "dummy.example.com", "dummy",
+ // and "bogus" are resolved to 127.0.0.1. Since "dummy.example.com" is on
+ // the first line, it is returned at the reverse lookup.
+
+ public static void main(String[] args) throws Exception {
+
+ Files.write(Paths.get("krb5.conf"), Arrays.asList(
+ "[libdefaults]",
+ "default_realm = R",
+ args[0].equals("none")
+ ? "# empty line"
+ : "dns_canonicalize_hostname = " + args[0],
+ "",
+ "[realms]",
+ "R = {",
+ " kdc = 127.0.0.1",
+ "}"
+ ));
+ System.setProperty("java.security.krb5.conf", "krb5.conf");
+
+ String n1 = new PrincipalName("host/dummy", PrincipalName.KRB_NT_SRV_HST)
+ .getNameStrings()[1];
+ String n2 = new PrincipalName("host/bogus", PrincipalName.KRB_NT_SRV_HST)
+ .getNameStrings()[1];
+
+ switch (args[0]) {
+ case "none":
+ case "true":
+ Asserts.assertEQ(n1, "dummy.example.com");
+ Asserts.assertEQ(n2, "bogus");
+ break;
+ case "false":
+ Asserts.assertEQ(n1, "dummy");
+ Asserts.assertEQ(n2, "bogus");
+ break;
+ }
+ }
+}
diff --git a/jdk/test/sun/security/krb5/auto/dns_canonicalize_hostname.hosts b/jdk/test/sun/security/krb5/auto/dns_canonicalize_hostname.hosts
new file mode 100644
index 000000000..d34f97611
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/dns_canonicalize_hostname.hosts
@@ -0,0 +1,8 @@
+# The preferred name at reverse lookup
+127.0.0.1 dummy.example.com
+
+# The short name
+127.0.0.1 dummy
+
+# The strange name
+127.0.0.1 bogus
\ No newline at end of file
--
2.22.0

View File

@ -0,0 +1,24 @@
Date: Fri, 9 Jun 2023 09:52:15 +0800
Subject: 8297656: AArch64: Enable AES/GCM Intrinsics
Bug url: https://bugs.openjdk.org/browse/JDK-8297656
---
hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
index ff28cf939..27ab00dda 100644
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
@@ -234,7 +234,7 @@ void VM_Version::get_processor_features() {
UseAES = true;
}
if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics)) {
- FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
+ FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true);
}
} else {
if (UseAES) {
--
2.22.0

View File

@ -0,0 +1,180 @@
Date: Fri, 9 Jun 2023 09:45:23 +0800
Subject: [PATCH 38/59] Record file descriptor when ExtensiveErrorReports is enabled
---
hotspot/src/os/aix/vm/os_aix.cpp | 4 +++
hotspot/src/os/bsd/vm/os_bsd.cpp | 4 +++
hotspot/src/os/linux/vm/os_linux.cpp | 40 ++++++++++++++++++++++
hotspot/src/os/solaris/vm/os_solaris.cpp | 4 +++
hotspot/src/os/windows/vm/os_windows.cpp | 4 +++
hotspot/src/share/vm/runtime/os.cpp | 7 ++++
hotspot/src/share/vm/runtime/os.hpp | 2 ++
hotspot/src/share/vm/utilities/vmError.cpp | 10 ++++++
8 files changed, 75 insertions(+)
diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp
index 6838f33bc..2cf08dce1 100644
--- a/hotspot/src/os/aix/vm/os_aix.cpp
+++ b/hotspot/src/os/aix/vm/os_aix.cpp
@@ -1617,6 +1617,10 @@ void os::pd_print_cpu_info(outputStream* st) {
st->cr();
}
+void os::pd_print_file_descriptor(outputStream* st) {
+ // Nothing to do for now.
+}
+
void os::print_siginfo(outputStream* st, void* siginfo) {
// Use common posix version.
os::Posix::print_siginfo_brief(st, (const siginfo_t*) siginfo);
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index 765b60c0d..7942c8545 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -1779,6 +1779,10 @@ void os::print_memory_info(outputStream* st) {
st->cr();
}
+void os::pd_print_file_descriptor(outputStream* st) {
+ // Nothing to do for now.
+}
+
void os::print_siginfo(outputStream* st, void* siginfo) {
const siginfo_t* si = (const siginfo_t*)siginfo;
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index e875fee77..b82997568 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -2509,6 +2509,46 @@ void os::print_siginfo(outputStream* st, void* siginfo) {
st->cr();
}
+// max length of file name in linux
+#define MAX_PATH_LEN 256
+// maximum number of file descriptors to print
+#define MAX_PRINT_FD_SIZE 2000
+
+void os::pd_print_file_descriptor(outputStream* st) {
+ int pid = os::current_process_id();
+ char process_path[MAX_PATH_LEN] = {0};
+ (void) snprintf(process_path, MAX_PATH_LEN, "/proc/%d/fd/", pid);
+ st->print_cr("path: %s", process_path);
+
+ DIR *dir = NULL;
+ dir = opendir(process_path);
+ if (dir == NULL) {
+ st->print_cr("opendir %s failed, errno: %d", process_path, errno);
+ return;
+ }
+
+ // Scan the directory, get symbolic link value
+ struct dirent *ptr;
+ ssize_t readlink_ret = 0;
+ char symbolic_link_value[MAX_PATH_LEN] = {0};
+ char filename[MAX_PATH_LEN] = {0};
+ unsigned long file_count = 0;
+ while ((ptr = readdir(dir)) != NULL) {
+ if (ptr->d_type == DT_DIR) continue;
+ if (file_count < MAX_PRINT_FD_SIZE) {
+ (void) snprintf(filename, MAX_PATH_LEN, "%s%s", process_path, ptr->d_name);
+ readlink_ret = readlink(filename, symbolic_link_value, MAX_PATH_LEN);
+ if (readlink_ret > 0) {
+ st->print_cr("%s -> %s", ptr->d_name, symbolic_link_value);
+ } else {
+ st->print_cr("%s: readlink failed, errno: %d", ptr->d_name, errno);
+ }
+ }
+ file_count++;
+ }
+ st->print_cr("Total fd count: %lu", file_count);
+ (void) closedir(dir);
+}
static void print_signal_handler(outputStream* st, int sig,
char* buf, size_t buflen);
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index 9f8c6a9bf..9029238e1 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -2094,6 +2094,10 @@ void os::pd_print_cpu_info(outputStream* st) {
// Nothing to do for now.
}
+void os::pd_print_file_descriptor(outputStream* st) {
+ // Nothing to do for now.
+}
+
void os::print_memory_info(outputStream* st) {
st->print("Memory:");
st->print(" %dk page", os::vm_page_size()>>10);
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index f0bc733c2..1017147c8 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -1865,6 +1865,10 @@ void os::pd_print_cpu_info(outputStream* st) {
// Nothing to do for now.
}
+void os::pd_print_file_descriptor(outputStream* st) {
+ // Nothing to do for now.
+}
+
void os::print_memory_info(outputStream* st) {
st->print("Memory:");
st->print(" %dk page", os::vm_page_size()>>10);
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index 84841b76e..43d66e85e 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -861,6 +861,13 @@ void os::print_hex_dump(outputStream* st, address start, address end, int unitsi
st->cr();
}
+void os::print_file_descriptor(outputStream* st) {
+ // file descriptor
+ st->print("File Descriptor:");
+ st->cr();
+ pd_print_file_descriptor(st);
+}
+
void os::print_environment_variables(outputStream* st, const char** env_list,
char* buffer, int len) {
if (env_list) {
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index 6ca220021..988977b17 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -661,6 +661,8 @@ class os: AllStatic {
static void print_siginfo(outputStream* st, void* siginfo);
static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
+ static void print_file_descriptor(outputStream* st);
+ static void pd_print_file_descriptor(outputStream* st);
static void print_location(outputStream* st, intptr_t x, bool verbose = false);
static size_t lasterror(char *buf, size_t len);
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index 5bbfade6c..0c5c955bf 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -810,6 +810,16 @@ void VMError::report(outputStream* st) {
st->cr();
}
+#if defined(AARCH64) || defined(X86)
+ STEP(207, "(printing file descriptor)" )
+
+ if (ExtensiveErrorReports && _verbose) {
+ // File Descriptor
+ os::print_file_descriptor(st);
+ st->cr();
+ }
+#endif
+
STEP(210, "(printing VM options)" )
if (_verbose) {
--
2.22.0

View File

@ -0,0 +1,91 @@
Date: Fri, 9 Jun 2023 09:26:54 +0800
Subject: 8243389: enhance os::pd_print_cpu_info on linux
Bug url: https://bugs.openjdk.org/browse/JDK-8243389
---
hotspot/src/os/linux/vm/os_linux.cpp | 56 ++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index e875fee77..0ea7eb189 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -2171,6 +2171,13 @@ static bool _print_ascii_file(const char* filename, outputStream* st) {
return true;
}
+static void _print_ascii_file_h(const char* header, const char* filename, outputStream* st) {
+ st->print("%s", header);
+ if (!_print_ascii_file(filename, st)) {
+ st->print_cr("<Not Available>");
+ }
+}
+
void os::print_dll_info(outputStream *st) {
st->print_cr("Dynamic libraries:");
@@ -2484,12 +2491,61 @@ void os::print_memory_info(outputStream* st) {
st->cr();
}
+// additional information about CPU e.g. available frequency ranges
+static void print_sys_devices_cpu_info(outputStream* st) {
+ _print_ascii_file_h("Online cpus:", "/sys/devices/system/cpu/online", st);
+ _print_ascii_file_h("Offline cpus:", "/sys/devices/system/cpu/offline", st);
+
+ if (ExtensiveErrorReports) {
+ // cache related info (cpu 0, should be similar for other CPUs)
+ for (unsigned int i=0; i < 10; i++) { // handle max. 10 cache entries
+ char hbuf_level[60];
+ char hbuf_type[60];
+ char hbuf_size[60];
+ char hbuf_coherency_line_size[80];
+ snprintf(hbuf_level, 60, "/sys/devices/system/cpu/cpu0/cache/index%u/level", i);
+ snprintf(hbuf_type, 60, "/sys/devices/system/cpu/cpu0/cache/index%u/type", i);
+ snprintf(hbuf_size, 60, "/sys/devices/system/cpu/cpu0/cache/index%u/size", i);
+ snprintf(hbuf_coherency_line_size, 80, "/sys/devices/system/cpu/cpu0/cache/index%u/coherency_line_size", i);
+ if (file_exists(hbuf_level)) {
+ _print_ascii_file_h("cache level:", hbuf_level, st);
+ _print_ascii_file_h("cache type:", hbuf_type, st);
+ _print_ascii_file_h("cache size:", hbuf_size, st);
+ _print_ascii_file_h("cache coherency line size:", hbuf_coherency_line_size, st);
+ }
+ }
+ }
+
+ // we miss the cpufreq entries on Power and s390x
+#if defined(IA32) || defined(AMD64)
+ _print_ascii_file_h("BIOS frequency limitation:", "/sys/devices/system/cpu/cpu0/cpufreq/bios_limit", st);
+ _print_ascii_file_h("Frequency switch latency (ns):", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency", st);
+ _print_ascii_file_h("Available cpu frequencies:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", st);
+ // min and max should be in the Available range but still print them (not all info might be available for all kernels)
+ if (ExtensiveErrorReports) {
+ _print_ascii_file_h("Maximum cpu frequency:", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", st);
+ _print_ascii_file_h("Minimum cpu frequency:", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq", st);
+ _print_ascii_file_h("Current cpu frequency:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", st);
+ }
+ // governors are power schemes, see https://wiki.archlinux.org/index.php/CPU_frequency_scaling
+ if (ExtensiveErrorReports) {
+ _print_ascii_file_h("Available governors:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors", st);
+ }
+ _print_ascii_file_h("Current governor:", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", st);
+ // Core performance boost, see https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt
+ // Raise operating frequency of some cores in a multi-core package if certain conditions apply, e.g.
+ // whole chip is not fully utilized
+ _print_ascii_file_h("Core performance/turbo boost:", "/sys/devices/system/cpu/cpufreq/boost", st);
+#endif
+}
+
void os::pd_print_cpu_info(outputStream* st) {
st->print("\n/proc/cpuinfo:\n");
if (!_print_ascii_file("/proc/cpuinfo", st)) {
st->print(" <Not Available>");
}
st->cr();
+ print_sys_devices_cpu_info(st);
}
void os::print_siginfo(outputStream* st, void* siginfo) {
--
2.22.0

View File

@ -0,0 +1,51 @@
Date: Fri, 9 Jun 2023 10:11:07 +0800
Subject: Print the Exception event in more detail
---
hotspot/src/share/vm/runtime/sharedRuntime.cpp | 6 +++---
hotspot/src/share/vm/runtime/sharedRuntime.hpp | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
index 5eabd3df0..58c302da7 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
@@ -599,19 +599,19 @@ oop SharedRuntime::retrieve_receiver( Symbol* sig, frame caller ) {
}
-void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception) {
+void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception, const char *message) {
if (JvmtiExport::can_post_on_exceptions()) {
vframeStream vfst(thread, true);
methodHandle method = methodHandle(thread, vfst.method());
address bcp = method()->bcp_from(vfst.bci());
JvmtiExport::post_exception_throw(thread, method(), bcp, h_exception());
}
- Exceptions::_throw(thread, __FILE__, __LINE__, h_exception);
+ Exceptions::_throw(thread, __FILE__, __LINE__, h_exception, message);
}
void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Symbol* name, const char *message) {
Handle h_exception = Exceptions::new_exception(thread, name, message);
- throw_and_post_jvmti_exception(thread, h_exception);
+ throw_and_post_jvmti_exception(thread, h_exception, message);
}
// The interpreter code to call this tracing function is only
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp
index c6a96a858..acab7ffc4 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp
@@ -246,7 +246,7 @@ class SharedRuntime: AllStatic {
#endif // PRODUCT
// Helper routine for full-speed JVMTI exception throwing support
- static void throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception);
+ static void throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception, const char *message = NULL);
static void throw_and_post_jvmti_exception(JavaThread *thread, Symbol* name, const char *message = NULL);
// RedefineClasses() tracing support for obsolete method entry
--
2.22.0

View File

@ -0,0 +1,276 @@
Date: Fri, 9 Jun 2023 10:29:38 +0800
Subject: Reuse translet in XSLTC for XML
---
.../share/vm/classfile/classFileParser.cpp | 52 +++++++++++-
.../share/vm/classfile/classFileParser.hpp | 2 +-
hotspot/src/share/vm/classfile/vmSymbols.hpp | 4 +-
hotspot/src/share/vm/runtime/arguments.cpp | 2 +
hotspot/src/share/vm/runtime/arguments.hpp | 3 +
.../src/share/vm/utilities/accessFlags.hpp | 1 +
.../transform/TestXmlTransletEnhance.java | 83 +++++++++++++++++++
8 files changed, 144 insertions(+), 3 deletions(-)
create mode 100644 jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index d8e99e622..b9fde38dc 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -59,12 +59,13 @@
#include "runtime/reflection.hpp"
#include "runtime/signature.hpp"
#include "runtime/timer.hpp"
+#include "runtime/arguments.hpp"
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/array.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
-
+#include "interpreter/bytecodeStream.hpp"
// We generally try to create the oops directly when parsing, rather than
// allocating temporary data structures and copying the bytes twice. A
// temporary area is only needed when parsing utf8 entries in the constant
@@ -2556,6 +2557,7 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
ClassFileStream* cfs = stream();
cfs->guarantee_more(2, CHECK_NULL); // length
u2 length = cfs->get_u2_fast();
+ Method* initializerMethod = NULL;
if (length == 0) {
_methods = Universe::the_empty_method_array();
} else {
@@ -2570,6 +2572,9 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
if (method->is_final()) {
*has_final_method = true;
}
+ if (method->name()== vmSymbols::object_initializer_name()) {
+ initializerMethod = method();
+ }
// declares_default_methods: declares concrete instance methods, any access flags
// used for interface initialization, and default method inheritance analysis
if (is_interface && !(*declares_default_methods)
@@ -2606,6 +2611,11 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
name->as_C_string(), sig->as_klass_external_name(), CHECK_NULL);
}
}
+
+ if (Arguments::transletEnhance()) {
+ bool isClassMatched = (_class_name == vmSymbols::transformerFactoryImpl_class_name());
+ if(isClassMatched) modify_fields_value(initializerMethod, vmSymbols::transformer_generateTranslet_field_name(), vmSymbols::transformer_autoTranslet_field_name(), Bytecodes::_iconst_1, CHECK_NULL);
+ }
}
return _methods;
}
@@ -5421,6 +5431,46 @@ char* ClassFileParser::skip_over_field_signature(char* signature,
return NULL;
}
+// This function sets the class's specific fields to a fixed value, ie: targetFieldName1 and targetFieldName2.
+// initializerMethod is the class's "<init>" method, should not be NULL.
+// For performance, two fields can be set at the same time. You can also set only one field, just set targetFieldName2 to NULL.
+// Bytecodes::Code can be bytecode between iconst_0 and dconst_0, range is 0x03 ~ 0x0f.
+void ClassFileParser::modify_fields_value(Method* initializerMethod, Symbol* targetFieldName1, Symbol* targetFieldName2, Bytecodes::Code targetCode, TRAPS) {
+ assert(initializerMethod != NULL, "The method can't be NULL.");
+ assert(initializerMethod->name() == vmSymbols::object_initializer_name(), "The method must be <init>.");
+ assert(targetFieldName1 != NULL, "At least targetFieldName1 can't be NULL.");
+ assert(targetCode >= Bytecodes::_iconst_0 && targetCode <= Bytecodes::_dconst_1, "The primitive constant's value range is 0x03 ~ 0x0f.");
+
+ ResourceMark rm(THREAD);
+ methodHandle mh(initializerMethod);
+ BytecodeStream bcs(mh);
+ while (!bcs.is_last_bytecode()) {
+ Bytecodes::Code code = bcs.next();
+ if (code == Bytecodes::_putfield) {
+ address p = bcs.bcp();
+ // get field index
+ int index = Bytes::get_Java_u2(p + 1);
+ Symbol *name = _cp->name_ref_at(index);
+ if (name == targetFieldName1) {
+ p = p - 1;
+ *(u1 *) p = (u1) targetCode;
+ }
+ if ((targetFieldName2 != NULL) && (name == targetFieldName2)) {
+ p = p - 1;
+ *(u1 *) p = (u1) targetCode;
+ }
+ }
+ }
+ _has_vanilla_constructor = false;
+ AccessFlags flags = mh()->access_flags();
+ flags.clear_has_vanilla_constructor();
+ if (mh->is_vanilla_constructor()) {
+ _has_vanilla_constructor = true;
+ flags.set_has_vanilla_constructor();
+ }
+ mh()->set_access_flags(flags);
+}
+
#if INCLUDE_JFR
// Caller responsible for ResourceMark
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index dfb56c990..1900f0abf 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -391,7 +391,7 @@ PRAGMA_DIAG_POP
bool verify_unqualified_name(char* name, unsigned int length, int type);
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
-
+ void modify_fields_value(Method* initializerMethod, Symbol* targetFieldName1, Symbol* targetFieldName2, Bytecodes::Code targetCode, TRAPS);
bool is_anonymous() {
assert(EnableInvokeDynamic || _host_klass.is_null(), "");
return _host_klass.not_null();
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 5f2a9a720..494fd9bdf 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -422,7 +422,9 @@
template(resolved_references_name, "<resolved_references>") \
template(referencequeue_null_name, "NULL") \
template(referencequeue_enqueued_name, "ENQUEUED") \
- \
+ template(transformerFactoryImpl_class_name, "com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl") \
+ template(transformer_generateTranslet_field_name, "_generateTranslet") \
+ template(transformer_autoTranslet_field_name, "_autoTranslet") \
/* non-intrinsic name/signature pairs: */ \
template(register_method_name, "register") \
do_alias(register_method_signature, object_void_signature) \
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 43fdd0b49..0c8a4012a 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -149,6 +149,8 @@ SystemProperty *Arguments::_sun_boot_class_path = NULL;
char* Arguments::_meta_index_path = NULL;
char* Arguments::_meta_index_dir = NULL;
+bool Arguments::_transletEnhance = false;
+
// Check if head of 'option' matches 'name', and sets 'tail' remaining part of option string
static bool match_option(const JavaVMOption *option, const char* name,
diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
index 88741e8c3..4f7232e48 100644
--- a/hotspot/src/share/vm/runtime/arguments.hpp
+++ b/hotspot/src/share/vm/runtime/arguments.hpp
@@ -267,6 +267,7 @@ class Arguments : AllStatic {
static char* _meta_index_path;
static char* _meta_index_dir;
+ static bool _transletEnhance;
// java.vendor.url.bug, bug reporting URL for fatal errors.
static const char* _java_vendor_url_bug;
@@ -633,6 +634,8 @@ class Arguments : AllStatic {
static Mode mode() { return _mode; }
static bool is_interpreter_only() { return mode() == _int; }
+ static void set_transletEnhance(bool arg) { _transletEnhance = arg; }
+ static bool transletEnhance() { return _transletEnhance; }
// Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp
index bc56262d1..b20f0f740 100644
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp
@@ -209,6 +209,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
void clear_not_c2_osr_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); }
// Klass* flags
void set_has_vanilla_constructor() { atomic_set_bits(JVM_ACC_HAS_VANILLA_CONSTRUCTOR); }
+ void clear_has_vanilla_constructor() { atomic_clear_bits(JVM_ACC_HAS_VANILLA_CONSTRUCTOR); }
void set_has_finalizer() { atomic_set_bits(JVM_ACC_HAS_FINALIZER); }
void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); }
void set_is_cloneable() { atomic_set_bits(JVM_ACC_IS_CLONEABLE); }
diff --git a/jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java b/jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java
new file mode 100644
index 000000000..73b848de8
--- /dev/null
+++ b/jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved.
+ */
+
+
+/* @test
+ * @summary a test for xml translet enhance
+ * @library /lib/testlibrary
+ * @run main TestXmlTransletEnhance
+ */
+
+import javax.xml.transform.TransformerFactory;
+import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
+import java.lang.reflect.Field;
+import static jdk.testlibrary.Asserts.assertEquals;
+
+public class TestXmlTransletEnhance {
+ static final boolean expectedResult = true;
+
+ public static void main(String[] args) throws InterruptedException {
+
+ Thread thread = new Mythread("BenchmarkThread xml ");
+ thread.start();
+ thread.join();
+ boolean ret = SharedData.getInstance().getResult();
+ assertEquals(ret, expectedResult);
+
+ }
+
+ static class Mythread extends Thread {
+ Mythread(String name){
+ super(name);
+ }
+
+ @Override
+ public void run(){
+
+ try {
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ TransformerFactoryImpl transformer = new TransformerFactoryImpl();
+ Class<?> clazz = transformer.getClass();
+
+ Field generateTransletFiled = clazz.getDeclaredField("_generateTranslet");
+ Field autoTransletFiled = clazz.getDeclaredField("_autoTranslet");
+
+ generateTransletFiled.setAccessible(true);
+ autoTransletFiled.setAccessible(true);
+
+ boolean value1 = (boolean)generateTransletFiled.get(transformer);
+ boolean value2 = (boolean)autoTransletFiled.get(transformer);
+
+ SharedData.getInstance().setResult(value1 && value2);
+
+ } catch (NoSuchFieldException| IllegalAccessException | SecurityException | IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ static class SharedData {
+ private static SharedData instance;
+ private boolean result;
+
+ private SharedData() {
+ }
+
+ public static synchronized SharedData getInstance() {
+ if (instance == null) {
+ instance = new SharedData();
+ }
+ return instance;
+ }
+
+ public synchronized boolean getResult() {
+ return result;
+ }
+
+ public synchronized void setResult(boolean result) {
+ this.result = result;
+ }
+ }
+}
--
2.22.0

View File

@ -0,0 +1,24 @@
Date: Fri, 9 Jun 2023 10:34:42 +0800
Subject: [PATCH 42/59] 8140581: Excluding compile messages should only be printed with PrintCompilation
Bug url: https://bugs.openjdk.org/browse/JDK-8140581
---
hotspot/src/share/vm/compiler/compileBroker.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp
index 63f7bde8f..e8f97074e 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp
@@ -1504,7 +1504,7 @@ bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci,
// The method may be explicitly excluded by the user.
bool quietly;
if (CompilerOracle::should_exclude(method, quietly)) {
- if (!quietly) {
+ if (PrintCompilation && !quietly) {
// This does not happen quietly...
ResourceMark rm;
tty->print("### Excluding %s:%s",
--
2.22.0

View File

@ -0,0 +1,55 @@
Date: Fri, 9 Jun 2023 10:18:10 +0800
Subject: Cache dom in xml transform
---
.../xalan/internal/xsltc/trax/TransformerImpl.java | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
index 8e783cee0..3d143d461 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
@@ -56,6 +56,7 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.xml.XMLConstants;
@@ -151,6 +152,11 @@ public final class TransformerImpl extends Transformer
*/
private DOM _dom = null;
+ /**
+ * A hashMap for DOMS.
+ */
+ private ConcurrentHashMap<String, DOM> _domMaps = new ConcurrentHashMap();
+
/**
* Number of indent spaces to add when indentation is on.
*/
@@ -530,8 +536,11 @@ public final class TransformerImpl extends Transformer
private DOM getDOM(Source source) throws TransformerException {
try {
DOM dom;
-
if (source != null) {
+ String ssId = source.getSystemId();
+ if ((ssId != null) && (_domMaps.containsKey(ssId))) {
+ return _domMaps.get(ssId);
+ }
DTMWSFilter wsfilter;
if (_translet != null && _translet instanceof StripFilter) {
wsfilter = new DOMWSFilter(_translet);
@@ -549,6 +558,7 @@ public final class TransformerImpl extends Transformer
}
dom = (DOM)_dtmManager.getDTM(source, false, wsfilter, true,
false, false, 0, hasIdCall);
+ if ((ssId != null) && (dom != null)) _domMaps.put(ssId, dom);
} else if (_dom != null) {
dom = _dom;
_dom = null; // use only once, so reset to 'null'
--
2.22.0

View File

@ -0,0 +1,31 @@
Date: Fri, 9 Jun 2023 11:10:42 +0800
Subject: [PATCH 44/59] Record file descriptor when ExtensiveErrorReports is enabled
---
hotspot/src/os/linux/vm/os_linux.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index ce4c6de09..a05ad07cf 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -2586,7 +2586,7 @@ void os::pd_print_file_descriptor(outputStream* st) {
// Scan the directory, get symbolic link value
struct dirent *ptr;
ssize_t readlink_ret = 0;
- char symbolic_link_value[MAX_PATH_LEN] = {0};
+ char symbolic_link_value[MAX_PATH_LEN + 1] = {0};
char filename[MAX_PATH_LEN] = {0};
unsigned long file_count = 0;
while ((ptr = readdir(dir)) != NULL) {
@@ -2595,6 +2595,7 @@ void os::pd_print_file_descriptor(outputStream* st) {
(void) snprintf(filename, MAX_PATH_LEN, "%s%s", process_path, ptr->d_name);
readlink_ret = readlink(filename, symbolic_link_value, MAX_PATH_LEN);
if (readlink_ret > 0) {
+ symbolic_link_value[readlink_ret] = '\0';
st->print_cr("%s -> %s", ptr->d_name, symbolic_link_value);
} else {
st->print_cr("%s: readlink failed, errno: %d", ptr->d_name, errno);
--
2.22.0

View File

@ -0,0 +1,66 @@
Date: Fri, 9 Jun 2023 11:15:09 +0800
Subject: 8276904: Optional.toString() is unnecessarily expensive
Bug url: https://bugs.openjdk.org/browse/JDK-8276904
---
jdk/src/share/classes/java/util/Optional.java | 2 +-
jdk/src/share/classes/java/util/OptionalDouble.java | 2 +-
jdk/src/share/classes/java/util/OptionalInt.java | 2 +-
jdk/src/share/classes/java/util/OptionalLong.java | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/jdk/src/share/classes/java/util/Optional.java b/jdk/src/share/classes/java/util/Optional.java
index d471058ec..ff2b4db7f 100644
--- a/jdk/src/share/classes/java/util/Optional.java
+++ b/jdk/src/share/classes/java/util/Optional.java
@@ -343,7 +343,7 @@ public final class Optional<T> {
@Override
public String toString() {
return value != null
- ? String.format("Optional[%s]", value)
+ ? ("Optional[" + value + "]")
: "Optional.empty";
}
}
diff --git a/jdk/src/share/classes/java/util/OptionalDouble.java b/jdk/src/share/classes/java/util/OptionalDouble.java
index 0efc770fa..9aff9be8d 100644
--- a/jdk/src/share/classes/java/util/OptionalDouble.java
+++ b/jdk/src/share/classes/java/util/OptionalDouble.java
@@ -246,7 +246,7 @@ public final class OptionalDouble {
@Override
public String toString() {
return isPresent
- ? String.format("OptionalDouble[%s]", value)
+ ? ("OptionalDouble[" + value + "]")
: "OptionalDouble.empty";
}
}
diff --git a/jdk/src/share/classes/java/util/OptionalInt.java b/jdk/src/share/classes/java/util/OptionalInt.java
index 5cb927524..584f6e2ba 100644
--- a/jdk/src/share/classes/java/util/OptionalInt.java
+++ b/jdk/src/share/classes/java/util/OptionalInt.java
@@ -246,7 +246,7 @@ public final class OptionalInt {
@Override
public String toString() {
return isPresent
- ? String.format("OptionalInt[%s]", value)
+ ? ("OptionalInt[" + value + "]")
: "OptionalInt.empty";
}
}
diff --git a/jdk/src/share/classes/java/util/OptionalLong.java b/jdk/src/share/classes/java/util/OptionalLong.java
index 589a59fd3..089f54adf 100644
--- a/jdk/src/share/classes/java/util/OptionalLong.java
+++ b/jdk/src/share/classes/java/util/OptionalLong.java
@@ -246,7 +246,7 @@ public final class OptionalLong {
@Override
public String toString() {
return isPresent
- ? String.format("OptionalLong[%s]", value)
+ ? ("OptionalLong[" + value + "]")
: "OptionalLong.empty";
}
}
--
2.22.0

View File

@ -0,0 +1,975 @@
Date: Fri, 9 Jun 2023 11:28:19 +0800
Subject: [PATCH 46/59] 8210960: Allow --with-boot-jdk-jvmargs to work during configure
Bug url: https://bugs.openjdk.org/browse/JDK-8210960
---
common/autoconf/basics.m4 | 2 +-
common/autoconf/boot-jdk.m4 | 28 +-
common/autoconf/generated-configure.sh | 506 ++++++++++++++++++++++---
3 files changed, 483 insertions(+), 53 deletions(-)
diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4
index 692ef831a..d80e7edad 100644
--- a/common/autoconf/basics.m4
+++ b/common/autoconf/basics.m4
@@ -30,7 +30,7 @@ AC_DEFUN([ADD_JVM_ARG_IF_OK],
[
$ECHO "Check if jvm arg is ok: $1" >&AS_MESSAGE_LOG_FD
$ECHO "Command: $3 $1 -version" >&AS_MESSAGE_LOG_FD
- OUTPUT=`$3 $1 -version 2>&1`
+ OUTPUT=`$3 $1 $USER_BOOT_JDK_OPTIONS -version 2>&1`
FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
diff --git a/common/autoconf/boot-jdk.m4 b/common/autoconf/boot-jdk.m4
index 5be15b869..f86f07644 100644
--- a/common/autoconf/boot-jdk.m4
+++ b/common/autoconf/boot-jdk.m4
@@ -51,7 +51,18 @@ AC_DEFUN([BOOTJDK_DO_CHECK],
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
+ if [ [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ]; then
+ AC_MSG_NOTICE([You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead.])
+ AC_MSG_NOTICE([Java reports: "$BOOT_JDK_VERSION".])
+ AC_MSG_ERROR([Cannot continue])
+ fi
+ if [ [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ]; then
+ AC_MSG_NOTICE([The specified --with-boot-jdk-jvmargs is invalid for the tested java])
+ AC_MSG_NOTICE([Error message: "$BOOT_JDK_VERSION".])
+ AC_MSG_NOTICE([Please fix arguments, or point to an explicit boot JDK which accept these arguments])
+ AC_MSG_ERROR([Cannot continue])
+ fi
# Extra M4 quote needed to protect [] in grep expression.
[FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`]
@@ -66,7 +77,7 @@ AC_DEFUN([BOOTJDK_DO_CHECK],
AC_MSG_CHECKING([for Boot JDK])
AC_MSG_RESULT([$BOOT_JDK])
AC_MSG_CHECKING([Boot JDK version])
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
AC_MSG_RESULT([$BOOT_JDK_VERSION])
fi # end check jdk version
fi # end check rt.jar
@@ -222,6 +233,11 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
AC_ARG_WITH(boot-jdk, [AS_HELP_STRING([--with-boot-jdk],
[path to Boot JDK (used to bootstrap build) @<:@probed@:>@])])
+ AC_ARG_WITH(boot-jdk-jvmargs, [AS_HELP_STRING([--with-boot-jdk-jvmargs],
+ [specify additional arguments to be passed to Boot JDK tools @<:@none@:>@])])
+
+ USER_BOOT_JDK_OPTIONS="$with_boot_jdk_jvmargs"
+
# We look for the Boot JDK through various means, going from more certain to
# more of a guess-work. After each test, BOOT_JDK_FOUND is set to "yes" if
# we detected something (if so, the path to the jdk is in BOOT_JDK). But we
@@ -307,17 +323,13 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
#
# Specify options for anything that is run with the Boot JDK.
#
- AC_ARG_WITH(boot-jdk-jvmargs, [AS_HELP_STRING([--with-boot-jdk-jvmargs],
- [specify JVM arguments to be passed to all invocations of the Boot JDK, overriding the default values,
- e.g --with-boot-jdk-jvmargs="-Xmx8G -enableassertions"])])
-
AC_MSG_CHECKING([flags for boot jdk java command] )
# Disable special log output when a debug build is used as Boot JDK...
ADD_JVM_ARG_IF_OK([-XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput],boot_jdk_jvmargs,[$JAVA])
- # Apply user provided options.
- ADD_JVM_ARG_IF_OK([$with_boot_jdk_jvmargs],boot_jdk_jvmargs,[$JAVA])
+ # Finally append user provided options to allow them to override.
+ ADD_JVM_ARG_IF_OK([$USER_BOOT_JDK_OPTIONS],boot_jdk_jvmargs,[$JAVA])
AC_MSG_RESULT([$boot_jdk_jvmargs])
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 3a622dee8..a7f76a15c 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -20447,10 +20447,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -20599,7 +20618,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -20790,10 +20809,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -20942,7 +20980,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -21130,10 +21168,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -21282,7 +21339,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -21329,10 +21386,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -21481,7 +21557,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -21668,10 +21744,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -21820,7 +21915,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -21894,10 +21989,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -22046,7 +22160,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -22085,10 +22199,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -22237,7 +22370,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -22304,10 +22437,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -22456,7 +22608,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -22495,10 +22647,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -22647,7 +22818,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -22714,10 +22885,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -22866,7 +23056,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -22905,10 +23095,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -23057,7 +23266,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -23124,10 +23333,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -23276,7 +23504,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -23315,10 +23543,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -23467,7 +23714,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -23521,10 +23768,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -23673,7 +23939,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -23710,10 +23976,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -23862,7 +24147,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -23917,10 +24202,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -24069,7 +24373,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -24106,10 +24410,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -24258,7 +24581,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -24312,10 +24635,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -24464,7 +24806,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -24501,10 +24843,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -24653,7 +25014,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -24708,10 +25069,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -24860,7 +25240,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -24897,10 +25277,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -25049,7 +25448,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
@@ -25085,10 +25484,29 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja
BOOT_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
FOUND_VERSION_78=`echo $BOOT_JDK_VERSION | grep '\"1\.[78]\.'`
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Picked up" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&5
+ $as_echo "$as_me: You have _JAVA_OPTIONS or JAVA_TOOL_OPTIONS set. This can mess up the build. Please use --with-boot-jdk-jvmargs instead." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Java reports: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Java reports: \"$BOOT_JDK_VERSION\"." >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
+ if [[ "$BOOT_JDK_VERSION" =~ "Unrecognized option" ]] ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&5
+ $as_echo "$as_me: The specified --with-boot-jdk-jvmargs is invalid for the tested java" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Error message: \"$BOOT_JDK_VERSION\"." >&5
+ $as_echo "$as_me: Error message: \"$BOOT_JDK_VERSION\"." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&5
+ $as_echo "$as_me: Please fix arguments, or point to an explicit boot JDK which accept these arguments" >&6;}
+ as_fn_error $? "Cannot continue" "$LINENO" 5
+ fi
+
if test "x$FOUND_VERSION_78" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5
$as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;}
@@ -25237,7 +25655,7 @@ $as_echo_n "checking for Boot JDK... " >&6; }
$as_echo "$BOOT_JDK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Boot JDK version" >&5
$as_echo_n "checking Boot JDK version... " >&6; }
- BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
+ BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" $USER_BOOT_JDK_OPTIONS -version 2>&1 | $TR '\n\r' ' '`
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BOOT_JDK_VERSION" >&5
$as_echo "$BOOT_JDK_VERSION" >&6; }
fi # end check jdk version
--
2.22.0

View File

@ -0,0 +1,651 @@
Date: Fri, 9 Jun 2023 12:13:26 +0800
Subject: [PATCH 47/59] 8025692: Log what methods are touched at run-time
Bug url: https://bugs.openjdk.org/browse/JDK-8025692
---
.../vm/templateInterpreter_aarch64.cpp | 4 +-
hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp | 2 +-
.../cpu/ppc/vm/templateInterpreter_ppc.cpp | 4 +-
.../src/cpu/sparc/vm/interp_masm_sparc.cpp | 2 +-
.../sparc/vm/templateInterpreter_sparc.cpp | 4 +-
.../cpu/x86/vm/templateInterpreter_x86_32.cpp | 4 +-
.../cpu/x86/vm/templateInterpreter_x86_64.cpp | 4 +-
hotspot/src/share/vm/ci/ciMethod.cpp | 3 +
hotspot/src/share/vm/oops/method.cpp | 84 +++++++++++
hotspot/src/share/vm/oops/method.hpp | 2 +
hotspot/src/share/vm/runtime/globals.hpp | 6 +
hotspot/src/share/vm/runtime/java.cpp | 8 ++
hotspot/src/share/vm/runtime/mutexLocker.cpp | 2 +
hotspot/src/share/vm/runtime/mutexLocker.hpp | 1 +
.../src/share/vm/runtime/vm_operations.hpp | 1 +
.../share/vm/services/diagnosticCommand.cpp | 33 +++++
.../share/vm/services/diagnosticCommand.hpp | 17 +++
.../CommandLine/PrintTouchedMethods.java | 134 ++++++++++++++++++
.../CommandLine/TestLogTouchedMethods.java | 35 +++++
19 files changed, 338 insertions(+), 12 deletions(-)
create mode 100644 hotspot/test/runtime/CommandLine/PrintTouchedMethods.java
create mode 100644 hotspot/test/runtime/CommandLine/TestLogTouchedMethods.java
diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
index a5a91e5f3..28b84cb51 100644
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
@@ -1135,7 +1135,7 @@ void InterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// native method than the typical interpreter frame setup.
address InterpreterGenerator::generate_native_entry(bool synchronized) {
// determine code generation flags
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// r1: Method*
// rscratch1: sender sp
@@ -1591,7 +1591,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
//
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// determine code generation flags
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// rscratch1: sender sp
address entry_point = __ pc();
diff --git a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp
index 463f9da92..594905ef7 100644
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp
@@ -2226,7 +2226,7 @@ void InterpreterMacroAssembler::get_method_counters(Register method,
}
void InterpreterMacroAssembler::increment_invocation_counter(Register Rcounters, Register iv_be_count, Register Rtmp_r0) {
- assert(UseCompiler, "incrementing must be useful");
+ assert(UseCompiler || LogTouchedMethods, "incrementing must be useful");
Register invocation_count = iv_be_count;
Register backedge_count = Rtmp_r0;
int delta = InvocationCounter::count_increment;
diff --git a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp
index 0fb934166..4e2cec39b 100644
--- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp
@@ -726,7 +726,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
address entry = __ pc();
- const bool inc_counter = UseCompiler || CountCompiledCalls;
+ const bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// -----------------------------------------------------------------------------
// Allocate a new frame that represents the native callee (i2n frame).
@@ -1176,7 +1176,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Generic interpreted method entry to (asm) interpreter.
//
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
address entry = __ pc();
// Generate the code to allocate the interpreter stack frame.
Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
diff --git a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
index 66bcfcaf1..83d54d731 100644
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
@@ -2362,7 +2362,7 @@ void InterpreterMacroAssembler::get_method_counters(Register method,
}
void InterpreterMacroAssembler::increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 ) {
- assert(UseCompiler, "incrementing must be useful");
+ assert(UseCompiler || LogTouchedMethods, "incrementing must be useful");
assert_different_registers(Rcounters, Rtmp, Rtmp2);
Address inv_counter(Rcounters, MethodCounters::invocation_counter_offset() +
diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index 540f9b287..9526866bd 100644
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -823,7 +823,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
// the following temporary registers are used during frame creation
const Register Gtmp1 = G3_scratch ;
const Register Gtmp2 = G1_scratch;
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// make sure registers are different!
assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
@@ -1261,7 +1261,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
address entry = __ pc();
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// the following temporary registers are used during frame creation
const Register Gtmp1 = G3_scratch ;
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
index b7c515031..662d82222 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -990,7 +990,7 @@ address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpret
address InterpreterGenerator::generate_native_entry(bool synchronized) {
// determine code generation flags
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// rbx,: Method*
// rsi: sender sp
@@ -1405,7 +1405,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
//
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// determine code generation flags
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// rbx,: Method*
// rsi: sender sp
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
index 209a3f676..0f3bfc979 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
@@ -962,7 +962,7 @@ address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpret
// native method than the typical interpreter frame setup.
address InterpreterGenerator::generate_native_entry(bool synchronized) {
// determine code generation flags
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// rbx: Method*
// r13: sender sp
@@ -1409,7 +1409,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
//
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// determine code generation flags
- bool inc_counter = UseCompiler || CountCompiledCalls;
+ bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods;
// ebx: Method*
// r13: sender sp
diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp
index 22fe6c8f1..50fafc4f8 100644
--- a/hotspot/src/share/vm/ci/ciMethod.cpp
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp
@@ -74,6 +74,9 @@ ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) :
{
assert(h_m() != NULL, "no null method");
+ if (LogTouchedMethods) {
+ h_m()->log_touched(Thread::current());
+ }
// These fields are always filled in in loaded methods.
_flags = ciFlags(h_m()->access_flags());
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index 305348bd0..406cd485e 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -408,6 +408,11 @@ MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
if (!mh->init_method_counters(counters)) {
MetadataFactory::free_metadata(loader_data, counters);
}
+
+ if (LogTouchedMethods) {
+ mh->log_touched(CHECK_NULL);
+ }
+
return mh->method_counters();
}
@@ -2088,6 +2093,85 @@ void Method::collect_statistics(KlassSizeStats *sz) const {
}
#endif // INCLUDE_SERVICES
+// LogTouchedMethods and PrintTouchedMethods
+
+// TouchedMethodRecord -- we can't use a HashtableEntry<Method*> because
+// the Method may be garbage collected. Let's roll our own hash table.
+class TouchedMethodRecord : CHeapObj<mtTracing> {
+public:
+ // It's OK to store Symbols here because they will NOT be GC'ed if
+ // LogTouchedMethods is enabled.
+ TouchedMethodRecord* _next;
+ Symbol* _class_name;
+ Symbol* _method_name;
+ Symbol* _method_signature;
+};
+
+static const int TOUCHED_METHOD_TABLE_SIZE = 20011;
+static TouchedMethodRecord** _touched_method_table = NULL;
+
+void Method::log_touched(TRAPS) {
+
+ const int table_size = TOUCHED_METHOD_TABLE_SIZE;
+ Symbol* my_class = klass_name();
+ Symbol* my_name = name();
+ Symbol* my_sig = signature();
+
+ unsigned int hash = my_class->identity_hash() +
+ my_name->identity_hash() +
+ my_sig->identity_hash();
+ juint index = juint(hash) % table_size;
+
+ MutexLocker ml(TouchedMethodLog_lock, THREAD);
+ if (_touched_method_table == NULL) {
+ _touched_method_table = NEW_C_HEAP_ARRAY2(TouchedMethodRecord*, table_size,
+ mtTracing, CURRENT_PC);
+ memset(_touched_method_table, 0, sizeof(TouchedMethodRecord*) * table_size);
+ }
+
+ TouchedMethodRecord* ptr = _touched_method_table[index];
+ while (ptr) {
+ if (ptr->_class_name == my_class &&
+ ptr->_method_name == my_name &&
+ ptr->_method_signature == my_sig) {
+ return;
+ }
+ if (ptr->_next == NULL) break;
+ ptr = ptr->_next;
+ }
+ TouchedMethodRecord* nptr = NEW_C_HEAP_OBJ(TouchedMethodRecord, mtTracing);
+ my_class->increment_refcount();
+ my_name->increment_refcount();
+ my_sig->increment_refcount();
+ nptr->_class_name = my_class;
+ nptr->_method_name = my_name;
+ nptr->_method_signature = my_sig;
+ nptr->_next = NULL;
+
+ if (ptr == NULL) {
+ // first
+ _touched_method_table[index] = nptr;
+ } else {
+ ptr->_next = nptr;
+ }
+}
+
+void Method::print_touched_methods(outputStream* out) {
+ MutexLockerEx ml(Thread::current()->is_VM_thread() ? NULL : TouchedMethodLog_lock);
+ out->print_cr("# Method::print_touched_methods version 1");
+ if (_touched_method_table) {
+ for (int i = 0; i < TOUCHED_METHOD_TABLE_SIZE; i++) {
+ TouchedMethodRecord* ptr = _touched_method_table[i];
+ while(ptr) {
+ ptr->_class_name->print_symbol_on(out); out->print(".");
+ ptr->_method_name->print_symbol_on(out); out->print(":");
+ ptr->_method_signature->print_symbol_on(out); out->cr();
+ ptr = ptr->_next;
+ }
+ }
+ }
+}
+
// Verification
void Method::verify_on(outputStream* st) {
diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp
index ec93f2fb4..ee74d959d 100644
--- a/hotspot/src/share/vm/oops/method.hpp
+++ b/hotspot/src/share/vm/oops/method.hpp
@@ -650,6 +650,8 @@ class Method : public Metadata {
#if INCLUDE_SERVICES
void collect_statistics(KlassSizeStats *sz) const;
#endif
+ void log_touched(TRAPS);
+ static void print_touched_methods(outputStream* out);
// interpreter support
static ByteSize const_offset() { return byte_offset_of(Method, _constMethod ); }
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 210e6bd67..11f713013 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -2694,6 +2694,12 @@ class CommandLineFlags {
develop(bool, EagerInitialization, false, \
"Eagerly initialize classes if possible") \
\
+ diagnostic(bool, LogTouchedMethods, false, \
+ "Log methods which have been ever touched in runtime") \
+ \
+ diagnostic(bool, PrintTouchedMethodsAtExit, false, \
+ "Print all methods that have been ever touched in runtime") \
+ \
develop(bool, TraceMethodReplacement, false, \
"Print when methods are replaced do to recompilation") \
\
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index c72a5a766..5a628b73e 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -360,6 +360,10 @@ void print_statistics() {
SystemDictionary::print();
}
+ if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
+ Method::print_touched_methods(tty);
+ }
+
if (PrintBiasedLockingStatistics) {
BiasedLocking::print_counters();
}
@@ -408,6 +412,10 @@ void print_statistics() {
if (PrintNMTStatistics) {
MemTracker::final_report(tty);
}
+
+ if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
+ Method::print_touched_methods(tty);
+ }
}
#endif
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp
index a1c61f864..0b4a98cb7 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp
@@ -63,6 +63,7 @@ Monitor* StringDedupQueue_lock = NULL;
Mutex* StringDedupTable_lock = NULL;
Mutex* CodeCache_lock = NULL;
Mutex* MethodData_lock = NULL;
+Mutex* TouchedMethodLog_lock = NULL;
Mutex* RetData_lock = NULL;
Monitor* VMOperationQueue_lock = NULL;
Monitor* VMOperationRequest_lock = NULL;
@@ -282,6 +283,7 @@ void mutex_init() {
def(Compile_lock , Mutex , nonleaf+3, true );
def(MethodData_lock , Mutex , nonleaf+3, false);
+ def(TouchedMethodLog_lock , Mutex , nonleaf+3, false);
def(MethodCompileQueue_lock , Monitor, nonleaf+4, true );
def(Debug2_lock , Mutex , nonleaf+4, true );
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp
index f28058b0e..0d6de9ea0 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp
@@ -71,6 +71,7 @@ extern Monitor* StringDedupQueue_lock; // a lock on the string dedupli
extern Mutex* StringDedupTable_lock; // a lock on the string deduplication table
extern Mutex* CodeCache_lock; // a lock on the CodeCache, rank is special, use MutexLockerEx
extern Mutex* MethodData_lock; // a lock on installation of method data
+extern Mutex* TouchedMethodLog_lock; // a lock on allocation of LogExecutedMethods info
extern Mutex* RetData_lock; // a lock on installation of RetData inside method data
extern Mutex* DerivedPointerTableGC_lock; // a lock to protect the derived pointer table
extern Monitor* VMOperationQueue_lock; // a lock on queue of vm_operations waiting to execute
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
index 19463b137..f2071a9d6 100644
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
@@ -99,6 +99,7 @@
template(WhiteBoxOperation) \
template(ClassLoaderStatsOperation) \
template(ClassLoaderHierarchyOperation) \
+ template(DumpTouchedMethods) \
template(JFROldObject) \
template(PrintClasses) \
template(PrintMetadata) \
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
index e37ba3cc8..50050a169 100644
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
@@ -76,6 +76,7 @@ void DCmdRegistrant::register_dcmds(){
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompileQueueDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeListDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeCacheDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TouchedMethodsDCmd>(full_export, true, false));
#ifdef LINUX
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false));
#endif // LINUX
@@ -569,6 +570,38 @@ int ThreadDumpDCmd::num_arguments() {
}
}
+class VM_DumpTouchedMethods : public VM_Operation {
+private:
+ outputStream* _out;
+public:
+ VM_DumpTouchedMethods(outputStream* out) {
+ _out = out;
+ }
+
+ virtual VMOp_Type type() const { return VMOp_DumpTouchedMethods; }
+
+ virtual void doit() {
+ Method::print_touched_methods(_out);
+ }
+};
+
+TouchedMethodsDCmd::TouchedMethodsDCmd(outputStream* output, bool heap) :
+ DCmdWithParser(output, heap)
+{}
+
+void TouchedMethodsDCmd::execute(DCmdSource source, TRAPS) {
+ if (!UnlockDiagnosticVMOptions) {
+ output()->print_cr("VM.touched_methods command requires -XX:+UnlockDiagnosticVMOptions");
+ return;
+ }
+ VM_DumpTouchedMethods dumper(output());
+ VMThread::execute(&dumper);
+}
+
+int TouchedMethodsDCmd::num_arguments() {
+ return 0;
+}
+
// Enhanced JMX Agent support
JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated) :
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp
index 65c04571b..3733fa7f7 100644
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp
@@ -36,6 +36,7 @@
#include "services/diagnosticFramework.hpp"
#include "services/diagnosticCommand_ext.hpp"
#include "utilities/macros.hpp"
+#include "oops/method.hpp"
class HelpDCmd : public DCmdWithParser {
protected:
@@ -358,6 +359,22 @@ public:
virtual void execute(DCmdSource source, TRAPS);
};
+class TouchedMethodsDCmd : public DCmdWithParser {
+public:
+ TouchedMethodsDCmd(outputStream* output, bool heap);
+ static const char* name() {
+ return "VM.print_touched_methods";
+ }
+ static const char* description() {
+ return "Print all methods that have ever been touched during the lifetime of this JVM.";
+ }
+ static const char* impact() {
+ return "Medium: Depends on Java content.";
+ }
+ static int num_arguments();
+ virtual void execute(DCmdSource source, TRAPS);
+};
+
// See also: thread_dump in attachListener.cpp
class ThreadDumpDCmd : public DCmdWithParser {
protected:
diff --git a/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java b/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java
new file mode 100644
index 000000000..c85b2a5d8
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/PrintTouchedMethods.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8025692
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @library /testlibrary
+ * @compile TestLogTouchedMethods.java PrintTouchedMethods.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+LogTouchedMethods PrintTouchedMethods
+ */
+
+import java.io.File;
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+
+public class PrintTouchedMethods {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:-UnlockDiagnosticVMOptions",
+ "-XX:+LogTouchedMethods",
+ "-XX:+PrintTouchedMethodsAtExit",
+ "TestLogTouchedMethods");
+
+ // UnlockDiagnostic turned off, should fail
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Error: VM option 'LogTouchedMethods' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.");
+ output.shouldContain("Error: Could not create the Java Virtual Machine.");
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+LogTouchedMethods",
+ "-XX:+PrintTouchedMethodsAtExit",
+ "TestLogTouchedMethods");
+ output = new OutputAnalyzer(pb.start());
+ // check order:
+ // 1 "# Method::print_touched_methods version 1" is the first in first line
+ // 2 should contain TestLogMethods.methodA:()V
+ // 3 should not contain TestLogMethods.methodB:()V
+ // Repeat above for another run with -Xint
+ List<String> lines = output.asLines();
+
+ if (lines.size() < 1) {
+ throw new Exception("Empty output");
+ }
+
+ String first = lines.get(0);
+ if (!first.equals("# Method::print_touched_methods version 1")) {
+ throw new Exception("First line mismatch");
+ }
+
+ output.shouldContain("TestLogTouchedMethods.methodA:()V");
+ output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-Xint",
+ "-XX:+LogTouchedMethods",
+ "-XX:+PrintTouchedMethodsAtExit",
+ "TestLogTouchedMethods");
+ output = new OutputAnalyzer(pb.start());
+ lines = output.asLines();
+
+ if (lines.size() < 1) {
+ throw new Exception("Empty output");
+ }
+
+ first = lines.get(0);
+ if (!first.equals("# Method::print_touched_methods version 1")) {
+ throw new Exception("First line mismatch");
+ }
+
+ output.shouldContain("TestLogTouchedMethods.methodA:()V");
+ output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-Xint",
+ "-XX:+LogTouchedMethods",
+ "-XX:+PrintTouchedMethodsAtExit",
+ "-XX:-TieredCompilation",
+ "TestLogTouchedMethods");
+ output = new OutputAnalyzer(pb.start());
+ lines = output.asLines();
+
+ if (lines.size() < 1) {
+ throw new Exception("Empty output");
+ }
+
+ first = lines.get(0);
+ if (!first.equals("# Method::print_touched_methods version 1")) {
+ throw new Exception("First line mismatch");
+ }
+
+ output.shouldContain("TestLogTouchedMethods.methodA:()V");
+ output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
+ output.shouldHaveExitValue(0);
+
+ // Test jcmd PrintTouchedMethods VM.print_touched_methods
+ String pid = Long.toString(ProcessTools.getProcessId());
+ pb = new ProcessBuilder();
+ pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.print_touched_methods"});
+ output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("PrintTouchedMethods.main:([Ljava/lang/String;)V");
+ } catch (RuntimeException e) {
+ output.shouldContain("Unknown diagnostic command");
+ }
+ }
+}
\ No newline at end of file
diff --git a/hotspot/test/runtime/CommandLine/TestLogTouchedMethods.java b/hotspot/test/runtime/CommandLine/TestLogTouchedMethods.java
new file mode 100644
index 000000000..655d4a916
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/TestLogTouchedMethods.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* used by PrintTouchedMethods.java */
+public class TestLogTouchedMethods {
+ public static void main(String[] args) {
+ new TestLogTouchedMethods().methodA();
+ }
+
+ // methods without return values and local variables are optimized in interpreter mode
+ // it can not be recorded
+ // leave at least one local variable
+ public void methodA() { int a = 0; } // called
+ public void methodB() { int b = 0; } // this should not be called
+}
--
2.22.0

View File

@ -0,0 +1,22 @@
Date: Fri, 9 Jun 2023 12:20:25 +0800
Subject: fix jdk8 fastdebug hotspot/test/compiler/c2/TestSplitDivisionThroughPhi.java crash
---
hotspot/src/share/vm/opto/loopopts.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp
index 006b1a203..cacad2a1a 100644
--- a/hotspot/src/share/vm/opto/loopopts.cpp
+++ b/hotspot/src/share/vm/opto/loopopts.cpp
@@ -226,7 +226,6 @@ bool PhaseIdealLoop::cannot_split_division(const Node* n, const Node* region) co
return false;
}
- assert(n->in(0) == NULL, "divisions with zero check should already have bailed out earlier in split-if");
Node* divisor = n->in(2);
return is_divisor_counted_loop_phi(divisor, region) &&
loop_phi_backedge_type_contains_zero(divisor, zero);
--
2.22.0

View File

@ -0,0 +1,32 @@
Date: Fri, 9 Jun 2023 14:18:54 +0800
Subject: Modify G1GC log information
---
hotspot/src/share/vm/gc_implementation/g1/g1NUMA.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1NUMA.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1NUMA.cpp
index 05b4d8989..c937ebc54 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1NUMA.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1NUMA.cpp
@@ -281,13 +281,13 @@ G1NodeIndexCheckClosure::G1NodeIndexCheckClosure(const char* desc, G1NUMA* numa)
}
G1NodeIndexCheckClosure::~G1NodeIndexCheckClosure() {
- if (G1Log::finer()) {
- gclog_or_tty->print("%s: NUMA region verification (id: matched/mismatched/total): ", _desc);
+ if (UseNUMA && G1Log::finer()) {
+ gclog_or_tty->print(" [%s: NUMA region verification (id: matched/mismatched/total): ", _desc);
const int* numa_ids = _numa->node_ids();
for (uint i = 0; i < _numa->num_active_nodes(); i++) {
- gclog_or_tty->print("%d: %u/%u/%u ", numa_ids[i], _matched[i], _mismatched[i], _total[i]);
+ gclog_or_tty->print("%d: %u/%u/%u", numa_ids[i], _matched[i], _mismatched[i], _total[i]);
}
- gclog_or_tty->print_cr(" ");
+ gclog_or_tty->print("]");
}
FREE_C_HEAP_ARRAY(uint, _matched, mtGC);
FREE_C_HEAP_ARRAY(uint, _mismatched, mtGC);
--
2.22.0

View File

@ -0,0 +1,242 @@
Date: Fri, 9 Jun 2023 14:30:14 +0800
Subject: 8181644: C1 crashes with -XX:+PrintCFGToFile
Bug url: https://bugs.openjdk.org/browse/JDK-8181644
---
hotspot/src/share/vm/c1/c1_CFGPrinter.cpp | 83 +++++-----------------
hotspot/src/share/vm/c1/c1_CFGPrinter.hpp | 45 ++++++++++--
hotspot/src/share/vm/c1/c1_Compilation.cpp | 6 ++
hotspot/src/share/vm/c1/c1_Compilation.hpp | 6 ++
4 files changed, 71 insertions(+), 69 deletions(-)
diff --git a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
index c5b35d00c..63997caf4 100644
--- a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
+++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
@@ -32,86 +32,41 @@
#ifndef PRODUCT
-
-class CFGPrinterOutput : public CHeapObj<mtCompiler> {
- private:
- outputStream* _output;
-
- Compilation* _compilation;
- bool _do_print_HIR;
- bool _do_print_LIR;
-
- class PrintBlockClosure: public BlockClosure {
- void block_do(BlockBegin* block) { if (block != NULL) CFGPrinter::output()->print_block(block); }
- };
-
-
- outputStream* output() { assert(_output != NULL, ""); return _output; }
-
- void inc_indent();
- void dec_indent();
- void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
- void print_begin(const char* tag);
- void print_end(const char* tag);
-
- char* method_name(ciMethod* method, bool short_name = false);
-
- public:
- CFGPrinterOutput();
-
- void set_compilation(Compilation* compilation) { _compilation = compilation; }
- void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; }
-
- void print_compilation();
- void print_intervals(IntervalList* intervals, const char* name);
-
- void print_state(BlockBegin* block);
- void print_operand(Value instr);
- void print_HIR(Value instr);
- void print_HIR(BlockBegin* block);
- void print_LIR(BlockBegin* block);
- void print_block(BlockBegin* block);
- void print_cfg(BlockList* blocks, const char* name);
- void print_cfg(IR* blocks, const char* name);
-};
-
-CFGPrinterOutput* CFGPrinter::_output = NULL;
-
-
-
-
void CFGPrinter::print_compilation(Compilation* compilation) {
- if (_output == NULL) {
- _output = new CFGPrinterOutput();
- }
- output()->set_compilation(compilation);
- output()->print_compilation();
+ CFGPrinterOutput* output = compilation->cfg_printer_output();
+ output->print_compilation();
}
void CFGPrinter::print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
- output()->set_print_flags(do_print_HIR, do_print_LIR);
- output()->print_cfg(blocks, name);
+ CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
+ output->set_print_flags(do_print_HIR, do_print_LIR);
+ output->print_cfg(blocks, name);
}
void CFGPrinter::print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
- output()->set_print_flags(do_print_HIR, do_print_LIR);
- output()->print_cfg(blocks, name);
+ CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
+ output->set_print_flags(do_print_HIR, do_print_LIR);
+ output->print_cfg(blocks, name);
}
-
void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) {
- output()->print_intervals(intervals, name);
+ CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
+ output->print_intervals(intervals, name);
}
-
-
-CFGPrinterOutput::CFGPrinterOutput()
- : _output(new(ResourceObj::C_HEAP, mtCompiler) fileStream("output.cfg"))
+CFGPrinterOutput::CFGPrinterOutput(Compilation* compilation)
+ : _output(NULL),
+ _compilation(compilation),
+ _do_print_HIR(false),
+ _do_print_LIR(false)
{
+ char file_name[O_BUFLEN];
+ jio_snprintf(file_name, sizeof(file_name), "output_tid" UINTX_FORMAT "_pid%u.cfg",
+ os::current_thread_id(), os::current_process_id());
+ _output = new(ResourceObj::C_HEAP, mtCompiler) fileStream(file_name, "at");
}
-
void CFGPrinterOutput::inc_indent() {
output()->inc();
output()->inc();
diff --git a/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp b/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp
index 1cdde1186..60d18814d 100644
--- a/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp
+++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp
@@ -37,18 +37,53 @@ class CFGPrinterOutput;
class IntervalList;
class CFGPrinter : public AllStatic {
-private:
- static CFGPrinterOutput* _output;
public:
- static CFGPrinterOutput* output() { assert(_output != NULL, ""); return _output; }
-
-
static void print_compilation(Compilation* compilation);
static void print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR);
static void print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR);
static void print_intervals(IntervalList* intervals, const char* name);
};
+class CFGPrinterOutput : public CHeapObj<mtCompiler> {
+ private:
+ outputStream* _output;
+
+ Compilation* _compilation;
+ bool _do_print_HIR;
+ bool _do_print_LIR;
+
+ class PrintBlockClosure: public BlockClosure {
+ void block_do(BlockBegin* block) { if (block != NULL) Compilation::current()->cfg_printer_output()->print_block(block); }
+ };
+
+ outputStream* output() { assert(_output != NULL, ""); return _output; }
+
+ void inc_indent();
+ void dec_indent();
+ void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
+ void print_begin(const char* tag);
+ void print_end(const char* tag);
+
+ char* method_name(ciMethod* method, bool short_name = false);
+
+ public:
+ CFGPrinterOutput(Compilation* compilation);
+
+ void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; }
+
+ void print_compilation();
+ void print_intervals(IntervalList* intervals, const char* name);
+
+ void print_state(BlockBegin* block);
+ void print_operand(Value instr);
+ void print_HIR(Value instr);
+ void print_HIR(BlockBegin* block);
+ void print_LIR(BlockBegin* block);
+ void print_block(BlockBegin* block);
+ void print_cfg(BlockList* blocks, const char* name);
+ void print_cfg(IR* blocks, const char* name);
+};
+
#endif
#endif // SHARE_VM_C1_C1_CFGPRINTER_HPP
diff --git a/hotspot/src/share/vm/c1/c1_Compilation.cpp b/hotspot/src/share/vm/c1/c1_Compilation.cpp
index 6a0b709f1..82e67fc02 100644
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp
@@ -549,6 +549,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
, _interpreter_frame_size(0)
#ifndef PRODUCT
, _last_instruction_printed(NULL)
+, _cfg_printer_output(NULL)
#endif // PRODUCT
{
PhaseTraceTime timeit(_t_compile);
@@ -556,6 +557,11 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
_env->set_compiler_data(this);
_exception_info_list = new ExceptionInfoList();
_implicit_exception_table.set_size(0);
+#ifndef PRODUCT
+ if (PrintCFGToFile) {
+ _cfg_printer_output = new CFGPrinterOutput(this);
+ }
+#endif
compile_method();
if (bailed_out()) {
_env->record_method_not_compilable(bailout_msg(), !TieredCompilation);
diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp
index 8ff7f3e50..aa7bd18b5 100644
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp
@@ -50,6 +50,7 @@ class ValueStack;
class LIR_OprDesc;
class C1_MacroAssembler;
class CFGPrinter;
+class CFGPrinterOutput;
typedef LIR_OprDesc* LIR_Opr;
@@ -113,6 +114,7 @@ class Compilation: public StackObj {
Instruction* _current_instruction; // the instruction currently being processed
#ifndef PRODUCT
Instruction* _last_instruction_printed; // the last instruction printed during traversal
+ CFGPrinterOutput* _cfg_printer_output;
#endif // PRODUCT
public:
@@ -182,6 +184,10 @@ class Compilation: public StackObj {
#ifndef PRODUCT
void maybe_print_current_instruction();
+ CFGPrinterOutput* cfg_printer_output() {
+ guarantee(_cfg_printer_output != NULL, "CFG printer output not initialized");
+ return _cfg_printer_output;
+ }
#endif // PRODUCT
// error handling
--
2.22.0

View File

@ -0,0 +1,170 @@
Date: Fri, 9 Jun 2023 10:06:28 +0800
Subject: 8071962: The SA code needs to be updated to support
Symbol lookup from the shared archive Support shared symbols lookup.(include
patch 8151368 and patch 8150607)
---
.../hotspot/utilities/CompactHashTable.java | 151 ++++++++++++++++++
1 file changed, 151 insertions(+)
create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java
new file mode 100644
index 000000000..a0144f236
--- /dev/null
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.utilities;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class CompactHashTable extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ // C++ struct is not defined, so it's null.
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {}
+
+ // Fields
+ public static CIntegerField bucketCountField;
+ public static CIntegerField entryCountField;
+ public static AddressField baseAddressField;
+ public static AddressField bucketsField;
+ public static AddressField entriesField;
+ public static long uintSize;
+
+ private static int BUCKET_OFFSET_MASK = 0x3FFFFFFF;
+ private static int BUCKET_TYPE_SHIFT = 30;
+ private static int VALUE_ONLY_BUCKET_TYPE = 1;
+
+ public CompactHashTable(Address addr) {
+ super(addr);
+ }
+
+ private int bucketCount() {
+ return (int)bucketCountField.getValue(addr);
+ }
+
+ private boolean isValueOnlyBucket(int bucket_info) {
+ return (bucket_info >> BUCKET_TYPE_SHIFT) == VALUE_ONLY_BUCKET_TYPE;
+ }
+
+ private int bucketOffset(int bucket_info) {
+ return bucket_info & BUCKET_OFFSET_MASK;
+ }
+
+ public Symbol probe(byte[] name, long hash) {
+ if (bucketCount() <= 0) {
+ // This CompactHashTable is not in use
+ return null;
+ }
+
+ long symOffset;
+ Symbol sym;
+ Address baseAddress = baseAddressField.getValue(addr);
+ Address bucket = bucketsField.getValue(addr);
+ long index = hash % bucketCount();
+ int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true);
+ int bucketOffset = bucketOffset(bucketInfo);
+ int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true);
+ int nextBucketOffset = bucketOffset(nextBucketInfo);
+
+ Address entry = entriesField.getValue(addr).addOffsetTo(bucketOffset * uintSize);
+
+ if (isValueOnlyBucket(bucketInfo)) {
+ symOffset = entry.getCIntegerAt(0, uintSize, true);
+ sym = Symbol.create(baseAddress.addOffsetTo(symOffset));
+ if (sym.equals(name)) {
+ return sym;
+ }
+ } else {
+ Address entryMax = entriesField.getValue(addr).addOffsetTo(nextBucketOffset * uintSize);
+ while (entry.lessThan(entryMax)) {
+ long symHash = entry.getCIntegerAt(0, uintSize, true);
+ if (symHash == hash) {
+ symOffset = entry.getCIntegerAt(uintSize, uintSize, true);
+ Address symAddr = baseAddress.addOffsetTo(symOffset);
+ sym = Symbol.create(symAddr);
+ if (sym.equals(name)) {
+ return sym;
+ }
+ }
+ entry = entry.addOffsetTo(2 * uintSize);
+ }
+ }
+ return null;
+ }
+
+ public interface SymbolVisitor {
+ public void visit(Symbol sym);
+ }
+
+ public void symbolsDo(SymbolVisitor visitor) {
+ long symOffset;
+ Symbol sym;
+ Address baseAddress = baseAddressField.getValue(addr);
+ Address bucket = bucketsField.getValue(addr);
+ for (long index = 0; index < bucketCount(); index++) {
+ int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true);
+ int bucketOffset = bucketOffset(bucketInfo);
+ int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true);
+ int nextBucketOffset = bucketOffset(nextBucketInfo);
+
+ Address entry = entriesField.getValue(addr).addOffsetTo(bucketOffset * uintSize);
+
+ if (isValueOnlyBucket(bucketInfo)) {
+ symOffset = entry.getCIntegerAt(0, uintSize, true);
+ sym = Symbol.create(baseAddress.addOffsetTo(symOffset));
+ visitor.visit(sym);
+ } else {
+ Address entryMax = entriesField.getValue(addr).addOffsetTo(nextBucketOffset * uintSize);
+ while (entry.lessThan(entryMax)) {
+ symOffset = entry.getCIntegerAt(uintSize, uintSize, true);
+ Address symAddr = baseAddress.addOffsetTo(symOffset);
+ sym = Symbol.create(symAddr);
+ visitor.visit(sym);
+ entry = entry.addOffsetTo(2 * uintSize);
+ }
+ }
+ }
+ }
+}
+
+
--
2.22.0

View File

@ -0,0 +1,26 @@
Date: Fri, 9 Jun 2023 14:35:50 +0800
Subject: [PATCH 52/59] 8177959: G1CollectedHeap::print_on prints incorrect capacity
Bug url: https://bugs.openjdk.org/browse/JDK-8177959
---
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index ebd07c2d5..1ce641cae 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -3466,9 +3466,8 @@ void G1CollectedHeap::print_on(outputStream* st) const {
st->print(" %-20s", "garbage-first heap");
st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
capacity()/K, used_unlocked()/K);
- st->print(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
+ st->print(" [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(_hrm.reserved().start()),
- p2i(_hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords),
p2i(_hrm.reserved().end()));
st->cr();
st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
--
2.22.0

View File

@ -0,0 +1,490 @@
Date: Mon, 5 Jun 2023 20:28:58 +0800
Subject: [PATCH 53/59] 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
Bug url: https://bugs.openjdk.org/browse/JDK-8146987
---
.../parallelScavenge/parMarkBitMap.cpp | 48 ++++++++++++++-
.../parallelScavenge/parMarkBitMap.hpp | 10 +++-
.../parallelScavenge/psCompactionManager.cpp | 10 ++++
.../parallelScavenge/psCompactionManager.hpp | 21 +++++++
.../parallelScavenge/psParallelCompact.cpp | 60 ++++++++++---------
.../parallelScavenge/psParallelCompact.hpp | 31 ++++++----
hotspot/src/share/vm/oops/instanceKlass.cpp | 2 +-
.../src/share/vm/oops/instanceMirrorKlass.cpp | 2 +-
.../src/share/vm/oops/instanceRefKlass.cpp | 6 +-
hotspot/src/share/vm/oops/objArrayKlass.cpp | 2 +-
10 files changed, 146 insertions(+), 46 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
index 1dde10746..06e930ca7 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
+#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/os.hpp"
@@ -110,7 +111,18 @@ ParMarkBitMap::mark_obj(HeapWord* addr, size_t size)
return false;
}
-size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
+inline bool ParMarkBitMap::is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const {
+ return cm->last_query_begin() == beg_addr;
+}
+
+inline void ParMarkBitMap::update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj,
+ size_t result) const {
+ cm->set_last_query_begin(beg_addr);
+ cm->set_last_query_object(end_obj);
+ cm->set_last_query_return(result);
+}
+
+size_t ParMarkBitMap::live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const
{
assert(beg_addr <= (HeapWord*)end_obj, "bad range");
assert(is_marked(end_obj), "end_obj must be live");
@@ -131,6 +143,40 @@ size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
return bits_to_words(live_bits);
}
+size_t ParMarkBitMap::live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
+{
+ HeapWord* last_beg = cm->last_query_begin();
+ oop last_obj = cm->last_query_object();
+ size_t last_ret = cm->last_query_return();
+ if (end_obj > last_obj) {
+ last_ret = last_ret + live_words_in_range_helper((HeapWord*)last_obj, end_obj);
+ last_obj = end_obj;
+ } else if (end_obj < last_obj) {
+ // The cached value is for an object that is to the left (lower address) of the current
+ // end_obj. Calculate back from that cached value.
+ if (pointer_delta((HeapWord*)end_obj, (HeapWord*)beg_addr) > pointer_delta((HeapWord*)last_obj, (HeapWord*)end_obj)) {
+ last_ret = last_ret - live_words_in_range_helper((HeapWord*)end_obj, last_obj);
+ } else {
+ last_ret = live_words_in_range_helper(beg_addr, end_obj);
+ }
+ last_obj = end_obj;
+ }
+
+ update_live_words_in_range_cache(cm, last_beg, last_obj, last_ret);
+ return last_ret;
+}
+
+size_t ParMarkBitMap::live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
+{
+ // Try to reuse result from ParCompactionManager cache first.
+ if (is_live_words_in_range_in_cache(cm, beg_addr)) {
+ return live_words_in_range_use_cache(cm, beg_addr, end_obj);
+ }
+ size_t ret = live_words_in_range_helper(beg_addr, end_obj);
+ update_live_words_in_range_cache(cm, beg_addr, end_obj, ret);
+ return ret;
+}
+
ParMarkBitMap::IterationStatus
ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
idx_t range_beg, idx_t range_end) const
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
index 8d0153d48..2d8ad9dd7 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
@@ -31,6 +31,7 @@
class ParMarkBitMapClosure;
class PSVirtualSpace;
+class ParCompactionManager;
class ParMarkBitMap: public CHeapObj<mtGC>
{
@@ -124,7 +125,7 @@ public:
// the range are included in the result. The end of the range must be a live object,
// which is the case when updating pointers. This allows a branch to be removed
// from inside the loop.
- size_t live_words_in_range(HeapWord* beg_addr, oop end_obj) const;
+ size_t live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const;
inline HeapWord* region_start() const;
inline HeapWord* region_end() const;
@@ -167,6 +168,13 @@ public:
#endif // #ifdef ASSERT
private:
+
+ size_t live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const;
+
+ inline bool is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const;
+ size_t live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const;
+ inline void update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj, size_t result) const;
+
// Each bit in the bitmap represents one unit of 'object granularity.' Objects
// are double-word aligned in 32-bit VMs, but not in 64-bit VMs, so the 32-bit
// granularity is 2, 64-bit is 1.
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
index 415d62947..e38997bc6 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
@@ -65,6 +65,8 @@ ParCompactionManager::ParCompactionManager() :
marking_stack()->initialize();
_objarray_stack.initialize();
+
+ reset_bitmap_query_cache();
}
ParCompactionManager::~ParCompactionManager() {
@@ -121,6 +123,14 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) {
"Not initialized?");
}
+void ParCompactionManager::reset_all_bitmap_query_caches() {
+ uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers();
+ for (uint i=0; i<=parallel_gc_threads; i++) {
+ _manager_array[i]->reset_bitmap_query_cache();
+ }
+}
+
+
int ParCompactionManager::pop_recycled_stack_index() {
assert(_recycled_bottom <= _recycled_top, "list is empty");
// Get the next available index
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
index a16a16762..9b1c4f9a0 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
@@ -114,6 +114,10 @@ private:
Action _action;
+ HeapWord* _last_query_beg;
+ oop _last_query_obj;
+ size_t _last_query_ret;
+
static PSOldGen* old_gen() { return _old_gen; }
static ObjectStartArray* start_array() { return _start_array; }
static OopTaskQueueSet* stack_array() { return _stack_array; }
@@ -132,9 +136,26 @@ private:
// marking stack and overflow stack directly.
public:
+ void reset_bitmap_query_cache() {
+ _last_query_beg = NULL;
+ _last_query_obj = NULL;
+ _last_query_ret = 0;
+ }
+
Action action() { return _action; }
void set_action(Action v) { _action = v; }
+ // Bitmap query support, cache last query and result
+ HeapWord* last_query_begin() { return _last_query_beg; }
+ oop last_query_object() { return _last_query_obj; }
+ size_t last_query_return() { return _last_query_ret; }
+
+ void set_last_query_begin(HeapWord *new_beg) { _last_query_beg = new_beg; }
+ void set_last_query_object(oop new_obj) { _last_query_obj = new_obj; }
+ void set_last_query_return(size_t new_ret) { _last_query_ret = new_ret; }
+
+ static void reset_all_bitmap_query_caches();
+
RegionTaskQueue* region_stack() { return _region_stack; }
void set_region_stack(RegionTaskQueue* v) { _region_stack = v; }
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index 26d64a135..2c75c4d68 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -748,7 +748,7 @@ bool ParallelCompactData::summarize(SplitInfo& split_info,
return true;
}
-HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
+HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionManager* cm) {
assert(addr != NULL, "Should detect NULL oop earlier");
assert(PSParallelCompact::gc_heap()->is_in(addr), "not in heap");
assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");
@@ -785,7 +785,7 @@ HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
const size_t block_offset = addr_to_block_ptr(addr)->offset();
const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
- const size_t live = bitmap->live_words_in_range(search_start, oop(addr));
+ const size_t live = bitmap->live_words_in_range(cm, search_start, oop(addr));
result += block_offset + live;
DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result));
return result;
@@ -825,11 +825,8 @@ bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap(
void PSParallelCompact::KeepAliveClosure::do_oop(oop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); }
void PSParallelCompact::KeepAliveClosure::do_oop(narrowOop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); }
-PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure;
-PSParallelCompact::AdjustKlassClosure PSParallelCompact::_adjust_klass_closure;
-
-void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p); }
-void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p); }
+void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _cm); }
+void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _cm); }
void PSParallelCompact::FollowStackClosure::do_void() { _compaction_manager->follow_marking_stacks(); }
@@ -842,7 +839,8 @@ void PSParallelCompact::FollowKlassClosure::do_klass(Klass* klass) {
klass->oops_do(_mark_and_push_closure);
}
void PSParallelCompact::AdjustKlassClosure::do_klass(Klass* klass) {
- klass->oops_do(&PSParallelCompact::_adjust_pointer_closure);
+ PSParallelCompact::AdjustPointerClosure closure(_cm);
+ klass->oops_do(&closure);
}
void PSParallelCompact::post_initialize() {
@@ -1021,6 +1019,8 @@ void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
// Have worker threads release resources the next time they run a task.
gc_task_manager()->release_all_resources();
+
+ ParCompactionManager::reset_all_bitmap_query_caches();
}
void PSParallelCompact::post_compact()
@@ -2093,7 +2093,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
// adjust_roots() updates Universe::_intArrayKlassObj which is
// needed by the compaction for filling holes in the dense prefix.
- adjust_roots();
+ adjust_roots(vmthread_cm);
compaction_start.update();
compact();
@@ -2450,40 +2450,46 @@ void PSParallelCompact::follow_class_loader(ParCompactionManager* cm,
cld->oops_do(&mark_and_push_closure, &follow_klass_closure, true);
}
-void PSParallelCompact::adjust_roots() {
+void PSParallelCompact::adjust_roots(ParCompactionManager* cm) {
// Adjust the pointers to reflect the new locations
GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
// Need new claim bits when tracing through and adjusting pointers.
ClassLoaderDataGraph::clear_claimed_marks();
+ PSParallelCompact::AdjustPointerClosure oop_closure(cm);
+ PSParallelCompact::AdjustKlassClosure klass_closure(cm);
+
// General strong roots.
- Universe::oops_do(adjust_pointer_closure());
- JNIHandles::oops_do(adjust_pointer_closure()); // Global (strong) JNI handles
- CLDToOopClosure adjust_from_cld(adjust_pointer_closure());
- Threads::oops_do(adjust_pointer_closure(), &adjust_from_cld, NULL);
- ObjectSynchronizer::oops_do(adjust_pointer_closure());
- FlatProfiler::oops_do(adjust_pointer_closure());
- Management::oops_do(adjust_pointer_closure());
- JvmtiExport::oops_do(adjust_pointer_closure());
- SystemDictionary::oops_do(adjust_pointer_closure());
- ClassLoaderDataGraph::oops_do(adjust_pointer_closure(), adjust_klass_closure(), true);
+ Universe::oops_do(&oop_closure);
+ JNIHandles::oops_do(&oop_closure); // Global (strong) JNI handles
+ CLDToOopClosure adjust_from_cld(&oop_closure);
+ Threads::oops_do(&oop_closure, &adjust_from_cld, NULL);
+ ObjectSynchronizer::oops_do(&oop_closure);
+ FlatProfiler::oops_do(&oop_closure);
+ Management::oops_do(&oop_closure);
+ JvmtiExport::oops_do(&oop_closure);
+ SystemDictionary::oops_do(&oop_closure);
+ ClassLoaderDataGraph::oops_do(&oop_closure, &klass_closure, true);
+
// Now adjust pointers in remaining weak roots. (All of which should
// have been cleared if they pointed to non-surviving objects.)
// Global (weak) JNI handles
- JNIHandles::weak_oops_do(adjust_pointer_closure());
- JFR_ONLY(Jfr::weak_oops_do(adjust_pointer_closure()));
+ JNIHandles::weak_oops_do(&oop_closure);
+ // adjust weak pointers in jfr oops. for TestJcmdDump.java
+ JFR_ONLY(Jfr::weak_oops_do(&oop_closure));
- CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
+ CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&adjust_from_blobs);
- StringTable::oops_do(adjust_pointer_closure());
- ref_processor()->weak_oops_do(adjust_pointer_closure());
+ StringTable::oops_do(&oop_closure);
+ ref_processor()->weak_oops_do(&oop_closure);
+
// Roots were visited so references into the young gen in roots
// may have been scanned. Process them also.
// Should the reference processor have a span that excludes
// young gen objects?
- PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
+ PSScavenge::reference_processor()->weak_oops_do(&oop_closure);
}
void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
@@ -3342,7 +3348,7 @@ MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) {
assert(bitmap()->obj_size(addr) == words, "bad size");
_source = addr;
- assert(PSParallelCompact::summary_data().calc_new_pointer(source()) ==
+ assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager()) ==
destination(), "wrong destination");
if (words > words_remaining()) {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
index f971383a0..efec18746 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
@@ -452,10 +452,10 @@ public:
HeapWord* partial_obj_end(size_t region_idx) const;
// Return the location of the object after compaction.
- HeapWord* calc_new_pointer(HeapWord* addr);
+ HeapWord* calc_new_pointer(HeapWord* addr, ParCompactionManager* cm);
- HeapWord* calc_new_pointer(oop p) {
- return calc_new_pointer((HeapWord*) p);
+ HeapWord* calc_new_pointer(oop p, ParCompactionManager* cm) {
+ return calc_new_pointer((HeapWord*) p, cm);
}
#ifdef ASSERT
@@ -957,15 +957,28 @@ class PSParallelCompact : AllStatic {
class AdjustPointerClosure: public OopClosure {
public:
+ AdjustPointerClosure(ParCompactionManager* cm) {
+ assert(cm != NULL, "associate ParCompactionManage should not be NULL");
+ _cm = cm;
+ }
+
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
// do not walk from thread stacks to the code cache on this phase
virtual void do_code_blob(CodeBlob* cb) const { }
+ private:
+ ParCompactionManager* _cm;
};
class AdjustKlassClosure : public KlassClosure {
public:
+ AdjustKlassClosure(ParCompactionManager* cm) {
+ assert(cm != NULL, "associate ParCompactionManage should not be NULL");
+ _cm = cm;
+ }
void do_klass(Klass* klass);
+ private:
+ ParCompactionManager* _cm;
};
friend class KeepAliveClosure;
@@ -989,8 +1002,6 @@ class PSParallelCompact : AllStatic {
static IsAliveClosure _is_alive_closure;
static SpaceInfo _space_info[last_space_id];
static bool _print_phases;
- static AdjustPointerClosure _adjust_pointer_closure;
- static AdjustKlassClosure _adjust_klass_closure;
// Reference processing (used in ...follow_contents)
static ReferenceProcessor* _ref_processor;
@@ -1114,7 +1125,7 @@ class PSParallelCompact : AllStatic {
static void summary_phase(ParCompactionManager* cm, bool maximum_compaction);
// Adjust addresses in roots. Does not adjust addresses in heap.
- static void adjust_roots();
+ static void adjust_roots(ParCompactionManager* cm);
DEBUG_ONLY(static void write_block_fill_histogram(outputStream* const out);)
@@ -1184,8 +1195,6 @@ class PSParallelCompact : AllStatic {
static bool initialize();
// Closure accessors
- static OopClosure* adjust_pointer_closure() { return (OopClosure*)&_adjust_pointer_closure; }
- static KlassClosure* adjust_klass_closure() { return (KlassClosure*)&_adjust_klass_closure; }
static BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&_is_alive_closure; }
// Public accessors
@@ -1205,7 +1214,7 @@ class PSParallelCompact : AllStatic {
// Check mark and maybe push on marking stack
template <class T> static inline void mark_and_push(ParCompactionManager* cm,
T* p);
- template <class T> static inline void adjust_pointer(T* p);
+ template <class T> static inline void adjust_pointer(T* p, ParCompactionManager* cm);
static inline void follow_klass(ParCompactionManager* cm, Klass* klass);
@@ -1368,11 +1377,11 @@ inline void PSParallelCompact::mark_and_push(ParCompactionManager* cm, T* p) {
}
template <class T>
-inline void PSParallelCompact::adjust_pointer(T* p) {
+inline void PSParallelCompact::adjust_pointer(T* p, ParCompactionManager* cm) {
T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
- oop new_obj = (oop)summary_data().calc_new_pointer(obj);
+ oop new_obj = (oop)summary_data().calc_new_pointer(obj, cm);
assert(new_obj != NULL, // is forwarding ptr?
"should be forwarded");
// Just always do the update unconditionally?
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 538645bbe..ad9eb8b01 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -2544,7 +2544,7 @@ int InstanceKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
int size = size_helper();
InstanceKlass_OOP_MAP_ITERATE( \
obj, \
- PSParallelCompact::adjust_pointer(p), \
+ PSParallelCompact::adjust_pointer(p, cm), \
assert_is_in)
return size;
}
diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
index fdf2e42af..ee911d190 100644
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
@@ -345,7 +345,7 @@ int InstanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj)
InstanceMirrorKlass_OOP_ITERATE( \
start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
- PSParallelCompact::adjust_pointer(p), \
+ PSParallelCompact::adjust_pointer(p, cm), \
assert_nothing)
return size;
}
diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.cpp b/hotspot/src/share/vm/oops/instanceRefKlass.cpp
index 2c3fe7496..eb6c12edd 100644
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp
@@ -429,11 +429,11 @@ template <class T>
void specialized_oop_update_pointers(InstanceRefKlass *ref,
ParCompactionManager* cm, oop obj) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
- PSParallelCompact::adjust_pointer(referent_addr);
+ PSParallelCompact::adjust_pointer(referent_addr, cm);
T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
- PSParallelCompact::adjust_pointer(next_addr);
+ PSParallelCompact::adjust_pointer(next_addr, cm);
T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
- PSParallelCompact::adjust_pointer(discovered_addr);
+ PSParallelCompact::adjust_pointer(discovered_addr, cm);
debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
referent_addr, next_addr, discovered_addr);)
}
diff --git a/hotspot/src/share/vm/oops/objArrayKlass.cpp b/hotspot/src/share/vm/oops/objArrayKlass.cpp
index 60d173e9e..c69abdc06 100644
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp
@@ -590,7 +590,7 @@ int ObjArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
assert (obj->is_objArray(), "obj must be obj array");
objArrayOop a = objArrayOop(obj);
int size = a->object_size();
- ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p))
+ ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p, cm))
return size;
}
#endif // INCLUDE_ALL_GCS
--
2.22.0

View File

@ -0,0 +1,222 @@
Date: Thu, 8 Jun 2023 19:52:36 +0800
Subject: [PATCH 55/59] Fix jmap heapdump symbols when the class is loaded from dynamicCDS' jsa
---
.../sun/jvm/hotspot/memory/SymbolTable.java | 16 +++++++-
.../utilities/OffsetCompactHashTable.java | 39 +++++++++++++++++++
.../src/share/vm/classfile/symbolTable.cpp | 16 ++------
.../src/share/vm/classfile/symbolTable.hpp | 15 +++++++
hotspot/src/share/vm/runtime/vmStructs.cpp | 16 +++++++-
5 files changed, 86 insertions(+), 16 deletions(-)
create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java
index 7510d08bf..015415fab 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java
@@ -44,15 +44,21 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("SymbolTable");
theTableField = type.getAddressField("_the_table");
+ dynamicSharedTableField = type.getAddressField("_dynamic_shared_table");
}
// Fields
private static AddressField theTableField;
+ private static AddressField dynamicSharedTableField;
+ private OffsetCompactHashTable dynamicSharedTable;
// Accessors
public static SymbolTable getTheTable() {
Address tmp = theTableField.getValue();
- return (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
+ SymbolTable table = (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
+ Address dynamicShared = dynamicSharedTableField.getStaticFieldAddress();
+ table.dynamicSharedTable = (OffsetCompactHashTable)VMObjectFactory.newObject(OffsetCompactHashTable.class, dynamicShared);
+ return table;
}
public SymbolTable(Address addr) {
@@ -77,14 +83,20 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
table. */
public Symbol probe(byte[] name) {
long hashValue = hashSymbol(name);
+
+ Symbol sym = null;
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
if (e.hash() == hashValue) {
- Symbol sym = Symbol.create(e.literalValue());
+ sym = Symbol.create(e.literalValue());
if (sym.equals(name)) {
return sym;
}
}
}
+ if(sym == null && dynamicSharedTable != null) {
+ sym = dynamicSharedTable.probe(name, hashValue);
+ return sym;
+ }
return null;
}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java
new file mode 100644
index 000000000..42c72d0c3
--- /dev/null
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/OffsetCompactHashTable.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved.
+ */
+
+package sun.jvm.hotspot.utilities;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class OffsetCompactHashTable extends CompactHashTable {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("SymbolOffsetCompactHashtable");
+ baseAddressField = type.getAddressField("_base_address");
+ bucketCountField = type.getCIntegerField("_bucket_count");
+ entryCountField = type.getCIntegerField("_entry_count");
+ bucketsField = type.getAddressField("_buckets");
+ entriesField = type.getAddressField("_entries");
+ uintSize = db.lookupType("u4").getSize();
+ }
+
+ public OffsetCompactHashTable(Address addr) {
+ super(addr);
+ }
+
+}
+
+
diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp
index 6a2d8077f..06da1e40e 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp
@@ -44,18 +44,10 @@
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-inline bool symbol_equals_compact_hashtable_entry(Symbol* value, const char* key, int len) {
- if (value->equals(key, len)) {
- return true;
- } else {
- return false;
- }
-}
-
-static OffsetCompactHashtable<
+OffsetCompactHashtable<
const char*, Symbol*,
symbol_equals_compact_hashtable_entry
-> _dynamic_shared_table;
+> SymbolTable::_dynamic_shared_table;
// --------------------------------------------------------------------------
@@ -254,7 +246,6 @@ Symbol* SymbolTable::lookup_shared(const char* name,
// always uses the same original hash code.
hash = java_lang_String::hash_code((const jbyte*)name, len);
}
-
sym = _dynamic_shared_table.lookup(name, hash, len);
}
return sym;
diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp
index 96eb173d1..f861e161f 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp
@@ -75,11 +75,25 @@ class TempNewSymbol : public StackObj {
operator Symbol*() { return _temp; }
};
+inline bool symbol_equals_compact_hashtable_entry(Symbol* value, const char* key, int len) {
+ if (value->equals(key, len)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
class SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> {
friend class VMStructs;
friend class ClassFileParser;
private:
+ // The dynamic shared table
+ static OffsetCompactHashtable<
+ const char*, Symbol*,
+ symbol_equals_compact_hashtable_entry
+ > _dynamic_shared_table;
+
// The symbol table
static SymbolTable* _the_table;
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index 5d1cf2b8e..744c43e02 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/symbolTable.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/loaderConstraints.hpp"
@@ -252,6 +253,8 @@ typedef Hashtable<Klass*, mtClass> KlassHashtable;
typedef HashtableEntry<Klass*, mtClass> KlassHashtableEntry;
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
+typedef OffsetCompactHashtable<const char*, Symbol*, symbol_equals_compact_hashtable_entry> SymbolOffsetCompactHashtable;
+
//--------------------------------------------------------------------------------
// VM_STRUCTS
//
@@ -628,9 +631,19 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
/***************/ \
/* SymbolTable */ \
/***************/ \
- \
+ static_field(SymbolTable, _dynamic_shared_table, SymbolOffsetCompactHashtable) \
static_field(SymbolTable, _the_table, SymbolTable*) \
\
+ /********************************/ \
+ /* SymbolOffsetCompactHashtable */ \
+ /********************************/ \
+ \
+ nonstatic_field(SymbolOffsetCompactHashtable, _base_address, address) \
+ nonstatic_field(SymbolOffsetCompactHashtable, _entry_count, u4) \
+ nonstatic_field(SymbolOffsetCompactHashtable, _bucket_count, u4) \
+ nonstatic_field(SymbolOffsetCompactHashtable, _buckets, u4*) \
+ nonstatic_field(SymbolOffsetCompactHashtable, _entries, u4*) \
+ \
/***************/ \
/* StringTable */ \
/***************/ \
@@ -1574,6 +1587,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
declare_type(KlassTwoOopHashtable, KlassHashtable) \
declare_type(Dictionary, KlassTwoOopHashtable) \
declare_type(PlaceholderTable, SymbolTwoOopHashtable) \
+ declare_toplevel_type(SymbolOffsetCompactHashtable) \
declare_toplevel_type(BasicHashtableEntry<mtInternal>) \
declare_type(IntptrHashtableEntry, BasicHashtableEntry<mtInternal>) \
declare_type(DictionaryEntry, KlassHashtableEntry) \
--
2.22.0

View File

@ -0,0 +1,35 @@
Date: Tue, 13 Jun 2023 12:19:03 +0800
Subject: [PATCH 58/59] Fix CodelistTest.java Failed to Execute CodelistTest.java Using -Xcomp
---
hotspot/src/share/vm/code/codeCache.cpp | 4 +--
1 file changed, 2 insertion(+), 3 deletions(-)
diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp
index 8df29d608..37f24b5e9 100644
--- a/hotspot/src/share/vm/code/codeCache.cpp
+++ b/hotspot/src/share/vm/code/codeCache.cpp
@@ -263,7 +263,6 @@ void CodeCache::flush() {
#define FOR_ALL_BLOBS(var) for (CodeBlob *var = first() ; var != NULL; var = next(var) )
#define FOR_ALL_ALIVE_BLOBS(var) for (CodeBlob *var = alive(first()); var != NULL; var = alive(next(var)))
#define FOR_ALL_ALIVE_NMETHODS(var) for (nmethod *var = alive_nmethod(first()); var != NULL; var = alive_nmethod(next(var)))
-#define FOR_ALL_NMETHODS(var) for (nmethod *var = first_nmethod(); var != NULL; var = next_nmethod(var))
bool CodeCache::contains(void *p) {
@@ -1011,10 +1010,10 @@ void CodeCache::print_summary(outputStream* st, bool detailed) {
void CodeCache::print_codelist(outputStream* st) {
assert_locked_or_safepoint(CodeCache_lock);
- FOR_ALL_NMETHODS(p) {
+ FOR_ALL_ALIVE_NMETHODS(p) {
ResourceMark rm;
char *method_name = p->method()->name_and_sig_as_C_string();
- st->print_cr("%d %d %s ["INTPTR_FORMAT", "INTPTR_FORMAT" - "INTPTR_FORMAT"]",
+ st->print_cr("%d %d %s [" INTPTR_FORMAT ", " INTPTR_FORMAT " - " INTPTR_FORMAT "]",
p->compile_id(), p->comp_level(), method_name, (intptr_t)p->header_begin(),
(intptr_t)p->code_begin(), (intptr_t)p->code_end());
}
--
2.22.0

View File

@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r
Name: java-%{javaver}-%{origin}
Version: %{javaver}.%{updatever}.%{buildver}
Release: 1
Release: 2
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
@ -1187,6 +1187,59 @@ Patch304: jcmd-mnt-add-start-time-and-end-time.patch
Patch305: Fix-localtime_r-not-defined-on-windows.patch
Patch306: 8057743-process-Synchronize-exiting-of-threads-and-p.patch
Patch307: 8305541-C2-Div-Mod-nodes-without-zero-check-could-be.patch
Patch308: 0002-8179498-attach-in-linux-should-be-relative-to-proc-p.patch
Patch309: 0003-8187408-AbstractQueuedSynchronizer-wait-queue-corrup.patch
Patch310: 0004-8193710-jcmd-l-and-jps-commands-do-not-list-Java-pro.patch
Patch311: 0005-8196743-jstatd-doesn-t-see-new-Java-processes-inside.patch
Patch312: 0006-8284330-jcmd-may-not-be-able-to-find-processes-in-th.patch
Patch313: 0007-8241670-Enhance-heap-region-size-ergonomics-to-impro.patch
Patch314: 0008-8223162-Improve-ergonomics-for-Sparse-PRT-entry-sizi.patch
Patch315: 0009-8262316-Reducing-locks-in-RSA-Blinding.patch
Patch316: 0010-8283994-Make-Xerces-DatatypeException-stackless.patch
Patch317: 0011-Optimizing-ObjectInputStream-by-FreqInlineSize.patch
Patch318: 0012-8301187-Memory-leaks-in-OopMapCache.patch
Patch319: 0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch
Patch320: 0014-8280511-AArch64-Combine-shift-and-negate-to-a-single.patch
Patch321: 0015-6605915-jinfo-flag-flag-name-functionality-doesn-t-w.patch
Patch322: 0016-8036599-Use-Diagnostic-Commands-instead-of-SA-by-def.patch
Patch323: 0017-8054889-Compiler-team-s-implementation-task.patch
Patch324: 0018-8130832-Extend-the-WhiteBox-API-to-provide-informati.patch
Patch325: 0019-8040213-C2-does-not-put-all-modified-nodes-on-IGVN-w.patch
Patch326: 0020-8251216-Implement-MD5-Intrinsics-on-aarch64.patch
Patch327: 0021-fastdebug-fix-TestMD5Intrinsics.java-and-TestMD5Mult.patch
Patch328: 0022-8198510-Enable-UseDynamicNumberOfGCThreads-by-defaul.patch
Patch329: 0023-8180421-Change-default-value-of-BiasedLockingStartup.patch
Patch330: 0024-Fix-the-trim-crash-caused-by-incorrect-assert-in-fas.patch
Patch331: 0025-8220166-Performance-regression-in-deserialization.patch
Patch332: 0026-8072070-Improve-interpreter-stack-banging.patch
Patch333: 0027-8193386-CompressedClassSize-too-large-with-MaxMetasp.patch
Patch334: 0028-Display-more-information-about-the-codedump-file-pat.patch
Patch335: 0029-8211845-A-new-switch-to-control-verbosity-of-hs-err-.patch
Patch336: 0030-add-more-specific-possible-reasons-in-hs_error-log-w.patch
Patch337: 0031-8187653-Lock-in-CoderResult.Cache-becomes-performanc.patch
Patch338: 0032-8299158-Improve-MD5-intrinsic-on-AArch64.patch
Patch339: 0033-8211326-add-OS-user-related-information-to-hs_err-fi.patch
Patch340: 0034-8250902-Implement-MD5-Intrinsics-on-x64.patch
Patch341: 0035-8210821-Support-dns_canonicalize_hostname-in-krb5.co.patch
Patch342: 0036-8297656-AArch64-Enable-AES-GCM-Intrinsics.patch
Patch343: 0038-Record-file-descriptor-when-ExtensiveErrorReports-is.patch
Patch344: 0039-8243389-enhance-os-pd_print_cpu_info-on-linux.patch
Patch345: 0040-Print-the-Exception-event-in-more-detail.patch
Patch346: 0041-Reuse-translet-in-XSLTC-for-specjvm-xml-transform.patch
Patch347: 0042-8140581-Excluding-compile-messages-should-only-be-pr.patch
Patch348: 0043-Cache-dom-in-xml-transform.patch
Patch349: 0044-Record-file-descriptor-when-ExtensiveErrorReports-is.patch
Patch350: 0045-8276904-Optional.toString-is-unnecessarily-expensive.patch
Patch351: 0046-8210960-Allow-with-boot-jdk-jvmargs-to-work-during-c.patch
Patch352: 0047-8025692-Log-what-methods-are-touched-at-run-time.patch
Patch353: 0048-fix-jdk8-fastdebug-hotspot-test-compiler-c2-TestSpli.patch
Patch354: 0049-Modify-G1GC-log-information.patch
Patch355: 0050-8181644-C1-crashes-with-XX-PrintCFGToFile.patch
Patch356: 0051-8071962-The-SA-code-needs-to-be-updated-to-support-S.patch
Patch357: 0052-8177959-G1CollectedHeap-print_on-prints-incorrect-ca.patch
Patch358: 0053-8146987-Improve-Parallel-GC-Full-GC-by-caching-resul.patch
Patch359: 0054-Fix-jmap-heapdump-symbols-when-the-class-is-loaded-f.patch
Patch360: 0055-Fix-CodelistTest.java-Failed-to-Execute-CodelistTest.patch
#############################################
#
@ -1710,6 +1763,59 @@ pushd %{top_level_dir_name}
%patch305 -p1
%patch306 -p1
%patch307 -p1
%patch308 -p1
%patch309 -p1
%patch310 -p1
%patch311 -p1
%patch312 -p1
%patch313 -p1
%patch314 -p1
%patch315 -p1
%patch316 -p1
%patch317 -p1
%patch318 -p1
%patch319 -p1
%patch320 -p1
%patch321 -p1
%patch322 -p1
%patch323 -p1
%patch324 -p1
%patch325 -p1
%patch326 -p1
%patch327 -p1
%patch328 -p1
%patch329 -p1
%patch330 -p1
%patch331 -p1
%patch332 -p1
%patch333 -p1
%patch334 -p1
%patch335 -p1
%patch336 -p1
%patch337 -p1
%patch338 -p1
%patch339 -p1
%patch340 -p1
%patch341 -p1
%patch342 -p1
%patch343 -p1
%patch344 -p1
%patch345 -p1
%patch346 -p1
%patch347 -p1
%patch348 -p1
%patch349 -p1
%patch350 -p1
%patch351 -p1
%patch352 -p1
%patch353 -p1
%patch354 -p1
%patch355 -p1
%patch356 -p1
%patch357 -p1
%patch358 -p1
%patch359 -p1
%patch360 -p1
popd
# System library fixes
@ -2334,6 +2440,61 @@ cjc.mainProgram(arg)
%endif
%changelog
* Thu Jun 29 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.372-b07.2
- 0002-8179498-attach-in-linux-should-be-relative-to-proc-p.patch
- 0003-8187408-AbstractQueuedSynchronizer-wait-queue-corrup.patch
- 0004-8193710-jcmd-l-and-jps-commands-do-not-list-Java-pro.patch
- 0005-8196743-jstatd-doesn-t-see-new-Java-processes-inside.patch
- 0006-8284330-jcmd-may-not-be-able-to-find-processes-in-th.patch
- 0007-8241670-Enhance-heap-region-size-ergonomics-to-impro.patch
- 0008-8223162-Improve-ergonomics-for-Sparse-PRT-entry-sizi.patch
- 0009-8262316-Reducing-locks-in-RSA-Blinding.patch
- 0010-8283994-Make-Xerces-DatatypeException-stackless.patch
- 0011-Optimizing-ObjectInputStream-by-FreqInlineSize.patch
- 0012-8301187-Memory-leaks-in-OopMapCache.patch
- 0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch
- 0014-8280511-AArch64-Combine-shift-and-negate-to-a-single.patch
- 0015-6605915-jinfo-flag-flag-name-functionality-doesn-t-w.patch
- 0016-8036599-Use-Diagnostic-Commands-instead-of-SA-by-def.patch
- 0017-8054889-Compiler-team-s-implementation-task.patch
- 0018-8130832-Extend-the-WhiteBox-API-to-provide-informati.patch
- 0019-8040213-C2-does-not-put-all-modified-nodes-on-IGVN-w.patch
- 0020-8251216-Implement-MD5-Intrinsics-on-aarch64.patch
- 0021-fastdebug-fix-TestMD5Intrinsics.java-and-TestMD5Mult.patch
- 0022-8198510-Enable-UseDynamicNumberOfGCThreads-by-defaul.patch
- 0023-8180421-Change-default-value-of-BiasedLockingStartup.patch
- 0024-Fix-the-trim-crash-caused-by-incorrect-assert-in-fas.patch
- 0025-8220166-Performance-regression-in-deserialization.patch
- 0026-8072070-Improve-interpreter-stack-banging.patch
- 0027-8193386-CompressedClassSize-too-large-with-MaxMetasp.patch
- 0028-Display-more-information-about-the-codedump-file-pat.patch
- 0029-8211845-A-new-switch-to-control-verbosity-of-hs-err-.patch
- 0030-add-more-specific-possible-reasons-in-hs_error-log-w.patch
- 0031-8187653-Lock-in-CoderResult.Cache-becomes-performanc.patch
- 0032-8299158-Improve-MD5-intrinsic-on-AArch64.patch
- 0033-8211326-add-OS-user-related-information-to-hs_err-fi.patch
- 0034-8250902-Implement-MD5-Intrinsics-on-x64.patch
- 0035-8210821-Support-dns_canonicalize_hostname-in-krb5.co.patch
- 0036-8297656-AArch64-Enable-AES-GCM-Intrinsics.patch
- 0038-Record-file-descriptor-when-ExtensiveErrorReports-is.patch
- 0039-8243389-enhance-os-pd_print_cpu_info-on-linux.patch
- 0040-Print-the-Exception-event-in-more-detail.patch
- 0041-Reuse-translet-in-XSLTC-for-specjvm-xml-transform.patch
- 0042-8140581-Excluding-compile-messages-should-only-be-pr.patch
- 0043-Cache-dom-in-xml-transform.patch
- 0044-Record-file-descriptor-when-ExtensiveErrorReports-is.patch
- 0045-8276904-Optional.toString-is-unnecessarily-expensive.patch
- 0046-8210960-Allow-with-boot-jdk-jvmargs-to-work-during-c.patch
- 0047-8025692-Log-what-methods-are-touched-at-run-time.patch
- 0048-fix-jdk8-fastdebug-hotspot-test-compiler-c2-TestSpli.patch
- 0049-Modify-G1GC-log-information.patch
- 0050-8181644-C1-crashes-with-XX-PrintCFGToFile.patch
- 0051-8071962-The-SA-code-needs-to-be-updated-to-support-S.patch
- 0052-8177959-G1CollectedHeap-print_on-prints-incorrect-ca.patch
- 0053-8146987-Improve-Parallel-GC-Full-GC-by-caching-resul.patch
- 0054-Fix-jmap-heapdump-symbols-when-the-class-is-loaded-f.patch
- 0055-Fix-CodelistTest.java-Failed-to-Execute-CodelistTest.patch
* Fri May 11 2023 crash888 <wangmengqi13@huawei.com> - 1:1.8.0.372-b07.1
- modified Fix-the-crash-that-occurs-when-the-process-exits-due.patch