I8Z6A9: Sync master to openEuler-22.03-LTS-Next

This commit is contained in:
neu-mobi 2024-01-27 14:08:45 +08:00
parent 5663cce5c3
commit 8d96d70970
156 changed files with 52239 additions and 6926 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,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,720 @@
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);
}
@@ -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,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,185 @@
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 +
7 files changed, 64 insertions(+), 3 deletions(-)
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); }
--
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,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

@ -293,7 +293,7 @@ index 4454cd18d..e9813d7c1 100644
guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp
index 7f8aff2bd..b4e69025f 100644
index 0c17989a7d..c4c43a0fe3 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp
@@ -1,5 +1,5 @@
@ -303,10 +303,10 @@ index 7f8aff2bd..b4e69025f 100644
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,13 +48,13 @@ private:
@@ -48,13 +48,14 @@ private:
bool _is_working; // True if participating in GC tasks
- public:
// Factory create and destroy methods.
static GCTaskThread* create(GCTaskManager* manager,
@ -314,19 +314,20 @@ index 7f8aff2bd..b4e69025f 100644
uint processor_id) {
return new GCTaskThread(manager, which, processor_id);
}
+ public:
+
+public:
static void destroy(GCTaskThread* manager) {
if (manager != NULL) {
delete manager;
@@ -65,8 +65,6 @@ private:
@@ -65,8 +66,6 @@ private:
return true;
}
virtual void run();
- // Methods.
- void start();
void print_task_time_stamps();
void print_on(outputStream* st) const;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp
index 3bfbddcb5..1e99e73e4 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp

View File

@ -2895,7 +2895,7 @@ new file mode 100644
index 000000000..510529baa
--- /dev/null
+++ b/jdk/test/java/security/Provider/BaseProviderValidator.java
@@ -0,0 +1,76 @@
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -2921,7 +2921,6 @@ index 000000000..510529baa
+ */
+
+/*
+ * @test
+ * @bug 7092821
+ * @library ../testlibrary
+ * @summary make sure that Sun providers do not miss any algorithms after
@ -3174,7 +3173,7 @@ new file mode 100644
index 000000000..8c4ef89c7
--- /dev/null
+++ b/jdk/test/java/security/Provider/ProviderValidationUtil.java
@@ -0,0 +1,270 @@
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2022, Huawei Technologies Co., Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -3200,7 +3199,6 @@ index 000000000..8c4ef89c7
+ */
+
+/*
+ * @test
+ * @bug 7092821
+ * @library ../testlibrary
+ * @summary make sure that Sun providers do not miss any algorithms after

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,314 @@
From ea08edece64add39a00a0bca558d11d41bf21513 Mon Sep 17 00:00:00 2001
Date: Thu, 27 Jul 2023 10:21:50 +0800
Subject: [PATCH] [Backport]8035986: KerberosKey algorithm names are not specified
---
.../javax/security/auth/kerberos/KerberosKey.java | 46 ++++++---
.../javax/security/auth/kerberos/KeyImpl.java | 26 ++---
.../classes/sun/security/krb5/EncryptionKey.java | 17 +++-
.../security/auth/kerberos/StandardNames.java | 108 +++++++++++++++++++++
4 files changed, 169 insertions(+), 28 deletions(-)
create mode 100644 jdk/test/javax/security/auth/kerberos/StandardNames.java
diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java
index 5c8b65f27..a8d12131a 100644
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java
@@ -52,7 +52,20 @@ import javax.security.auth.DestroyFailedException;
* application depends on the default JGSS Kerberos mechanism to access the
* KerberosKey. In that case, however, the application will need an
* appropriate
- * {@link javax.security.auth.kerberos.ServicePermission ServicePermission}.
+ * {@link javax.security.auth.kerberos.ServicePermission ServicePermission}.<p>
+ *
+ * When creating a {@code KerberosKey} using the
+ * {@link #KerberosKey(KerberosPrincipal, char[], String)} constructor,
+ * an implementation may accept non-IANA algorithm names (For example,
+ * "ArcFourMac" for "rc4-hmac"), but the {@link #getAlgorithm} method
+ * must always return the IANA algorithm name.<p>
+ *
+ * @implNote Old algorithm names used before JDK 9 are supported in the
+ * {@link #KerberosKey(KerberosPrincipal, char[], String)} constructor in this
+ * implementation for compatibility reasons, which are "DES" (and null) for
+ * "des-cbc-md5", "DESede" for "des3-cbc-sha1-kd", "ArcFourHmac" for "rc4-hmac",
+ * "AES128" for "aes128-cts-hmac-sha1-96", and "AES256" for
+ * "aes256-cts-hmac-sha1-96".
*
* @author Mayank Upadhyay
* @since 1.4
@@ -73,7 +86,7 @@ public class KerberosKey implements SecretKey, Destroyable {
*
* @serial
*/
- private int versionNum;
+ private final int versionNum;
/**
* {@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes
@@ -113,13 +126,16 @@ public class KerberosKey implements SecretKey, Destroyable {
}
/**
- * Constructs a KerberosKey from a principal's password.
+ * Constructs a KerberosKey from a principal's password using the specified
+ * algorithm name. The algorithm name (case insensitive) should be provided
+ * as the encryption type string defined on the IANA
+ * <a href="https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-1">Kerberos Encryption Type Numbers</a>
+ * page. The version number of the key generated will be 0.
*
* @param principal the principal that this password belongs to
* @param password the password that should be used to compute the key
* @param algorithm the name for the algorithm that this key will be
- * used for. This parameter may be null in which case the default
- * algorithm "DES" will be assumed.
+ * used for
* @throws IllegalArgumentException if the name of the
* algorithm passed is unsupported.
*/
@@ -128,6 +144,7 @@ public class KerberosKey implements SecretKey, Destroyable {
String algorithm) {
this.principal = principal;
+ this.versionNum = 0;
// Pass principal in for salt
key = new KeyImpl(principal, password, algorithm);
}
@@ -170,13 +187,18 @@ public class KerberosKey implements SecretKey, Destroyable {
*/
/**
- * Returns the standard algorithm name for this key. For
- * example, "DES" would indicate that this key is a DES key.
- * See Appendix A in the <a href=
- * "../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
- * Java Cryptography Architecture API Specification &amp; Reference
- * </a>
- * for information about standard algorithm names.
+ * Returns the standard algorithm name for this key. The algorithm names
+ * are the encryption type string defined on the IANA
+ * <a href="https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-1">Kerberos Encryption Type Numbers</a>
+ * page.
+ * <p>
+ * This method can return the following value not defined on the IANA page:
+ * <ol>
+ * <li>none: for etype equal to 0</li>
+ * <li>unknown: for etype greater than 0 but unsupported by
+ * the implementation</li>
+ * <li>private: for etype smaller than 0</li>
+ * </ol>
*
* @return the name of the algorithm associated with this key.
*/
diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java
index f4ee94721..9d36d1e9e 100644
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java
@@ -36,7 +36,6 @@ import sun.security.krb5.PrincipalName;
import sun.security.krb5.EncryptionKey;
import sun.security.krb5.EncryptedData;
import sun.security.krb5.KrbException;
-import sun.security.krb5.KrbCryptoException;
import sun.security.util.DerValue;
/**
@@ -86,8 +85,12 @@ class KeyImpl implements SecretKey, Destroyable, Serializable {
try {
PrincipalName princ = new PrincipalName(principal.getName());
- EncryptionKey key =
- new EncryptionKey(password, princ.getSalt(), algorithm);
+ EncryptionKey key;
+ if ("none".equalsIgnoreCase(algorithm)) {
+ key = EncryptionKey.NULL_KEY;
+ } else {
+ key = new EncryptionKey(password, princ.getSalt(), algorithm);
+ }
this.keyBytes = key.getBytes();
this.keyType = key.getEType();
} catch (KrbException e) {
@@ -118,27 +121,28 @@ class KeyImpl implements SecretKey, Destroyable, Serializable {
switch (eType) {
case EncryptedData.ETYPE_DES_CBC_CRC:
+ return "des-cbc-crc";
+
case EncryptedData.ETYPE_DES_CBC_MD5:
- return "DES";
+ return "des-cbc-md5";
case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD:
- return "DESede";
+ return "des3-cbc-sha1-kd";
case EncryptedData.ETYPE_ARCFOUR_HMAC:
- return "ArcFourHmac";
+ return "rc4-hmac";
case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
- return "AES128";
+ return "aes128-cts-hmac-sha1-96";
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
- return "AES256";
+ return "aes256-cts-hmac-sha1-96";
case EncryptedData.ETYPE_NULL:
- return "NULL";
+ return "none";
default:
- throw new IllegalArgumentException(
- "Unsupported encryption type: " + eType);
+ return eType > 0 ? "unknown" : "private";
}
}
diff --git a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java
index 4823b2525..d484d7c55 100644
--- a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java
+++ b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java
@@ -271,15 +271,22 @@ public class EncryptionKey
String salt,
String algorithm) throws KrbCryptoException {
- if (algorithm == null || algorithm.equalsIgnoreCase("DES")) {
+ if (algorithm == null || algorithm.equalsIgnoreCase("DES")
+ || algorithm.equalsIgnoreCase("des-cbc-md5")) {
keyType = EncryptedData.ETYPE_DES_CBC_MD5;
- } else if (algorithm.equalsIgnoreCase("DESede")) {
+ } else if (algorithm.equalsIgnoreCase("des-cbc-crc")) {
+ keyType = EncryptedData.ETYPE_DES_CBC_CRC;
+ } else if (algorithm.equalsIgnoreCase("DESede")
+ || algorithm.equalsIgnoreCase("des3-cbc-sha1-kd")) {
keyType = EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD;
- } else if (algorithm.equalsIgnoreCase("AES128")) {
+ } else if (algorithm.equalsIgnoreCase("AES128")
+ || algorithm.equalsIgnoreCase("aes128-cts-hmac-sha1-96")) {
keyType = EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96;
- } else if (algorithm.equalsIgnoreCase("ArcFourHmac")) {
+ } else if (algorithm.equalsIgnoreCase("ArcFourHmac")
+ || algorithm.equalsIgnoreCase("rc4-hmac")) {
keyType = EncryptedData.ETYPE_ARCFOUR_HMAC;
- } else if (algorithm.equalsIgnoreCase("AES256")) {
+ } else if (algorithm.equalsIgnoreCase("AES256")
+ || algorithm.equalsIgnoreCase("aes256-cts-hmac-sha1-96")) {
keyType = EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96;
// validate if AES256 is enabled
if (!EType.isSupported(keyType)) {
diff --git a/jdk/test/javax/security/auth/kerberos/StandardNames.java b/jdk/test/javax/security/auth/kerberos/StandardNames.java
new file mode 100644
index 000000000..40590f6d0
--- /dev/null
+++ b/jdk/test/javax/security/auth/kerberos/StandardNames.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, 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 8035986
+ * @summary KerberosKey algorithm names are not specified
+ */
+
+import sun.security.krb5.EncryptedData;
+
+import javax.crypto.Cipher;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import java.util.Locale;
+
+public class StandardNames {
+ static KerberosPrincipal kp = new KerberosPrincipal("user@REALM");
+ static char[] pass = "secret".toCharArray();
+ static byte[] keyBytes = new byte[1];
+
+ public static void main(String[] args) throws Exception {
+ for (EncType e: EncType.values()) {
+ if (e == EncType.e18) {
+ if (Cipher.getMaxAllowedKeyLength("AES") < 256) {
+ System.out.println("Skipping aes256-cts-hmac-sha1-96");
+ continue;
+ }
+ }
+ checkByName(e.name, e);
+ checkByName(e.name.toUpperCase(Locale.US), e);
+ for (String n: e.oldnames) {
+ checkByName(n, e);
+ if (n != null) {
+ checkByName(n.toLowerCase(Locale.US), e);
+ }
+ }
+ checkByEType(e.etype, e.name);
+ }
+ checkByEType(100, "unknown");
+ checkByEType(-1, "private");
+
+ try {
+ System.out.println("unsupported");
+ new KerberosKey(kp, pass, "unsupported");
+ throw new Exception("unsupported");
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ }
+ }
+
+ private static void checkByName(String n, EncType e) throws Exception {
+ System.out.println("CheckByName " + n);
+ KerberosKey k = new KerberosKey(kp, pass, n);
+ if (!k.getAlgorithm().equals(e.name)) throw new Exception(n);
+ if (k.getKeyType() != e.etype) throw new Exception(n);
+ if (k.getVersionNumber() != 0) throw new Exception(n);
+ }
+
+ private static void checkByEType(int i, String n) throws Exception {
+ System.out.println("CheckByInt " + i);
+ KerberosKey k = new KerberosKey(kp, keyBytes, i, 13);
+ if (!k.getAlgorithm().equals(n)) throw new Exception("" + i);
+ if (k.getKeyType() != i) throw new Exception("" + i);
+ if (k.getVersionNumber() != 13) throw new Exception("" + i);
+ }
+}
+
+enum EncType {
+ e0("none", EncryptedData.ETYPE_NULL),
+ e1("des-cbc-crc", EncryptedData.ETYPE_DES_CBC_CRC),
+ e3("des-cbc-md5", EncryptedData.ETYPE_DES_CBC_MD5, "DES", null),
+ e16("des3-cbc-sha1-kd", EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD, "DESede"),
+ e17("aes128-cts-hmac-sha1-96", EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96, "AES128"),
+ e18("aes256-cts-hmac-sha1-96", EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96, "AES256"),
+ e23("rc4-hmac", EncryptedData.ETYPE_ARCFOUR_HMAC, "ArcFourHmac"),
+ ;
+
+ final String name;
+ final int etype;
+ final String[] oldnames;
+
+ EncType(String name, int etype, String... oldnames) {
+ this.name = name;
+ this.etype = etype;
+ this.oldnames = oldnames;
+ }
+}
--
2.12.3

View File

@ -0,0 +1,303 @@
From 120367d947c297709134167d3e4d8e1b91fe97f3 Mon Sep 17 00:00:00 2001
From: z30010524 <zhangyunbo7@huawei.com>
Date: Tue, 14 Mar 2023 19:17:50 +0800
Subject: [PATCH 10/15] 8057743: (process) Synchronize exiting of threads and
process [win]
DTS/AR: DTS2023031516597
Summary: <JDK> :8057744: (process) Synchronize exiting of threads and process [win]
LLT: NA
Patch Type: backport
Bug url: https://bugs.openjdk.org/browse/JDK-8057744
---
hotspot/src/os/aix/vm/os_aix.inline.hpp | 5 ++
hotspot/src/os/bsd/vm/os_bsd.inline.hpp | 4 +
hotspot/src/os/linux/vm/os_linux.inline.hpp | 4 +
.../src/os/solaris/vm/os_solaris.inline.hpp | 5 ++
hotspot/src/os/windows/vm/os_windows.cpp | 87 +++++++++++++++++--
hotspot/src/os/windows/vm/os_windows.hpp | 10 +++
.../src/os/windows/vm/os_windows.inline.hpp | 4 +
hotspot/src/share/vm/runtime/java.cpp | 2 +-
hotspot/src/share/vm/runtime/os.hpp | 4 +-
9 files changed, 115 insertions(+), 10 deletions(-)
diff --git a/hotspot/src/os/aix/vm/os_aix.inline.hpp b/hotspot/src/os/aix/vm/os_aix.inline.hpp
index 421ea342e..afa034411 100644
--- a/hotspot/src/os/aix/vm/os_aix.inline.hpp
+++ b/hotspot/src/os/aix/vm/os_aix.inline.hpp
@@ -245,4 +245,9 @@ inline int os::set_sock_opt(int fd, int level, int optname,
const char* optval, socklen_t optlen) {
return ::setsockopt(fd, level, optname, optval, optlen);
}
+
+inline void os::exit(int num) {
+ ::exit(num);
+}
+
#endif // OS_AIX_VM_OS_AIX_INLINE_HPP
diff --git a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
index c35abf486..1eff6b724 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
@@ -247,4 +247,8 @@ inline int os::set_sock_opt(int fd, int level, int optname,
return ::setsockopt(fd, level, optname, optval, optlen);
}
+inline void os::exit(int num) {
+ ::exit(num);
+}
+
#endif // OS_BSD_VM_OS_BSD_INLINE_HPP
diff --git a/hotspot/src/os/linux/vm/os_linux.inline.hpp b/hotspot/src/os/linux/vm/os_linux.inline.hpp
index a23bd5631..eb8c8ca1b 100644
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp
@@ -240,4 +240,8 @@ inline int os::set_sock_opt(int fd, int level, int optname,
return ::setsockopt(fd, level, optname, optval, optlen);
}
+inline void os::exit(int num) {
+ ::exit(num);
+}
+
#endif // OS_LINUX_VM_OS_LINUX_INLINE_HPP
diff --git a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
index 8e095ab69..aad6debf9 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
@@ -223,4 +223,9 @@ inline int os::set_sock_opt(int fd, int level, int optname,
const char *optval, socklen_t optlen) {
return ::setsockopt(fd, level, optname, optval, optlen);
}
+
+inline void os::exit(int num) {
+ ::exit(num);
+}
+
#endif // OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 11bd14f6f..f0bc733c2 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -22,8 +22,8 @@
*
*/
-// Must be at least Windows 2000 or XP to use IsDebuggerPresent
-#define _WIN32_WINNT 0x500
+// Must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce
+#define _WIN32_WINNT 0x0600
// no precompiled headers
#include "classfile/classLoader.hpp"
@@ -432,6 +432,11 @@ static unsigned __stdcall java_start(Thread* thread) {
}
}
+ // Diagnostic code to investigate JDK-6573254
+ int res = 90115; // non-java thread
+ if (thread->is_Java_thread()) {
+ res = 60115; // java thread
+ }
// Install a win32 structured exception handler around every thread created
// by VM, so VM can genrate error dump when an exception occurred in non-
@@ -450,7 +455,9 @@ static unsigned __stdcall java_start(Thread* thread) {
Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
}
- return 0;
+ // Thread must not return from exit_process_or_thread(), but if it does,
+ // let it proceed to exit normally
+ return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res);
}
static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, int thread_id) {
@@ -1082,15 +1089,13 @@ void os::abort(bool dump_core, void* siginfo, void* context) {
win32::exit_process_or_thread(win32::EPT_PROCESS, 1);
}
-
-void os::abort(bool dump_core)
-{
+void os::abort(bool dump_core) {
abort(dump_core, NULL, NULL);
}
// Die immediately, no exit hook, no abort hook, no cleanup.
void os::die() {
- _exit(-1);
+ win32::exit_process_or_thread(win32::EPT_PROCESS_DIE, -1);
}
// Directory routines copied from src/win32/native/java/io/dirent_md.c
@@ -3857,6 +3862,11 @@ bool os::win32::_is_nt = false;
bool os::win32::_is_windows_2003 = false;
bool os::win32::_is_windows_server = false;
+// 6573254
+// Currently, the bug is observed across all the supported Windows releases,
+// including the latest one (as of this writing - Windows Server 2012 R2)
+bool os::win32::_has_exit_bug = true;
+
void os::win32::initialize_system_info() {
SYSTEM_INFO si;
GetSystemInfo(&si);
@@ -3951,6 +3961,69 @@ HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf, int ebuflen)
return NULL;
}
+#define MIN_EXIT_MUTEXES 1
+#define MAX_EXIT_MUTEXES 16
+
+struct ExitMutexes {
+ DWORD count;
+ HANDLE handles[MAX_EXIT_MUTEXES];
+};
+
+static BOOL CALLBACK init_muts_call(PINIT_ONCE, PVOID ppmuts, PVOID*) {
+ static ExitMutexes muts;
+
+ muts.count = os::processor_count();
+ if (muts.count < MIN_EXIT_MUTEXES) {
+ muts.count = MIN_EXIT_MUTEXES;
+ } else if (muts.count > MAX_EXIT_MUTEXES) {
+ muts.count = MAX_EXIT_MUTEXES;
+ }
+
+ for (DWORD i = 0; i < muts.count; ++i) {
+ muts.handles[i] = CreateMutex(NULL, FALSE, NULL);
+ if (muts.handles[i] == NULL) {
+ return FALSE;
+ }
+ }
+ *((ExitMutexes**)ppmuts) = &muts;
+ return TRUE;
+}
+
+int os::win32::exit_process_or_thread(Ept what, int exit_code) {
+ if (os::win32::has_exit_bug()) {
+ static INIT_ONCE init_once_muts = INIT_ONCE_STATIC_INIT;
+ static ExitMutexes* pmuts;
+
+ if (!InitOnceExecuteOnce(&init_once_muts, init_muts_call, &pmuts, NULL)) {
+ warning("ExitMutex initialization failed in %s: %d\n", __FILE__, __LINE__);
+ } else if (WaitForMultipleObjects(pmuts->count, pmuts->handles,
+ (what != EPT_THREAD), // exiting process waits for all mutexes
+ INFINITE) == WAIT_FAILED) {
+ warning("ExitMutex acquisition failed in %s: %d\n", __FILE__, __LINE__);
+ }
+ }
+
+ switch (what) {
+ case EPT_THREAD:
+ _endthreadex((unsigned)exit_code);
+ break;
+
+ case EPT_PROCESS:
+ ::exit(exit_code);
+ break;
+
+ case EPT_PROCESS_DIE:
+ _exit(exit_code);
+ break;
+ }
+
+ // should not reach here
+ return exit_code;
+}
+
+#undef MIN_EXIT_MUTEXES
+#undef MAX_EXIT_MUTEXES
+
void os::win32::setmode_streams() {
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
diff --git a/hotspot/src/os/windows/vm/os_windows.hpp b/hotspot/src/os/windows/vm/os_windows.hpp
index 20e2ca2f5..3fdc9bcd6 100644
--- a/hotspot/src/os/windows/vm/os_windows.hpp
+++ b/hotspot/src/os/windows/vm/os_windows.hpp
@@ -31,6 +31,7 @@ static bool zero_page_read_protected() { return true; }
class win32 {
friend class os;
+ friend unsigned __stdcall java_start(class Thread*);
protected:
static int _vm_page_size;
@@ -42,6 +43,7 @@ class win32 {
static bool _is_nt;
static bool _is_windows_2003;
static bool _is_windows_server;
+ static bool _has_exit_bug;
static void print_windows_version(outputStream* st);
@@ -63,6 +65,11 @@ class win32 {
// load dll from Windows system directory or Windows directory
static HINSTANCE load_Windows_dll(const char* name, char *ebuf, int ebuflen);
+ private:
+ enum Ept { EPT_THREAD, EPT_PROCESS, EPT_PROCESS_DIE };
+ // Wrapper around _endthreadex(), exit() and _exit()
+ static int exit_process_or_thread(Ept what, int exit_code);
+
public:
// Generic interface:
@@ -79,6 +86,9 @@ class win32 {
// Tells whether the platform is Windows 2003
static bool is_windows_2003() { return _is_windows_2003; }
+ // Tells whether there can be the race bug during process exit on this platform
+ static bool has_exit_bug() { return _has_exit_bug; }
+
// Returns the byte size of a virtual memory page
static int vm_page_size() { return _vm_page_size; }
diff --git a/hotspot/src/os/windows/vm/os_windows.inline.hpp b/hotspot/src/os/windows/vm/os_windows.inline.hpp
index 5dac11c90..83c51935d 100644
--- a/hotspot/src/os/windows/vm/os_windows.inline.hpp
+++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp
@@ -96,6 +96,10 @@ inline int os::close(int fd) {
return ::close(fd);
}
+inline void os::exit(int num) {
+ win32::exit_process_or_thread(win32::EPT_PROCESS, num);
+}
+
#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \
os::win32::call_test_func_with_wrapper(f)
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index 5b82a7a36..c72a5a766 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -625,7 +625,7 @@ void notify_vm_shutdown() {
void vm_direct_exit(int code) {
notify_vm_shutdown();
os::wait_for_keypress_at_exit();
- ::exit(code);
+ os::exit(code);
}
void vm_perform_shutdown_actions() {
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index e696321ab..6ca220021 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -545,8 +545,8 @@ class os: AllStatic {
// run cmd in a separate process and return its exit code; or -1 on failures
static int fork_and_exec(char *cmd, bool use_vfork_if_available = false);
- // os::exit() is merged with vm_exit()
- // static void exit(int num);
+ // Call ::exit() on all platforms but Windows
+ static void exit(int num);
// Terminate the VM, but don't exit the process
static void shutdown();
--
2.19.0

View File

@ -0,0 +1,753 @@
From 1059c5d5f9d1e50607c726b619f39ac68954bda7 Mon Sep 17 00:00:00 2001
From: zhangyipeng <zhangyipeng7@huawei.com>
Date: Mon, 15 Jan 2024 11:40:07 +0800
Subject: [PATCH] [Backport]8057967: CallSite dependency tracking scales devastatingly
poorly
---
hotspot/src/share/vm/ci/ciCallSite.cpp | 19 +++
hotspot/src/share/vm/ci/ciCallSite.hpp | 1 +
hotspot/src/share/vm/classfile/javaClasses.cpp | 48 +++++-
hotspot/src/share/vm/classfile/javaClasses.hpp | 9 +-
hotspot/src/share/vm/classfile/vmSymbols.hpp | 4 +-
hotspot/src/share/vm/code/dependencies.cpp | 27 ++--
hotspot/src/share/vm/code/dependencies.hpp | 7 +-
hotspot/src/share/vm/memory/universe.cpp | 8 +-
hotspot/src/share/vm/prims/methodHandles.cpp | 50 +++++-
hotspot/src/share/vm/prims/methodHandles.hpp | 3 +
.../compiler/jsr292/CallSiteDepContextTest.java | 179 +++++++++++++++++++++
.../share/classes/java/lang/invoke/CallSite.java | 55 ++++++-
.../java/lang/invoke/MethodHandleNatives.java | 4 +
13 files changed, 385 insertions(+), 29 deletions(-)
create mode 100644 hotspot/test/compiler/jsr292/CallSiteDepContextTest.java
diff --git a/hotspot/src/share/vm/ci/ciCallSite.cpp b/hotspot/src/share/vm/ci/ciCallSite.cpp
index 794042a79..f58346aea 100644
--- a/hotspot/src/share/vm/ci/ciCallSite.cpp
+++ b/hotspot/src/share/vm/ci/ciCallSite.cpp
@@ -49,6 +49,25 @@ ciMethodHandle* ciCallSite::get_target() const {
}
// ------------------------------------------------------------------
+// ciCallSite::get_context
+//
+// Return the target MethodHandle of this CallSite.
+ciKlass* ciCallSite::get_context() {
+ assert(!is_constant_call_site(), "");
+
+ VM_ENTRY_MARK;
+ oop call_site_oop = get_oop();
+ InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site_oop);
+ if (ctxk == NULL) {
+ // The call site doesn't have a context associated. Set it to the default context.
+ oop def_context_oop = java_lang_invoke_CallSite::default_context();
+ java_lang_invoke_CallSite::set_context_cas(call_site_oop, def_context_oop, /*expected=*/NULL);
+ ctxk = MethodHandles::get_call_site_context(call_site_oop);
+ }
+ return (CURRENT_ENV->get_metadata(ctxk))->as_klass();
+}
+
+// ------------------------------------------------------------------
// ciCallSite::print
//
// Print debugging information about the CallSite.
diff --git a/hotspot/src/share/vm/ci/ciCallSite.hpp b/hotspot/src/share/vm/ci/ciCallSite.hpp
index 063f1e3a5..040e894d0 100644
--- a/hotspot/src/share/vm/ci/ciCallSite.hpp
+++ b/hotspot/src/share/vm/ci/ciCallSite.hpp
@@ -43,6 +43,7 @@ public:
// Return the target MethodHandle of this CallSite.
ciMethodHandle* get_target() const;
+ ciKlass* get_context();
void print();
};
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
index 9db88611b..fc4165b04 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
@@ -100,21 +100,22 @@ InjectedField* JavaClasses::get_injected(Symbol* class_name, int* field_count) {
static bool find_field(InstanceKlass* ik,
Symbol* name_symbol, Symbol* signature_symbol,
fieldDescriptor* fd,
- bool allow_super = false) {
- if (allow_super)
- return ik->find_field(name_symbol, signature_symbol, fd) != NULL;
- else
+ bool is_static = false, bool allow_super = false) {
+ if (allow_super || is_static) {
+ return ik->find_field(name_symbol, signature_symbol, is_static, fd) != NULL;
+ } else {
return ik->find_local_field(name_symbol, signature_symbol, fd);
+ }
}
// Helpful routine for computing field offsets at run time rather than hardcoding them
static void
compute_offset(int &dest_offset,
Klass* klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
- bool allow_super = false) {
+ bool is_static = false, bool allow_super = false) {
fieldDescriptor fd;
InstanceKlass* ik = InstanceKlass::cast(klass_oop);
- if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) {
+ if (!find_field(ik, name_symbol, signature_symbol, &fd, is_static, allow_super)) {
ResourceMark rm;
tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string());
#ifndef PRODUCT
@@ -3002,15 +3003,50 @@ int java_lang_invoke_MethodType::rtype_slot_count(oop mt) {
// Support for java_lang_invoke_CallSite
int java_lang_invoke_CallSite::_target_offset;
+int java_lang_invoke_CallSite::_context_offset;
+int java_lang_invoke_CallSite::_default_context_offset;
void java_lang_invoke_CallSite::compute_offsets() {
if (!EnableInvokeDynamic) return;
Klass* k = SystemDictionary::CallSite_klass();
if (k != NULL) {
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
+ compute_offset(_context_offset, k, vmSymbols::context_name(), vmSymbols::sun_misc_Cleaner_signature());
+ compute_offset(_default_context_offset, k,
+ vmSymbols::DEFAULT_CONTEXT_name(), vmSymbols::sun_misc_Cleaner_signature(),
+ /*is_static=*/true, /*allow_super=*/false);
}
}
+oop java_lang_invoke_CallSite::context_volatile(oop call_site) {
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
+
+ oop dep_oop = call_site->obj_field_volatile(_context_offset);
+ return dep_oop;
+}
+
+void java_lang_invoke_CallSite::set_context_volatile(oop call_site, oop context) {
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
+ call_site->obj_field_put_volatile(_context_offset, context);
+}
+
+bool java_lang_invoke_CallSite::set_context_cas(oop call_site, oop context, oop expected) {
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
+ HeapWord* context_addr = call_site->obj_field_addr<HeapWord>(_context_offset);
+ oop res = oopDesc::atomic_compare_exchange_oop(context, context_addr, expected, true);
+ bool success = (res == expected);
+ if (success) {
+ update_barrier_set((void*)context_addr, context);
+ }
+ return success;
+}
+
+oop java_lang_invoke_CallSite::default_context() {
+ InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::CallSite_klass());
+ oop def_context_oop = ik->java_mirror()->obj_field(_default_context_offset);
+ assert(!oopDesc::is_null(def_context_oop), "");
+ return def_context_oop;
+}
// Support for java_security_AccessControlContext
diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp
index d6e288fb8..35934319d 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp
@@ -1212,6 +1212,9 @@ class java_lang_invoke_CallSite: AllStatic {
private:
static int _target_offset;
+ static int _context_offset;
+ static int _default_context_offset;
+
static void compute_offsets();
@@ -1222,6 +1225,11 @@ public:
static volatile oop target_volatile(oop site) { return oop((oopDesc *)(site->obj_field_volatile(_target_offset))); }
static void set_target_volatile(oop site, oop target) { site->obj_field_put_volatile(_target_offset, target); }
+ static oop context_volatile(oop site);
+ static void set_context_volatile(oop site, oop context);
+ static bool set_context_cas (oop site, oop context, oop expected);
+
+ static oop default_context();
// Testers
static bool is_subclass(Klass* klass) {
@@ -1235,7 +1243,6 @@ public:
static int target_offset_in_bytes() { return _target_offset; }
};
-
// Interface to java.security.AccessControlContext objects
class java_security_AccessControlContext: AllStatic {
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 494fd9bdf..f92b709ed 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -301,6 +301,7 @@
template(setTargetNormal_name, "setTargetNormal") \
template(setTargetVolatile_name, "setTargetVolatile") \
template(setTarget_signature, "(Ljava/lang/invoke/MethodHandle;)V") \
+ template(DEFAULT_CONTEXT_name, "DEFAULT_CONTEXT") \
NOT_LP64( do_alias(intptr_signature, int_signature) ) \
LP64_ONLY( do_alias(intptr_signature, long_signature) ) \
\
@@ -517,6 +518,7 @@
template(string_signature, "Ljava/lang/String;") \
template(reference_signature, "Ljava/lang/ref/Reference;") \
template(referencequeue_signature, "Ljava/lang/ref/ReferenceQueue;") \
+ template(sun_misc_Cleaner_signature, "Lsun/misc/Cleaner;") \
template(executable_signature, "Ljava/lang/reflect/Executable;") \
template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \
template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \
@@ -570,7 +572,7 @@
template(createGarbageCollectorMBean_signature, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/management/GarbageCollectorMBean;") \
template(trigger_name, "trigger") \
template(clear_name, "clear") \
- template(trigger_method_signature, "(ILjava/lang/management/MemoryUsage;)V") \
+ template(trigger_method_signature, "(ILjava/lang/management/MemoryUsage;)V") \
template(startAgent_name, "startAgent") \
template(startRemoteAgent_name, "startRemoteManagementAgent") \
template(startLocalAgent_name, "startLocalManagementAgent") \
diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp
index d1fe08b54..decbce8be 100644
--- a/hotspot/src/share/vm/code/dependencies.cpp
+++ b/hotspot/src/share/vm/code/dependencies.cpp
@@ -123,8 +123,9 @@ void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) {
}
void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) {
- check_ctxk(call_site->klass());
- assert_common_2(call_site_target_value, call_site, method_handle);
+ ciKlass* ctxk = call_site->get_context();
+ check_ctxk(ctxk);
+ assert_common_3(call_site_target_value, ctxk, call_site, method_handle);
}
// Helper function. If we are adding a new dep. under ctxk2,
@@ -396,7 +397,7 @@ int Dependencies::_dep_args[TYPE_LIMIT] = {
3, // unique_concrete_methods_2 ctxk, m1, m2
2, // unique_implementor ctxk, implementor
1, // no_finalizable_subclasses ctxk
- 2 // call_site_target_value call_site, method_handle
+ 3 // call_site_target_value ctxk, call_site, method_handle
};
const char* Dependencies::dep_name(Dependencies::DepType dept) {
@@ -598,7 +599,7 @@ void Dependencies::DepStream::log_dependency(Klass* witness) {
const int nargs = argument_count();
GrowableArray<DepArgument>* args = new GrowableArray<DepArgument>(nargs);
for (int j = 0; j < nargs; j++) {
- if (type() == call_site_target_value) {
+ if (is_oop_argument(j)) {
args->push(argument_oop(j));
} else {
args->push(argument(j));
@@ -726,7 +727,7 @@ Klass* Dependencies::DepStream::context_type() {
}
// Some dependencies are using the klass of the first object
- // argument as implicit context type (e.g. call_site_target_value).
+ // argument as implicit context type.
{
int ctxkj = dep_implicit_context_arg(type());
if (ctxkj >= 0) {
@@ -1647,9 +1648,16 @@ Klass* Dependencies::check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepCh
return find_finalizable_subclass(search_at);
}
-Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
- assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "sanity");
- assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
+Klass* Dependencies::check_call_site_target_value(Klass* recorded_ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes) {
+ assert(call_site->is_a(SystemDictionary::CallSite_klass()), "sanity");
+ assert(!oopDesc::is_null(method_handle), "sanity");
+
+ Klass* call_site_ctxk = MethodHandles::get_call_site_context(call_site);
+ assert(!Klass::is_null(call_site_ctxk), "call site context should be initialized already");
+ if (recorded_ctxk != call_site_ctxk) {
+ // Stale context
+ return recorded_ctxk;
+ }
if (changes == NULL) {
// Validate all CallSites
if (java_lang_invoke_CallSite::target(call_site) != method_handle)
@@ -1664,7 +1672,6 @@ Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_hand
return NULL; // assertion still valid
}
-
void Dependencies::DepStream::trace_and_log_witness(Klass* witness) {
if (witness != NULL) {
if (TraceDependencies) {
@@ -1728,7 +1735,7 @@ Klass* Dependencies::DepStream::check_call_site_dependency(CallSiteDepChange* ch
Klass* witness = NULL;
switch (type()) {
case call_site_target_value:
- witness = check_call_site_target_value(argument_oop(0), argument_oop(1), changes);
+ witness = check_call_site_target_value(context_type(), argument_oop(1), argument_oop(2), changes);
break;
default:
witness = NULL;
diff --git a/hotspot/src/share/vm/code/dependencies.hpp b/hotspot/src/share/vm/code/dependencies.hpp
index 0392d4e3d..da2201c3f 100644
--- a/hotspot/src/share/vm/code/dependencies.hpp
+++ b/hotspot/src/share/vm/code/dependencies.hpp
@@ -176,7 +176,7 @@ class Dependencies: public ResourceObj {
klass_types = all_types & ~non_klass_types,
non_ctxk_types = (1 << evol_method),
- implicit_ctxk_types = (1 << call_site_target_value),
+ implicit_ctxk_types = 0,
explicit_ctxk_types = all_types & ~(non_ctxk_types | implicit_ctxk_types),
max_arg_count = 3, // current maximum number of arguments (incl. ctxk)
@@ -340,7 +340,7 @@ class Dependencies: public ResourceObj {
static Klass* check_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2,
KlassDepChange* changes = NULL);
static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL);
- static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
+ static Klass* check_call_site_target_value(Klass* recorded_ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
// A returned Klass* is NULL if the dependency assertion is still
// valid. A non-NULL Klass* is a 'witness' to the assertion
// failure, a point in the class hierarchy where the assertion has
@@ -506,6 +506,7 @@ class Dependencies: public ResourceObj {
bool next();
DepType type() { return _type; }
+ bool is_oop_argument(int i) { return type() == call_site_target_value && i > 0; }
int argument_count() { return dep_args(type()); }
int argument_index(int i) { assert(0 <= i && i < argument_count(), "oob");
return _xi[i]; }
@@ -664,7 +665,7 @@ class CallSiteDepChange : public DepChange {
_method_handle(method_handle)
{
assert(_call_site() ->is_a(SystemDictionary::CallSite_klass()), "must be");
- assert(_method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be");
+ assert(_method_handle.is_null() || _method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be");
}
// What kind of DepChange is this?
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 23433d187..7028d378e 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -56,6 +56,7 @@
#include "oops/oop.inline.hpp"
#include "oops/typeArrayKlass.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
+#include "prims/methodHandles.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fprofiler.hpp"
@@ -1233,8 +1234,11 @@ void Universe::flush_dependents_on(Handle call_site, Handle method_handle) {
int marked = 0;
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- InstanceKlass* call_site_klass = InstanceKlass::cast(call_site->klass());
- marked = call_site_klass->mark_dependent_nmethods(changes);
+ InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
+ if (ctxk == NULL) {
+ return; // No dependencies to invalidate yet.
+ }
+ marked = ctxk->mark_dependent_nmethods(changes);
}
if (marked > 0) {
// At least one nmethod has been marked for deoptimization
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index 29598d500..c1cbabec2 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -946,6 +946,24 @@ int MethodHandles::find_MemberNames(KlassHandle k,
return rfill + overflow;
}
+// Get context class for a CallSite instance: either extract existing context or use default one.
+InstanceKlass* MethodHandles::get_call_site_context(oop call_site) {
+ // In order to extract a context the following traversal is performed:
+ // CallSite.context => Cleaner.referent => Class._klass => Klass
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
+ oop context_oop = java_lang_invoke_CallSite::context_volatile(call_site);
+ if (oopDesc::is_null(context_oop)) {
+ return NULL; // The context hasn't been initialized yet.
+ }
+ oop context_class_oop = java_lang_ref_Reference::referent(context_oop);
+ if (oopDesc::is_null(context_class_oop)) {
+ // The context reference was cleared by GC, so current dependency context
+ // isn't usable anymore. Context should be fetched from CallSite again.
+ return NULL;
+ }
+ return InstanceKlass::cast(java_lang_Class::as_Klass(context_class_oop));
+}
+
//------------------------------------------------------------------------------
// MemberNameTable
//
@@ -1305,7 +1323,7 @@ JVM_END
JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
- Handle target (THREAD, JNIHandles::resolve(target_jh));
+ Handle target (THREAD, JNIHandles::resolve_non_null(target_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
@@ -1317,7 +1335,7 @@ JVM_END
JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
- Handle target (THREAD, JNIHandles::resolve(target_jh));
+ Handle target (THREAD, JNIHandles::resolve_non_null(target_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
@@ -1327,6 +1345,33 @@ JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobjec
}
JVM_END
+JVM_ENTRY(void, MHN_invalidateDependentNMethods(JNIEnv* env, jobject igcls, jobject call_site_jh)) {
+ Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
+ {
+ // Walk all nmethods depending on this call site.
+ MutexLocker mu1(Compile_lock, thread);
+
+ CallSiteDepChange changes(call_site(), Handle());
+
+ InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
+ if (ctxk == NULL) {
+ return; // No dependencies to invalidate yet.
+ }
+ int marked = 0;
+ {
+ MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ marked = ctxk->mark_dependent_nmethods(changes);
+ }
+ java_lang_invoke_CallSite::set_context_volatile(call_site(), NULL); // Reset call site to initial state
+ if (marked > 0) {
+ // At least one nmethod has been marked for deoptimization
+ VM_Deoptimize op;
+ VMThread::execute(&op);
+ }
+ }
+}
+JVM_END
+
/**
* Throws a java/lang/UnsupportedOperationException unconditionally.
* This is required by the specification of MethodHandle.invoke if
@@ -1381,6 +1426,7 @@ static JNINativeMethod MHN_methods[] = {
{CC "objectFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_objectFieldOffset)},
{CC "setCallSiteTargetNormal", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetNormal)},
{CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
+ {CC"invalidateDependentNMethods", CC"("CS")V", FN_PTR(MHN_invalidateDependentNMethods)},
{CC "staticFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_staticFieldOffset)},
{CC "staticFieldBase", CC "(" MEM ")" OBJ, FN_PTR(MHN_staticFieldBase)},
{CC "getMemberVMInfo", CC "(" MEM ")" OBJ, FN_PTR(MHN_getMemberVMInfo)}
diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp
index db6e06180..4b6af60df 100644
--- a/hotspot/src/share/vm/prims/methodHandles.hpp
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp
@@ -68,6 +68,9 @@ class MethodHandles: AllStatic {
// bit values for suppress argument to expand_MemberName:
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
+ // CallSite support
+ static InstanceKlass* get_call_site_context(oop call_site);
+
// Generate MethodHandles adapters.
static void generate_adapters();
diff --git a/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java
new file mode 100644
index 000000000..11e46ed03
--- /dev/null
+++ b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2015, 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 8057967
+ * @run main/bootclasspath -Xbatch java.lang.invoke.CallSiteDepContextTest
+ */
+package java.lang.invoke;
+
+import java.lang.ref.*;
+import jdk.internal.org.objectweb.asm.*;
+import sun.misc.Unsafe;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+public class CallSiteDepContextTest {
+ static final Unsafe UNSAFE = Unsafe.getUnsafe();
+ static final MethodHandles.Lookup LOOKUP = MethodHandles.Lookup.IMPL_LOOKUP;
+ static final String CLASS_NAME = "java/lang/invoke/Test";
+ static final String METHOD_NAME = "m";
+ static final MethodType TYPE = MethodType.methodType(int.class);
+
+ static MutableCallSite mcs;
+ static MethodHandle bsmMH;
+
+ static {
+ try {
+ bsmMH = LOOKUP.findStatic(
+ CallSiteDepContextTest.class, "bootstrap",
+ MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));
+ } catch(Throwable e) {
+ throw new InternalError(e);
+ }
+ }
+
+ public static CallSite bootstrap(MethodHandles.Lookup caller,
+ String invokedName,
+ MethodType invokedType) {
+ return mcs;
+ }
+
+ static class T {
+ static int f1() { return 1; }
+ static int f2() { return 2; }
+ }
+
+ static byte[] getClassFile(String suffix) {
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
+ MethodVisitor mv;
+ cw.visit(52, ACC_PUBLIC | ACC_SUPER, CLASS_NAME + suffix, null, "java/lang/Object", null);
+ {
+ mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, METHOD_NAME, TYPE.toMethodDescriptorString(), null, null);
+ mv.visitCode();
+ Handle bsm = new Handle(H_INVOKESTATIC,
+ "java/lang/invoke/CallSiteDepContextTest", "bootstrap",
+ bsmMH.type().toMethodDescriptorString());
+ mv.visitInvokeDynamicInsn("methodName", TYPE.toMethodDescriptorString(), bsm);
+ mv.visitInsn(IRETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+ private static void execute(int expected, MethodHandle... mhs) throws Throwable {
+ for (int i = 0; i < 20_000; i++) {
+ for (MethodHandle mh : mhs) {
+ int r = (int) mh.invokeExact();
+ if (r != expected) {
+ throw new Error(r + " != " + expected);
+ }
+ }
+ }
+ }
+
+ public static void testSharedCallSite() throws Throwable {
+ Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_1"), null);
+ Class<?> cls2 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_2"), null);
+
+ MethodHandle[] mhs = new MethodHandle[] {
+ LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
+ LOOKUP.findStatic(cls2, METHOD_NAME, TYPE)
+ };
+
+ mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
+ execute(1, mhs);
+ mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
+ execute(2, mhs);
+ }
+
+ public static void testNonBoundCallSite() throws Throwable {
+ mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
+
+ // mcs.context == null
+ MethodHandle mh = mcs.dynamicInvoker();
+ execute(1, mh);
+
+ // mcs.context == cls1
+ Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("NonBound_1"), null);
+ MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
+
+ execute(1, mh1);
+
+ mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
+
+ execute(2, mh, mh1);
+ }
+
+ static ReferenceQueue rq = new ReferenceQueue();
+ static PhantomReference ref;
+
+ public static void testGC() throws Throwable {
+ mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
+
+ Class<?>[] cls = new Class[] {
+ UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1"), null),
+ UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2"), null),
+ };
+
+ MethodHandle[] mhs = new MethodHandle[] {
+ LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE),
+ LOOKUP.findStatic(cls[1], METHOD_NAME, TYPE),
+ };
+
+ // mcs.context == cls[0]
+ int r = (int) mhs[0].invokeExact();
+
+ execute(1, mhs);
+
+ ref = new PhantomReference<>(cls[0], rq);
+ cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3"), null);
+ mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
+
+ do {
+ System.gc();
+ try {
+ Reference ref1 = rq.remove(1000);
+ if (ref1 == ref) {
+ ref1.clear();
+ System.gc(); // Ensure that the stale context is cleared
+ break;
+ }
+ } catch(InterruptedException e) { /* ignore */ }
+ } while (true);
+
+ execute(1, mhs);
+ mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
+ execute(2, mhs);
+ }
+
+ public static void main(String[] args) throws Throwable {
+ testSharedCallSite();
+ testNonBoundCallSite();
+ testGC();
+ System.out.println("TEST PASSED");
+ }
+}
diff --git a/jdk/src/share/classes/java/lang/invoke/CallSite.java b/jdk/src/share/classes/java/lang/invoke/CallSite.java
index 10ac1c071..11e452b96 100644
--- a/jdk/src/share/classes/java/lang/invoke/CallSite.java
+++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java
@@ -25,9 +25,10 @@
package java.lang.invoke;
-import sun.invoke.empty.Empty;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+import java.lang.reflect.Field;
+import sun.misc.Cleaner;
/**
* A {@code CallSite} is a holder for a variable {@link MethodHandle},
@@ -136,6 +137,50 @@ public class CallSite {
}
/**
+ * {@code CallSite} dependency context.
+ * VM uses context class to store nmethod dependencies on the call site target.
+ * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance.
+ * Lazily initialized when CallSite instance is linked to some indy call site or VM needs
+ * it to store dependencies. As a corollary, "null" context means there are no dependencies
+ * registered yet. {@code Cleaner} is used in 2 roles:
+ * (a) context class access for VM;
+ * (b) stale context class cleanup.
+ * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}).
+ * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly
+ * from {@code Reference.referent} field.
+ */
+ private volatile Cleaner context = null;
+
+ /**
+ * Default context.
+ * VM uses it to initialize non-linked CallSite context.
+ */
+ private static class DefaultContext {}
+ private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null);
+
+ private static Cleaner makeContext(Class<?> referent, final CallSite holder) {
+ return Cleaner.create(referent,
+ new Runnable() {
+ @Override public void run() {
+ MethodHandleNatives.invalidateDependentNMethods(holder);
+ }
+ });
+ }
+
+ /** Initialize context class used for nmethod dependency tracking */
+ /*package-private*/
+ void initContext(Class<?> newContext) {
+ // If there are concurrent actions, exactly one succeeds.
+ if (context == null) {
+ UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this));
+ // No need to care about failed CAS attempt.
+ // Since initContext is called from indy call site linkage in newContext class, there's no risk
+ // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup
+ // action in the wrong context).
+ }
+ }
+
+ /**
* Returns the type of this call site's target.
* Although targets may change, any call site's type is permanent, and can never change to an unequal type.
* The {@code setTarget} method enforces this invariant by refusing any new target that does
@@ -246,11 +291,13 @@ public class CallSite {
}
// unsafe stuff:
- private static final long TARGET_OFFSET;
+ private static final long TARGET_OFFSET;
+ private static final long CONTEXT_OFFSET;
static {
try {
- TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
- } catch (Exception ex) { throw new Error(ex); }
+ TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
+ CONTEXT_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("context"));
+ } catch (Exception ex) { throw newInternalError(ex); }
}
/*package-private*/
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
index ecc146078..9a1343c50 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
@@ -71,6 +71,9 @@ class MethodHandleNatives {
static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
+ /** Invalidate CallSite context: clean up dependent nmethods and reset call site context to initial state (null). */
+ static native void invalidateDependentNMethods(CallSite site);
+
private static native void registerNatives();
static {
registerNatives();
@@ -314,6 +317,7 @@ class MethodHandleNatives {
return Invokers.linkToTargetMethod(type);
} else {
appendixResult[0] = callSite;
+ callSite.initContext(caller);
return Invokers.linkToCallSiteMethod(type);
}
}
--
2.12.3

View File

@ -1,170 +0,0 @@
From c97998519552b7d8287125e46a3db2f29293784f Mon Sep 17 00:00:00 2001
From: xiezhaokun <xiezhaokun@huawei.com>
Date: Wed, 8 Jun 2022 10:32:52 +0800
Subject: [PATCH 08/10] 8067941: [TESTBUG] Fix tests for OS with 64K page size
---
hotspot/src/share/vm/memory/metaspace.cpp | 8 +++++---
hotspot/test/compiler/6865265/StackOverflowBug.java | 2 +-
hotspot/test/compiler/8009761/Test8009761.java | 2 +-
.../exceptions/TestRecursiveReplacedException.java | 2 +-
.../compiler/uncommontrap/StackOverflowGuardPagesOff.java | 2 +-
.../compiler/uncommontrap/TestStackBangMonitorOwned.java | 2 +-
hotspot/test/compiler/uncommontrap/TestStackBangRbp.java | 2 +-
hotspot/test/gc/arguments/TestMaxHeapSizeTools.java | 2 +-
hotspot/test/gc/g1/TestHumongousAllocInitialMark.java | 4 +++-
9 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index 600bcfd1..2912f41b 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -3937,11 +3937,13 @@ class TestVirtualSpaceNodeTest {
assert(cm.sum_free_chunks() == 2*MediumChunk, "sizes should add up");
}
- { // 4 pages of VSN is committed, some is used by chunks
+ const size_t page_chunks = 4 * (size_t)os::vm_page_size() / BytesPerWord;
+ // This doesn't work for systems with vm_page_size >= 16K.
+ if (page_chunks < MediumChunk) {
+ // 4 pages of VSN is committed, some is used by chunks
ChunkManager cm(SpecializedChunk, SmallChunk, MediumChunk);
VirtualSpaceNode vsn(vsn_test_size_bytes);
- const size_t page_chunks = 4 * (size_t)os::vm_page_size() / BytesPerWord;
- assert(page_chunks < MediumChunk, "Test expects medium chunks to be at least 4*page_size");
+
vsn.initialize();
vsn.expand_by(page_chunks, page_chunks);
vsn.get_chunk_vs(SmallChunk);
diff --git a/hotspot/test/compiler/6865265/StackOverflowBug.java b/hotspot/test/compiler/6865265/StackOverflowBug.java
index 295a6b41..c5d0f3b6 100644
--- a/hotspot/test/compiler/6865265/StackOverflowBug.java
+++ b/hotspot/test/compiler/6865265/StackOverflowBug.java
@@ -28,7 +28,7 @@
* @summary JVM crashes with "missing exception handler" error
* @author volker.simonis@sap.com
*
- * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss248k StackOverflowBug
+ * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss512k StackOverflowBug
*/
diff --git a/hotspot/test/compiler/8009761/Test8009761.java b/hotspot/test/compiler/8009761/Test8009761.java
index 401458b6..b41f49fd 100644
--- a/hotspot/test/compiler/8009761/Test8009761.java
+++ b/hotspot/test/compiler/8009761/Test8009761.java
@@ -25,7 +25,7 @@
* @test
* @bug 8009761
* @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
- * @run main/othervm -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss256K Test8009761
+ * @run main/othervm -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss512K Test8009761
*
*/
diff --git a/hotspot/test/compiler/exceptions/TestRecursiveReplacedException.java b/hotspot/test/compiler/exceptions/TestRecursiveReplacedException.java
index 996d82a0..950ed18c 100644
--- a/hotspot/test/compiler/exceptions/TestRecursiveReplacedException.java
+++ b/hotspot/test/compiler/exceptions/TestRecursiveReplacedException.java
@@ -25,7 +25,7 @@
* @test
* @bug 8054224
* @summary Recursive method compiled by C1 is unable to catch StackOverflowError
- * @run main/othervm -Xcomp -XX:CompileOnly=Test.run -XX:+TieredCompilation -XX:TieredStopAtLevel=2 -Xss256K TestRecursiveReplacedException
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test.run -XX:+TieredCompilation -XX:TieredStopAtLevel=2 -Xss512K TestRecursiveReplacedException
*
*/
diff --git a/hotspot/test/compiler/uncommontrap/StackOverflowGuardPagesOff.java b/hotspot/test/compiler/uncommontrap/StackOverflowGuardPagesOff.java
index 4ad409bb..835283c0 100644
--- a/hotspot/test/compiler/uncommontrap/StackOverflowGuardPagesOff.java
+++ b/hotspot/test/compiler/uncommontrap/StackOverflowGuardPagesOff.java
@@ -25,7 +25,7 @@
* @test
* @bug 8029383
* @summary stack overflow if callee is marked for deoptimization causes crash
- * @run main/othervm -XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,StackOverflowGuardPagesOff::m1 -XX:CompileCommand=exclude,StackOverflowGuardPagesOff::m2 -Xss256K -XX:-UseOnStackReplacement StackOverflowGuardPagesOff
+ * @run main/othervm -XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,StackOverflowGuardPagesOff::m1 -XX:CompileCommand=exclude,StackOverflowGuardPagesOff::m2 -Xss512K -XX:-UseOnStackReplacement StackOverflowGuardPagesOff
*
*/
diff --git a/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java b/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java
index 3d93d7d5..c07a995d 100644
--- a/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java
+++ b/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java
@@ -25,7 +25,7 @@
* @test
* @bug 8032410
* @summary Stack overflow at deoptimization doesn't release owned monitors
- * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss256K -XX:-UseOnStackReplacement TestStackBangMonitorOwned
+ * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss512K -XX:-UseOnStackReplacement TestStackBangMonitorOwned
*
*/
public class TestStackBangMonitorOwned {
diff --git a/hotspot/test/compiler/uncommontrap/TestStackBangRbp.java b/hotspot/test/compiler/uncommontrap/TestStackBangRbp.java
index 38d4e206..9b96951a 100644
--- a/hotspot/test/compiler/uncommontrap/TestStackBangRbp.java
+++ b/hotspot/test/compiler/uncommontrap/TestStackBangRbp.java
@@ -25,7 +25,7 @@
* @test
* @bug 8028308
* @summary rbp not restored when stack overflow is thrown from deopt/uncommon trap blobs
- * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangRbp::m1 -XX:CompileCommand=exclude,TestStackBangRbp::m2 -Xss256K -XX:-UseOnStackReplacement TestStackBangRbp
+ * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangRbp::m1 -XX:CompileCommand=exclude,TestStackBangRbp::m2 -Xss512K -XX:-UseOnStackReplacement TestStackBangRbp
*
*/
public class TestStackBangRbp {
diff --git a/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java b/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java
index b5859b5c..99ed508d 100644
--- a/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java
+++ b/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java
@@ -112,7 +112,7 @@ class TestMaxHeapSizeTools {
}
private static void checkInvalidMinInitialHeapCombinations(String gcflag) throws Exception {
- expectError(new String[] { gcflag, "-Xms8M", "-XX:InitialHeapSize=4M", "-version" });
+ expectError(new String[] { gcflag, "-Xms64M", "-XX:InitialHeapSize=32M", "-version" });
}
private static void checkValidMinInitialHeapCombinations(String gcflag) throws Exception {
diff --git a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java
index 473ce666..b6e5c3d6 100644
--- a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java
+++ b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java
@@ -31,7 +31,9 @@
import com.oracle.java.testlibrary.*;
public class TestHumongousAllocInitialMark {
- private static final int heapSize = 200; // MB
+ // Heap sizes < 224 MB are increased to 224 MB if vm_page_size == 64K to
+ // fulfill alignment constraints.
+ private static final int heapSize = 224; // MB
private static final int heapRegionSize = 1; // MB
private static final int initiatingHeapOccupancyPercent = 50; // %
diff --git a/hotspot/test/runtime/6929067/invoke.c b/hotspot/test/runtime/6929067/invoke.c
index 8dde2cd6..cf8014be 100644
--- a/hotspot/test/runtime/6929067/invoke.c
+++ b/hotspot/test/runtime/6929067/invoke.c
@@ -68,7 +68,7 @@ floobydust (void *p)
int
main (int argc, const char** argv)
{
- options[0].optionString = "-Xss320k";
+ options[0].optionString = "-Xss512k";
vm_args.version = JNI_VERSION_1_2;
vm_args.ignoreUnrecognized = JNI_TRUE;
diff --git a/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx b/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx
index 55213c0f..2bca88f1 100644
--- a/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx
+++ b/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx
@@ -48,7 +48,7 @@ floobydust (void *p) {
int
main (int argc, const char** argv) {
JavaVMOption options[1];
- options[0].optionString = (char*) "-Xss320k";
+ options[0].optionString = (char*) "-Xss512k";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;

View File

@ -0,0 +1,468 @@
From b48d4df404756872fb7b1ef7be5f9880ba6a0abc Mon Sep 17 00:00:00 2001
From: zhangyunbo <zhangyunbo7@huawei.com>
Date: Sun, 29 Jan 2023 10:44:01 +0800
Subject: [PATCH 07/15] 8074354: Make CreateMinidumpOnCrash a new name and
available on all platforms
DTS/AR: AR.SR.ccd816c9.001
Summary: <JDK> :8074354: Make CreateMinidumpOnCrash a new name and available on all platforms
LLT: NA
Patch Type: backport
Bug url: https://bugs.openjdk.org/browse/JDK-8074354
---
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 | 4 +
hotspot/src/os/posix/vm/os_posix.cpp | 4 +-
hotspot/src/os/solaris/vm/os_solaris.cpp | 4 +
hotspot/src/os/windows/vm/os_windows.cpp | 117 +++++++++---------
hotspot/src/share/vm/runtime/arguments.cpp | 9 ++
hotspot/src/share/vm/runtime/globals.hpp | 4 +-
hotspot/src/share/vm/runtime/os.hpp | 10 +-
hotspot/src/share/vm/utilities/vmError.cpp | 19 +--
hotspot/src/share/vm/utilities/vmError.hpp | 6 +-
hotspot/test/runtime/Unsafe/RangeCheck.java | 1 +
.../runtime/memory/ReadFromNoaccessArea.java | 1 +
.../test/runtime/memory/ReserveMemory.java | 1 +
14 files changed, 111 insertions(+), 77 deletions(-)
diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp
index 519b08550..6838f33bc 100644
--- a/hotspot/src/os/aix/vm/os_aix.cpp
+++ b/hotspot/src/os/aix/vm/os_aix.cpp
@@ -1214,6 +1214,10 @@ void os::shutdown() {
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
void os::abort(bool dump_core) {
+ abort(dump_core, NULL, NULL);
+}
+
+void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
#ifndef PRODUCT
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index 85e28619c..765b60c0d 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -1147,6 +1147,10 @@ void os::shutdown() {
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
void os::abort(bool dump_core) {
+ abort(dump_core, NULL, NULL);
+}
+
+void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
#ifndef PRODUCT
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index b82352c9f..05c8b254c 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -1588,6 +1588,10 @@ void os::shutdown() {
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
void os::abort(bool dump_core) {
+ abort(dump_core, NULL, NULL);
+}
+
+void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
#ifndef PRODUCT
diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp
index d2663bd86..678a1059f 100644
--- a/hotspot/src/os/posix/vm/os_posix.cpp
+++ b/hotspot/src/os/posix/vm/os_posix.cpp
@@ -48,7 +48,7 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#define ROOT_UID 0
// Check core dump limit and report possible place where core can be found
-void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
+void os::check_dump_limit(char* buffer, size_t bufferSize) {
int n;
struct rlimit rlim;
bool success;
@@ -74,7 +74,7 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
break;
}
}
- VMError::report_coredump_status(buffer, success);
+ VMError::record_coredump_status(buffer, success);
}
int os::get_native_stack(address* stack, int frames, int toSkip) {
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index d995f51e3..9f8c6a9bf 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -1581,6 +1581,10 @@ void os::shutdown() {
// called from signal handler. Before adding something to os::abort(), make
// sure it is async-safe and can handle partially initialized VM.
void os::abort(bool dump_core) {
+ abort(dump_core, NULL, NULL);
+}
+
+void os::abort(bool dump_core, void* siginfo, void* context) {
os::shutdown();
if (dump_core) {
#ifndef PRODUCT
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 23dec5b67..11bd14f6f 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -980,7 +980,43 @@ void os::shutdown() {
static BOOL (WINAPI *_MiniDumpWriteDump) ( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,
PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION);
-void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
+static HANDLE dumpFile = NULL;
+
+// Check if dump file can be created.
+void os::check_dump_limit(char* buffer, size_t buffsz) {
+ bool status = true;
+ if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {
+ jio_snprintf(buffer, buffsz, "CreateCoredumpOnCrash is disabled from command line");
+ status = false;
+ }
+
+#ifndef ASSERT
+ if (!os::win32::is_windows_server() && FLAG_IS_DEFAULT(CreateCoredumpOnCrash)) {
+ jio_snprintf(buffer, buffsz, "Minidumps are not enabled by default on client versions of Windows");
+ status = false;
+ }
+#endif
+
+ if (status) {
+ const char* cwd = get_current_directory(NULL, 0);
+ int pid = current_process_id();
+ if (cwd != NULL) {
+ jio_snprintf(buffer, buffsz, "%s\\hs_err_pid%u.mdmp", cwd, pid);
+ } else {
+ jio_snprintf(buffer, buffsz, ".\\hs_err_pid%u.mdmp", pid);
+ }
+
+ if (dumpFile == NULL &&
+ (dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))
+ == INVALID_HANDLE_VALUE) {
+ jio_snprintf(buffer, buffsz, "Failed to create minidump file (0x%x).", GetLastError());
+ status = false;
+ }
+ }
+ VMError::record_coredump_status(buffer, status);
+}
+
+void os::abort(bool dump_core, void* siginfo, void* context) {
HINSTANCE dbghelp;
EXCEPTION_POINTERS ep;
MINIDUMP_EXCEPTION_INFORMATION mei;
@@ -988,33 +1024,22 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
HANDLE hProcess = GetCurrentProcess();
DWORD processId = GetCurrentProcessId();
- HANDLE dumpFile;
MINIDUMP_TYPE dumpType;
- static const char* cwd;
-// Default is to always create dump for debug builds, on product builds only dump on server versions of Windows.
-#ifndef ASSERT
- // If running on a client version of Windows and user has not explicitly enabled dumping
- if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
- VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
- return;
- // If running on a server version of Windows and user has explictly disabled dumping
- } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
- VMError::report_coredump_status("Minidump has been disabled from the command line", false);
- return;
- }
-#else
- if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
- VMError::report_coredump_status("Minidump has been disabled from the command line", false);
- return;
+ shutdown();
+ if (!dump_core || dumpFile == NULL) {
+ if (dumpFile != NULL) {
+ CloseHandle(dumpFile);
+ }
+ win32::exit_process_or_thread(win32::EPT_PROCESS, 1);
}
-#endif
dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);
if (dbghelp == NULL) {
- VMError::report_coredump_status("Failed to load dbghelp.dll", false);
- return;
+ jio_fprintf(stderr, "Failed to load dbghelp.dll\n");
+ CloseHandle(dumpFile);
+ win32::exit_process_or_thread(win32::EPT_PROCESS, 1);
}
_MiniDumpWriteDump = CAST_TO_FN_PTR(
@@ -1023,30 +1048,22 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
GetProcAddress(dbghelp, "MiniDumpWriteDump"));
if (_MiniDumpWriteDump == NULL) {
- VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false);
- return;
+ jio_fprintf(stderr, "Failed to find MiniDumpWriteDump() in module dbghelp.dll.\n");
+ CloseHandle(dumpFile);
+ win32::exit_process_or_thread(win32::EPT_PROCESS, 1);
}
dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData);
-// Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with
-// API_VERSION_NUMBER 11 or higher contains the ones we want though
+ // Older versions of dbghelp.h do not contain all the dumptypes we want, dbghelp.h with
+ // API_VERSION_NUMBER 11 or higher contains the ones we want though
#if API_VERSION_NUMBER >= 11
dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo |
MiniDumpWithUnloadedModules);
#endif
-
- cwd = get_current_directory(NULL, 0);
- jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp",cwd, current_process_id());
- dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (dumpFile == INVALID_HANDLE_VALUE) {
- VMError::report_coredump_status("Failed to create file for dumping", false);
- return;
- }
- if (exceptionRecord != NULL && contextRecord != NULL) {
- ep.ContextRecord = (PCONTEXT) contextRecord;
- ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord;
+ if (siginfo != NULL && context != NULL) {
+ ep.ContextRecord = (PCONTEXT) context;
+ ep.ExceptionRecord = (PEXCEPTION_RECORD) siginfo;
mei.ThreadId = GetCurrentThreadId();
mei.ExceptionPointers = &ep;
@@ -1055,40 +1072,20 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
pmei = NULL;
}
-
// Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all
// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
- DWORD error = GetLastError();
- LPTSTR msgbuf = NULL;
-
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) {
-
- jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf);
- LocalFree(msgbuf);
- } else {
- // Call to FormatMessage failed, just include the result from GetLastError
- jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error);
- }
- VMError::report_coredump_status(buffer, false);
- } else {
- VMError::report_coredump_status(buffer, true);
+ jio_fprintf(stderr, "Call to MiniDumpWriteDump() failed (Error 0x%x)\n", GetLastError());
}
-
CloseHandle(dumpFile);
+ win32::exit_process_or_thread(win32::EPT_PROCESS, 1);
}
-
void os::abort(bool dump_core)
{
- os::shutdown();
- // no core dump on Windows
- ::exit(1);
+ abort(dump_core, NULL, NULL);
}
// Die immediately, no exit hook, no abort hook, no cleanup.
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index b0b541482..43fdd0b49 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -3599,6 +3599,15 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} else if (match_jfr_option(&option)) {
return JNI_EINVAL;
#endif
+ // CreateMinidumpOnCrash is removed, and replaced by CreateCoredumpOnCrash
+ } else if (match_option(option, "-XX:+CreateMinidumpOnCrash", &tail)) {
+ FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, true);
+ jio_fprintf(defaultStream::output_stream(),
+ "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is on\n");
+ } else if (match_option(option, "-XX:-CreateMinidumpOnCrash", &tail)) {
+ FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, false);
+ jio_fprintf(defaultStream::output_stream(),
+ "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is off\n");
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
// Skip -XX:Flags= since that case has already been handled
if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 3dd4c51a9..3b2776ce5 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -948,8 +948,8 @@ class CommandLineFlags {
product(bool, ShowMessageBoxOnError, false, \
"Keep process alive on VM fatal error") \
\
- product(bool, CreateMinidumpOnCrash, false, \
- "Create minidump on VM fatal error") \
+ product(bool, CreateCoredumpOnCrash, true, \
+ "Create core/mini dump on VM fatal error") \
\
product_pd(bool, UseOSErrorReporting, \
"Let VM fatal error propagate to the OS (ie. WER on Windows)") \
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index 092459c99..e696321ab 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -553,6 +553,7 @@ class os: AllStatic {
// Terminate with an error. Default is to generate a core file on platforms
// that support such things. This calls shutdown() and then aborts.
+ static void abort(bool dump_core, void *siginfo, void *context);
static void abort(bool dump_core = true);
// Die immediately, no exit hook, no abort hook, no cleanup.
@@ -803,8 +804,13 @@ class os: AllStatic {
// Structured OS Exception support
static void os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
- // On Windows this will create an actual minidump, on Linux/Solaris it will simply check core dump limits
- static void check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize);
+ // On Posix compatible OS it will simply check core dump limits while on Windows
+ // it will check if dump file can be created. Check or prepare a core dump to be
+ // taken at a later point in the same thread in os::abort(). Use the caller
+ // provided buffer as a scratch buffer. The status message which will be written
+ // into the error log either is file location or a short error message, depending
+ // on the checking result.
+ static void check_dump_limit(char* buffer, size_t bufferSize);
// Get the default path to the core file
// Returns the length of the string
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index 26408fa5e..56ae50fe5 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -220,7 +220,7 @@ static void print_bug_submit_message(outputStream *out, Thread *thread) {
bool VMError::coredump_status;
char VMError::coredump_message[O_BUFLEN];
-void VMError::report_coredump_status(const char* message, bool status) {
+void VMError::record_coredump_status(const char* message, bool status) {
coredump_status = status;
strncpy(coredump_message, message, sizeof(coredump_message));
coredump_message[sizeof(coredump_message)-1] = 0;
@@ -533,10 +533,14 @@ void VMError::report(outputStream* st) {
}
STEP(63, "(printing core file information)")
st->print("# ");
- if (coredump_status) {
- st->print("Core dump written. Default location: %s", coredump_message);
+ if (CreateCoredumpOnCrash) {
+ if (coredump_status) {
+ st->print("Core dump will be written. %s", coredump_message);
+ } else {
+ st->print("No core dump will be written. %s", coredump_message);
+ }
} else {
- st->print("Failed to write core dump. %s", coredump_message);
+ st->print("CreateCoredumpOnCrash turned off, no core file dumped");
}
st->cr();
st->print_cr("#");
@@ -944,7 +948,7 @@ void VMError::report_and_die() {
static bool transmit_report_done = false; // done error reporting
if (SuppressFatalErrorMessage) {
- os::abort();
+ os::abort(CreateCoredumpOnCrash);
}
jlong mytid = os::current_thread_id();
if (first_error == NULL &&
@@ -962,8 +966,7 @@ void VMError::report_and_die() {
ShowMessageBoxOnError = false;
}
- // Write a minidump on Windows, check core dump limits on Linux/Solaris
- os::check_or_create_dump(_siginfo, _context, buffer, sizeof(buffer));
+ os::check_dump_limit(buffer, sizeof(buffer));
// reset signal handlers or exception filter; make sure recursive crashes
// are handled properly.
@@ -1153,7 +1156,7 @@ void VMError::report_and_die() {
if (!skip_os_abort) {
skip_os_abort = true;
bool dump_core = should_report_bug(first_error->_id);
- os::abort(dump_core);
+ os::abort(dump_core && CreateCoredumpOnCrash, _siginfo, _context);
}
// if os::abort() doesn't abort, try os::die();
diff --git a/hotspot/src/share/vm/utilities/vmError.hpp b/hotspot/src/share/vm/utilities/vmError.hpp
index 21db84d0c..dc455c6fa 100644
--- a/hotspot/src/share/vm/utilities/vmError.hpp
+++ b/hotspot/src/share/vm/utilities/vmError.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -117,8 +117,8 @@ public:
// return a string to describe the error
char *error_string(char* buf, int buflen);
- // Report status of core/minidump
- static void report_coredump_status(const char* message, bool status);
+ // Record status of core/minidump
+ static void record_coredump_status(const char* message, bool status);
// main error reporting function
void report_and_die();
diff --git a/hotspot/test/runtime/Unsafe/RangeCheck.java b/hotspot/test/runtime/Unsafe/RangeCheck.java
index 9ded944cb..602f22500 100644
--- a/hotspot/test/runtime/Unsafe/RangeCheck.java
+++ b/hotspot/test/runtime/Unsafe/RangeCheck.java
@@ -43,6 +43,7 @@ public class RangeCheck {
true,
"-Xmx32m",
"-XX:-TransmitErrorReport",
+ "-XX:-CreateCoredumpOnCrash",
DummyClassWithMainRangeCheck.class.getName());
OutputAnalyzer output = new OutputAnalyzer(pb.start());
diff --git a/hotspot/test/runtime/memory/ReadFromNoaccessArea.java b/hotspot/test/runtime/memory/ReadFromNoaccessArea.java
index 1078dd2e4..b2a58ae0a 100644
--- a/hotspot/test/runtime/memory/ReadFromNoaccessArea.java
+++ b/hotspot/test/runtime/memory/ReadFromNoaccessArea.java
@@ -45,6 +45,7 @@ public class ReadFromNoaccessArea {
"-Xbootclasspath/a:.",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
+ "-XX:-CreateCoredumpOnCrash",
"-XX:+UseCompressedOops",
"-XX:HeapBaseMinAddress=33G",
DummyClassWithMainTryingToReadFromNoaccessArea.class.getName());
diff --git a/hotspot/test/runtime/memory/ReserveMemory.java b/hotspot/test/runtime/memory/ReserveMemory.java
index 9e37d52cc..ef4dde1a7 100644
--- a/hotspot/test/runtime/memory/ReserveMemory.java
+++ b/hotspot/test/runtime/memory/ReserveMemory.java
@@ -57,6 +57,7 @@ public class ReserveMemory {
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"-XX:-TransmitErrorReport",
+ "-XX:-CreateCoredumpOnCrash",
"ReserveMemory",
"test");
--
2.19.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
From 42bb9ed9c5d4b0c8b07fb184ce1ab26718b376a5 Mon Sep 17 00:00:00 2001
Subject: 8148470: Metadata print routines should not print to tty
---
hotspot/src/share/vm/oops/metadata.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hotspot/src/share/vm/oops/metadata.hpp b/hotspot/src/share/vm/oops/metadata.hpp
index 372faa953..34dd66afd 100644
--- a/hotspot/src/share/vm/oops/metadata.hpp
+++ b/hotspot/src/share/vm/oops/metadata.hpp
@@ -60,13 +60,13 @@ class Metadata : public MetaspaceObj {
if (this == NULL)
st->print("NULL");
else
- print_on(tty);
+ print_on(st);
}
void print_value_on_maybe_null(outputStream* st) const {
if (this == NULL)
st->print("NULL");
else
- print_value_on(tty);
+ print_value_on(st);
}
virtual void print_on(outputStream* st) const; // First level print
--
2.22.0

View File

@ -1,114 +0,0 @@
From 717ae5f43045b1e2d6f95c52fbd81c54ebf50977 Mon Sep 17 00:00:00 2001
Date: Fri, 16 Sep 2022 01:12:20 +0000
Subject: 8159720: Failure of C2 compilation with tiered prevents some
C1 compilations.
---
hotspot/src/share/vm/opto/compile.cpp | 2 +-
hotspot/src/share/vm/opto/compile.hpp | 10 +++-------
hotspot/src/share/vm/opto/matcher.cpp | 8 ++++----
hotspot/src/share/vm/opto/parse1.cpp | 4 ++--
4 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index 5a42422e1..4a32e8a9f 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -791,7 +791,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
}
if (failing()) return;
if (cg == NULL) {
- record_method_not_compilable_all_tiers("cannot parse method");
+ record_method_not_compilable("cannot parse method");
return;
}
JVMState* jvms = build_start_state(start(), tf());
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index 1150fd549..fb12b6874 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -742,16 +742,12 @@ class Compile : public Phase {
bool failure_reason_is(const char* r) { return (r==_failure_reason) || (r!=NULL && _failure_reason!=NULL && strcmp(r, _failure_reason)==0); }
void record_failure(const char* reason);
- void record_method_not_compilable(const char* reason, bool all_tiers = false) {
- // All bailouts cover "all_tiers" when TieredCompilation is off.
- if (!TieredCompilation) all_tiers = true;
- env()->record_method_not_compilable(reason, all_tiers);
+ void record_method_not_compilable(const char* reason) {
+ // Bailouts cover "all_tiers" when TieredCompilation is off.
+ env()->record_method_not_compilable(reason, !TieredCompilation);
// Record failure reason.
record_failure(reason);
}
- void record_method_not_compilable_all_tiers(const char* reason) {
- record_method_not_compilable(reason, true);
- }
bool check_node_count(uint margin, const char* reason) {
if (live_nodes() + margin > max_node_limit()) {
record_method_not_compilable(reason);
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
index 07b8ee4c6..b26015ce6 100644
--- a/hotspot/src/share/vm/opto/matcher.cpp
+++ b/hotspot/src/share/vm/opto/matcher.cpp
@@ -137,7 +137,7 @@ OptoReg::Name Matcher::warp_incoming_stk_arg( VMReg reg ) {
_in_arg_limit = OptoReg::add(warped, 1); // Bump max stack slot seen
if (!RegMask::can_represent_arg(warped)) {
// the compiler cannot represent this method's calling sequence
- C->record_method_not_compilable_all_tiers("unsupported incoming calling sequence");
+ C->record_method_not_compilable("unsupported incoming calling sequence");
return OptoReg::Bad;
}
return warped;
@@ -1148,7 +1148,7 @@ OptoReg::Name Matcher::warp_outgoing_stk_arg( VMReg reg, OptoReg::Name begin_out
if( warped >= out_arg_limit_per_call )
out_arg_limit_per_call = OptoReg::add(warped,1);
if (!RegMask::can_represent_arg(warped)) {
- C->record_method_not_compilable_all_tiers("unsupported calling sequence");
+ C->record_method_not_compilable("unsupported calling sequence");
return OptoReg::Bad;
}
return warped;
@@ -1327,7 +1327,7 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
uint r_cnt = mcall->tf()->range()->cnt();
MachProjNode *proj = new (C) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj );
if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) {
- C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence");
+ C->record_method_not_compilable("unsupported outgoing calling sequence");
} else {
for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
proj->_rout.Insert(OptoReg::Name(i));
@@ -1515,7 +1515,7 @@ Node *Matcher::Label_Root( const Node *n, State *svec, Node *control, const Node
// out of stack space. See bugs 6272980 & 6227033 for more info.
LabelRootDepth++;
if (LabelRootDepth > MaxLabelRootDepth) {
- C->record_method_not_compilable_all_tiers("Out of stack space, increase MaxLabelRootDepth");
+ C->record_method_not_compilable("Out of stack space, increase MaxLabelRootDepth");
return NULL;
}
uint care = 0; // Edges matcher cares about
diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp
index a9ef4f910..4fcd58cb4 100644
--- a/hotspot/src/share/vm/opto/parse1.cpp
+++ b/hotspot/src/share/vm/opto/parse1.cpp
@@ -415,7 +415,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
_iter.reset_to_method(method());
_flow = method()->get_flow_analysis();
if (_flow->failing()) {
- C->record_method_not_compilable_all_tiers(_flow->failure_reason());
+ C->record_method_not_compilable(_flow->failure_reason());
}
#ifndef PRODUCT
@@ -1088,7 +1088,7 @@ SafePointNode* Parse::create_entry_map() {
// Check for really stupid bail-out cases.
uint len = TypeFunc::Parms + method()->max_locals() + method()->max_stack();
if (len >= 32760) {
- C->record_method_not_compilable_all_tiers("too many local variables");
+ C->record_method_not_compilable("too many local variables");
return NULL;
}
--
2.18.0.huawei.25

View File

@ -117,14 +117,14 @@ index 000000000..fb6618688
+import java.nio.channels.OverlappingFileLockException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import jdk.test.lib.util.FileUtils;
+import jdk.testlibrary.FileUtils;
+
+/*
+ * @test
+ * @bug 8166253
+ * @summary Verify that OverlappingFileLockException is thrown when expected.
+ * @library .. /test/lib
+ * @build jdk.test.lib.util.FileUtils
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.Utils
+ * @run main/othervm FileLockGC
+ */
+public class FileLockGC {

View File

@ -0,0 +1,221 @@
From 5fbf4e8b326dd8453822ae40f3c6e4adffbf42ac Mon Sep 17 00:00:00 2001
From: zhangyipeng <zhangyipeng7@huawei.com>
Date: Fri, 3 Nov 2023 16:21:09 +0800
Subject: [PATCH] [Backport]8177146: MethodHandles.Lookup::bind allows illegal protected
access
---
.../classes/java/lang/invoke/MethodHandles.java | 22 +++--
.../lang/invoke/8177146/TestMethodHandleBind.java | 96 ++++++++++++++++++++++
jdk/test/java/lang/invoke/8177146/pkg/A.java | 40 +++++++++
3 files changed, 149 insertions(+), 9 deletions(-)
create mode 100644 jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
create mode 100644 jdk/test/java/lang/invoke/8177146/pkg/A.java
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
index 7b9353ab0..62888c019 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -1148,7 +1148,13 @@ return mh1;
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
Class<? extends Object> refc = receiver.getClass(); // may get NPE
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
- MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
+ MethodHandle mh = getDirectMethodNoRestrictInvokeSpecial(refc, method, findBoundCallerClass(method));
+ if (!mh.type().leadingReferenceParameter().isAssignableFrom(receiver.getClass())) {
+ throw new IllegalAccessException("The restricted defining class " +
+ mh.type().leadingReferenceParameter().getName() +
+ " is not assignable from receiver class " +
+ receiver.getClass().getName());
+ }
return mh.bindArgumentL(0, receiver).setVarargs(method);
}
@@ -1591,7 +1597,7 @@ return mh1;
throw method.makeAccessException("caller class must be a subclass below the method", caller);
}
MethodType rawType = mh.type();
- if (rawType.parameterType(0) == caller) return mh;
+ if (caller.isAssignableFrom(rawType.parameterType(0))) return mh; // no need to restrict; already narrow
MethodType narrowType = rawType.changeParameterType(0, caller);
assert(!mh.isVarargsCollector()); // viewAsType will lose varargs-ness
assert(mh.viewAsTypeChecks(narrowType, true));
@@ -1604,11 +1610,11 @@ return mh1;
final boolean checkSecurity = true;
return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
}
- /** Check access and get the requested method, eliding receiver narrowing rules. */
- private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
+ /** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
+ private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
final boolean doRestrict = false;
final boolean checkSecurity = true;
- return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
+ return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerClass);
}
/** Check access and get the requested method, eliding security manager checks. */
private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
@@ -1660,10 +1666,8 @@ return mh1;
DirectMethodHandle dmh = DirectMethodHandle.make(refKind, refc, method);
MethodHandle mh = dmh;
// Optionally narrow the receiver argument to refc using restrictReceiver.
- if (doRestrict &&
- (refKind == REF_invokeSpecial ||
- (MethodHandleNatives.refKindHasReceiver(refKind) &&
- restrictProtectedReceiver(method)))) {
+ if ((doRestrict && refKind == REF_invokeSpecial) ||
+ (MethodHandleNatives.refKindHasReceiver(refKind) && restrictProtectedReceiver(method))) {
mh = restrictReceiver(method, dmh, lookupClass());
}
mh = maybeBindCaller(method, mh, callerClass);
diff --git a/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java b/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
new file mode 100644
index 000000000..134cc9f75
--- /dev/null
+++ b/jdk/test/java/lang/invoke/8177146/TestMethodHandleBind.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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 8177146
+ * @run testng/othervm TestMethodHandleBind
+ */
+
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+import static java.lang.invoke.MethodHandles.lookup;
+
+import static org.testng.Assert.*;
+
+public class TestMethodHandleBind extends pkg.A {
+ static class B extends TestMethodHandleBind {}
+
+ @Test
+ public void testInstanceOfCallerClass() throws Throwable {
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m1", MethodType.methodType(String.class));
+ String x = (String)bound.invoke();
+ assertEquals(x, this.getClass().getSimpleName());
+ }
+
+ @Test
+ public void testInstanceOfCallerSubclass() throws Throwable {
+ MethodHandle bound = lookup().bind(new B() , "m1", MethodType.methodType(String.class));
+ // MethodHandle bound = lookup().findVirtual(B.class, "m1", MethodType.methodType(String.class)).bindTo(new B());
+ String x = (String)bound.invoke();
+ assertEquals(x, "B");
+ }
+
+ @Test
+ public void testInstanceOfReceiverClass() throws Throwable {
+ try {
+ MethodHandle bound = lookup().bind(new pkg.A() , "m1", MethodType.methodType(String.class));
+ bound.invoke();
+ fail("IllegalAccessException expected");
+ } catch (IllegalAccessException e) {
+ }
+ }
+
+ @Test
+ public void testPublicMethod() throws Throwable {
+ MethodHandle bound = lookup().bind(new pkg.A() , "m2", MethodType.methodType(String.class));
+ String x = (String)bound.invoke();
+ assertEquals(x, "A");
+ }
+
+ @Test
+ public void testPublicMethod2() throws Throwable {
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind(), "m2", MethodType.methodType(String.class));
+ String x = (String)bound.invoke();
+ assertEquals(x, this.getClass().getSimpleName());
+ }
+
+ @Test
+ public void testInstanceOfCallerClassVarargs() throws Throwable {
+ MethodHandle bound = lookup().bind(new TestMethodHandleBind() , "m3", MethodType.methodType(String.class, String[].class));
+ String x = (String)bound.invoke("a", "b", "c");
+ assertEquals(x, this.getClass().getSimpleName() + "abc");
+ }
+
+ @Test
+ public void testInstanceOfReceiverClassVarargs() throws Throwable {
+ try {
+ MethodHandle bound = lookup().bind(new pkg.A(), "m3", MethodType.methodType(String.class, String[].class));
+ bound.invoke();
+ fail("IllegalAccessException expected");
+ } catch (IllegalAccessException e) {
+ }
+ }
+}
diff --git a/jdk/test/java/lang/invoke/8177146/pkg/A.java b/jdk/test/java/lang/invoke/8177146/pkg/A.java
new file mode 100644
index 000000000..f34d52b8e
--- /dev/null
+++ b/jdk/test/java/lang/invoke/8177146/pkg/A.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, 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 pkg;
+
+public class A {
+ protected String m1() {
+ return this.getClass().getSimpleName();
+ }
+
+ public String m2() {
+ return this.getClass().getSimpleName();
+ }
+
+ protected String m3(String... args) {
+ StringBuilder sb = new StringBuilder();
+ for (String s : args)
+ sb.append(s);
+ return this.getClass().getSimpleName() + sb.toString();
+ }
+}
--
2.12.3

View File

@ -0,0 +1,25 @@
From bf0ddc70f543a1847d8822bc01537322aa5bbe6d Mon Sep 17 00:00:00 2001
From: hedongbo <hedongbo@huawei.com>
Date: Thu, 5 Jan 2023 19:40:11 +0000
Subject: 8178968: AArch64: Remove non-standard code cache size
---
hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp | 4 ----
1 file changed, 4 deletions(-)
diff --git a/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp
index f15ed99fb..ed623c435 100644
--- a/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp
+++ b/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp
@@ -37,8 +37,4 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
#define SUPPORTS_NATIVE_CX8
-// The maximum B/BL offset range on AArch64 is 128MB.
-#undef CODE_CACHE_DEFAULT_LIMIT
-#define CODE_CACHE_DEFAULT_LIMIT (128*M)
-
#endif // CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
--
2.12.3

View File

@ -0,0 +1,53 @@
From b1c3eca9320e83db1fe6fe281c2d4a8875e8f16b Mon Sep 17 00:00:00 2001
Date: Thu, 27 Jul 2023 20:07:00 +0800
Subject: [PATCH] [Backport]8179273: sun.net.httpserver.LeftOverInputStream should stop
attempting to drain the stream when the server is stopped
---
.../classes/sun/net/httpserver/LeftOverInputStream.java | 7 +++++--
jdk/src/share/classes/sun/net/httpserver/ServerImpl.java | 4 ++++
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/jdk/src/share/classes/sun/net/httpserver/LeftOverInputStream.java b/jdk/src/share/classes/sun/net/httpserver/LeftOverInputStream.java
index c715d72ad..d3a6e1b08 100644
--- a/jdk/src/share/classes/sun/net/httpserver/LeftOverInputStream.java
+++ b/jdk/src/share/classes/sun/net/httpserver/LeftOverInputStream.java
@@ -41,8 +41,8 @@ import com.sun.net.httpserver.spi.*;
* isEOF() returns true, when all expected bytes have been read
*/
abstract class LeftOverInputStream extends FilterInputStream {
- ExchangeImpl t;
- ServerImpl server;
+ final ExchangeImpl t;
+ final ServerImpl server;
protected boolean closed = false;
protected boolean eof = false;
byte[] one = new byte [1];
@@ -109,6 +109,9 @@ abstract class LeftOverInputStream extends FilterInputStream {
int bufSize = 2048;
byte[] db = new byte [bufSize];
while (l > 0) {
+ if (server.isFinishing()) {
+ break;
+ }
long len = readImpl (db, 0, bufSize);
if (len == -1) {
eof = true;
diff --git a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
index a5adbf609..271a5bbc7 100644
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
@@ -219,6 +219,10 @@ class ServerImpl {
return httpsConfig;
}
+ public final boolean isFinishing() {
+ return finished;
+ }
+
public void stop (int delay) {
if (delay < 0) {
throw new IllegalArgumentException ("negative delay parameter");
--
2.19.1

View File

@ -0,0 +1,53 @@
From da7a2005a2c181737b163f60dd705acc00002463 Mon Sep 17 00:00:00 2001
From: hedongbo <hedongbo@huawei.com>
Date: Thu, 5 Jan 2023 10:22:15 +0000
Subject: 8185736: missing default exception handler in calls to
rethrow_Stub
---
hotspot/src/share/vm/opto/doCall.cpp | 9 +++++++++
hotspot/src/share/vm/opto/output.cpp | 1 +
2 files changed, 10 insertions(+)
diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp
index 366769356..1b2b77c71 100644
--- a/hotspot/src/share/vm/opto/doCall.cpp
+++ b/hotspot/src/share/vm/opto/doCall.cpp
@@ -702,6 +702,7 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
GrowableArray<const Type*>* extypes = new (C->node_arena()) GrowableArray<const Type*>(C->node_arena(), 8, 0, NULL);
GrowableArray<int>* saw_unloaded = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, 0);
+ bool default_handler = false;
for (; !handlers.is_done(); handlers.next()) {
ciExceptionHandler* h = handlers.handler();
int h_bci = h->handler_bci();
@@ -724,6 +725,14 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
// Note: It's OK if the BCIs repeat themselves.
bcis->append(h_bci);
extypes->append(h_extype);
+ if (h_bci == -1) {
+ default_handler = true;
+ }
+ }
+
+ if (!default_handler) {
+ bcis->append(-1);
+ extypes->append(TypeOopPtr::make_from_klass(env()->Throwable_klass())->is_instptr());
}
int len = bcis->length();
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index 5c9566e1e..6032b72a9 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -1761,6 +1761,7 @@ void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_start
}
// Set the offset of the return from the call
+ assert(handler_bcis.find(-1) != -1, "must have default handler");
_handler_table.add_subtable(call_return, &handler_bcis, NULL, &handler_pcos);
continue;
}
--
2.12.3

View File

@ -0,0 +1,352 @@
From ba4213c7350e7a145a142d0cbe54718a8c92b93c Mon Sep 17 00:00:00 2001
Subject: 8193682: Infinite loop in ZipOutputStream.close()
---
.../java/util/zip/DeflaterOutputStream.java | 9 +-
.../java/util/zip/GZIPOutputStream.java | 38 +++--
.../java/util/zip/ZipOutputStream.java | 96 ++++++------
jdk/test/java/util/zip/CloseDeflaterTest.java | 147 ++++++++++++++++++
4 files changed, 226 insertions(+), 64 deletions(-)
create mode 100644 jdk/test/java/util/zip/CloseDeflaterTest.java
diff --git a/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java b/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java
index a1f768cae..f4cf79693 100644
--- a/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java
+++ b/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java
@@ -235,9 +235,12 @@ class DeflaterOutputStream extends FilterOutputStream {
*/
public void close() throws IOException {
if (!closed) {
- finish();
- if (usesDefaultDeflater)
- def.end();
+ try {
+ finish();
+ } finally {
+ if (usesDefaultDeflater)
+ def.end();
+ }
out.close();
closed = true;
}
diff --git a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
index 2c1cd409b..1c3f8592e 100644
--- a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
+++ b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
@@ -154,24 +154,30 @@ class GZIPOutputStream extends DeflaterOutputStream {
*/
public void finish() throws IOException {
if (!def.finished()) {
- def.finish();
- while (!def.finished()) {
- int len = def.deflate(buf, 0, buf.length);
- if (def.finished() && len <= buf.length - TRAILER_SIZE) {
- // last deflater buffer. Fit trailer at the end
- writeTrailer(buf, len);
- len = len + TRAILER_SIZE;
- out.write(buf, 0, len);
- return;
+ try {
+ def.finish();
+ while (!def.finished()) {
+ int len = def.deflate(buf, 0, buf.length);
+ if (def.finished() && len <= buf.length - TRAILER_SIZE) {
+ // last deflater buffer. Fit trailer at the end
+ writeTrailer(buf, len);
+ len = len + TRAILER_SIZE;
+ out.write(buf, 0, len);
+ return;
+ }
+ if (len > 0)
+ out.write(buf, 0, len);
}
- if (len > 0)
- out.write(buf, 0, len);
+ // if we can't fit the trailer at the end of the last
+ // deflater buffer, we write it separately
+ byte[] trailer = new byte[TRAILER_SIZE];
+ writeTrailer(trailer, 0);
+ out.write(trailer);
+ } catch (IOException e) {
+ if (usesDefaultDeflater)
+ def.end();
+ throw e;
}
- // if we can't fit the trailer at the end of the last
- // deflater buffer, we write it separately
- byte[] trailer = new byte[TRAILER_SIZE];
- writeTrailer(trailer, 0);
- out.write(trailer);
}
}
diff --git a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java
index 6b480aa1d..f001ddf00 100644
--- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java
+++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java
@@ -247,59 +247,65 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
public void closeEntry() throws IOException {
ensureOpen();
if (current != null) {
- ZipEntry e = current.entry;
- switch (e.method) {
- case DEFLATED:
- def.finish();
- while (!def.finished()) {
- deflate();
- }
- if ((e.flag & 8) == 0) {
- // verify size, compressed size, and crc-32 settings
- if (e.size != def.getBytesRead()) {
- throw new ZipException(
- "invalid entry size (expected " + e.size +
- " but got " + def.getBytesRead() + " bytes)");
+ try {
+ ZipEntry e = current.entry;
+ switch (e.method) {
+ case DEFLATED:
+ def.finish();
+ while (!def.finished()) {
+ deflate();
}
- if (e.csize != def.getBytesWritten()) {
+ if ((e.flag & 8) == 0) {
+ // verify size, compressed size, and crc-32 settings
+ if (e.size != def.getBytesRead()) {
+ throw new ZipException(
+ "invalid entry size (expected " + e.size +
+ " but got " + def.getBytesRead() + " bytes)");
+ }
+ if (e.csize != def.getBytesWritten()) {
+ throw new ZipException(
+ "invalid entry compressed size (expected " +
+ e.csize + " but got " + def.getBytesWritten() + " bytes)");
+ }
+ if (e.crc != crc.getValue()) {
+ throw new ZipException(
+ "invalid entry CRC-32 (expected 0x" +
+ Long.toHexString(e.crc) + " but got 0x" +
+ Long.toHexString(crc.getValue()) + ")");
+ }
+ } else {
+ e.size = def.getBytesRead();
+ e.csize = def.getBytesWritten();
+ e.crc = crc.getValue();
+ writeEXT(e);
+ }
+ def.reset();
+ written += e.csize;
+ break;
+ case STORED:
+ // we already know that both e.size and e.csize are the same
+ if (e.size != written - locoff) {
throw new ZipException(
- "invalid entry compressed size (expected " +
- e.csize + " but got " + def.getBytesWritten() + " bytes)");
+ "invalid entry size (expected " + e.size +
+ " but got " + (written - locoff) + " bytes)");
}
if (e.crc != crc.getValue()) {
throw new ZipException(
- "invalid entry CRC-32 (expected 0x" +
- Long.toHexString(e.crc) + " but got 0x" +
- Long.toHexString(crc.getValue()) + ")");
+ "invalid entry crc-32 (expected 0x" +
+ Long.toHexString(e.crc) + " but got 0x" +
+ Long.toHexString(crc.getValue()) + ")");
}
- } else {
- e.size = def.getBytesRead();
- e.csize = def.getBytesWritten();
- e.crc = crc.getValue();
- writeEXT(e);
+ break;
+ default:
+ throw new ZipException("invalid compression method");
}
- def.reset();
- written += e.csize;
- break;
- case STORED:
- // we already know that both e.size and e.csize are the same
- if (e.size != written - locoff) {
- throw new ZipException(
- "invalid entry size (expected " + e.size +
- " but got " + (written - locoff) + " bytes)");
- }
- if (e.crc != crc.getValue()) {
- throw new ZipException(
- "invalid entry crc-32 (expected 0x" +
- Long.toHexString(e.crc) + " but got 0x" +
- Long.toHexString(crc.getValue()) + ")");
- }
- break;
- default:
- throw new ZipException("invalid compression method");
+ crc.reset();
+ current = null;
+ } catch (IOException e) {
+ if (usesDefaultDeflater && !(e instanceof ZipException))
+ def.end();
+ throw e;
}
- crc.reset();
- current = null;
}
}
diff --git a/jdk/test/java/util/zip/CloseDeflaterTest.java b/jdk/test/java/util/zip/CloseDeflaterTest.java
new file mode 100644
index 000000000..8aa4960f5
--- /dev/null
+++ b/jdk/test/java/util/zip/CloseDeflaterTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 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
+ * 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 8193682
+ * @summary Test Infinite loop while writing on closed GZipOutputStream , ZipOutputStream and JarOutputStream.
+ * @run testng CloseDeflaterTest
+ */
+import java.io.*;
+import java.util.Random;
+import java.util.jar.JarOutputStream;
+import java.util.zip.GZIPOutputStream;
+import java.util.zip.ZipOutputStream;
+import java.util.zip.ZipEntry;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.fail;
+
+
+public class CloseDeflaterTest {
+
+ //number of bytes to write
+ private static final int INPUT_LENGTH= 512;
+ //OutputStream that will throw an exception during a write operation
+ private static OutputStream outStream = new OutputStream() {
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ //throw exception during write
+ throw new IOException();
+ }
+ @Override
+ public void write(byte b[]) throws IOException {}
+ @Override
+ public void write(int b) throws IOException {}
+ };
+ private static byte[] inputBytes = new byte[INPUT_LENGTH];
+ private static Random rand = new Random();
+
+ @DataProvider(name = "testgzipinput")
+ public Object[][] testGZipInput() {
+ //testGZip will close the GZipOutputStream using close() method when the boolean
+ //useCloseMethod is set to true and finish() method if the value is set to false
+ return new Object[][] {
+ { GZIPOutputStream.class, true },
+ { GZIPOutputStream.class, false },
+ };
+ }
+
+ @DataProvider(name = "testzipjarinput")
+ public Object[][] testZipAndJarInput() {
+ //testZipAndJarInput will perfrom write/closeEntry operations on JarOutputStream when the boolean
+ //useJar is set to true and on ZipOutputStream if the value is set to false
+ return new Object[][] {
+ { JarOutputStream.class, true },
+ { ZipOutputStream.class, false },
+ };
+ }
+
+ @BeforeTest
+ public void before_test()
+ {
+ //add inputBytes array with random bytes to write into Zip
+ rand.nextBytes(inputBytes);
+ }
+
+ //Test for infinite loop by writing bytes to closed GZIPOutputStream
+ @Test(dataProvider = "testgzipinput")
+ public void testGZip(Class<?> type, boolean useCloseMethod) throws IOException {
+ GZIPOutputStream zip = new GZIPOutputStream(outStream);
+ try {
+ zip.write(inputBytes, 0, INPUT_LENGTH);
+ //close zip
+ if(useCloseMethod) {
+ zip.close();
+ } else {
+ zip.finish();
+ }
+ } catch (IOException e) {
+ //expected
+ }
+ for (int i = 0; i < 3; i++) {
+ try {
+ //write on a closed GZIPOutputStream
+ zip.write(inputBytes, 0, INPUT_LENGTH);
+ fail("Deflater closed exception not thrown");
+ } catch (NullPointerException e) {
+ //expected , Deflater has been closed exception
+ }
+ }
+ }
+
+ //Test for infinite loop by writing bytes to closed ZipOutputStream/JarOutputStream
+ @Test(dataProvider = "testzipjarinput")
+ public void testZipCloseEntry(Class<?> type,boolean useJar) throws IOException {
+ ZipOutputStream zip = null;
+ if(useJar) {
+ zip = new JarOutputStream(outStream);
+ } else {
+ zip = new ZipOutputStream(outStream);
+ }
+ try {
+ zip.putNextEntry(new ZipEntry(""));
+ } catch (IOException e) {
+ //expected to throw IOException since putNextEntry calls write method
+ }
+ try {
+ zip.write(inputBytes, 0, INPUT_LENGTH);
+ //close zip entry
+ zip.closeEntry();
+ } catch (IOException e) {
+ //expected
+ }
+ for (int i = 0; i < 3; i++) {
+ try {
+ //write on a closed ZipOutputStream
+ zip.write(inputBytes, 0, INPUT_LENGTH);
+ fail("Deflater closed exception not thrown");
+ } catch (NullPointerException e) {
+ //expected , Deflater has been closed exception
+ }
+ }
+ }
+
+}
--
2.22.0

View File

@ -153,21 +153,18 @@ new file mode 100644
index 000000000..92950cf68
--- /dev/null
+++ b/hotspot/test/gc/g1/TestFromCardCacheIndex.java
@@ -0,0 +1,119 @@
@@ -0,0 +1,116 @@
+/*
+ * @test TestFromCardCacheIndex.java
+ * @bug 8196485
+ * @summary Ensure that G1 does not miss a remembered set entry due to from card cache default value indices.
+ * @key gc
+ * @requires vm.gc.G1
+ * @requires vm.debug
+ * @requires vm.bits != "32"
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @library /testlibrary/whitebox /testlibrary
+ * @modules java.base/jdk.internal.misc java.management
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -Xms20M -Xmx20M -XX:+UseCompressedOops -XX:G1HeapRegionSize=1M -XX:HeapBaseMinAddress=2199011721216 -XX:+UseG1GC -verbose:gc TestFromCardCacheIndex
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -Xms20M -Xmx20M -XX:+UseCompressedOops -XX:G1HeapRegionSize=1M -XX:HeapBaseMinAddress=2199011721216 -XX:+UseG1GC -verbose:gc TestFromCardCacheIndex
+ */
+
+import sun.hotspot.WhiteBox;

View File

@ -129,7 +129,7 @@ index 61627e4..bd35e95 100644
if (internal_format) {
p->trace_stack();
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
index fcd4814..be53498 100644
index 7d80daba..0e126964 100644
--- a/hotspot/src/share/vm/runtime/thread.hpp
+++ b/hotspot/src/share/vm/runtime/thread.hpp
@@ -41,6 +41,7 @@
@ -162,22 +162,22 @@ index fcd4814..be53498 100644
void set_lgrp_id(int value) { _lgrp_id = value; }
// Printing
- void print_on(outputStream* st) const;
- virtual void print_on(outputStream* st) const;
+ void print_on(outputStream* st, bool print_extended_info) const;
+ void print_on(outputStream* st) const { print_on(st, false); }
void print() const { print_on(tty); }
virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
@@ -1463,7 +1469,8 @@ class JavaThread: public Thread {
@@ -1464,7 +1470,8 @@ class JavaThread: public Thread {
// Misc. operations
char* name() const { return (char*)get_thread_name(); }
- void print_on(outputStream* st) const;
+ void print_on(outputStream* st, bool print_extended_info) const;
+ void print_on(outputStream* st) const { print_on(st, false); }
void print() const { print_on(tty); }
void print_value();
void print_thread_state_on(outputStream* ) const PRODUCT_RETURN;
void print_thread_state() const PRODUCT_RETURN;
@@ -1975,10 +1982,10 @@ class Threads: AllStatic {
// Verification
@ -190,7 +190,7 @@ index fcd4814..be53498 100644
+ print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */, false /* simple format */);
}
static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen);
diff --git a/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp b/hotspot/src/share/vm/runtime/threadStatisticalInfo.hpp
new file mode 100644
index 0000000..9dbe62d

View File

@ -171,8 +171,8 @@ diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in
index 4c3a9f61..79248cbf 100644
--- a/common/autoconf/spec.gmk.in
+++ b/common/autoconf/spec.gmk.in
@@ -611,6 +611,10 @@ LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@
MSVCR_DLL:=@MSVCR_DLL@
@@ -612,6 +612,10 @@ LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@
VCRUNTIME_1_DLL:=@VCRUNTIME_1_DLL@
MSVCP_DLL:=@MSVCP_DLL@
UCRT_DLL_DIR:=@UCRT_DLL_DIR@
+# CDS_ARCHIVE

View File

@ -1,25 +0,0 @@
From 5fafa8bd0a85d93ff0480bc2d163c4070742d8f5 Mon Sep 17 00:00:00 2001
Date: Fri, 22 Jan 2021 11:26:11 +0800
Subject: 8202952:C2:Unexpected dead nodes after
matching
Bug url: https://bugs.openjdk.java.net/browse/JDK-8202952
---
hotspot/src/share/vm/opto/matcher.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
index 70e8af221..f5d30c3af 100644
--- a/hotspot/src/share/vm/opto/matcher.cpp
+++ b/hotspot/src/share/vm/opto/matcher.cpp
@@ -2230,6 +2230,7 @@ void Matcher::find_shared( Node *n ) {
// AtomicAdd is not an addressing expression.
// Cheap to find it by looking for screwy base.
!adr->in(AddPNode::Base)->is_top() &&
+ LP64_ONLY( off->get_long() == (int) (off->get_long()) && ) // immL32
// Are there other uses besides address expressions?
!is_visited(adr) ) {
address_visited.set(adr->_idx); // Flag as address_visited
--
2.19.0

View File

@ -12,22 +12,6 @@ Bug url: https://bugs.openjdk.java.net/browse/JDK-8203699
2 files changed, 171 insertions(+)
create mode 100644 jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
index f771c5f07..70ab1bcb8 100644
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
@@ -1209,6 +1209,11 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
mov(r0, super_klass);
}
+ // Get super_klass value into r0 (even if it was in r5 or r2)
+ if (super_klass != r0) {
+ mov(r0, super_klass);
+ }
+
#ifndef PRODUCT
mov(rscratch2, (address)&SharedRuntime::_partial_subtype_ctr);
Address pst_counter_addr(rscratch2);
diff --git a/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java
new file mode 100644
index 000000000..8ab268b57

View File

@ -1,5 +1,4 @@
From 16caa051cb7299312cdaf9d79eaef01d294474f6 Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Thu, 15 Dec 2022 17:06:41 +0800
Subject: [PATCH 21/33] I68TO2: 8204595: add more thread-related system settings info
to hs_error file on Linux
@ -44,7 +43,7 @@ index abf2031..1ec68ab 100644
+}
+
void os::Linux::print_container_info(outputStream* st) {
if (!OSContainer::is_containerized()) {
if (!OSContainer::is_containerized()) {
return;
@@ -6928,4 +6948,4 @@ bool os::trim_native_heap(os::size_change_t* rss_change) {
#else

View File

@ -0,0 +1,392 @@
From 3a774c78473c4fc3dcd1dc39f8c9daec4c5a6502 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 14:45:54 +0800
Subject: 8213397-Stack-dump-should-show-more-clearly-when-a-t.patch
---
hotspot/src/share/vm/oops/instanceKlass.cpp | 23 +-
hotspot/src/share/vm/runtime/thread.cpp | 2 +
hotspot/src/share/vm/runtime/thread.hpp | 8 +
.../src/share/vm/runtime/thread.inline.hpp | 12 +
hotspot/src/share/vm/runtime/vframe.cpp | 8 +
.../TestThreadDumpClassInitMonitor.java | 217 ++++++++++++++++++
6 files changed, 259 insertions(+), 11 deletions(-)
create mode 100644 hotspot/test/runtime/Thread/TestThreadDumpClassInitMonitor.java
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 538645bbe..993778270 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -920,25 +920,28 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
bool wait = false;
+ assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
+ JavaThread* jt = (JavaThread*)THREAD;
+
// refer to the JVM book page 47 for description of steps
// Step 1
{
oop init_lock = this_oop->init_lock();
ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
- Thread *self = THREAD; // it's passed the current thread
-
// Step 2
// If we were to use wait() instead of waitInterruptibly() then
// we might end up throwing IE from link/symbol resolution sites
// that aren't expected to throw. This would wreak havoc. See 6320309.
- while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) {
- wait = true;
- ol.waitUninterruptibly(CHECK);
+ while (this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(jt)) {
+ wait = true;
+ jt->set_class_to_be_initialized(this_oop());
+ ol.waitUninterruptibly(jt);
+ jt->set_class_to_be_initialized(NULL);
}
// Step 3
- if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) {
+ if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(jt)) {
DTRACE_CLASSINIT_PROBE_WAIT(recursive, InstanceKlass::cast(this_oop()), -1,wait);
return;
}
@@ -968,7 +971,7 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
// Step 6
this_oop->set_init_state(being_initialized);
- this_oop->set_init_thread(self);
+ this_oop->set_init_thread(jt);
}
// Step 7
@@ -1004,8 +1007,6 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
// Step 8
{
- assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
- JavaThread* jt = (JavaThread*)THREAD;
DTRACE_CLASSINIT_PROBE_WAIT(clinit, InstanceKlass::cast(this_oop()), -1,wait);
// Timer includes any side effects of class initialization (resolution,
// etc), but not recursive entry into call_class_initializer().
@@ -1031,14 +1032,14 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
CLEAR_PENDING_EXCEPTION;
// JVMTI has already reported the pending exception
// JVMTI internal flag reset is needed in order to report ExceptionInInitializerError
- JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
+ JvmtiExport::clear_detected_exception(jt);
{
EXCEPTION_MARK;
this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below
// JVMTI has already reported the pending exception
// JVMTI internal flag reset is needed in order to report ExceptionInInitializerError
- JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
+ JvmtiExport::clear_detected_exception(jt);
}
DTRACE_CLASSINIT_PROBE_WAIT(error, InstanceKlass::cast(this_oop()), -1,wait);
if (e->is_a(SystemDictionary::Error_klass())) {
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
index 2be226463..50543ac73 100644
--- a/hotspot/src/share/vm/runtime/thread.cpp
+++ b/hotspot/src/share/vm/runtime/thread.cpp
@@ -1538,6 +1538,8 @@ void JavaThread::initialize() {
_popframe_preserved_args_size = 0;
_frames_to_pop_failed_realloc = 0;
+_class_to_be_initialized = NULL;
+
pd_initialize();
}
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
index 220fe9316..1d3caf9aa 100644
--- a/hotspot/src/share/vm/runtime/thread.hpp
+++ b/hotspot/src/share/vm/runtime/thread.hpp
@@ -1802,11 +1802,19 @@ public:
bool is_attaching_via_jni() const { return _jni_attach_state == _attaching_via_jni; }
bool has_attached_via_jni() const { return is_attaching_via_jni() || _jni_attach_state == _attached_via_jni; }
inline void set_done_attaching_via_jni();
+
+ // Stack dump assistance: Track the class we want to initialize but for which we have to wait
+ // on its init_lock() because it is already being initialized.
+ inline void set_class_to_be_initialized(InstanceKlass* k);
+ inline InstanceKlass* class_to_be_initialized() const;
+
private:
// This field is used to determine if a thread has claimed
// a par_id: it is UINT_MAX if the thread has not claimed a par_id;
// otherwise its value is the par_id that has been claimed.
uint _claimed_par_id;
+
+ InstanceKlass* _class_to_be_initialized;
public:
uint get_claimed_par_id() { return _claimed_par_id; }
void set_claimed_par_id(uint id) { _claimed_par_id = id;}
diff --git a/hotspot/src/share/vm/runtime/thread.inline.hpp b/hotspot/src/share/vm/runtime/thread.inline.hpp
index b05e0ec5c..d3ab3aba9 100644
--- a/hotspot/src/share/vm/runtime/thread.inline.hpp
+++ b/hotspot/src/share/vm/runtime/thread.inline.hpp
@@ -74,4 +74,16 @@ inline void JavaThread::set_done_attaching_via_jni() {
OrderAccess::fence();
}
+// Allow tracking of class initialization monitor use
+inline void JavaThread::set_class_to_be_initialized(InstanceKlass* k) {
+ assert((k == NULL && _class_to_be_initialized != NULL) ||
+ (k != NULL && _class_to_be_initialized == NULL), "incorrect usage");
+ assert(this == Thread::current(), "Only the current thread can set this field");
+ _class_to_be_initialized = k;
+}
+
+inline InstanceKlass* JavaThread::class_to_be_initialized() const {
+ return _class_to_be_initialized;
+}
+
#endif // SHARE_VM_RUNTIME_THREAD_INLINE_HPP
diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp
index b3a6d0770..93d62ade7 100644
--- a/hotspot/src/share/vm/runtime/vframe.cpp
+++ b/hotspot/src/share/vm/runtime/vframe.cpp
@@ -176,6 +176,14 @@ void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
Klass* k = obj->klass();
st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", (address)obj, k->external_name());
}
+ else if (thread()->osthread()->get_state() == OBJECT_WAIT) {
+ // We are waiting on an Object monitor but Object.wait() isn't the
+ // top-frame, so we should be waiting on a Class initialization monitor.
+ InstanceKlass* k = thread()->class_to_be_initialized();
+ if (k != NULL) {
+ st->print_cr("\t- waiting on the Class initialization monitor for %s", k->external_name());
+ }
+ }
}
diff --git a/hotspot/test/runtime/Thread/TestThreadDumpClassInitMonitor.java b/hotspot/test/runtime/Thread/TestThreadDumpClassInitMonitor.java
new file mode 100644
index 000000000..8aa218efb
--- /dev/null
+++ b/hotspot/test/runtime/Thread/TestThreadDumpClassInitMonitor.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8213397 8217337
+ * @summary Check that the thread dump shows when a thread is blocked
+ * on a class initialization monitor
+ *
+ * @library /testlibrary
+ * @run main/othervm TestThreadDumpClassInitMonitor
+ */
+
+import com.oracle.java.testlibrary.*;
+
+import java.io.IOException;
+import java.util.List;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+
+public class TestThreadDumpClassInitMonitor {
+ // jstack tends to be closely bound to the VM that we are running
+ // so use getTestJDKTool() instead of getCompileJDKTool() or even
+ // getJDKTool() which can fall back to "compile.jdk".
+ final static String JSTACK = JDKToolFinder.getTestJDKTool("jstack");
+ final static String PID = getPid();
+ final static Thread current = Thread.currentThread();
+
+ /*
+ * This is the output we're looking for:
+ *
+ * "TestThread" #22 prio=5 os_prio=0 cpu=1.19ms elapsed=0.80s tid=0x00007f8f9405d800 nid=0x568b in Object.wait() [0x00007f8fd94d0000]
+ * java.lang.Thread.State: RUNNABLE
+ * Thread: 0x00007f8f9405d800 [0x568b] State: _at_safepoint _has_called_back 0 _at_poll_safepoint 0 // DEBUG ONLY
+ * JavaThread state: _thread_blocked // DEBUG ONLY
+ * at TestThreadDumpClassInitMonitor$Target$1.run(TestThreadDumpClassInitMonitor.java:69)
+ * - waiting on the Class initialization monitor for TestThreadDumpClassInitMonitor$Target
+ *
+ */
+ final static String TEST_THREAD = "TestThread";
+ final static String TEST_THREAD_ENTRY = "\"" + TEST_THREAD;
+ final static String IN_OBJECT_WAIT = "in Object.wait()";
+ final static String THREAD_STATE = "java.lang.Thread.State: RUNNABLE";
+ final static String THREAD_INFO = "Thread:"; // the details are not important
+ final static String JAVATHREAD_STATE = "JavaThread state: _thread_blocked";
+ final static String CURRENT_METHOD = "at TestThreadDumpClassInitMonitor$Target$1.run";
+ final static String WAIT_INFO = "- waiting on the Class initialization monitor for TestThreadDumpClassInitMonitor$Target";
+
+ volatile static boolean ready = false;
+
+ static List<String> stackDump; // jstack output as lines
+
+ static class Target {
+
+ static int field;
+
+ // The main thread will initialize this class and so
+ // execute the actual test logic here.
+ static {
+ if (Thread.currentThread() != current) {
+ throw new Error("Initialization logic error");
+ }
+ System.out.println("Initializing Target class in main thread");
+
+ Thread t = new Thread() {
+ public void run() {
+ System.out.println("Test thread about to access Target");
+ ready = true; // tell main thread we're close
+ // This will block until the main thread completes
+ // static initialization of target
+ Target.field = 42;
+ System.out.println("Test thread done");
+ }
+ };
+ t.setName(TEST_THREAD);
+ t.start();
+
+ // We want to run jstack once the test thread is blocked but
+ // there's no programmatic way to detect that. So we check the flag
+ // that will be set just before it should block, then by the time
+ // we can exec jstack it should be ready.
+ try {
+ while (!ready) {
+ Thread.sleep(200);
+ }
+ }
+ catch (InterruptedException ie) {
+ throw new Error("Shouldn't happen");
+ }
+
+ // Now run jstack
+ try {
+ ProcessBuilder pb = new ProcessBuilder(JSTACK, PID);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+ stackDump = output.asLines();
+ }
+ catch (IOException ioe) {
+ throw new Error("Launching jstack failed", ioe);
+ }
+ }
+ }
+
+
+ public static void main(String[] args) throws Throwable {
+ // Implicitly run the main test logic
+ Target.field = 21;
+
+ // Now check the output of jstack
+ try {
+ // product builds miss 2 lines of information in the stack
+ boolean isProduct = !Platform.isDebugBuild();
+ int foundLines = 0;
+ parseStack: for (String line : stackDump) {
+ switch(foundLines) {
+ case 0: {
+ if (!line.startsWith(TEST_THREAD_ENTRY)) {
+ continue;
+ }
+ foundLines++;
+ if (!line.contains(IN_OBJECT_WAIT)) {
+ throw new Error("Unexpected initial stack line: " + line);
+ }
+ continue;
+ }
+ case 1: {
+ if (!line.trim().equals(THREAD_STATE)) {
+ throw new Error("Unexpected thread state line: " + line);
+ }
+ if (isProduct) {
+ foundLines += 3;
+ } else {
+ foundLines++;
+ }
+ continue;
+ }
+ case 2: { // Debug build
+ if (!line.startsWith(THREAD_INFO)) {
+ throw new Error("Unexpected thread info line: " + line);
+ }
+ foundLines++;
+ continue;
+ }
+ case 3: { // Debug build
+ if (!line.trim().equals(JAVATHREAD_STATE)) {
+ throw new Error("Unexpected JavaThread state line: " + line);
+ }
+ foundLines++;
+ continue;
+ }
+ case 4: {
+ if (!line.trim().startsWith(CURRENT_METHOD)) {
+ throw new Error("Unexpected current method line: " + line);
+ }
+ foundLines++;
+ continue;
+ }
+ case 5: {
+ if (!line.trim().equals(WAIT_INFO)) {
+ throw new Error("Unexpected monitor information line: " + line);
+ }
+ break parseStack;
+ }
+ default: throw new Error("Logic error in case statement");
+ }
+ }
+
+ if (foundLines == 0) {
+ throw new Error("Unexpected stack content - did not find line starting with "
+ + TEST_THREAD_ENTRY);
+ }
+ }
+ catch (Error e) {
+ // Dump the full stack trace on error so we can check the content
+ for (String line : stackDump) {
+ System.out.println(line);
+ }
+ throw e;
+ }
+ }
+
+ // This helper relies on RuntimeMXBean.getName() returning a string
+ // that looks like this: 5436@mt-haku
+ //
+ // The testlibrary has tryFindJvmPid(), but that uses a separate
+ // process which is much more expensive for finding out your own PID.
+ //
+ static String getPid() {
+ RuntimeMXBean runtimebean = ManagementFactory.getRuntimeMXBean();
+ String vmname = runtimebean.getName();
+ int i = vmname.indexOf('@');
+ if (i != -1) {
+ vmname = vmname.substring(0, i);
+ }
+ return vmname;
+ }
+}
\ No newline at end of file
--
2.22.0

View File

@ -0,0 +1,277 @@
From 6a5759c82b869c4d931273609aa19eb1a84df8db Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:12:51 +0800
Subject: 8254723-Add-diagnostic-command-to-write-Linux-perf-m.patch
---
hotspot/src/os/linux/vm/globals_linux.hpp | 5 +-
hotspot/src/os/linux/vm/os_linux.cpp | 6 ++
hotspot/src/share/vm/code/codeCache.cpp | 36 ++++++++
hotspot/src/share/vm/code/codeCache.hpp | 1 +
hotspot/src/share/vm/runtime/java.cpp | 6 ++
.../share/vm/services/diagnosticCommand.cpp | 7 ++
.../share/vm/services/diagnosticCommand.hpp | 23 +++++
.../test/serviceability/dcmd/PerfMapTest.java | 84 +++++++++++++++++++
8 files changed, 167 insertions(+), 1 deletion(-)
create mode 100644 hotspot/test/serviceability/dcmd/PerfMapTest.java
diff --git a/hotspot/src/os/linux/vm/globals_linux.hpp b/hotspot/src/os/linux/vm/globals_linux.hpp
index f98bde41a..5cbe686d3 100644
--- a/hotspot/src/os/linux/vm/globals_linux.hpp
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp
@@ -55,7 +55,10 @@
product(bool, PreferContainerQuotaForCPUCount, true, \
"Calculate the container CPU availability based on the value" \
" of quotas (if set), when true. Otherwise, use the CPU" \
- " shares value, provided it is less than quota.")
+ " shares value, provided it is less than quota.") \
+ \
+ diagnostic(bool, DumpPerfMapAtExit, false, \
+ "Write map file for Linux perf tool at exit")
//
// Defines Linux-specific default values. The flags are available on all
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index a1cc85ca3..197b5c193 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -5648,6 +5648,12 @@ jint os::init_2(void)
// initialize thread priority policy
prio_init();
+ if (DumpPerfMapAtExit && FLAG_IS_DEFAULT(UseCodeCacheFlushing)) {
+ // Disable code cache flushing to ensure the map file written at
+ // exit contains all nmethods generated during execution.
+ FLAG_SET_DEFAULT(UseCodeCacheFlushing, false);
+ }
+
return JNI_OK;
}
diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp
index 37f24b5e9..97ad3ba79 100644
--- a/hotspot/src/share/vm/code/codeCache.cpp
+++ b/hotspot/src/share/vm/code/codeCache.cpp
@@ -1033,3 +1033,39 @@ void CodeCache::log_state(outputStream* st) {
unallocated_capacity());
}
+#ifdef LINUX
+void CodeCache::write_perf_map() {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+
+ // Perf expects to find the map file at /tmp/perf-<pid>.map.
+ char fname[32];
+ jio_snprintf(fname, sizeof(fname), "/tmp/perf-%d.map", os::current_process_id());
+
+ fileStream fs(fname, "w");
+ if (!fs.is_open()) {
+ DEBUG_ONLY(warning("[codecache] Failed to create %s for perf map", fname));
+ return;
+ }
+
+ FOR_ALL_ALIVE_BLOBS(cb) {
+ if (cb->is_nmethod()) {
+ nmethod *nm = (nmethod *) cb;
+ assert(!nm->is_unloaded(), "Tautology");
+ ResourceMark rm;
+ const char* method_name = nm->method()->name_and_sig_as_C_string();
+ fs.print_cr(INTPTR_FORMAT " " INTPTR_FORMAT " %s",
+ (intptr_t)cb->code_begin(), (intptr_t)cb->code_size(),
+ method_name);
+ }
+ if (cb->is_runtime_stub()) {
+ RuntimeStub *stub = (RuntimeStub *) cb;
+ ResourceMark rm;
+ const char* method_name = stub->name();
+ fs.print_cr(INTPTR_FORMAT " " INTPTR_FORMAT " %s",
+ (intptr_t)cb->code_begin(), (intptr_t)cb->code_size(),
+ method_name);
+ }
+ }
+}
+
+#endif // LINUX
diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp
index ab1417b19..0aad2d648 100644
--- a/hotspot/src/share/vm/code/codeCache.hpp
+++ b/hotspot/src/share/vm/code/codeCache.hpp
@@ -158,6 +158,7 @@ class CodeCache : AllStatic {
static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage
static void log_state(outputStream* st);
+ LINUX_ONLY(static void write_perf_map();)
// Dcmd (Diagnostic commands)
static void print_codelist(outputStream* st);
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index 5a628b73e..fec8fb94d 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -537,6 +537,12 @@ void before_exit(JavaThread * thread) {
BytecodeHistogram::print();
}
+#ifdef LINUX
+ if (DumpPerfMapAtExit) {
+ CodeCache::write_perf_map();
+ }
+#endif
+
if (JvmtiExport::should_post_thread_life()) {
JvmtiExport::post_thread_end(thread);
}
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
index 416dc77ce..f8f6ad546 100644
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
@@ -36,6 +36,7 @@
#include "services/management.hpp"
#include "utilities/macros.hpp"
#include "oops/objArrayOop.hpp"
+#include "code/codeCache.hpp"
#ifdef LINUX
#include "trimCHeapDCmd.hpp"
@@ -81,6 +82,7 @@ void DCmdRegistrant::register_dcmds(){
#ifdef LINUX
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<MallocInfoDcmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PerfMapDCmd>(full_export, true, false));
#endif // LINUX
// Enhanced JMX Agent Support
@@ -868,3 +870,8 @@ void CodeCacheDCmd::execute(DCmdSource source, TRAPS) {
VMThread::execute(&printCodeCacheOp);
}
+#ifdef LINUX
+void PerfMapDCmd::execute(DCmdSource source, TRAPS) {
+ CodeCache::write_perf_map();
+}
+#endif // LINUX
\ No newline at end of file
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp
index 3733fa7f7..d446aab4e 100644
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp
@@ -590,4 +590,27 @@ public:
virtual void execute(DCmdSource source, TRAPS);
};
+#ifdef LINUX
+class PerfMapDCmd : public DCmd {
+public:
+ PerfMapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+ static const char* name() {
+ return "Compiler.perfmap";
+ }
+ static const char* description() {
+ return "Write map file for Linux perf tool.";
+ }
+ static const char* impact() {
+ return "Low";
+ }
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
+ static int num_arguments() { return 0; }
+ virtual void execute(DCmdSource source, TRAPS);
+};
+#endif // LINUX
+
#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
diff --git a/hotspot/test/serviceability/dcmd/PerfMapTest.java b/hotspot/test/serviceability/dcmd/PerfMapTest.java
new file mode 100644
index 000000000..1807b2a7f
--- /dev/null
+++ b/hotspot/test/serviceability/dcmd/PerfMapTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. 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 PerfMapTest
+ * @bug 8254723
+ * @requires os.family == "linux"
+ * @library /testlibrary
+ * @run testng/othervm PerfMapTest
+ * @summary Test of diagnostic command Compiler.perfmap
+ */
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.CommandExecutor;
+import com.oracle.java.testlibrary.JMXExecutor;
+import com.oracle.java.testlibrary.ProcessTools;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Call jcmd Compiler.perfmap and check the output file has the expected
+ * format.
+ */
+public class PerfMapTest {
+
+ static final Pattern LINE_PATTERN =
+ Pattern.compile("^((?:0x)?\\p{XDigit}+)\\s+((?:0x)?\\p{XDigit}+)\\s+(.*)$");
+
+ public void run(CommandExecutor executor) throws Exception {
+ OutputAnalyzer output = executor.execute("Compiler.perfmap");
+
+ output.stderrShouldBeEmpty();
+ output.stdoutShouldBeEmpty();
+
+ final long pid = ProcessTools.getProcessId();
+ final Path path = Paths.get(String.format("/tmp/perf-%d.map", pid));
+
+ Assert.assertTrue(Files.exists(path));
+
+ // Sanity check the file contents
+ try {
+ for (String entry : Files.readAllLines(path)) {
+ Matcher m = LINE_PATTERN.matcher(entry);
+ Assert.assertTrue(m.matches(), "Invalid file format: " + entry);
+ }
+ } catch (IOException e) {
+ Assert.fail(e.toString());
+ }
+ }
+
+ @Test
+ public void jmx() throws Exception {
+ run(new JMXExecutor());
+ }
+}
--
2.22.0

View File

@ -1,5 +1,4 @@
From d68c637a36b65d0bce893991e9c910efbc06239a Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Mon, 12 Dec 2022 16:10:41 +0800
Subject: [PATCH 10/33] I68TO2: 8257695: [linux] Add process-memory information to
hs-err and VM.info
@ -22,7 +21,7 @@ index 6dbedf5..4c265d5 100644
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
@@ -2216,7 +2219,10 @@ void os::print_os_info(outputStream* st) {
@@ -2215,7 +2218,10 @@ void os::print_os_info(outputStream* st) {
os::Posix::print_load_average(st);
@ -34,7 +33,7 @@ index 6dbedf5..4c265d5 100644
os::Linux::print_container_info(st);
}
@@ -2278,12 +2284,69 @@ void os::Linux::print_libversion_info(outputStream* st) {
@@ -2280,12 +2286,69 @@ void os::Linux::print_libversion_info(outputStream* st) {
st->cr();
}
@ -103,7 +102,7 @@ index 6dbedf5..4c265d5 100644
+}
+
void os::Linux::print_container_info(outputStream* st) {
if (!OSContainer::is_containerized()) {
if (!OSContainer::is_containerized()) {
return;
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index c674882..066b03a 100644

View File

@ -0,0 +1,131 @@
From c3aae68d629a3adc02fb0764c95d922e716f0ee3 Mon Sep 17 00:00:00 2001
From: zhangyipeng <zhangyipeng7@huawei.com>
Date: Mon, 15 Jan 2024 11:13:55 +0800
Subject: [PATCH] [Backport]8260923: Add more tests for SSLSocket input/output shutdown
---
.../ssl/SSLSocketImpl/SSLSocketCloseHang.java | 69 ++++++++++++++--------
1 file changed, 46 insertions(+), 23 deletions(-)
diff --git a/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
index f74c1fe76..ff6334feb 100644
--- a/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
+++ b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
@@ -23,12 +23,17 @@
/*
* @test
- * @bug 8184328 8253368
+ * @bug 8184328 8253368 8260923
* @summary JDK8u131-b34-socketRead0 hang at SSL read
- * @run main/othervm SSLSocketCloseHang
- * @run main/othervm SSLSocketCloseHang shutdownInputTest
+ * @run main/othervm SSLSocketCloseHang TLSv1.2
+ * @run main/othervm SSLSocketCloseHang TLSv1.2 shutdownInput
+ * @run main/othervm SSLSocketCloseHang TLSv1.2 shutdownOutput
+ * @run main/othervm SSLSocketCloseHang TLSv1.3
+ * @run main/othervm SSLSocketCloseHang TLSv1.3 shutdownInput
+ * @run main/othervm SSLSocketCloseHang TLSv1.3 shutdownOutput
*/
+
import java.io.*;
import java.net.*;
import java.util.*;
@@ -36,7 +41,6 @@ import java.security.*;
import javax.net.ssl.*;
public class SSLSocketCloseHang {
-
/*
* =============================================================
* Set the various variables needed for the tests, then
@@ -73,7 +77,7 @@ public class SSLSocketCloseHang {
*/
static boolean debug = false;
- static boolean shutdownInputTest = false;
+ static String socketCloseType;
/*
* If the client or server is doing some kind of object creation
@@ -148,28 +152,45 @@ public class SSLSocketCloseHang {
Thread.sleep(500);
System.err.println("Client closing: " + System.nanoTime());
- if (shutdownInputTest) {
- try {
- sslSocket.shutdownInput();
- } catch (SSLException e) {
- if (!e.getMessage().contains
- ("closing inbound before receiving peer's close_notify")) {
- throw new RuntimeException("expected different exception message. " +
- e.getMessage());
- }
- }
- if (!sslSocket.getSession().isValid()) {
- throw new RuntimeException("expected session to remain valid");
- }
+ closeConnection(sslSocket);
+
+ clientClosed = true;
+ System.err.println("Client closed: " + System.nanoTime());
+ }
+ private void closeConnection(SSLSocket sslSocket) throws IOException {
+ if ("shutdownInput".equals(socketCloseType)) {
+ shutdownInput(sslSocket);
+ // second call to shutdownInput() should just return,
+ // shouldn't throw any exception
+ sslSocket.shutdownInput();
+ // invoking shutdownOutput() just after shutdownInput()
+ sslSocket.shutdownOutput();
+ } else if ("shutdownOutput".equals(socketCloseType)) {
+ sslSocket.shutdownOutput();
+ // second call to shutdownInput() should just return,
+ // shouldn't throw any exception
+ sslSocket.shutdownOutput();
+ // invoking shutdownInput() just after shutdownOutput()
+ shutdownInput(sslSocket);
} else {
sslSocket.close();
}
+ }
-
-
- clientClosed = true;
- System.err.println("Client closed: " + System.nanoTime());
+ private void shutdownInput(SSLSocket sslSocket) throws IOException {
+ try {
+ sslSocket.shutdownInput();
+ } catch (SSLException e) {
+ if (!e.getMessage().contains
+ ("closing inbound before receiving peer's close_notify")) {
+ throw new RuntimeException("expected different exception "
+ + "message. " + e.getMessage());
+ }
+ }
+ if (!sslSocket.getSession().isValid()) {
+ throw new RuntimeException("expected session to remain valid");
+ }
}
/*
@@ -197,11 +218,13 @@ public class SSLSocketCloseHang {
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+ System.setProperty("jdk.tls.client.protocols", args[0]);
if (debug)
System.setProperty("javax.net.debug", "all");
- shutdownInputTest = args.length > 0 ? true : false;
+ socketCloseType = args.length > 1 ? args[1] : "";
+
/*
* Start the tests.
--
2.12.3

View File

@ -0,0 +1,25 @@
From facc89d6a5776a26193c9321111c8489e4af525f Mon Sep 17 00:00:00 2001
Subject: 8263557: Possible NULL dereference in Arena::destruct_contents()
---
hotspot/src/share/vm/memory/allocation.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp
index 3cd30a686..abbcc6c49 100644
--- a/hotspot/src/share/vm/memory/allocation.cpp
+++ b/hotspot/src/share/vm/memory/allocation.cpp
@@ -521,7 +521,9 @@ void Arena::destruct_contents() {
// reset size before chop to avoid a rare racing condition
// that can have total arena memory exceed total chunk memory
set_size_in_bytes(0);
- _first->chop();
+ if (_first != NULL) {
+ _first->chop();
+ }
reset();
}
--
2.22.0

View File

@ -0,0 +1,581 @@
From 4e32bc622c1f73c2ab6a4ef4b4bbd92e381a3439 Mon Sep 17 00:00:00 2001
From: zhangyipeng <zhangyipeng7@huawei.com>
Date: Mon, 15 Jan 2024 11:11:41 +0800
Subject: [PATCH] [Backport]8273553: sun.security.ssl.SSLEngineImpl.closeInbound also has
similar error of JDK-8253368
---
.../classes/sun/security/ssl/SSLEngineImpl.java | 24 +-
.../classes/sun/security/ssl/SSLSocketImpl.java | 7 +-
.../SSLSocketSSLEngineCloseInbound.java | 491 +++++++++++++++++++++
3 files changed, 508 insertions(+), 14 deletions(-)
create mode 100644 jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
index 05ffb8a00..a9cc989f2 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
@@ -47,7 +47,7 @@ import javax.net.ssl.SSLProtocolException;
import javax.net.ssl.SSLSession;
/**
- * Implementation of an non-blocking SSLEngine.
+ * Implementation of a non-blocking SSLEngine.
*
* @author Brad Wetmore
*/
@@ -230,7 +230,7 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
if (ciphertext == null && !conContext.isNegotiated &&
conContext.isInboundClosed() &&
hsStatus == HandshakeStatus.NEED_WRAP) {
- // Even the outboud is open, no futher data could be wrapped as:
+ // Even the outbound is open, no further data could be wrapped as:
// 1. the outbound is empty
// 2. no negotiated connection
// 3. the inbound has closed, cannot complete the handshake
@@ -631,17 +631,19 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
SSLLogger.finest("Closing inbound of SSLEngine");
}
- // Is it ready to close inbound?
- //
- // No need to throw exception if the initial handshake is not started.
- if (!conContext.isInputCloseNotified &&
- (conContext.isNegotiated || conContext.handshakeContext != null)) {
- throw conContext.fatal(Alert.INTERNAL_ERROR,
- "closing inbound before receiving peer's close_notify");
+ try {
+ // Is it ready to close inbound?
+ //
+ // No need to throw exception if the initial handshake is not started.
+ if (!conContext.isInputCloseNotified &&
+ (conContext.isNegotiated || conContext.handshakeContext != null)) {
+ throw new SSLException(
+ "closing inbound before receiving peer's close_notify");
+ }
+ } finally {
+ conContext.closeInbound();
}
-
- conContext.closeInbound();
}
@Override
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
index 69c96f226..7e8b131bb 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -742,9 +742,10 @@ public final class SSLSocketImpl
// No need to throw exception if the initial handshake is not started.
try {
if (checkCloseNotify && !conContext.isInputCloseNotified &&
- (conContext.isNegotiated || conContext.handshakeContext != null)) {
- throw new SSLException(
- "closing inbound before receiving peer's close_notify");
+ (conContext.isNegotiated ||
+ conContext.handshakeContext != null)) {
+ throw new SSLException(
+ "closing inbound before receiving peer's close_notify");
}
} finally {
conContext.closeInbound();
diff --git a/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java
new file mode 100644
index 000000000..abf1571ca
--- /dev/null
+++ b/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2011, 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
+ * 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8273553 8253368
+ * @summary sun.security.ssl.SSLEngineImpl.closeInbound also has similar error
+ * of JDK-8253368
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.3
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.2
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.1
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1
+ * @run main/othervm SSLSocketSSLEngineCloseInbound TLS
+ */
+
+/**
+ * A SSLSocket/SSLEngine interop test case. This is not the way to
+ * code SSLEngine-based servers, but works for what we need to do here,
+ * which is to make sure that SSLEngine/SSLSockets can talk to each other.
+ * SSLEngines can use direct or indirect buffers, and different code
+ * is used to get at the buffer contents internally, so we test that here.
+ *
+ * The test creates one SSLSocket (client) and one SSLEngine (server).
+ * The SSLSocket talks to a raw ServerSocket, and the server code
+ * does the translation between byte [] and ByteBuffers that the SSLEngine
+ * can use. The "transport" layer consists of a Socket Input/OutputStream
+ * and two byte buffers for the SSLEngines: think of them
+ * as directly connected pipes.
+ *
+ * Again, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ *
+ * client server message
+ * ====== ====== =======
+ * write() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * read() ... ServerHello/Certificate
+ * write() ... ClientKeyExchange
+ * write() ... ChangeCipherSpec
+ * write() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * read() ... ChangeCipherSpec
+ * read() ... Finished
+ */
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.nio.*;
+
+public class SSLSocketSSLEngineCloseInbound {
+
+ /*
+ * Enables logging of the SSL/TLS operations.
+ */
+ private static final boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static final boolean debug = false;
+ private final SSLContext sslc;
+ private SSLEngine serverEngine; // server-side SSLEngine
+ private SSLSocket clientSocket;
+
+ private final byte[] serverMsg =
+ "Hi there Client, I'm a Server.".getBytes();
+ private final byte[] clientMsg =
+ "Hello Server, I'm a Client! Pleased to meet you!".getBytes();
+
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ private volatile Exception clientException;
+ private volatile Exception serverException;
+
+ /*
+ * For data transport, this example uses local ByteBuffers.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores/trust material.
+ */
+ private static final String pathToStores = "../../../../javax/net/ssl/etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + keyStoreFile;
+ private static final String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + trustStoreFile;
+
+ /*
+ * Main entry point for this test.
+ */
+ public static void main(String[] args) throws Exception {
+ String protocol = args[0];
+
+ // reset security properties to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ Security.setProperty("jdk.certpath.disabledAlgorithms", "");
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ /*
+ * Run the tests with direct and indirect buffers.
+ */
+ SSLSocketSSLEngineCloseInbound test =
+ new SSLSocketSSLEngineCloseInbound(protocol);
+ log("-------------------------------------");
+ log("Testing " + protocol + " for direct buffers ...");
+ test.runTest(true);
+
+ log("---------------------------------------");
+ log("Testing " + protocol + " for indirect buffers ...");
+ test.runTest(false);
+
+ log("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for these tests.
+ */
+ public SSLSocketSSLEngineCloseInbound(String protocol) throws Exception {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ try (FileInputStream keyFile = new FileInputStream(keyFilename);
+ FileInputStream trustFile = new FileInputStream(trustFilename)) {
+ ks.load(keyFile, passphrase);
+ ts.load(trustFile, passphrase);
+ }
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance(protocol);
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+ }
+
+ /*
+ * Run the test.
+ *
+ * Sit in a tight loop, with the server engine calling wrap/unwrap
+ * regardless of whether data is available or not. We do this until
+ * we get the application data. Then we shutdown and go to the next one.
+ *
+ * The main loop handles all the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+ private void runTest(boolean direct) throws Exception {
+ clientSocket = null;
+
+ // generates the server-side Socket
+ try (ServerSocket serverSocket = new ServerSocket()) {
+ serverSocket.setReuseAddress(false);
+ serverSocket.bind(null);
+ int port = serverSocket.getLocalPort();
+ log("Port: " + port);
+ Thread thread = createClientThread(port);
+
+ createSSLEngine();
+ createBuffers(direct);
+
+ // server-side socket that will read
+ try (Socket socket = serverSocket.accept()) {
+ socket.setSoTimeout(500);
+
+ InputStream is = socket.getInputStream();
+ OutputStream os = socket.getOutputStream();
+
+ SSLEngineResult serverResult; // results from last operation
+
+ /*
+ * Examining the SSLEngineResults could be much more involved,
+ * and may alter the overall flow of the application.
+ *
+ * For example, if we received a BUFFER_OVERFLOW when trying
+ * to write to the output pipe, we could reallocate a larger
+ * pipe, but instead we wait for the peer to drain it.
+ */
+ byte[] inbound = new byte[8192];
+ byte[] outbound = new byte[8192];
+
+ while (!isEngineClosed(serverEngine)) {
+ int len;
+
+ // Inbound data
+ log("================");
+
+ // Try reading Client side, even if it's already closed.
+ try {
+ len = is.read(inbound);
+ if (len > 0) {
+ cTOs.put(inbound, 0, len);
+ }
+ } catch (IOException e) {
+ /*
+ * swallow IO/SocketTimeoutExceptions. We'll do
+ * the testing/exit after the unwraps.
+ */
+ }
+
+ cTOs.flip();
+
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ cTOs.compact();
+
+ // Outbound data
+ log("----");
+
+ // After we've received our app bytes, close input side
+ // and see what happens. Exit the test at the end.
+ if (serverIn.position() != 0) {
+ try {
+ serverEngine.closeInbound();
+ throw new Exception(
+ "No error shutting down client's input");
+ } catch (SSLException e) {
+ System.out.println(
+ "Server caught the right Exception");
+ }
+
+ if (serverEngine.getSession().isValid()) {
+ System.out.println("Server session is still valid");
+ } else {
+ throw new Exception("Server session is not valid");
+ }
+
+ return;
+ }
+
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+
+ sTOc.flip();
+
+ if ((len = sTOc.remaining()) != 0) {
+ sTOc.get(outbound, 0, len);
+ os.write(outbound, 0, len);
+ // Give the other side a chance to process
+ }
+
+ sTOc.compact();
+ }
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ // Wait for the client to join up with us.
+ if (thread != null) {
+ thread.join();
+ }
+ }
+ } finally {
+ if (serverException != null) {
+ if (clientException != null) {
+ serverException.initCause(clientException);
+ }
+ throw serverException;
+ }
+ if (clientException != null) {
+ if (serverException != null) {
+ clientException.initCause(serverException);
+ }
+ throw clientException;
+ }
+ }
+ }
+
+ /*
+ * Create a client thread which does simple SSLSocket operations.
+ * We'll write and read one data packet.
+ */
+ private Thread createClientThread(final int port) {
+
+ Thread t = new Thread("ClientThread") {
+
+ @Override
+ public void run() {
+ // client-side socket
+ try (SSLSocket sslSocket = (SSLSocket)sslc.getSocketFactory().
+ createSocket("localhost", port)) {
+ clientSocket = sslSocket;
+
+ OutputStream os = sslSocket.getOutputStream();
+
+ // write(byte[]) goes in one shot.
+ os.write(clientMsg);
+ os.flush();
+
+ try {
+ sslSocket.shutdownInput();
+ throw new Exception(
+ "No error shutting down client's input");
+ } catch (SSLException e) {
+ System.out.println("Client caught the right Exception");
+ }
+
+ if (sslSocket.getSession().isValid()) {
+ System.out.println("Client session is still valid");
+ } else {
+ throw new Exception("Client's session is not valid");
+ }
+
+ // Give server a chance to read before we shutdown via
+ // the try-with-resources block.
+ Thread.sleep(2000);
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ };
+ t.start();
+ return t;
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this test.
+ */
+ private void createSSLEngine() {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ serverEngine.getNeedClientAuth();
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+ private void createBuffers(boolean direct) {
+
+ SSLSession session = serverEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ if (direct) {
+ serverIn = ByteBuffer.allocateDirect(appBufferMax + 50);
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+ } else {
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+ cTOs = ByteBuffer.allocate(netBufferMax);
+ sTOc = ByteBuffer.allocate(netBufferMax);
+ }
+
+ serverOut = ByteBuffer.wrap(serverMsg);
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine) {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result) {
+ if (!logging) {
+ return;
+ }
+ if (resultOnce) {
+ resultOnce = false;
+ log("The format of the SSLEngineResult is: \n"
+ + "\t\"getStatus() / getHandshakeStatus()\" +\n"
+ + "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str
+ + result.getStatus() + "/" + hsStatus + ", "
+ + result.bytesConsumed() + "/" + result.bytesProduced()
+ + " bytes");
+ if (hsStatus == HandshakeStatus.FINISHED) {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str) {
+ if (logging) {
+ if (debug) {
+ System.err.println(str);
+ } else {
+ System.out.println(str);
+ }
+ }
+ }
+}
--
2.12.3

View File

@ -0,0 +1,238 @@
From e5bf7f105c0066f770f5cdc65f94410d45d11f0f Mon Sep 17 00:00:00 2001
Subject: 8278794: Infinite loop in DeflaterOutputStream.finish()
---
.../share/classes/java/util/zip/Deflater.java | 10 ++
.../java/util/zip/DeflaterOutputStream.java | 14 +-
.../java/util/zip/ZipOutputStream.java | 4 +-
jdk/test/java/util/zip/CloseDeflaterTest.java | 147 ------------------
4 files changed, 22 insertions(+), 153 deletions(-)
delete mode 100644 jdk/test/java/util/zip/CloseDeflaterTest.java
diff --git a/jdk/src/share/classes/java/util/zip/Deflater.java b/jdk/src/share/classes/java/util/zip/Deflater.java
index 3bb5f9901..bffa397d9 100644
--- a/jdk/src/share/classes/java/util/zip/Deflater.java
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java
@@ -559,6 +559,16 @@ class Deflater {
throw new NullPointerException("Deflater has been closed");
}
+ /**
+ * Returns the value of 'finish' flag.
+ * 'finish' will be set to true if def.finish() method is called.
+ */
+ boolean shouldFinish() {
+ synchronized (zsRef) {
+ return finish;
+ }
+ }
+
private static native void initIDs();
private native static long init(int level, int strategy, boolean nowrap);
private native static void setDictionary(long addr, byte[] b, int off, int len);
diff --git a/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java b/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java
index f4cf79693..c698a0147 100644
--- a/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java
+++ b/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -221,9 +221,15 @@ class DeflaterOutputStream extends FilterOutputStream {
*/
public void finish() throws IOException {
if (!def.finished()) {
- def.finish();
- while (!def.finished()) {
- deflate();
+ try{
+ def.finish();
+ while (!def.finished()) {
+ deflate();
+ }
+ } catch(IOException e) {
+ if (usesDefaultDeflater)
+ def.end();
+ throw e;
}
}
}
diff --git a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java
index f001ddf00..cd9194276 100644
--- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java
+++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -302,7 +302,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
crc.reset();
current = null;
} catch (IOException e) {
- if (usesDefaultDeflater && !(e instanceof ZipException))
+ if (def.shouldFinish() && usesDefaultDeflater && !(e instanceof ZipException))
def.end();
throw e;
}
diff --git a/jdk/test/java/util/zip/CloseDeflaterTest.java b/jdk/test/java/util/zip/CloseDeflaterTest.java
deleted file mode 100644
index 8aa4960f5..000000000
--- a/jdk/test/java/util/zip/CloseDeflaterTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 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
- * 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 8193682
- * @summary Test Infinite loop while writing on closed GZipOutputStream , ZipOutputStream and JarOutputStream.
- * @run testng CloseDeflaterTest
- */
-import java.io.*;
-import java.util.Random;
-import java.util.jar.JarOutputStream;
-import java.util.zip.GZIPOutputStream;
-import java.util.zip.ZipOutputStream;
-import java.util.zip.ZipEntry;
-
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-import static org.testng.Assert.fail;
-
-
-public class CloseDeflaterTest {
-
- //number of bytes to write
- private static final int INPUT_LENGTH= 512;
- //OutputStream that will throw an exception during a write operation
- private static OutputStream outStream = new OutputStream() {
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- //throw exception during write
- throw new IOException();
- }
- @Override
- public void write(byte b[]) throws IOException {}
- @Override
- public void write(int b) throws IOException {}
- };
- private static byte[] inputBytes = new byte[INPUT_LENGTH];
- private static Random rand = new Random();
-
- @DataProvider(name = "testgzipinput")
- public Object[][] testGZipInput() {
- //testGZip will close the GZipOutputStream using close() method when the boolean
- //useCloseMethod is set to true and finish() method if the value is set to false
- return new Object[][] {
- { GZIPOutputStream.class, true },
- { GZIPOutputStream.class, false },
- };
- }
-
- @DataProvider(name = "testzipjarinput")
- public Object[][] testZipAndJarInput() {
- //testZipAndJarInput will perfrom write/closeEntry operations on JarOutputStream when the boolean
- //useJar is set to true and on ZipOutputStream if the value is set to false
- return new Object[][] {
- { JarOutputStream.class, true },
- { ZipOutputStream.class, false },
- };
- }
-
- @BeforeTest
- public void before_test()
- {
- //add inputBytes array with random bytes to write into Zip
- rand.nextBytes(inputBytes);
- }
-
- //Test for infinite loop by writing bytes to closed GZIPOutputStream
- @Test(dataProvider = "testgzipinput")
- public void testGZip(Class<?> type, boolean useCloseMethod) throws IOException {
- GZIPOutputStream zip = new GZIPOutputStream(outStream);
- try {
- zip.write(inputBytes, 0, INPUT_LENGTH);
- //close zip
- if(useCloseMethod) {
- zip.close();
- } else {
- zip.finish();
- }
- } catch (IOException e) {
- //expected
- }
- for (int i = 0; i < 3; i++) {
- try {
- //write on a closed GZIPOutputStream
- zip.write(inputBytes, 0, INPUT_LENGTH);
- fail("Deflater closed exception not thrown");
- } catch (NullPointerException e) {
- //expected , Deflater has been closed exception
- }
- }
- }
-
- //Test for infinite loop by writing bytes to closed ZipOutputStream/JarOutputStream
- @Test(dataProvider = "testzipjarinput")
- public void testZipCloseEntry(Class<?> type,boolean useJar) throws IOException {
- ZipOutputStream zip = null;
- if(useJar) {
- zip = new JarOutputStream(outStream);
- } else {
- zip = new ZipOutputStream(outStream);
- }
- try {
- zip.putNextEntry(new ZipEntry(""));
- } catch (IOException e) {
- //expected to throw IOException since putNextEntry calls write method
- }
- try {
- zip.write(inputBytes, 0, INPUT_LENGTH);
- //close zip entry
- zip.closeEntry();
- } catch (IOException e) {
- //expected
- }
- for (int i = 0; i < 3; i++) {
- try {
- //write on a closed ZipOutputStream
- zip.write(inputBytes, 0, INPUT_LENGTH);
- fail("Deflater closed exception not thrown");
- } catch (NullPointerException e) {
- //expected , Deflater has been closed exception
- }
- }
- }
-
-}
--
2.22.0

View File

@ -0,0 +1,33 @@
From 42884748f75ef4ea6e0cc8e537c831cb258961f8 Mon Sep 17 00:00:00 2001
Subject: 8285516: clearPassword should be called in a finally try block
---
.../share/classes/sun/security/pkcs12/PKCS12KeyStore.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
index 0457b1e5c..63e0afc2a 100644
--- a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
+++ b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
@@ -837,14 +837,14 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
{
SecretKey skey = null;
+ PBEKeySpec keySpec = new PBEKeySpec(password);
try {
- PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE");
skey = skFac.generateSecret(keySpec);
- keySpec.clearPassword();
} catch (Exception e) {
- throw new IOException("getSecretKey failed: " +
- e.getMessage(), e);
+ throw new IOException("getSecretKey failed: " + e.getMessage(), e);
+ } finally {
+ keySpec.clearPassword();
}
return skey;
}
--
2.22.0

View File

@ -1,237 +0,0 @@
From d2d3408154beb52370ee8784767375a7cc8d325d Mon Sep 17 00:00:00 2001
Date: Wed, 21 Sep 2022 10:31:17 +0800
Subject: 8287109: Distrust.java failed with CertificateExpiredException
---
.../Symantec/Distrust.java | 26 +++++-
.../Symantec/appleistca2g1-chain.pem | 80 -------------------
.../Symantec/geotrustglobalca-chain.pem | 66 ---------------
3 files changed, 23 insertions(+), 149 deletions(-)
delete mode 100644 jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca2g1-chain.pem
delete mode 100644 jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/geotrustglobalca-chain.pem
diff --git a/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java b/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java
index d394f417..22266255 100644
--- a/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java
+++ b/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java
@@ -51,15 +51,14 @@ public class Distrust {
// Each of the roots have a test certificate chain stored in a file
// named "<root>-chain.pem".
private static String[] rootsToTest = new String[] {
- "geotrustglobalca", "geotrustprimarycag2", "geotrustprimarycag3",
+ "geotrustprimarycag2", "geotrustprimarycag3",
"geotrustuniversalca", "thawteprimaryrootca", "thawteprimaryrootcag2",
"thawteprimaryrootcag3", "verisignclass3g3ca", "verisignclass3g4ca",
"verisignclass3g5ca", "verisignuniversalrootca" };
// Each of the subCAs with a delayed distrust date have a test certificate
// chain stored in a file named "<subCA>-chain.pem".
- private static String[] subCAsToTest = new String[] {
- "appleistca2g1", "appleistca8g1" };
+ private static String[] subCAsToTest = new String[] {"appleistca8g1"};
// A date that is after the restrictions take affect
private static final Date APRIL_17_2019 =
@@ -177,6 +176,11 @@ public class Distrust {
throw new Exception("chain should be invalid");
}
} catch (CertificateException ce) {
+ // expired TLS certificates should not be treated as failure
+ if (expired(ce)) {
+ System.err.println("Test is N/A, chain is expired");
+ return;
+ }
if (valid) {
throw new Exception("Unexpected exception, chain " +
"should be valid", ce);
@@ -184,6 +188,7 @@ public class Distrust {
if (ce instanceof ValidatorException) {
ValidatorException ve = (ValidatorException)ce;
if (ve.getErrorType() != ValidatorException.T_UNTRUSTED_CERT) {
+ ce.printStackTrace(System.err);
throw new Exception("Unexpected exception: " + ce);
}
} else {
@@ -192,6 +197,21 @@ public class Distrust {
}
}
+ // check if a cause of exception is an expired cert
+ private static boolean expired(CertificateException ce) {
+ if (ce instanceof CertificateExpiredException) {
+ return true;
+ }
+ Throwable t = ce.getCause();
+ while (t != null) {
+ if (t instanceof CertificateExpiredException) {
+ return true;
+ }
+ t = t.getCause();
+ }
+ return false;
+ }
+
private static X509Certificate[] loadCertificateChain(String name)
throws Exception {
try (InputStream in = new FileInputStream(TEST_SRC + File.separator +
diff --git a/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca2g1-chain.pem b/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca2g1-chain.pem
deleted file mode 100644
index 0235631d..00000000
--- a/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca2g1-chain.pem
+++ /dev/null
@@ -1,80 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGGzCCBQOgAwIBAgIITJltLCqcD0gwDQYJKoZIhvcNAQELBQAwYjEcMBoGA1UE
-AxMTQXBwbGUgSVNUIENBIDIgLSBHMTEgMB4GA1UECxMXQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkxEzARBgNVBAoTCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE5
-MDEwODIxMTcxNFoXDTIwMDgwODIxMjcwMFowgaoxSjBIBgNVBAMMQWFjdGl2ZS5n
-ZW90cnVzdC1nbG9iYWwtY2EudGVzdC1wYWdlcy5jZXJ0aWZpY2F0ZW1hbmFnZXIu
-YXBwbGUuY29tMSUwIwYDVQQLDBxtYW5hZ2VtZW50OmlkbXMuZ3JvdXAuODY0ODU5
-MRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYD
-VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCjFUrVHTEX
-0aVU6x9LiGa6oVr9blaCsMFrLicPQguc43Vs/pN+g4jzRXsTSMe9XefezBQb6tzZ
-SMRXVB4kWMr4K1BVgQDkXeyoh4KrXRkdEF9ZIJPNxwTmmYUOc5M6NOYwkLelYz+t
-7n1iNIGylbjwU4qwauElk2alFVqYTEPDLzwvqVDb9jMAJ8MPSDjfUlXW0XD9oXZM
-hC+8LU9JBgJ3YBdzRHa4WnrudUbWjspqaNfAYpVIX0cfCJKnMsKqaSKjS4pIRtWm
-L6NlCTCoIMyOh+wmbWPPX24H2D3+ump5FA35fRYbVznmosl5n1AK34S9tD4XZ7lO
-WZKfaFi1liMCAwEAAaOCAoowggKGMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU
-2HqURHyQcJAWnt0XnAFEA4bWKikwfgYIKwYBBQUHAQEEcjBwMDQGCCsGAQUFBzAC
-hihodHRwOi8vY2VydHMuYXBwbGUuY29tL2FwcGxlaXN0Y2EyZzEuZGVyMDgGCCsG
-AQUFBzABhixodHRwOi8vb2NzcC5hcHBsZS5jb20vb2NzcDAzLWFwcGxlaXN0Y2Ey
-ZzEwMTBMBgNVHREERTBDgkFhY3RpdmUuZ2VvdHJ1c3QtZ2xvYmFsLWNhLnRlc3Qt
-cGFnZXMuY2VydGlmaWNhdGVtYW5hZ2VyLmFwcGxlLmNvbTCB/wYDVR0gBIH3MIH0
-MIHxBgoqhkiG92NkBQsEMIHiMIGkBggrBgEFBQcCAjCBlwyBlFJlbGlhbmNlIG9u
-IHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5j
-ZSBvZiBhbnkgYXBwbGljYWJsZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2Ug
-YW5kL29yIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wOQYIKwYB
-BQUHAgEWLWh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5
-L3JwYTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwNwYDVR0fBDAwLjAs
-oCqgKIYmaHR0cDovL2NybC5hcHBsZS5jb20vYXBwbGVpc3RjYTJnMS5jcmwwHQYD
-VR0OBBYEFP0qkmFJhArI0MsfW0V+/wY9x4GSMA4GA1UdDwEB/wQEAwIFoDANBgkq
-hkiG9w0BAQsFAAOCAQEATjT8M0bIq+mFc8k5cd4KDjCMBjYl/l3/8zKlWYGP+nl1
-KRogXcGRa3LcfpdJcqgMrx8e9Xohduvl8MBzwv671rYkppzZdsmZdLVorAdbL5GL
-suhTjAS5yL3NBWNMRpeOgFsVr7YtPDEvo3CFsnzjg7THe0S6Y35oYukJtUzGUvSY
-kC3ApBTdjj0vAeow+dbt+AHKnQiEnon4ToSFmtnkru08Uxe7uyHCQ2sLUg0EPYc9
-t9I8lviaHfK/mQoCzlme2O/H5Rher8dXCv8hVT1NKbsi28EpgpqcTLS+hn/Edc/q
-4dPDoO1Ozs+ixRzFeMpA+JrnAyARb6qbSrAPBgtIbQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEQDCCAyigAwIBAgIDAjp0MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTQwNjE2MTU0MjAyWhcNMjIwNTIwMTU0MjAyWjBiMRwwGgYDVQQD
-ExNBcHBsZSBJU1QgQ0EgMiAtIEcxMSAwHgYDVQQLExdDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTETMBEGA1UEChMKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQk6EdR0MgFrILa+vD1bTox5jN896/
-6E3p4zaAB/xFG2p8RYauVtOkCX9hDWtdflJrfbTIOcT0Zzr3g84Zb4YvfkV+Rxxn
-UsqVBV3iNlGFwNRngDVvFd0+/R3S/Y80UNjsdiq+49Pa5P3I6ygClhGXF2Ec6cRZ
-O0LcMtEJHdqm0UOG/16yvIzPZtsBiwKulEjzOI/96jKoCOyGl1GUJD5JSZZT6Hmh
-QIHpBbuTlVH84/18EUv3ngizFUkVB/nRN6CbSzL2tcTcatH8Cu324MUpoKiLcf4N
-krz+VHAYCm3H7Qz7yS0Gw4yF/MuGXNY2jhKLCX/7GRo41fCUMHoPpozzAgMBAAGj
-ggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1luMrMTjAdBgNVHQ4E
-FgQU2HqURHyQcJAWnt0XnAFEA4bWKikwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV
-HQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2cuc3ltY2IuY29t
-L2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYS
-aHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARFMEMwQQYKYIZIAYb4RQEHNjAzMDEG
-CCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvY3Bz
-MA0GCSqGSIb3DQEBCwUAA4IBAQAWR3NvhaJi4ecqdruJlUIml7xKrKxwUzo/MYM9
-PByrmuKxXRx2GqA8DHJXvtOeUODImdZY1wLqzg0pVHzN9cLGkClVo28UqAtCDTqY
-bQZ4nvBqox0CCqIopI3CgUY+bWfa3j/+hQ5CKhLetbf7uBunlux3n+zUU5V6/wf0
-8goUwFFSsdaOUAsamVy8C8m97e34XsFW201+I6QRoSzUGwWa5BtS9nw4mQVLunKN
-QolgBGYq9P1o12v3mUEo1mwkq+YlUy7Igpnioo8jvjCDsSeL+mh/AUnoxphrEC6Y
-XorXykuxx8lYmtA225aV7LaB5PLNbxt5h0wQPInkTfpU3Kqm
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
-R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
-9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
-fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
-iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
-1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
-bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
-MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
-ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
-uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
-Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
-tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
-hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
-5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
------END CERTIFICATE-----
diff --git a/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/geotrustglobalca-chain.pem b/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/geotrustglobalca-chain.pem
deleted file mode 100644
index 3249716b..00000000
--- a/jdk/test/sun/security/ssl/X509TrustManagerImpl/Symantec/geotrustglobalca-chain.pem
+++ /dev/null
@@ -1,66 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIHBjCCBe6gAwIBAgIQanINWwJAuap0V7lFjnfUwTANBgkqhkiG9w0BAQsFADBE
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU
-R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTcwNTAzMDAwMDAwWhcNMjAwNTAyMjM1
-OTU5WjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV
-BAcMDU1vdW50YWluIFZpZXcxFzAVBgNVBAoMDkdlb1RydXN0LCBJbmMuMRgwFgYD
-VQQLDA9Sb290IDEwIC0gVkFMSUQxIjAgBgNVBAMMGXZhbGlkLXJvb3QxMC5nZW90
-cnVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTegUYhAh0
-P7aF6jzk8dit4Vzddo3hM+J7Eak/+N1sqVUS2HpNd7VO50FrbEWKIRusv7QNtlpY
-1Cgrla8M4RAhCB0wkkHXZ1Evz6E1AEFQqNSjyuRQxeEXl+xCL+MF+yAMhDRnHh+E
-eSJ3ie0T66saOyaLM9fPpr3xomAQ/IRlP1atJ/Z8XbPo25HuxwzxiWFW+RjwVIfI
-gxHz4Okwc1uImDUIDlEu9Uaqqb4jHhxU1EkKMmgEncpqwCROcZMujUkogfB49Z7+
-K17r6ARIrUuxqfNPrPwe+O88WgIeDSWffPM67UlvtomZOwuTNdv9OoCX1wUCLS7m
-/gZ3rqqqeJvfAgMBAAGjggOkMIIDoDAkBgNVHREEHTAbghl2YWxpZC1yb290MTAu
-Z2VvdHJ1c3QuY29tMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQk
-MCIwIKAeoByGGmh0dHA6Ly9nbi5zeW1jYi5jb20vZ24uY3JsMIGdBgNVHSAEgZUw
-gZIwgY8GBmeBDAECAjCBhDA/BggrBgEFBQcCARYzaHR0cHM6Ly93d3cuZ2VvdHJ1
-c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5L2xlZ2FsMEEGCCsGAQUFBwICMDUM
-M2h0dHBzOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeS9s
-ZWdhbDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAU
-0m/3lvSFP3I8MH0j2oV4m6N8WnwwVwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzAB
-hhNodHRwOi8vZ24uc3ltY2QuY29tMCYGCCsGAQUFBzAChhpodHRwOi8vZ24uc3lt
-Y2IuY29tL2duLmNydDCCAfUGCisGAQQB1nkCBAIEggHlBIIB4QHfAHUA3esdK3oN
-T6Ygi4GtgWhwfi6OnQHVXIiNPRHEzbbsvswAAAFbz9h5vQAABAMARjBEAiAx/C0U
-5NdHxK4v2oHnstYksb1Vny8PcQkSvgpx9PsZEwIgNTOU70Zc5szG23xdbvtoH5lN
-SAoVswiF5gFQS5MGu1sAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3c
-EAAAAVvP2HnZAAAEAwBHMEUCIFGjB8r2H0VDwTUE/aY/Mv+M97sqAvEP1doOcHpg
-0qyfAiEArw/S2F7OEcmKGUY1WRBuApfAx5d7hzrTSV/jZv95qJwAdgDuS723dc5g
-uuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAVvP2HoDAAAEAwBHMEUCIQCH6MFZ
-tZF3Cqukt3/69fkU0Y5ePXXx8+xkOXRsIG3EGgIgSmCBWrnmPiiGA3x5QP8I8m4r
-Uee0y7s4NQNwjMgHrjwAdgC8eOHfxfY8aEZJM02hD6FfCXlpIAnAgbTz9pF/Ptm4
-pQAAAVvP2HqcAAAEAwBHMEUCIA8e2kAVYYuQCtn4PqK98BuHnLm9rC40DboFLCle
-SmQsAiEApbCJR05hr9VkNWmjaaUUGGZdVyUu9XX504LHVWyXZDUwDQYJKoZIhvcN
-AQELBQADggEBAEtfBfZ2y5uTohvW3h00Kcuop6Nq7Y59GU3MeizPKtx48DB8qHyd
-y5bLFwXzsGA1WkwpKzPbROsTGcAAXJHh03bj24AemUr/J/eQcjkfSoNBdHDpiSsk
-VZkQK2fGJDiYJ/r9mxKZcgd2pyN3l2OtVtNMv2dnFGF35UkkeqO3jqImwbypAmRX
-HdQV9dvW2YDRjzkebNNey6UwY9+YTSzr4da2hcaMHrj588Eqa4DDgNcY9QnE2RzN
-giArA+4RlM4AZ3jC2A756I67hrlvH+lhumHLp06hGfMiQJF1aaauFVSa36HKc3C/
-ty+sLdJbemEJLAr8uNXggFD+U8TKw1S4LSw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K
-hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ
-U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B
-89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx
-j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB
-I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv
-vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk
-DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl
-aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB
-AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw
-QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1
-c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5
-bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq
-n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9
-Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg
-3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45
-SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N
-QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp
-zNSS
------END CERTIFICATE-----
--
2.22.0

View File

@ -503,7 +503,7 @@ index e39fd7a..024499a 100644
+++ b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*

View File

@ -0,0 +1,21 @@
From 1b17272792968ae8b888c7ccb99133a4aee6b97f Mon Sep 17 00:00:00 2001
Subject: 8293344: JDK-8242181 broke stack printing for non-attached threads
---
hotspot/src/share/vm/utilities/elfFile.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/hotspot/src/share/vm/utilities/elfFile.cpp b/hotspot/src/share/vm/utilities/elfFile.cpp
index 81bd44109..448963b2d 100644
--- a/hotspot/src/share/vm/utilities/elfFile.cpp
+++ b/hotspot/src/share/vm/utilities/elfFile.cpp
@@ -318,7 +318,6 @@ bool ElfFile::specifies_noexecstack() {
bool ElfFile::get_source_info(const uint32_t offset_in_library, char* filename, const size_t filename_len,
int* line, bool is_pc_after_call) {
- ResourceMark rm;
if (!load_dwarf_file()) {
// Some ELF libraries do not provide separate .debuginfo files. Check if the current ELF file has the required
// DWARF sections. If so, treat the current ELF file as DWARF file.
--
2.22.0

View File

@ -1,526 +0,0 @@
From 78c19b03f00f61f673311cf3c70a21ce25933eec Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Wed, 30 Nov 2022 11:39:58 +0000
Subject: [PATCH 07/33] I68TO2: 8294357: (tz) Update Timezone Data to 2022d
---
jdk/make/data/tzdata/VERSION | 2 +-
jdk/make/data/tzdata/asia | 30 +++++++----
jdk/make/data/tzdata/backward | 2 +
jdk/make/data/tzdata/europe | 58 ++++------------------
jdk/make/data/tzdata/southamerica | 10 +++-
jdk/make/data/tzdata/zone.tab | 2 -
.../classes/sun/util/calendar/ZoneInfoFile.java | 9 +---
jdk/test/java/util/TimeZone/TimeZoneData/VERSION | 2 +-
.../java/util/TimeZone/TimeZoneData/aliases.txt | 2 +
.../util/TimeZone/TimeZoneData/displaynames.txt | 2 -
jdk/test/sun/util/calendar/zi/TestZoneInfo310.java | 15 ++++--
jdk/test/sun/util/calendar/zi/tzdata/VERSION | 2 +-
jdk/test/sun/util/calendar/zi/tzdata/asia | 30 +++++++----
jdk/test/sun/util/calendar/zi/tzdata/backward | 2 +
jdk/test/sun/util/calendar/zi/tzdata/europe | 58 ++++------------------
jdk/test/sun/util/calendar/zi/tzdata/southamerica | 10 +++-
jdk/test/sun/util/calendar/zi/tzdata/zone.tab | 2 -
17 files changed, 99 insertions(+), 139 deletions(-)
diff --git a/jdk/make/data/tzdata/VERSION b/jdk/make/data/tzdata/VERSION
index decb871..889d0e6 100644
--- a/jdk/make/data/tzdata/VERSION
+++ b/jdk/make/data/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2022c
+tzdata2022d
diff --git a/jdk/make/data/tzdata/asia b/jdk/make/data/tzdata/asia
index 6cb6d2c..1dc7d34 100644
--- a/jdk/make/data/tzdata/asia
+++ b/jdk/make/data/tzdata/asia
@@ -3398,10 +3398,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# The winter time in 2015 started on October 23 at 01:00.
# https://wafa.ps/ar_page.aspx?id=CgpCdYa670694628582aCgpCdY
# http://www.palestinecabinet.gov.ps/portal/meeting/details/27583
-#
-# From Paul Eggert (2019-04-10):
-# For now, guess spring-ahead transitions are at 00:00 on the Saturday
-# preceding March's last Sunday (i.e., Sat>=24).
# From P Chan (2021-10-18):
# http://wafa.ps/Pages/Details/34701
@@ -3418,6 +3414,18 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# From Heba Hamad (2022-03-10):
# summer time will begin in Palestine from Sunday 03-27-2022, 00:00 AM.
+# From Heba Hamad (2022-08-30):
+# winter time will begin in Palestine from Saturday 10-29, 02:00 AM by
+# 60 minutes backwards. Also the state of Palestine adopted the summer
+# and winter time for the years: 2023,2024,2025,2026 ...
+# https://mm.icann.org/pipermail/tz/attachments/20220830/9f024566/Time-0001.pdf
+# (2022-08-31): ... the Saturday before the last Sunday in March and October
+# at 2:00 AM ,for the years from 2023 to 2026.
+# (2022-09-05): https://mtit.pna.ps/Site/New/1453
+#
+# From Paul Eggert (2022-08-31):
+# For now, assume that this rule will also be used after 2026.
+
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 -
@@ -3448,14 +3456,16 @@ Rule Palestine 2013 only - Sep 27 0:00 0 -
Rule Palestine 2014 only - Oct 24 0:00 0 -
Rule Palestine 2015 only - Mar 28 0:00 1:00 S
Rule Palestine 2015 only - Oct 23 1:00 0 -
-Rule Palestine 2016 2018 - Mar Sat>=24 1:00 1:00 S
-Rule Palestine 2016 2018 - Oct Sat>=24 1:00 0 -
+Rule Palestine 2016 2018 - Mar Sat<=30 1:00 1:00 S
+Rule Palestine 2016 2018 - Oct Sat<=30 1:00 0 -
Rule Palestine 2019 only - Mar 29 0:00 1:00 S
-Rule Palestine 2019 only - Oct Sat>=24 0:00 0 -
-Rule Palestine 2020 2021 - Mar Sat>=24 0:00 1:00 S
+Rule Palestine 2019 only - Oct Sat<=30 0:00 0 -
+Rule Palestine 2020 2021 - Mar Sat<=30 0:00 1:00 S
Rule Palestine 2020 only - Oct 24 1:00 0 -
-Rule Palestine 2021 max - Oct Fri>=23 1:00 0 -
-Rule Palestine 2022 max - Mar Sun>=25 0:00 1:00 S
+Rule Palestine 2021 only - Oct 29 1:00 0 -
+Rule Palestine 2022 only - Mar 27 0:00 1:00 S
+Rule Palestine 2022 max - Oct Sat<=30 2:00 0 -
+Rule Palestine 2023 max - Mar Sat<=30 2:00 1:00 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
diff --git a/jdk/make/data/tzdata/backward b/jdk/make/data/tzdata/backward
index d4a29e8..7765d99 100644
--- a/jdk/make/data/tzdata/backward
+++ b/jdk/make/data/tzdata/backward
@@ -113,6 +113,8 @@ Link Etc/UTC Etc/UCT
Link Europe/London Europe/Belfast
Link Europe/Kyiv Europe/Kiev
Link Europe/Chisinau Europe/Tiraspol
+Link Europe/Kyiv Europe/Uzhgorod
+Link Europe/Kyiv Europe/Zaporozhye
Link Europe/London GB
Link Europe/London GB-Eire
Link Etc/GMT GMT+0
diff --git a/jdk/make/data/tzdata/europe b/jdk/make/data/tzdata/europe
index f7eb7a3..9e0a538 100644
--- a/jdk/make/data/tzdata/europe
+++ b/jdk/make/data/tzdata/europe
@@ -2638,10 +2638,14 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880
# From Alexander Krivenyshev (2014-03-17):
# time change at 2:00 (2am) on March 30, 2014
# https://vz.ru/news/2014/3/17/677464.html
-# From Paul Eggert (2014-03-30):
-# Simferopol and Sevastopol reportedly changed their central town clocks
-# late the previous day, but this appears to have been ceremonial
-# and the discrepancies are small enough to not worry about.
+# From Tim Parenti (2022-07-01), per Paul Eggert (2014-03-30):
+# The clocks at the railway station in Simferopol were put forward from 22:00
+# to 24:00 the previous day in a "symbolic ceremony"; however, per
+# contemporaneous news reports, "ordinary Crimeans [made] the daylight savings
+# time switch at 2am" on Sunday.
+# https://www.business-standard.com/article/pti-stories/crimea-to-set-clocks-to-russia-time-114033000014_1.html
+# https://www.reuters.com/article/us-ukraine-crisis-crimea-time/crimea-switches-to-moscow-time-amid-incorporation-frenzy-idUKBREA2S0LT20140329
+# https://www.bbc.com/news/av/world-europe-26806583
2:00 EU EE%sT 2014 Mar 30 2:00
4:00 - MSK 2014 Oct 26 2:00s
3:00 - MSK
@@ -3774,8 +3778,8 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# US colleague David Cochrane) are still trying to get more
# information upon these local deviations from Kiev rules.
#
-# From Paul Eggert (2022-02-08):
-# For now, assume that Ukraine's other three zones followed the same rules,
+# From Paul Eggert (2022-08-27):
+# For now, assume that Ukraine's zones all followed the same rules,
# except that Crimea switched to Moscow time in 1994 as described elsewhere.
# From Igor Karpov, who works for the Ukrainian Ministry of Justice,
@@ -3845,21 +3849,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# * Ukrainian Government's Resolution of 20.03.1992, No. 139.
# http://www.uazakon.com/documents/date_8u/pg_grcasa.htm
-# From Paul Eggert (2022-04-12):
-# As is usual in tzdb, Ukrainian zones use the most common English spellings.
-# In particular, tzdb's name Europe/Kyiv uses the most common spelling in
-# English for Ukraine's capital. Although tzdb's former name was Europe/Kiev,
-# "Kyiv" is now more common due to widespread reporting of the current conflict.
-# Conversely, tzdb continues to use the names Europe/Uzhgorod and
-# Europe/Zaporozhye; this is similar to tzdb's use of Europe/Prague, which is
-# certainly wrong as a transliteration of the Czech "Praha".
-# English-language spelling of Ukrainian names is in flux, and
-# some day "Uzhhorod" or "Zaporizhzhia" may become substantially more
-# common in English; in the meantime, do not change these
-# English spellings as that means less disruption for our users.
-
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-# This represents most of Ukraine. See above for the spelling of "Kyiv".
Zone Europe/Kyiv 2:02:04 - LMT 1880
2:02:04 - KMT 1924 May 2 # Kyiv Mean Time
2:00 - EET 1930 Jun 21
@@ -3869,34 +3859,6 @@ Zone Europe/Kyiv 2:02:04 - LMT 1880
2:00 1:00 EEST 1991 Sep 29 3:00
2:00 C-Eur EE%sT 1996 May 13
2:00 EU EE%sT
-# Transcarpathia used CET 1990/1991.
-# "Uzhhorod" is the transliteration of the Rusyn/Ukrainian pronunciation, but
-# "Uzhgorod" is more common in English.
-Zone Europe/Uzhgorod 1:29:12 - LMT 1890 Oct
- 1:00 - CET 1940
- 1:00 C-Eur CE%sT 1944 Oct
- 1:00 1:00 CEST 1944 Oct 26
- 1:00 - CET 1945 Jun 29
- 3:00 Russia MSK/MSD 1990
- 3:00 - MSK 1990 Jul 1 2:00
- 1:00 - CET 1991 Mar 31 3:00
- 2:00 - EET 1992 Mar 20
- 2:00 C-Eur EE%sT 1996 May 13
- 2:00 EU EE%sT
-# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
-# "Zaporizhzhia" is the transliteration of the Ukrainian name, but
-# "Zaporozh'ye" is more common in English. Use the common English
-# spelling, except omit the apostrophe as it is not allowed in
-# portable Posix file names.
-Zone Europe/Zaporozhye 2:20:40 - LMT 1880
- 2:20 - +0220 1924 May 2
- 2:00 - EET 1930 Jun 21
- 3:00 - MSK 1941 Aug 25
- 1:00 C-Eur CE%sT 1943 Oct 25
- 3:00 Russia MSK/MSD 1991 Mar 31 2:00
- 2:00 E-Eur EE%sT 1992 Mar 20
- 2:00 C-Eur EE%sT 1996 May 13
- 2:00 EU EE%sT
# Vatican City
# See Europe/Rome.
diff --git a/jdk/make/data/tzdata/southamerica b/jdk/make/data/tzdata/southamerica
index 13ec081..3c0e0e2 100644
--- a/jdk/make/data/tzdata/southamerica
+++ b/jdk/make/data/tzdata/southamerica
@@ -1332,8 +1332,14 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# for America/Santiago will start on midnight of September 11th;
# and will end on April 1st, 2023. Magallanes region (America/Punta_Arenas)
# will keep UTC -3 "indefinitely"... This is because on September 4th
-# we will have a voting whether to approve a new Constitution....
-# https://www.interior.gob.cl/noticias/2022/08/09/comunicado-el-proximo-sabado-10-de-septiembre-los-relojes-se-deben-adelantar-una-hora/
+# we will have a voting whether to approve a new Constitution.
+#
+# From Eduardo Romero Urra (2022-08-17):
+# https://www.diariooficial.interior.gob.cl/publicaciones/2022/08/13/43327/01/2172567.pdf
+#
+# From Paul Eggert (2022-08-17):
+# Although the presidential decree stops at fall 2026, assume that
+# similar DST rules will continue thereafter.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
diff --git a/jdk/make/data/tzdata/zone.tab b/jdk/make/data/tzdata/zone.tab
index 51b65fa..ee02519 100644
--- a/jdk/make/data/tzdata/zone.tab
+++ b/jdk/make/data/tzdata/zone.tab
@@ -424,8 +424,6 @@ TV -0831+17913 Pacific/Funafuti
TW +2503+12130 Asia/Taipei
TZ -0648+03917 Africa/Dar_es_Salaam
UA +5026+03031 Europe/Kyiv Ukraine (most areas)
-UA +4837+02218 Europe/Uzhgorod Transcarpathia
-UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk
UG +0019+03225 Africa/Kampala
UM +2813-17722 Pacific/Midway Midway Islands
UM +1917+16637 Pacific/Wake Wake Island
diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
index 43bddd5..4b84cda 100644
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
@@ -573,12 +573,8 @@ public final class ZoneInfoFile {
// we can then pass in the dom = -1, dow > 0 into ZoneInfo
//
// hacking, assume the >=24 is the result of ZRB optimization for
- // "last", it works for now. From tzdata2020d this hacking
- // will not work for Asia/Gaza and Asia/Hebron which follow
- // Palestine DST rules.
- if (dom < 0 || dom >= 24 &&
- !(zoneId.equals("Asia/Gaza") ||
- zoneId.equals("Asia/Hebron"))) {
+ // "last", it works for now.
+ if (dom < 0 || dom >= 24) {
params[1] = -1;
params[2] = toCalendarDOW[dow];
} else {
@@ -600,7 +596,6 @@ public final class ZoneInfoFile {
params[7] = 0;
} else {
// hacking: see comment above
- // No need of hacking for Asia/Gaza and Asia/Hebron from tz2021e
if (dom < 0 || dom >= 24) {
params[6] = -1;
params[7] = toCalendarDOW[dow];
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
index c32bee3..7147016 100644
--- a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
@@ -1 +1 @@
-tzdata2022c
+tzdata2022d
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt b/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt
index a5e6428..e3ce742 100644
--- a/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/aliases.txt
@@ -183,6 +183,8 @@ Link Etc/UTC Etc/UCT
Link Europe/London Europe/Belfast
Link Europe/Kyiv Europe/Kiev
Link Europe/Chisinau Europe/Tiraspol
+Link Europe/Kyiv Europe/Uzhgorod
+Link Europe/Kyiv Europe/Zaporozhye
Link Europe/London GB
Link Europe/London GB-Eire
Link Etc/GMT GMT+0
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
index fc14853..b382395 100644
--- a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
@@ -163,11 +163,9 @@ Europe/Simferopol MSK
Europe/Sofia EET EEST
Europe/Tallinn EET EEST
Europe/Tirane CET CEST
-Europe/Uzhgorod EET EEST
Europe/Vienna CET CEST
Europe/Vilnius EET EEST
Europe/Warsaw CET CEST
-Europe/Zaporozhye EET EEST
Europe/Zurich CET CEST
HST HST
MET MET MEST
diff --git a/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java b/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
index 3aad69f..c682531 100644
--- a/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
+++ b/jdk/test/sun/util/calendar/zi/TestZoneInfo310.java
@@ -173,10 +173,19 @@ public class TestZoneInfo310 {
* Temporary ignoring the failing TimeZones which are having zone
* rules defined till year 2037 and/or above and have negative DST
* save time in IANA tzdata. This bug is tracked via JDK-8223388.
+ *
+ * Tehran/Iran rule has rules beyond 2037, in which javazic assumes
+ * to be the last year. Thus javazic's rule is based on year 2037
+ * (Mar 20th/Sep 20th are the cutover dates), while the real rule
+ * has year 2087 where Mar 21st/Sep 21st are the cutover dates.
*/
- if (zid.equals("Africa/Casablanca") || zid.equals("Africa/El_Aaiun")
- || zid.equals("Asia/Tehran") || zid.equals("Iran")) {
- continue;
+ if (zid.equals("Africa/Casablanca") || // uses "Morocco" rule
+ zid.equals("Africa/El_Aaiun") || // uses "Morocco" rule
+ zid.equals("Asia/Tehran") || // last rule mismatch
+ zid.equals("Asia/Gaza") || // uses "Palestine" rule
+ zid.equals("Asia/Hebron") || // uses "Palestine" rule
+ zid.equals("Iran")) { // last rule mismatch
+ continue;
}
if (! zi.equalsTo(ziOLD)) {
System.out.println(zi.diffsTo(ziOLD));
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/VERSION b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
index decb871..889d0e6 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2022c
+tzdata2022d
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/asia b/jdk/test/sun/util/calendar/zi/tzdata/asia
index 6cb6d2c..1dc7d34 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia
@@ -3398,10 +3398,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# The winter time in 2015 started on October 23 at 01:00.
# https://wafa.ps/ar_page.aspx?id=CgpCdYa670694628582aCgpCdY
# http://www.palestinecabinet.gov.ps/portal/meeting/details/27583
-#
-# From Paul Eggert (2019-04-10):
-# For now, guess spring-ahead transitions are at 00:00 on the Saturday
-# preceding March's last Sunday (i.e., Sat>=24).
# From P Chan (2021-10-18):
# http://wafa.ps/Pages/Details/34701
@@ -3418,6 +3414,18 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# From Heba Hamad (2022-03-10):
# summer time will begin in Palestine from Sunday 03-27-2022, 00:00 AM.
+# From Heba Hamad (2022-08-30):
+# winter time will begin in Palestine from Saturday 10-29, 02:00 AM by
+# 60 minutes backwards. Also the state of Palestine adopted the summer
+# and winter time for the years: 2023,2024,2025,2026 ...
+# https://mm.icann.org/pipermail/tz/attachments/20220830/9f024566/Time-0001.pdf
+# (2022-08-31): ... the Saturday before the last Sunday in March and October
+# at 2:00 AM ,for the years from 2023 to 2026.
+# (2022-09-05): https://mtit.pna.ps/Site/New/1453
+#
+# From Paul Eggert (2022-08-31):
+# For now, assume that this rule will also be used after 2026.
+
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 -
@@ -3448,14 +3456,16 @@ Rule Palestine 2013 only - Sep 27 0:00 0 -
Rule Palestine 2014 only - Oct 24 0:00 0 -
Rule Palestine 2015 only - Mar 28 0:00 1:00 S
Rule Palestine 2015 only - Oct 23 1:00 0 -
-Rule Palestine 2016 2018 - Mar Sat>=24 1:00 1:00 S
-Rule Palestine 2016 2018 - Oct Sat>=24 1:00 0 -
+Rule Palestine 2016 2018 - Mar Sat<=30 1:00 1:00 S
+Rule Palestine 2016 2018 - Oct Sat<=30 1:00 0 -
Rule Palestine 2019 only - Mar 29 0:00 1:00 S
-Rule Palestine 2019 only - Oct Sat>=24 0:00 0 -
-Rule Palestine 2020 2021 - Mar Sat>=24 0:00 1:00 S
+Rule Palestine 2019 only - Oct Sat<=30 0:00 0 -
+Rule Palestine 2020 2021 - Mar Sat<=30 0:00 1:00 S
Rule Palestine 2020 only - Oct 24 1:00 0 -
-Rule Palestine 2021 max - Oct Fri>=23 1:00 0 -
-Rule Palestine 2022 max - Mar Sun>=25 0:00 1:00 S
+Rule Palestine 2021 only - Oct 29 1:00 0 -
+Rule Palestine 2022 only - Mar 27 0:00 1:00 S
+Rule Palestine 2022 max - Oct Sat<=30 2:00 0 -
+Rule Palestine 2023 max - Mar Sat<=30 2:00 1:00 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/backward b/jdk/test/sun/util/calendar/zi/tzdata/backward
index d4a29e8..7765d99 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/backward
+++ b/jdk/test/sun/util/calendar/zi/tzdata/backward
@@ -113,6 +113,8 @@ Link Etc/UTC Etc/UCT
Link Europe/London Europe/Belfast
Link Europe/Kyiv Europe/Kiev
Link Europe/Chisinau Europe/Tiraspol
+Link Europe/Kyiv Europe/Uzhgorod
+Link Europe/Kyiv Europe/Zaporozhye
Link Europe/London GB
Link Europe/London GB-Eire
Link Etc/GMT GMT+0
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/europe b/jdk/test/sun/util/calendar/zi/tzdata/europe
index f7eb7a3..9e0a538 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe
@@ -2638,10 +2638,14 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880
# From Alexander Krivenyshev (2014-03-17):
# time change at 2:00 (2am) on March 30, 2014
# https://vz.ru/news/2014/3/17/677464.html
-# From Paul Eggert (2014-03-30):
-# Simferopol and Sevastopol reportedly changed their central town clocks
-# late the previous day, but this appears to have been ceremonial
-# and the discrepancies are small enough to not worry about.
+# From Tim Parenti (2022-07-01), per Paul Eggert (2014-03-30):
+# The clocks at the railway station in Simferopol were put forward from 22:00
+# to 24:00 the previous day in a "symbolic ceremony"; however, per
+# contemporaneous news reports, "ordinary Crimeans [made] the daylight savings
+# time switch at 2am" on Sunday.
+# https://www.business-standard.com/article/pti-stories/crimea-to-set-clocks-to-russia-time-114033000014_1.html
+# https://www.reuters.com/article/us-ukraine-crisis-crimea-time/crimea-switches-to-moscow-time-amid-incorporation-frenzy-idUKBREA2S0LT20140329
+# https://www.bbc.com/news/av/world-europe-26806583
2:00 EU EE%sT 2014 Mar 30 2:00
4:00 - MSK 2014 Oct 26 2:00s
3:00 - MSK
@@ -3774,8 +3778,8 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# US colleague David Cochrane) are still trying to get more
# information upon these local deviations from Kiev rules.
#
-# From Paul Eggert (2022-02-08):
-# For now, assume that Ukraine's other three zones followed the same rules,
+# From Paul Eggert (2022-08-27):
+# For now, assume that Ukraine's zones all followed the same rules,
# except that Crimea switched to Moscow time in 1994 as described elsewhere.
# From Igor Karpov, who works for the Ukrainian Ministry of Justice,
@@ -3845,21 +3849,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# * Ukrainian Government's Resolution of 20.03.1992, No. 139.
# http://www.uazakon.com/documents/date_8u/pg_grcasa.htm
-# From Paul Eggert (2022-04-12):
-# As is usual in tzdb, Ukrainian zones use the most common English spellings.
-# In particular, tzdb's name Europe/Kyiv uses the most common spelling in
-# English for Ukraine's capital. Although tzdb's former name was Europe/Kiev,
-# "Kyiv" is now more common due to widespread reporting of the current conflict.
-# Conversely, tzdb continues to use the names Europe/Uzhgorod and
-# Europe/Zaporozhye; this is similar to tzdb's use of Europe/Prague, which is
-# certainly wrong as a transliteration of the Czech "Praha".
-# English-language spelling of Ukrainian names is in flux, and
-# some day "Uzhhorod" or "Zaporizhzhia" may become substantially more
-# common in English; in the meantime, do not change these
-# English spellings as that means less disruption for our users.
-
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-# This represents most of Ukraine. See above for the spelling of "Kyiv".
Zone Europe/Kyiv 2:02:04 - LMT 1880
2:02:04 - KMT 1924 May 2 # Kyiv Mean Time
2:00 - EET 1930 Jun 21
@@ -3869,34 +3859,6 @@ Zone Europe/Kyiv 2:02:04 - LMT 1880
2:00 1:00 EEST 1991 Sep 29 3:00
2:00 C-Eur EE%sT 1996 May 13
2:00 EU EE%sT
-# Transcarpathia used CET 1990/1991.
-# "Uzhhorod" is the transliteration of the Rusyn/Ukrainian pronunciation, but
-# "Uzhgorod" is more common in English.
-Zone Europe/Uzhgorod 1:29:12 - LMT 1890 Oct
- 1:00 - CET 1940
- 1:00 C-Eur CE%sT 1944 Oct
- 1:00 1:00 CEST 1944 Oct 26
- 1:00 - CET 1945 Jun 29
- 3:00 Russia MSK/MSD 1990
- 3:00 - MSK 1990 Jul 1 2:00
- 1:00 - CET 1991 Mar 31 3:00
- 2:00 - EET 1992 Mar 20
- 2:00 C-Eur EE%sT 1996 May 13
- 2:00 EU EE%sT
-# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
-# "Zaporizhzhia" is the transliteration of the Ukrainian name, but
-# "Zaporozh'ye" is more common in English. Use the common English
-# spelling, except omit the apostrophe as it is not allowed in
-# portable Posix file names.
-Zone Europe/Zaporozhye 2:20:40 - LMT 1880
- 2:20 - +0220 1924 May 2
- 2:00 - EET 1930 Jun 21
- 3:00 - MSK 1941 Aug 25
- 1:00 C-Eur CE%sT 1943 Oct 25
- 3:00 Russia MSK/MSD 1991 Mar 31 2:00
- 2:00 E-Eur EE%sT 1992 Mar 20
- 2:00 C-Eur EE%sT 1996 May 13
- 2:00 EU EE%sT
# Vatican City
# See Europe/Rome.
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/southamerica b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
index 13ec081..3c0e0e2 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/southamerica
+++ b/jdk/test/sun/util/calendar/zi/tzdata/southamerica
@@ -1332,8 +1332,14 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# for America/Santiago will start on midnight of September 11th;
# and will end on April 1st, 2023. Magallanes region (America/Punta_Arenas)
# will keep UTC -3 "indefinitely"... This is because on September 4th
-# we will have a voting whether to approve a new Constitution....
-# https://www.interior.gob.cl/noticias/2022/08/09/comunicado-el-proximo-sabado-10-de-septiembre-los-relojes-se-deben-adelantar-una-hora/
+# we will have a voting whether to approve a new Constitution.
+#
+# From Eduardo Romero Urra (2022-08-17):
+# https://www.diariooficial.interior.gob.cl/publicaciones/2022/08/13/43327/01/2172567.pdf
+#
+# From Paul Eggert (2022-08-17):
+# Although the presidential decree stops at fall 2026, assume that
+# similar DST rules will continue thereafter.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
index 51b65fa..ee02519 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
+++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab
@@ -424,8 +424,6 @@ TV -0831+17913 Pacific/Funafuti
TW +2503+12130 Asia/Taipei
TZ -0648+03917 Africa/Dar_es_Salaam
UA +5026+03031 Europe/Kyiv Ukraine (most areas)
-UA +4837+02218 Europe/Uzhgorod Transcarpathia
-UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk
UG +0019+03225 Africa/Kampala
UM +2813-17722 Pacific/Midway Midway Islands
UM +1917+16637 Pacific/Wake Wake Island
--
1.8.3.1

View File

@ -0,0 +1,338 @@
From 44a22ec75a0ef4200ba824e9e00b56b735b911a0 Mon Sep 17 00:00:00 2001
Subject: 8294906: Memory leak in PKCS11 NSS TLS server
---
.../pkcs11/P11TlsKeyMaterialGenerator.java | 14 ++--
.../crypto/provider/TLS/TestKeyMaterial.java | 31 ++++++++-
.../sun/crypto/provider/TLS/keymatdata.txt | 34 ++++++++++
.../security/pkcs11/tls/TestKeyMaterial.java | 65 +++++++++++++------
.../sun/security/pkcs11/tls/keymatdata.txt | 34 ++++++++++
5 files changed, 151 insertions(+), 27 deletions(-)
diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java b/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
index f6848278c..4242ff756 100644
--- a/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -193,15 +193,19 @@ public final class P11TlsKeyMaterialGenerator extends KeyGeneratorSpi {
SecretKey clientMacKey, serverMacKey;
// The MAC size may be zero for GCM mode.
- //
- // PKCS11 does not support GCM mode as the author made the comment,
- // so the macBits is unlikely to be zero. It's only a place holder.
if (macBits != 0) {
clientMacKey = P11Key.secretKey
(session, out.hClientMacSecret, "MAC", macBits, attributes);
serverMacKey = P11Key.secretKey
(session, out.hServerMacSecret, "MAC", macBits, attributes);
} else {
+ // NSS allocates MAC keys even if macBits is zero
+ if (out.hClientMacSecret != CK_INVALID_HANDLE) {
+ token.p11.C_DestroyObject(session.id(), out.hClientMacSecret);
+ }
+ if (out.hServerMacSecret != CK_INVALID_HANDLE) {
+ token.p11.C_DestroyObject(session.id(), out.hServerMacSecret);
+ }
clientMacKey = null;
serverMacKey = null;
}
@@ -213,6 +217,8 @@ public final class P11TlsKeyMaterialGenerator extends KeyGeneratorSpi {
serverCipherKey = P11Key.secretKey(session, out.hServerKey,
cipherAlgorithm, expandedKeyBits, attributes);
} else {
+ assert out.hClientKey == 0;
+ assert out.hServerKey == 0;
clientCipherKey = null;
serverCipherKey = null;
}
diff --git a/jdk/test/com/sun/crypto/provider/TLS/TestKeyMaterial.java b/jdk/test/com/sun/crypto/provider/TLS/TestKeyMaterial.java
index 8874070f4..6569c0c4f 100644
--- a/jdk/test/com/sun/crypto/provider/TLS/TestKeyMaterial.java
+++ b/jdk/test/com/sun/crypto/provider/TLS/TestKeyMaterial.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -60,6 +60,7 @@ public class TestKeyMaterial extends Utils {
byte[] clientRandom = null;
byte[] serverRandom = null;
String cipherAlgorithm = null;
+ String hashAlgorithm = null; // TLS1.2+ only
int keyLength = 0;
int expandedKeyLength = 0;
int ivLength = 0;
@@ -93,6 +94,8 @@ public class TestKeyMaterial extends Utils {
serverRandom = parse(data);
} else if (line.startsWith("km-cipalg:")) {
cipherAlgorithm = data;
+ } else if (line.startsWith("km-hashalg:")) {
+ hashAlgorithm = data;
} else if (line.startsWith("km-keylen:")) {
keyLength = Integer.parseInt(data);
} else if (line.startsWith("km-explen:")) {
@@ -118,14 +121,36 @@ public class TestKeyMaterial extends Utils {
n++;
KeyGenerator kg =
- KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
+ KeyGenerator.getInstance(minor == 3 ?
+ "SunTls12KeyMaterial" :
+ "SunTlsKeyMaterial", provider);
SecretKey masterKey =
new SecretKeySpec(master, "TlsMasterSecret");
+ int prfHashLength, prfBlockSize;
+
+ if (hashAlgorithm != null) {
+ switch (hashAlgorithm) {
+ case "SHA-256":
+ prfHashLength = 32;
+ prfBlockSize = 64;
+ break;
+ case "SHA-384":
+ prfHashLength = 48;
+ prfBlockSize = 128;
+ break;
+ default:
+ throw new RuntimeException("Unexpected hashalg: " +
+ hashAlgorithm);
+ }
+ } else {
+ prfHashLength = -1;
+ prfBlockSize = -1;
+ }
TlsKeyMaterialParameterSpec spec =
new TlsKeyMaterialParameterSpec(masterKey, major, minor,
clientRandom, serverRandom, cipherAlgorithm,
keyLength, expandedKeyLength, ivLength, macLength,
- null, -1, -1);
+ hashAlgorithm, prfHashLength, prfBlockSize);
kg.init(spec);
TlsKeyMaterialSpec result =
diff --git a/jdk/test/com/sun/crypto/provider/TLS/keymatdata.txt b/jdk/test/com/sun/crypto/provider/TLS/keymatdata.txt
index 391f30000..a3ff869b6 100644
--- a/jdk/test/com/sun/crypto/provider/TLS/keymatdata.txt
+++ b/jdk/test/com/sun/crypto/provider/TLS/keymatdata.txt
@@ -3646,3 +3646,37 @@ km-civ: 17:bd:47:89:54:be:04:23
km-siv: 34:8a:e8:24:84:38:c4:e1
km-cmackey: e8:f0:b5:7b:a7:cc:2f:5e:43:ef:d3:dd:4e:8c:f9:6f:51:d7:84:df
km-smackey: fc:0c:77:20:c2:28:d3:11:ba:57:13:d8:0b:2d:f1:30:89:c6:35:69
+km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc
+km-major: 3
+km-minor: 3
+km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56
+km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97
+km-cipalg: AES
+km-hashalg: SHA-256
+km-keylen: 16
+km-explen: 0
+km-ivlen: 4
+km-maclen: 0
+km-ccipkey: 60:7a:45:a9:6e:76:58:ea:d9:44:c5:25:f8:92:f1:26
+km-scipkey: 42:c0:ed:75:a2:51:21:7c:50:74:9d:78:9a:f7:35:2b
+km-civ: a1:3c:3e:4a
+km-siv: 85:ab:ee:70
+km-cmackey: (null)
+km-smackey: (null)
+km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc
+km-major: 3
+km-minor: 3
+km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56
+km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97
+km-cipalg: AES
+km-hashalg: SHA-384
+km-keylen: 32
+km-explen: 0
+km-ivlen: 4
+km-maclen: 0
+km-ccipkey: 3c:03:17:61:1e:88:4a:aa:01:4c:ac:6c:f8:bb:91:c3:0e:ec:57:c7:bf:07:ff:eb:49:22:f9:80:12:64:72:2a
+km-scipkey: f8:00:8e:b2:dc:25:98:f1:97:00:55:28:60:a3:65:da:42:89:18:bb:40:94:53:d2:75:2a:29:e5:aa:94:1d:7a
+km-civ: 24:02:76:6f
+km-siv: 3b:6d:33:5a
+km-cmackey: (null)
+km-smackey: (null)
\ No newline at end of file
diff --git a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java
index 534398a1a..e138a5b1d 100644
--- a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java
+++ b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -21,9 +21,9 @@
* questions.
*/
-/**
+/*
* @test
- * @bug 6316539
+ * @bug 6316539 8136355 8294906
* @summary Known-answer-test for TlsKeyMaterial generator
* @author Andreas Sterbenz
* @library ..
@@ -34,12 +34,16 @@
import java.io.BufferedReader;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.security.InvalidAlgorithmParameterException;
import java.security.Provider;
+import java.security.ProviderException;
import java.util.Arrays;
+
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
+
import sun.security.internal.spec.TlsKeyMaterialParameterSpec;
import sun.security.internal.spec.TlsKeyMaterialSpec;
@@ -48,6 +52,7 @@ public class TestKeyMaterial extends PKCS11Test {
private static final int PREFIX_LENGTH = "km-master: ".length();
public static void main(String[] args) throws Exception {
+ System.out.println("NSS Version: " + getNSSVersion());
main(new TestKeyMaterial(), args);
}
@@ -70,6 +75,7 @@ public class TestKeyMaterial extends PKCS11Test {
byte[] clientRandom = null;
byte[] serverRandom = null;
String cipherAlgorithm = null;
+ String hashAlgorithm = null; // TLS1.2+ only
int keyLength = 0;
int expandedKeyLength = 0;
int ivLength = 0;
@@ -103,6 +109,8 @@ public class TestKeyMaterial extends PKCS11Test {
serverRandom = parse(data);
} else if (line.startsWith("km-cipalg:")) {
cipherAlgorithm = data;
+ } else if (line.startsWith("km-hashalg:")) {
+ hashAlgorithm = data;
} else if (line.startsWith("km-keylen:")) {
keyLength = Integer.parseInt(data);
} else if (line.startsWith("km-explen:")) {
@@ -128,30 +136,47 @@ public class TestKeyMaterial extends PKCS11Test {
n++;
KeyGenerator kg =
- KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
+ KeyGenerator.getInstance(minor == 3 ?
+ "SunTls12KeyMaterial" :
+ "SunTlsKeyMaterial", provider);
SecretKey masterKey =
new SecretKeySpec(master, "TlsMasterSecret");
+ // prfHashLength and prfBlockSize are ignored by PKCS11 provider
TlsKeyMaterialParameterSpec spec =
new TlsKeyMaterialParameterSpec(masterKey, major, minor,
clientRandom, serverRandom, cipherAlgorithm,
keyLength, expandedKeyLength, ivLength, macLength,
- null, -1, -1);
-
- kg.init(spec);
- TlsKeyMaterialSpec result =
- (TlsKeyMaterialSpec)kg.generateKey();
- match(lineNumber, clientCipherBytes,
- result.getClientCipherKey(), cipherAlgorithm);
- match(lineNumber, serverCipherBytes,
- result.getServerCipherKey(), cipherAlgorithm);
- match(lineNumber, clientIv, result.getClientIv(), "");
- match(lineNumber, serverIv, result.getServerIv(), "");
- match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
- match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
-
- } else {
+ hashAlgorithm, -1 /*ignored*/, -1 /*ignored*/);
+
+ try {
+ kg.init(spec);
+ TlsKeyMaterialSpec result =
+ (TlsKeyMaterialSpec)kg.generateKey();
+ match(lineNumber, clientCipherBytes,
+ result.getClientCipherKey(), cipherAlgorithm);
+ match(lineNumber, serverCipherBytes,
+ result.getServerCipherKey(), cipherAlgorithm);
+ match(lineNumber, clientIv, result.getClientIv(), "");
+ match(lineNumber, serverIv, result.getServerIv(), "");
+ match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
+ match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
+ } catch (ProviderException pe) {
+ if (provider.getName().indexOf("NSS") != -1) {
+ Throwable t = pe.getCause();
+ if (expandedKeyLength != 0
+ && t.getMessage().indexOf(
+ "CKR_MECHANISM_PARAM_INVALID") != -1) {
+ // NSS removed support for export-grade cipher suites in 3.28,
+ // see https://bugzilla.mozilla.org/show_bug.cgi?id=1252849
+ System.out.println("Ignore known NSS failure on CKR_MECHANISM_PARAM_INVALID");
+ continue;
+ }
+ }
+ throw pe;
+ }
+ } else {
throw new Exception("Unknown line: " + line);
- }
+ }
}
if (n == 0) {
throw new Exception("no tests");
diff --git a/jdk/test/sun/security/pkcs11/tls/keymatdata.txt b/jdk/test/sun/security/pkcs11/tls/keymatdata.txt
index 391f30000..1d1ee6369 100644
--- a/jdk/test/sun/security/pkcs11/tls/keymatdata.txt
+++ b/jdk/test/sun/security/pkcs11/tls/keymatdata.txt
@@ -3646,3 +3646,37 @@ km-civ: 17:bd:47:89:54:be:04:23
km-siv: 34:8a:e8:24:84:38:c4:e1
km-cmackey: e8:f0:b5:7b:a7:cc:2f:5e:43:ef:d3:dd:4e:8c:f9:6f:51:d7:84:df
km-smackey: fc:0c:77:20:c2:28:d3:11:ba:57:13:d8:0b:2d:f1:30:89:c6:35:69
+km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc
+km-major: 3
+km-minor: 3
+km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56
+km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97
+km-cipalg: AES
+km-hashalg: SHA-256
+km-keylen: 16
+km-explen: 0
+km-ivlen: 4
+km-maclen: 0
+km-ccipkey: 60:7a:45:a9:6e:76:58:ea:d9:44:c5:25:f8:92:f1:26
+km-scipkey: 42:c0:ed:75:a2:51:21:7c:50:74:9d:78:9a:f7:35:2b
+km-civ: a1:3c:3e:4a
+km-siv: 85:ab:ee:70
+km-cmackey: (null)
+km-smackey: (null)
+km-master: f1:05:15:45:33:be:50:d6:88:0b:03:bb:88:9b:ef:d4:3b:98:aa:40:13:71:3c:1c:d9:df:34:c7:50:75:ad:5c:0a:d4:fe:ed:d5:58:6b:ff:2b:ce:c6:12:bc:6b:7e:dc
+km-major: 3
+km-minor: 3
+km-crandom: 42:f3:36:8e:9d:c9:69:3e:c1:8a:38:d3:e0:ec:2b:58:c2:e0:0c:de:4f:f3:af:51:d2:5c:bc:b2:c3:3b:1e:56
+km-srandom: 42:f3:36:8e:fa:fd:23:3e:fd:f9:bc:88:3c:98:93:f3:c3:1d:9c:2a:4a:3b:02:a7:40:d4:64:04:59:e9:65:97
+km-cipalg: AES
+km-hashalg: SHA-384
+km-keylen: 32
+km-explen: 0
+km-ivlen: 4
+km-maclen: 0
+km-ccipkey: 3c:03:17:61:1e:88:4a:aa:01:4c:ac:6c:f8:bb:91:c3:0e:ec:57:c7:bf:07:ff:eb:49:22:f9:80:12:64:72:2a
+km-scipkey: f8:00:8e:b2:dc:25:98:f1:97:00:55:28:60:a3:65:da:42:89:18:bb:40:94:53:d2:75:2a:29:e5:aa:94:1d:7a
+km-civ: 24:02:76:6f
+km-siv: 3b:6d:33:5a
+km-cmackey: (null)
+km-smackey: (null)
--
2.22.0

View File

@ -0,0 +1,25 @@
From 559bf67072bcf7fe854d03aebdfb49e02bd75899 Mon Sep 17 00:00:00 2001
From: DXwangg <wangjiawei80@huawei.com>
Date: Mon, 25 Sep 2023 09:50:38 +0800
Subject: [PATCH] 8295068: SSLEngine throws NPE parsing CertificateRequests
---
jdk/src/share/classes/sun/security/ssl/CertificateRequest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jdk/src/share/classes/sun/security/ssl/CertificateRequest.java b/jdk/src/share/classes/sun/security/ssl/CertificateRequest.java
index 475ec42c..ad0325e4 100644
--- a/jdk/src/share/classes/sun/security/ssl/CertificateRequest.java
+++ b/jdk/src/share/classes/sun/security/ssl/CertificateRequest.java
@@ -135,7 +135,7 @@ final class CertificateRequest {
ArrayList<String> keyTypes = new ArrayList<>(3);
for (byte id : ids) {
ClientCertificateType cct = ClientCertificateType.valueOf(id);
- if (cct.isAvailable) {
+ if (cct != null && cct.isAvailable) {
keyTypes.add(cct.keyAlgorithm);
}
}
--
2.39.0

File diff suppressed because it is too large Load Diff

View File

@ -1,826 +0,0 @@
From d31b6120315ecc095ddffa7a5fb92c53bb70bc3b Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Wed, 30 Nov 2022 14:57:07 +0000
Subject: [PATCH 08/33] I68TO2: 8296241: (tz) Update Timezone Data to 2022e
---
jdk/make/data/tzdata/VERSION | 2 +-
jdk/make/data/tzdata/asia | 36 +++++++---
jdk/make/data/tzdata/europe | 2 +-
jdk/make/data/tzdata/northamerica | 84 ++++++++++------------
jdk/test/java/util/TimeZone/TimeZoneData/VERSION | 2 +-
.../util/TimeZone/TimeZoneData/displaynames.txt | 2 -
jdk/test/sun/util/calendar/zi/tzdata/VERSION | 2 +-
jdk/test/sun/util/calendar/zi/tzdata/asia | 36 +++++++---
jdk/test/sun/util/calendar/zi/tzdata/europe | 2 +-
jdk/test/sun/util/calendar/zi/tzdata/northamerica | 84 ++++++++++------------
10 files changed, 135 insertions(+), 117 deletions(-)
diff --git a/jdk/make/data/tzdata/VERSION b/jdk/make/data/tzdata/VERSION
index 889d0e6..b8cb36e 100644
--- a/jdk/make/data/tzdata/VERSION
+++ b/jdk/make/data/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2022d
+tzdata2022e
diff --git a/jdk/make/data/tzdata/asia b/jdk/make/data/tzdata/asia
index 1dc7d34..f1771e4 100644
--- a/jdk/make/data/tzdata/asia
+++ b/jdk/make/data/tzdata/asia
@@ -2254,6 +2254,17 @@ Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
# From the Arabic version, it seems to say it would be at midnight
# (assume 24:00) on the last Thursday in February, starting from 2022.
+# From Issam Al-Zuwairi (2022-10-05):
+# The Council of Ministers in Jordan decided Wednesday 5th October 2022,
+# that daylight saving time (DST) will be throughout the year....
+#
+# From Brian Inglis (2022-10-06):
+# https://petra.gov.jo/Include/InnerPage.jsp?ID=45567&lang=en&name=en_news
+#
+# From Paul Eggert (2022-10-05):
+# Like Syria, model this as a transition from EEST +03 (DST) to plain +03
+# (non-DST) at the point where DST would otherwise have ended.
+
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Jordan 1973 only - Jun 6 0:00 1:00 S
Rule Jordan 1973 1975 - Oct 1 0:00 0 -
@@ -2285,11 +2296,12 @@ Rule Jordan 2005 only - Sep lastFri 0:00s 0 -
Rule Jordan 2006 2011 - Oct lastFri 0:00s 0 -
Rule Jordan 2013 only - Dec 20 0:00 0 -
Rule Jordan 2014 2021 - Mar lastThu 24:00 1:00 S
-Rule Jordan 2014 max - Oct lastFri 0:00s 0 -
-Rule Jordan 2022 max - Feb lastThu 24:00 1:00 S
+Rule Jordan 2014 2022 - Oct lastFri 0:00s 0 -
+Rule Jordan 2022 only - Feb lastThu 24:00 1:00 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Amman 2:23:44 - LMT 1931
- 2:00 Jordan EE%sT
+ 2:00 Jordan EE%sT 2022 Oct 28 0:00s
+ 3:00 - +03
# Kazakhstan
@@ -3838,19 +3850,27 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 -
# Our brief summary:
# https://www.timeanddate.com/news/time/syria-dst-2012.html
-# From Arthur David Olson (2012-03-27):
-# Assume last Friday in March going forward XXX.
+# From Steffen Thorsen (2022-10-05):
+# Syria is adopting year-round DST, starting this autumn....
+# From https://www.enabbaladi.net/archives/607812
+# "This [the decision] came after the weekly government meeting today,
+# Tuesday 4 October ..."
+#
+# From Paul Eggert (2022-10-05):
+# Like Jordan, model this as a transition from EEST +03 (DST) to plain +03
+# (non-DST) at the point where DST would otherwise have ended.
Rule Syria 2008 only - Apr Fri>=1 0:00 1:00 S
Rule Syria 2008 only - Nov 1 0:00 0 -
Rule Syria 2009 only - Mar lastFri 0:00 1:00 S
Rule Syria 2010 2011 - Apr Fri>=1 0:00 1:00 S
-Rule Syria 2012 max - Mar lastFri 0:00 1:00 S
-Rule Syria 2009 max - Oct lastFri 0:00 0 -
+Rule Syria 2012 2022 - Mar lastFri 0:00 1:00 S
+Rule Syria 2009 2022 - Oct lastFri 0:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq
- 2:00 Syria EE%sT
+ 2:00 Syria EE%sT 2022 Oct 28 0:00
+ 3:00 - +03
# Tajikistan
# From Shanks & Pottenger.
diff --git a/jdk/make/data/tzdata/europe b/jdk/make/data/tzdata/europe
index 9e0a538..930cede 100644
--- a/jdk/make/data/tzdata/europe
+++ b/jdk/make/data/tzdata/europe
@@ -3417,7 +3417,7 @@ Zone Europe/Madrid -0:14:44 - LMT 1901 Jan 1 0:00u
0:00 Spain WE%sT 1940 Mar 16 23:00
1:00 Spain CE%sT 1979
1:00 EU CE%sT
-Zone Africa/Ceuta -0:21:16 - LMT 1900 Dec 31 23:38:44
+Zone Africa/Ceuta -0:21:16 - LMT 1901 Jan 1 0:00u
0:00 - WET 1918 May 6 23:00
0:00 1:00 WEST 1918 Oct 7 23:00
0:00 - WET 1924
diff --git a/jdk/make/data/tzdata/northamerica b/jdk/make/data/tzdata/northamerica
index 114cef1..ce4ee74 100644
--- a/jdk/make/data/tzdata/northamerica
+++ b/jdk/make/data/tzdata/northamerica
@@ -462,7 +462,7 @@ Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D
Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S
Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
+Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1920
-6:00 Chicago C%sT 1936 Mar 1 2:00
-5:00 - EST 1936 Nov 15 2:00
@@ -471,7 +471,7 @@ Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
-6:00 Chicago C%sT 1967
-6:00 US C%sT
# Oliver County, ND switched from mountain to central time on 1992-10-25.
-Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
+Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 1992 Oct 25 2:00
-6:00 US C%sT
# Morton County, ND, switched from mountain to central time on
@@ -481,7 +481,7 @@ Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
# Jones, Mellette, and Todd Counties in South Dakota;
# but in practice these other counties were already observing central time.
# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
-Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
+Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 2003 Oct 26 2:00
-6:00 US C%sT
@@ -498,7 +498,7 @@ Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
# largest city in Mercer County). Google Maps places Beulah's city hall
# at 47° 15' 51" N, 101° 46' 40" W, which yields an offset of 6h47'07".
-Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
+Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 2010 Nov 7 2:00
-6:00 US C%sT
@@ -530,7 +530,7 @@ Rule Denver 1921 only - May 22 2:00 0 S
Rule Denver 1965 1966 - Apr lastSun 2:00 1:00 D
Rule Denver 1965 1966 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04
+Zone America/Denver -6:59:56 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 1920
-7:00 Denver M%sT 1942
-7:00 US M%sT 1946
@@ -583,7 +583,7 @@ Rule CA 1950 1966 - Apr lastSun 1:00 1:00 D
Rule CA 1950 1961 - Sep lastSun 2:00 0 S
Rule CA 1962 1966 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02
+Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u
-8:00 US P%sT 1946
-8:00 CA P%sT 1967
-8:00 US P%sT
@@ -845,7 +845,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
# Go with the Arizona State Library instead.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 11:31:42
+Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 1944 Jan 1 0:01
-7:00 - MST 1944 Apr 1 0:01
-7:00 US M%sT 1944 Oct 1 0:01
@@ -873,7 +873,7 @@ Link America/Phoenix America/Creston
# switched four weeks late in 1974.
#
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Boise -7:44:49 - LMT 1883 Nov 18 12:15:11
+Zone America/Boise -7:44:49 - LMT 1883 Nov 18 20:00u
-8:00 US P%sT 1923 May 13 2:00
-7:00 US M%sT 1974
-7:00 - MST 1974 Feb 3 2:00
@@ -945,7 +945,7 @@ Rule Indianapolis 1941 only - Jun 22 2:00 1:00 D
Rule Indianapolis 1941 1954 - Sep lastSun 2:00 0 S
Rule Indianapolis 1946 1954 - Apr lastSun 2:00 1:00 D
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
+Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1920
-6:00 Indianapolis C%sT 1942
-6:00 US C%sT 1946
@@ -965,7 +965,7 @@ Rule Marengo 1951 only - Sep lastSun 2:00 0 S
Rule Marengo 1954 1960 - Apr lastSun 2:00 1:00 D
Rule Marengo 1954 1960 - Sep lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 12:14:37
+Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1951
-6:00 Marengo C%sT 1961 Apr 30 2:00
-5:00 - EST 1969
@@ -989,7 +989,7 @@ Rule Vincennes 1960 only - Oct lastSun 2:00 0 S
Rule Vincennes 1961 only - Sep lastSun 2:00 0 S
Rule Vincennes 1962 1963 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 12:09:53
+Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 Vincennes C%sT 1964 Apr 26 2:00
-5:00 - EST 1969
@@ -1009,7 +1009,7 @@ Rule Perry 1955 1960 - Sep lastSun 2:00 0 S
Rule Perry 1956 1963 - Apr lastSun 2:00 1:00 D
Rule Perry 1961 1963 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 12:12:57
+Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 Perry C%sT 1964 Apr 26 2:00
-5:00 - EST 1967 Oct 29 2:00
@@ -1026,7 +1026,7 @@ Rule Pike 1955 1960 - Sep lastSun 2:00 0 S
Rule Pike 1956 1964 - Apr lastSun 2:00 1:00 D
Rule Pike 1961 1964 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 12:10:53
+Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1955
-6:00 Pike C%sT 1965 Apr 25 2:00
-5:00 - EST 1966 Oct 30 2:00
@@ -1048,7 +1048,7 @@ Rule Starke 1955 1956 - Oct lastSun 2:00 0 S
Rule Starke 1957 1958 - Sep lastSun 2:00 0 S
Rule Starke 1959 1961 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 12:13:30
+Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1947
-6:00 Starke C%sT 1962 Apr 29 2:00
-5:00 - EST 1963 Oct 27 2:00
@@ -1064,7 +1064,7 @@ Rule Pulaski 1946 1954 - Sep lastSun 2:00 0 S
Rule Pulaski 1955 1956 - Oct lastSun 2:00 0 S
Rule Pulaski 1957 1960 - Sep lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
+Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 Pulaski C%sT 1961 Apr 30 2:00
-5:00 - EST 1969
@@ -1075,7 +1075,7 @@ Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
#
# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 12:19:44
+Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1954 Apr 25 2:00
-5:00 - EST 1969
-5:00 US E%sT 1973
@@ -1111,7 +1111,7 @@ Rule Louisville 1950 1961 - Apr lastSun 2:00 1:00 D
Rule Louisville 1950 1955 - Sep lastSun 2:00 0 S
Rule Louisville 1956 1961 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
+Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1921
-6:00 Louisville C%sT 1942
-6:00 US C%sT 1946
@@ -1145,7 +1145,7 @@ Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
# Federal Register 65, 160 (2000-08-17), pp 50154-50158.
# https://www.gpo.gov/fdsys/pkg/FR-2000-08-17/html/00-20854.htm
#
-Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36
+Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 - CST 1968
-6:00 US C%sT 2000 Oct 29 2:00
@@ -2640,6 +2640,8 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20
# longitude they are located at.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
+Rule Mexico 1931 only - May 1 23:00 1:00 D
+Rule Mexico 1931 only - Oct 1 0:00 0 S
Rule Mexico 1939 only - Feb 5 0:00 1:00 D
Rule Mexico 1939 only - Jun 25 0:00 0 S
Rule Mexico 1940 only - Dec 9 0:00 1:00 D
@@ -2656,13 +2658,13 @@ Rule Mexico 2002 max - Apr Sun>=1 2:00 1:00 D
Rule Mexico 2002 max - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Quintana Roo; represented by Cancún
-Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56
+Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1981 Dec 23
-5:00 Mexico E%sT 1998 Aug 2 2:00
-6:00 Mexico C%sT 2015 Feb 1 2:00
-5:00 - EST
# Campeche, Yucatán; represented by Mérida
-Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
+Zone America/Merida -5:58:28 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1981 Dec 23
-5:00 - EST 1982 Dec 2
-6:00 Mexico C%sT
@@ -2676,23 +2678,21 @@ Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
# See: Inicia mañana Horario de Verano en zona fronteriza, El Universal,
# 2016-03-12
# http://www.eluniversal.com.mx/articulo/estados/2016/03/12/inicia-manana-horario-de-verano-en-zona-fronteriza
-Zone America/Matamoros -6:40:00 - LMT 1921 Dec 31 23:20:00
+Zone America/Matamoros -6:30:00 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1988
-6:00 US C%sT 1989
-6:00 Mexico C%sT 2010
-6:00 US C%sT
# Durango; Coahuila, Nuevo León, Tamaulipas (away from US border)
-Zone America/Monterrey -6:41:16 - LMT 1921 Dec 31 23:18:44
+Zone America/Monterrey -6:41:16 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1988
-6:00 US C%sT 1989
-6:00 Mexico C%sT
# Central Mexico
-Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
+Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 Mexico C%sT 2001 Sep 30 2:00
-6:00 - CST 2002 Feb 20
-6:00 Mexico C%sT
@@ -2700,35 +2700,29 @@ Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
# This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe,
# Práxedis G Guerrero, Coyame del Sotol, Ojinaga, and Manuel Benavides.
# (See the 2016-03-12 El Universal source mentioned above.)
-Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 0:02:20
+Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1996
-6:00 Mexico C%sT 1998
-6:00 - CST 1998 Apr Sun>=1 3:00
-7:00 Mexico M%sT 2010
-7:00 US M%sT
# Chihuahua (away from US border)
-Zone America/Chihuahua -7:04:20 - LMT 1921 Dec 31 23:55:40
+Zone America/Chihuahua -7:04:20 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1996
-6:00 Mexico C%sT 1998
-6:00 - CST 1998 Apr Sun>=1 3:00
-7:00 Mexico M%sT
# Sonora
-Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
+Zone America/Hermosillo -7:23:52 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1942 Apr 24
-7:00 - MST 1949 Jan 14
-8:00 - PST 1970
@@ -2763,24 +2757,20 @@ Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
# Use "Bahia_Banderas" to keep the name to fourteen characters.
# Mazatlán
-Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20
+Zone America/Mazatlan -7:05:40 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1942 Apr 24
-7:00 - MST 1949 Jan 14
-8:00 - PST 1970
-7:00 Mexico M%sT
# Bahía de Banderas
-Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
+Zone America/Bahia_Banderas -7:01:00 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1942 Apr 24
-7:00 - MST 1949 Jan 14
-8:00 - PST 1970
@@ -2788,7 +2778,7 @@ Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
-6:00 Mexico C%sT
# Baja California
-Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56
+Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1924
-8:00 - PST 1927 Jun 10 23:00
-7:00 - MST 1930 Nov 15
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
index 7147016..0cad939 100644
--- a/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/VERSION
@@ -1 +1 @@
-tzdata2022d
+tzdata2022e
diff --git a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
index b382395..2f2786f 100644
--- a/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
+++ b/jdk/test/java/util/TimeZone/TimeZoneData/displaynames.txt
@@ -97,9 +97,7 @@ America/Winnipeg CST CDT
America/Yakutat AKST AKDT
America/Yellowknife MST MDT
Antarctica/Macquarie AEST AEDT
-Asia/Amman EET EEST
Asia/Beirut EET EEST
-Asia/Damascus EET EEST
Asia/Famagusta EET EEST
Asia/Gaza EET EEST
Asia/Hebron EET EEST
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/VERSION b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
index 889d0e6..b8cb36e 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2022d
+tzdata2022e
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/asia b/jdk/test/sun/util/calendar/zi/tzdata/asia
index 1dc7d34..f1771e4 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia
@@ -2254,6 +2254,17 @@ Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
# From the Arabic version, it seems to say it would be at midnight
# (assume 24:00) on the last Thursday in February, starting from 2022.
+# From Issam Al-Zuwairi (2022-10-05):
+# The Council of Ministers in Jordan decided Wednesday 5th October 2022,
+# that daylight saving time (DST) will be throughout the year....
+#
+# From Brian Inglis (2022-10-06):
+# https://petra.gov.jo/Include/InnerPage.jsp?ID=45567&lang=en&name=en_news
+#
+# From Paul Eggert (2022-10-05):
+# Like Syria, model this as a transition from EEST +03 (DST) to plain +03
+# (non-DST) at the point where DST would otherwise have ended.
+
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Jordan 1973 only - Jun 6 0:00 1:00 S
Rule Jordan 1973 1975 - Oct 1 0:00 0 -
@@ -2285,11 +2296,12 @@ Rule Jordan 2005 only - Sep lastFri 0:00s 0 -
Rule Jordan 2006 2011 - Oct lastFri 0:00s 0 -
Rule Jordan 2013 only - Dec 20 0:00 0 -
Rule Jordan 2014 2021 - Mar lastThu 24:00 1:00 S
-Rule Jordan 2014 max - Oct lastFri 0:00s 0 -
-Rule Jordan 2022 max - Feb lastThu 24:00 1:00 S
+Rule Jordan 2014 2022 - Oct lastFri 0:00s 0 -
+Rule Jordan 2022 only - Feb lastThu 24:00 1:00 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Amman 2:23:44 - LMT 1931
- 2:00 Jordan EE%sT
+ 2:00 Jordan EE%sT 2022 Oct 28 0:00s
+ 3:00 - +03
# Kazakhstan
@@ -3838,19 +3850,27 @@ Rule Syria 2007 only - Nov Fri>=1 0:00 0 -
# Our brief summary:
# https://www.timeanddate.com/news/time/syria-dst-2012.html
-# From Arthur David Olson (2012-03-27):
-# Assume last Friday in March going forward XXX.
+# From Steffen Thorsen (2022-10-05):
+# Syria is adopting year-round DST, starting this autumn....
+# From https://www.enabbaladi.net/archives/607812
+# "This [the decision] came after the weekly government meeting today,
+# Tuesday 4 October ..."
+#
+# From Paul Eggert (2022-10-05):
+# Like Jordan, model this as a transition from EEST +03 (DST) to plain +03
+# (non-DST) at the point where DST would otherwise have ended.
Rule Syria 2008 only - Apr Fri>=1 0:00 1:00 S
Rule Syria 2008 only - Nov 1 0:00 0 -
Rule Syria 2009 only - Mar lastFri 0:00 1:00 S
Rule Syria 2010 2011 - Apr Fri>=1 0:00 1:00 S
-Rule Syria 2012 max - Mar lastFri 0:00 1:00 S
-Rule Syria 2009 max - Oct lastFri 0:00 0 -
+Rule Syria 2012 2022 - Mar lastFri 0:00 1:00 S
+Rule Syria 2009 2022 - Oct lastFri 0:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq
- 2:00 Syria EE%sT
+ 2:00 Syria EE%sT 2022 Oct 28 0:00
+ 3:00 - +03
# Tajikistan
# From Shanks & Pottenger.
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/europe b/jdk/test/sun/util/calendar/zi/tzdata/europe
index 9e0a538..930cede 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe
@@ -3417,7 +3417,7 @@ Zone Europe/Madrid -0:14:44 - LMT 1901 Jan 1 0:00u
0:00 Spain WE%sT 1940 Mar 16 23:00
1:00 Spain CE%sT 1979
1:00 EU CE%sT
-Zone Africa/Ceuta -0:21:16 - LMT 1900 Dec 31 23:38:44
+Zone Africa/Ceuta -0:21:16 - LMT 1901 Jan 1 0:00u
0:00 - WET 1918 May 6 23:00
0:00 1:00 WEST 1918 Oct 7 23:00
0:00 - WET 1924
diff --git a/jdk/test/sun/util/calendar/zi/tzdata/northamerica b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
index 114cef1..ce4ee74 100644
--- a/jdk/test/sun/util/calendar/zi/tzdata/northamerica
+++ b/jdk/test/sun/util/calendar/zi/tzdata/northamerica
@@ -462,7 +462,7 @@ Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D
Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S
Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
+Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1920
-6:00 Chicago C%sT 1936 Mar 1 2:00
-5:00 - EST 1936 Nov 15 2:00
@@ -471,7 +471,7 @@ Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
-6:00 Chicago C%sT 1967
-6:00 US C%sT
# Oliver County, ND switched from mountain to central time on 1992-10-25.
-Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
+Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 1992 Oct 25 2:00
-6:00 US C%sT
# Morton County, ND, switched from mountain to central time on
@@ -481,7 +481,7 @@ Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48
# Jones, Mellette, and Todd Counties in South Dakota;
# but in practice these other counties were already observing central time.
# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
-Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
+Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 2003 Oct 26 2:00
-6:00 US C%sT
@@ -498,7 +498,7 @@ Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
# largest city in Mercer County). Google Maps places Beulah's city hall
# at 47° 15' 51" N, 101° 46' 40" W, which yields an offset of 6h47'07".
-Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
+Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 2010 Nov 7 2:00
-6:00 US C%sT
@@ -530,7 +530,7 @@ Rule Denver 1921 only - May 22 2:00 0 S
Rule Denver 1965 1966 - Apr lastSun 2:00 1:00 D
Rule Denver 1965 1966 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04
+Zone America/Denver -6:59:56 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 1920
-7:00 Denver M%sT 1942
-7:00 US M%sT 1946
@@ -583,7 +583,7 @@ Rule CA 1950 1966 - Apr lastSun 1:00 1:00 D
Rule CA 1950 1961 - Sep lastSun 2:00 0 S
Rule CA 1962 1966 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02
+Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u
-8:00 US P%sT 1946
-8:00 CA P%sT 1967
-8:00 US P%sT
@@ -845,7 +845,7 @@ Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
# Go with the Arizona State Library instead.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 11:31:42
+Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 19:00u
-7:00 US M%sT 1944 Jan 1 0:01
-7:00 - MST 1944 Apr 1 0:01
-7:00 US M%sT 1944 Oct 1 0:01
@@ -873,7 +873,7 @@ Link America/Phoenix America/Creston
# switched four weeks late in 1974.
#
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Boise -7:44:49 - LMT 1883 Nov 18 12:15:11
+Zone America/Boise -7:44:49 - LMT 1883 Nov 18 20:00u
-8:00 US P%sT 1923 May 13 2:00
-7:00 US M%sT 1974
-7:00 - MST 1974 Feb 3 2:00
@@ -945,7 +945,7 @@ Rule Indianapolis 1941 only - Jun 22 2:00 1:00 D
Rule Indianapolis 1941 1954 - Sep lastSun 2:00 0 S
Rule Indianapolis 1946 1954 - Apr lastSun 2:00 1:00 D
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
+Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1920
-6:00 Indianapolis C%sT 1942
-6:00 US C%sT 1946
@@ -965,7 +965,7 @@ Rule Marengo 1951 only - Sep lastSun 2:00 0 S
Rule Marengo 1954 1960 - Apr lastSun 2:00 1:00 D
Rule Marengo 1954 1960 - Sep lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 12:14:37
+Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1951
-6:00 Marengo C%sT 1961 Apr 30 2:00
-5:00 - EST 1969
@@ -989,7 +989,7 @@ Rule Vincennes 1960 only - Oct lastSun 2:00 0 S
Rule Vincennes 1961 only - Sep lastSun 2:00 0 S
Rule Vincennes 1962 1963 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 12:09:53
+Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 Vincennes C%sT 1964 Apr 26 2:00
-5:00 - EST 1969
@@ -1009,7 +1009,7 @@ Rule Perry 1955 1960 - Sep lastSun 2:00 0 S
Rule Perry 1956 1963 - Apr lastSun 2:00 1:00 D
Rule Perry 1961 1963 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 12:12:57
+Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 Perry C%sT 1964 Apr 26 2:00
-5:00 - EST 1967 Oct 29 2:00
@@ -1026,7 +1026,7 @@ Rule Pike 1955 1960 - Sep lastSun 2:00 0 S
Rule Pike 1956 1964 - Apr lastSun 2:00 1:00 D
Rule Pike 1961 1964 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 12:10:53
+Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1955
-6:00 Pike C%sT 1965 Apr 25 2:00
-5:00 - EST 1966 Oct 30 2:00
@@ -1048,7 +1048,7 @@ Rule Starke 1955 1956 - Oct lastSun 2:00 0 S
Rule Starke 1957 1958 - Sep lastSun 2:00 0 S
Rule Starke 1959 1961 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 12:13:30
+Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1947
-6:00 Starke C%sT 1962 Apr 29 2:00
-5:00 - EST 1963 Oct 27 2:00
@@ -1064,7 +1064,7 @@ Rule Pulaski 1946 1954 - Sep lastSun 2:00 0 S
Rule Pulaski 1955 1956 - Oct lastSun 2:00 0 S
Rule Pulaski 1957 1960 - Sep lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
+Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 Pulaski C%sT 1961 Apr 30 2:00
-5:00 - EST 1969
@@ -1075,7 +1075,7 @@ Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
#
# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 12:19:44
+Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1954 Apr 25 2:00
-5:00 - EST 1969
-5:00 US E%sT 1973
@@ -1111,7 +1111,7 @@ Rule Louisville 1950 1961 - Apr lastSun 2:00 1:00 D
Rule Louisville 1950 1955 - Sep lastSun 2:00 0 S
Rule Louisville 1956 1961 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
-Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
+Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1921
-6:00 Louisville C%sT 1942
-6:00 US C%sT 1946
@@ -1145,7 +1145,7 @@ Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
# Federal Register 65, 160 (2000-08-17), pp 50154-50158.
# https://www.gpo.gov/fdsys/pkg/FR-2000-08-17/html/00-20854.htm
#
-Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36
+Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 18:00u
-6:00 US C%sT 1946
-6:00 - CST 1968
-6:00 US C%sT 2000 Oct 29 2:00
@@ -2640,6 +2640,8 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20
# longitude they are located at.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
+Rule Mexico 1931 only - May 1 23:00 1:00 D
+Rule Mexico 1931 only - Oct 1 0:00 0 S
Rule Mexico 1939 only - Feb 5 0:00 1:00 D
Rule Mexico 1939 only - Jun 25 0:00 0 S
Rule Mexico 1940 only - Dec 9 0:00 1:00 D
@@ -2656,13 +2658,13 @@ Rule Mexico 2002 max - Apr Sun>=1 2:00 1:00 D
Rule Mexico 2002 max - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Quintana Roo; represented by Cancún
-Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56
+Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1981 Dec 23
-5:00 Mexico E%sT 1998 Aug 2 2:00
-6:00 Mexico C%sT 2015 Feb 1 2:00
-5:00 - EST
# Campeche, Yucatán; represented by Mérida
-Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
+Zone America/Merida -5:58:28 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1981 Dec 23
-5:00 - EST 1982 Dec 2
-6:00 Mexico C%sT
@@ -2676,23 +2678,21 @@ Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32
# See: Inicia mañana Horario de Verano en zona fronteriza, El Universal,
# 2016-03-12
# http://www.eluniversal.com.mx/articulo/estados/2016/03/12/inicia-manana-horario-de-verano-en-zona-fronteriza
-Zone America/Matamoros -6:40:00 - LMT 1921 Dec 31 23:20:00
+Zone America/Matamoros -6:30:00 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1988
-6:00 US C%sT 1989
-6:00 Mexico C%sT 2010
-6:00 US C%sT
# Durango; Coahuila, Nuevo León, Tamaulipas (away from US border)
-Zone America/Monterrey -6:41:16 - LMT 1921 Dec 31 23:18:44
+Zone America/Monterrey -6:41:16 - LMT 1922 Jan 1 6:00u
-6:00 - CST 1988
-6:00 US C%sT 1989
-6:00 Mexico C%sT
# Central Mexico
-Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
+Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 Mexico C%sT 2001 Sep 30 2:00
-6:00 - CST 2002 Feb 20
-6:00 Mexico C%sT
@@ -2700,35 +2700,29 @@ Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24
# This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe,
# Práxedis G Guerrero, Coyame del Sotol, Ojinaga, and Manuel Benavides.
# (See the 2016-03-12 El Universal source mentioned above.)
-Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 0:02:20
+Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1996
-6:00 Mexico C%sT 1998
-6:00 - CST 1998 Apr Sun>=1 3:00
-7:00 Mexico M%sT 2010
-7:00 US M%sT
# Chihuahua (away from US border)
-Zone America/Chihuahua -7:04:20 - LMT 1921 Dec 31 23:55:40
+Zone America/Chihuahua -7:04:20 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1996
-6:00 Mexico C%sT 1998
-6:00 - CST 1998 Apr Sun>=1 3:00
-7:00 Mexico M%sT
# Sonora
-Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
+Zone America/Hermosillo -7:23:52 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1942 Apr 24
-7:00 - MST 1949 Jan 14
-8:00 - PST 1970
@@ -2763,24 +2757,20 @@ Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08
# Use "Bahia_Banderas" to keep the name to fourteen characters.
# Mazatlán
-Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20
+Zone America/Mazatlan -7:05:40 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1942 Apr 24
-7:00 - MST 1949 Jan 14
-8:00 - PST 1970
-7:00 Mexico M%sT
# Bahía de Banderas
-Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
+Zone America/Bahia_Banderas -7:01:00 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1927 Jun 10 23:00
-6:00 - CST 1930 Nov 15
- -7:00 - MST 1931 May 1 23:00
- -6:00 - CST 1931 Oct
- -7:00 - MST 1932 Apr 1
+ -7:00 Mexico M%sT 1932 Apr 1
-6:00 - CST 1942 Apr 24
-7:00 - MST 1949 Jan 14
-8:00 - PST 1970
@@ -2788,7 +2778,7 @@ Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00
-6:00 Mexico C%sT
# Baja California
-Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56
+Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 7:00u
-7:00 - MST 1924
-8:00 - PST 1927 Jun 10 23:00
-7:00 - MST 1930 Nov 15
--
1.8.3.1

View File

@ -1,42 +0,0 @@
From 6d1c5b1ee82b2b2481a16f3510078fdc7ddc08f9 Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Tue, 15 Nov 2022 11:26:33 +0800
Subject: [PATCH 04/33] 8296480: Fix the problem that the TestPolicy.java case
fails because the certificate expires.
---
jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java b/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java
index a92eee2..b37debf 100644
--- a/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java
+++ b/jdk/test/java/security/cert/pkix/policyChanges/TestPolicy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -34,6 +34,7 @@
*/
import java.io.*;
+import java.text.DateFormat;
import java.util.*;
import java.security.Security;
@@ -97,6 +98,10 @@ public class TestPolicy {
params.setRevocationEnabled(false);
params.setInitialPolicies(testCase.initialPolicies);
+ // Certs expired on 7th Nov 2022
+ params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM,
+ Locale.US).parse("June 01, 2022"));
+
CertPath path = factory.generateCertPath(Arrays.asList(new X509Certificate[] {ee, ca}));
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(path, params);
--
1.8.3.1

View File

@ -1,39 +0,0 @@
From b8aedd236ca707cfc15eb5daf91aab697a8014ed Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Wed, 23 Nov 2022 08:31:14 +0800
Subject: [PATCH 06/33] I68TO2: 8296485: BuildEEBasicConstraints.java test fails with
SunCertPathBuilderException
---
.../CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java b/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
index 6be5562..44926d2 100644
--- a/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
+++ b/jdk/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java
@@ -46,9 +46,11 @@ import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
+import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
public final class BuildEEBasicConstraints {
@@ -65,6 +67,11 @@ public final class BuildEEBasicConstraints {
PKIXBuilderParameters params = new PKIXBuilderParameters
(Collections.singleton(anchor), sel);
params.setRevocationEnabled(false);
+
+ // Certs expired on 7th Nov 2022
+ params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM,
+ Locale.US).parse("June 01, 2022"));
+
X509Certificate eeCert = CertUtils.getCertFromFile("ee.cer");
X509Certificate caCert = CertUtils.getCertFromFile("ca.cer");
ArrayList<X509Certificate> certs = new ArrayList<X509Certificate>();
--
1.8.3.1

View File

@ -0,0 +1,255 @@
From 5a21d735ffa345f956d2c637b4e13f55c907a219 Mon Sep 17 00:00:00 2001
From: wangjiawei <wangjiawei80@huawei.com>
Date: Fri, 28 Apr 2023 10:41:14 +0800
Subject: [PATCH 15/15] 8305541: C2 Div/Mod nodes without zero check could be
split through iv phi of loop resulting in SIGFPE
DTS/AR: DTS2023041008055
Summary: <hotspot> : 8305541: C2 Div/Mod nodes without zero check could be split through iv phi of loop resulting in SIGFPE
LLT: NA
Patch Type: backport
Bug url: https://bugs.openjdk.org/browse/JDK-8305541
---
hotspot/src/share/vm/opto/loopnode.hpp | 4 +-
hotspot/src/share/vm/opto/loopopts.cpp | 40 +++++
.../c2/TestSplitDivisionThroughPhi.java | 155 ++++++++++++++++++
3 files changed, 198 insertions(+), 1 deletion(-)
create mode 100644 hotspot/test/compiler/c2/TestSplitDivisionThroughPhi.java
diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp
index 6f70b5065..f8750e54a 100644
--- a/hotspot/src/share/vm/opto/loopnode.hpp
+++ b/hotspot/src/share/vm/opto/loopnode.hpp
@@ -1071,7 +1071,9 @@ private:
Node *place_near_use( Node *useblock ) const;
Node* try_move_store_before_loop(Node* n, Node *n_ctrl);
void try_move_store_after_loop(Node* n);
-
+ bool cannot_split_division(const Node* n, const Node* region) const;
+ static bool is_divisor_counted_loop_phi(const Node* divisor, const Node* loop);
+ bool loop_phi_backedge_type_contains_zero(const Node* phi_divisor, const Type* zero) const;
bool _created_loop_node;
public:
void set_created_loop_node() { _created_loop_node = true; }
diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp
index 20bdb1493..28bfcb75b 100644
--- a/hotspot/src/share/vm/opto/loopopts.cpp
+++ b/hotspot/src/share/vm/opto/loopopts.cpp
@@ -51,6 +51,10 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
return NULL;
}
+ if (cannot_split_division(n, region)) {
+ return NULL;
+ }
+
int wins = 0;
assert(!n->is_CFG(), "");
assert(region->is_Region(), "");
@@ -200,6 +204,42 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
return phi;
}
+// Return true if 'n' is a Div or Mod node (without zero check If node which was removed earlier) with a loop phi divisor
+// of a trip-counted (integer or long) loop with a backedge input that could be zero (include zero in its type range). In
+// this case, we cannot split the division to the backedge as it could freely float above the loop exit check resulting in
+// a division by zero. This situation is possible because the type of an increment node of an iv phi (trip-counter) could
+// include zero while the iv phi does not (see PhiNode::Value() for trip-counted loops where we improve types of iv phis).
+// We also need to check other loop phis as they could have been created in the same split-if pass when applying
+// PhaseIdealLoop::split_thru_phi() to split nodes through an iv phi.
+bool PhaseIdealLoop::cannot_split_division(const Node* n, const Node* region) const {
+ const Type* zero;
+ switch (n->Opcode()) {
+ case Op_DivI:
+ case Op_ModI:
+ zero = TypeInt::ZERO;
+ break;
+ case Op_DivL:
+ case Op_ModL:
+ zero = TypeLong::ZERO;
+ break;
+ default:
+ 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);
+}
+
+bool PhaseIdealLoop::is_divisor_counted_loop_phi(const Node* divisor, const Node* loop) {
+ return loop->is_CountedLoop() && divisor->is_Phi() && divisor->in(0) == loop;
+}
+
+bool PhaseIdealLoop::loop_phi_backedge_type_contains_zero(const Node* phi_divisor, const Type* zero) const {
+ return _igvn.type(phi_divisor->in(LoopNode::LoopBackControl))->filter_speculative(zero) != Type::TOP;
+}
+
//------------------------------dominated_by------------------------------------
// Replace the dominated test with an obvious true or false. Place it on the
// IGVN worklist for later cleanup. Move control-dependent data Nodes on the
diff --git a/hotspot/test/compiler/c2/TestSplitDivisionThroughPhi.java b/hotspot/test/compiler/c2/TestSplitDivisionThroughPhi.java
new file mode 100644
index 000000000..0a59783fa
--- /dev/null
+++ b/hotspot/test/compiler/c2/TestSplitDivisionThroughPhi.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2023, 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 8299259
+ * @summary Test various cases of divisions/modulo which should not be split through iv phis.
+ * @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:LoopUnrollLimit=0 -XX:+StressGCM
+ * -XX:CompileCommand=compileonly,TestSplitDivisionThroughPhi::* TestSplitDivisionThroughPhi
+ */
+
+/**
+ * @test
+ * @bug 8299259
+ * @summary Test various cases of divisions/modulo which should not be split through iv phis.
+ * @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:LoopUnrollLimit=0 -XX:+StressGCM
+ * -XX:CompileCommand=compileonly,TestSplitDivisionThroughPhi::* TestSplitDivisionThroughPhi
+ */
+
+
+public class TestSplitDivisionThroughPhi {
+ static int iFld;
+ static long lFld;
+ static boolean flag;
+
+
+ public static void main(String[] strArr) {
+ for (int i = 0; i < 5000; i++) {
+ testPushDivIThruPhi();
+ testPushDivIThruPhiInChain();
+ testPushModIThruPhi();
+ testPushModIThruPhiInChain();
+ testPushDivLThruPhi();
+ testPushDivLThruPhiInChain();
+ testPushModLThruPhi();
+ testPushModLThruPhiInChain();
+ }
+ }
+
+ // Already fixed by JDK-8248552.
+ static void testPushDivIThruPhi() {
+ for (int i = 10; i > 1; i -= 2) {
+ // The Div node is only split in later loop opts phase because the zero divisor check is only removed
+ // in IGVN after the first loop opts phase.
+ //
+ // iv phi i type: [2..10]
+ // When splitting the DivI through the iv phi, it ends up on the back edge with the trip count decrement
+ // as input which has type [0..8]. We end up executing a division by zero on the last iteration because
+ // the DivI it is not pinned to the loop exit test and can freely float above the loop exit check.
+ iFld = 10 / i;
+ }
+ }
+
+ // Same as above but with an additional Mul node between the iv phi and the Div node. Both nodes are split through
+ // the iv phi in one pass of Split If.
+ static void testPushDivIThruPhiInChain() {
+ for (int i = 10; i > 1; i -= 2) {
+ // Empty one iteration loop which is only removed after split if in first loop opts phase. This prevents
+ // that the Mul node is already split through the iv phi while the Div node cannot be split yet due to
+ // the zero divisor check which can only be removed in the IGVN after the first loop opts pass.
+ for (int j = 0; j < 1; j++) {
+ }
+ iFld = 10 / (i * 100);
+ }
+ }
+
+ // Already fixed by JDK-8248552.
+ static void testPushModIThruPhi() {
+ for (int i = 10; i > 1; i -= 2) {
+ iFld = 10 / i;
+ }
+ }
+
+ // Same as above but with ModI.
+ static void testPushModIThruPhiInChain() {
+ for (int i = 10; i > 1; i -= 2) {
+ for (int j = 0; j < 1; j++) {
+ }
+ iFld = 10 / (i * 100);
+ }
+ }
+
+ // Long cases only trigger since JDK-8256655.
+
+ // Same as above but with DivL.
+ static void testPushDivLThruPhi() {
+ for (long i = 10; i > 1; i -= 2) {
+ lFld = 10L / i;
+
+ // Loop that is not removed such that we do not transform the outer LongCountedLoop (only done if innermost)
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+
+ // Same as above but with DivL.
+ static void testPushDivLThruPhiInChain() {
+ for (long i = 10; i > 1; i -= 2) {
+ for (int j = 0; j < 1; j++) {
+ }
+ lFld = 10L / (i * 100L);
+
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+
+ // Same as above but with ModL
+ static void testPushModLThruPhi() {
+ for (long i = 10; i > 1; i -= 2) {
+ lFld = 10L % i;
+
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+
+ // Same as above but with ModL
+ static void testPushModLThruPhiInChain() {
+ for (long i = 10; i > 1; i -= 2) {
+ for (int j = 0; j < 1; j++) {
+ }
+ lFld = 10L % (i * 100L);
+
+ for (int j = 0; j < 10; j++) {
+ flag = !flag;
+ }
+ }
+ }
+}
+
--
2.19.0

View File

@ -0,0 +1,708 @@
From 6926e9b83bc3f9b785d5298786a5c41e247b2a3f Mon Sep 17 00:00:00 2001
Date: Mon, 16 Oct 2023 10:56:30 +0800
Subject: [PATCH 1/5] 8308682: Enhance AES performance
Bug url: https://bugs.openjdk.org/browse/JDK-8308682
---
.../src/cpu/aarch64/vm/assembler_aarch64.hpp | 2 +
.../cpu/aarch64/vm/stubGenerator_aarch64.cpp | 451 +++++++++---------
.../compiler/codegen/aes/CTR_Wraparound.java | 169 +++++++
3 files changed, 406 insertions(+), 216 deletions(-)
create mode 100644 hotspot/test/compiler/codegen/aes/CTR_Wraparound.java
diff --git a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp
index 9202e61f8..b12095aca 100644
--- a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp
+++ b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp
@@ -2140,6 +2140,8 @@ public:
INSN(sshl, 0, 0b010001);
INSN(ushl, 1, 0b010001);
+ INSN(cmhi, 1, 0b001101); // accepted arrangements: T8B, T16B, T4H, T8H, T2S, T4S, T2D
+
#undef INSN
#define INSN(NAME, opc, opc2) \
diff --git a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
index 565fe559c..f61028d50 100644
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp
@@ -2804,265 +2804,284 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
+ // Big-endian 128-bit + 64-bit -> 128-bit addition.
+ // Inputs: 128-bits. in is preserved.
+ // The least-significant 64-bit word is in the upper dword of the vector
+ // inc (the 64-bit increment) is preserved. Its lower dword must be zero
+ // Output: result
+ void be_add_128_64(FloatRegister result, FloatRegister in,
+ FloatRegister inc, FloatRegister tmp) {
+ assert_different_registers(result, tmp, inc);
+
+ __ addv(result, __ T2D, in, inc); // Add inc to the least-significant dword of input
+ __ cmhi(tmp, __ T2D, inc, result); // Check for result overflowing
+ __ ins(tmp, __ D, tmp, 0, 1); // Move LSD of comparison result to MSD
+ __ ins(tmp, __ D, inc, 1, 0); // Move 0 to LSD of comparison result
+ __ subv(result, __ T2D, result, tmp); // Subtract -1 from MSD if there was an overflow
+ }
+
// CTR AES crypt.
- // Arguments:
- //
- // Inputs:
- // c_rarg0 - source byte array address
- // c_rarg1 - destination byte array address
- // c_rarg2 - K (key) in little endian int array
- // c_rarg3 - counter vector byte array address
- // c_rarg4 - input length
- // c_rarg5 - saved encryptedCounter start
- // c_rarg6 - saved used length
+ // Arguments:
+ //
+ // Inputs:
+ // c_rarg0 - source byte array address
+ // c_rarg1 - destination byte array address
+ // c_rarg2 - K (key) in little endian int array
+ // c_rarg3 - counter vector byte array address
+ // c_rarg4 - input length
+ // c_rarg5 - saved encryptedCounter start
+ // c_rarg6 - saved used length
+ //
+ // Output:
+ // r0 - input length
+ //
+ address generate_counterMode_AESCrypt() {
+ const Register in = c_rarg0;
+ const Register out = c_rarg1;
+ const Register key = c_rarg2;
+ const Register counter = c_rarg3;
+ const Register saved_len = c_rarg4, len = r10;
+ const Register saved_encrypted_ctr = c_rarg5;
+ const Register used_ptr = c_rarg6, used = r12;
+
+ const Register offset = r7;
+ const Register keylen = r11;
+
+ const unsigned char block_size = 16;
+ const int bulk_width = 4;
+ // NB: bulk_width can be 4 or 8. 8 gives slightly faster
+ // performance with larger data sizes, but it also means that the
+ // fast path isn't used until you have at least 8 blocks, and up
+ // to 127 bytes of data will be executed on the slow path. For
+ // that reason, and also so as not to blow away too much icache, 4
+ // blocks seems like a sensible compromise.
+
+ // Algorithm:
//
- // Output:
- // r0 - input length
+ // if (len == 0) {
+ // goto DONE;
+ // }
+ // int result = len;
+ // do {
+ // if (used >= blockSize) {
+ // if (len >= bulk_width * blockSize) {
+ // CTR_large_block();
+ // if (len == 0)
+ // goto DONE;
+ // }
+ // for (;;) {
+ // 16ByteVector v0 = counter;
+ // embeddedCipher.encryptBlock(v0, 0, encryptedCounter, 0);
+ // used = 0;
+ // if (len < blockSize)
+ // break; /* goto NEXT */
+ // 16ByteVector v1 = load16Bytes(in, offset);
+ // v1 = v1 ^ encryptedCounter;
+ // store16Bytes(out, offset);
+ // used = blockSize;
+ // offset += blockSize;
+ // len -= blockSize;
+ // if (len == 0)
+ // goto DONE;
+ // }
+ // }
+ // NEXT:
+ // out[outOff++] = (byte)(in[inOff++] ^ encryptedCounter[used++]);
+ // len--;
+ // } while (len != 0);
+ // DONE:
+ // return result;
//
- address generate_counterMode_AESCrypt() {
- const Register in = c_rarg0;
- const Register out = c_rarg1;
- const Register key = c_rarg2;
- const Register counter = c_rarg3;
- const Register saved_len = c_rarg4, len = r10;
- const Register saved_encrypted_ctr = c_rarg5;
- const Register used_ptr = c_rarg6, used = r12;
-
- const Register offset = r7;
- const Register keylen = r11;
-
- const unsigned char block_size = 16;
- const int bulk_width = 4;
- // NB: bulk_width can be 4 or 8. 8 gives slightly faster
- // performance with larger data sizes, but it also means that the
- // fast path isn't used until you have at least 8 blocks, and up
- // to 127 bytes of data will be executed on the slow path. For
- // that reason, and also so as not to blow away too much icache, 4
- // blocks seems like a sensible compromise.
-
- // Algorithm:
- //
- // if (len == 0) {
- // goto DONE;
- // }
- // int result = len;
- // do {
- // if (used >= blockSize) {
- // if (len >= bulk_width * blockSize) {
- // CTR_large_block();
- // if (len == 0)
- // goto DONE;
- // }
- // for (;;) {
- // 16ByteVector v0 = counter;
- // embeddedCipher.encryptBlock(v0, 0, encryptedCounter, 0);
- // used = 0;
- // if (len < blockSize)
- // break; /* goto NEXT */
- // 16ByteVector v1 = load16Bytes(in, offset);
- // v1 = v1 ^ encryptedCounter;
- // store16Bytes(out, offset);
- // used = blockSize;
- // offset += blockSize;
- // len -= blockSize;
- // if (len == 0)
- // goto DONE;
- // }
- // }
- // NEXT:
- // out[outOff++] = (byte)(in[inOff++] ^ encryptedCounter[used++]);
- // len--;
- // } while (len != 0);
- // DONE:
- // return result;
- //
- // CTR_large_block()
- // Wide bulk encryption of whole blocks.
+ // CTR_large_block()
+ // Wide bulk encryption of whole blocks.
- __ align(CodeEntryAlignment);
- StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt");
- const address start = __ pc();
- __ enter();
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt");
+ const address start = __ pc();
+ __ enter();
- Label DONE, CTR_large_block, large_block_return;
- __ ldrw(used, Address(used_ptr));
- __ cbzw(saved_len, DONE);
+ Label DONE, CTR_large_block, large_block_return;
+ __ ldrw(used, Address(used_ptr));
+ __ cbzw(saved_len, DONE);
- __ mov(len, saved_len);
- __ mov(offset, 0);
+ __ mov(len, saved_len);
+ __ mov(offset, 0);
- // Compute #rounds for AES based on the length of the key array
- __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+ // Compute #rounds for AES based on the length of the key array
+ __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
- __ aesenc_loadkeys(key, keylen);
+ __ aesenc_loadkeys(key, keylen);
- {
- Label L_CTR_loop, NEXT;
+ {
+ Label L_CTR_loop, NEXT;
- __ bind(L_CTR_loop);
+ __ bind(L_CTR_loop);
- __ cmp(used, block_size);
- __ br(__ LO, NEXT);
+ __ cmp(used, block_size);
+ __ br(__ LO, NEXT);
- // Maybe we have a lot of data
- __ subsw(rscratch1, len, bulk_width * block_size);
- __ br(__ HS, CTR_large_block);
- __ BIND(large_block_return);
- __ cbzw(len, DONE);
+ // Maybe we have a lot of data
+ __ subsw(rscratch1, len, bulk_width * block_size);
+ __ br(__ HS, CTR_large_block);
+ __ BIND(large_block_return);
+ __ cbzw(len, DONE);
- // Setup the counter
- __ movi(v4, __ T4S, 0);
- __ movi(v5, __ T4S, 1);
- __ ins(v4, __ S, v5, 3, 3); // v4 contains { 0, 0, 0, 1 }
+ // Setup the counter
+ __ movi(v4, __ T4S, 0);
+ __ movi(v5, __ T4S, 1);
+ __ ins(v4, __ S, v5, 2, 2); // v4 contains { 0, 1 }
- __ ld1(v0, __ T16B, counter); // Load the counter into v0
- __ rev32(v16, __ T16B, v0);
- __ addv(v16, __ T4S, v16, v4);
- __ rev32(v16, __ T16B, v16);
- __ st1(v16, __ T16B, counter); // Save the incremented counter back
+ // 128-bit big-endian increment
+ __ ld1(v0, __ T16B, counter);
+ __ rev64(v16, __ T16B, v0);
+ be_add_128_64(v16, v16, v4, /*tmp*/v5);
+ __ rev64(v16, __ T16B, v16);
+ __ st1(v16, __ T16B, counter);
+ // Previous counter value is in v0
+ // v4 contains { 0, 1 }
- {
- // We have fewer than bulk_width blocks of data left. Encrypt
- // them one by one until there is less than a full block
- // remaining, being careful to save both the encrypted counter
- // and the counter.
-
- Label inner_loop;
- __ bind(inner_loop);
- // Counter to encrypt is in v0
- __ aesecb_encrypt(noreg, noreg, keylen);
- __ st1(v0, __ T16B, saved_encrypted_ctr);
-
- // Do we have a remaining full block?
-
- __ mov(used, 0);
- __ cmp(len, block_size);
- __ br(__ LO, NEXT);
-
- // Yes, we have a full block
- __ ldrq(v1, Address(in, offset));
- __ eor(v1, __ T16B, v1, v0);
- __ strq(v1, Address(out, offset));
- __ mov(used, block_size);
- __ add(offset, offset, block_size);
-
- __ subw(len, len, block_size);
- __ cbzw(len, DONE);
-
- // Increment the counter, store it back
- __ orr(v0, __ T16B, v16, v16);
- __ rev32(v16, __ T16B, v16);
- __ addv(v16, __ T4S, v16, v4);
- __ rev32(v16, __ T16B, v16);
- __ st1(v16, __ T16B, counter); // Save the incremented counter back
-
- __ b(inner_loop);
- }
+ {
+ // We have fewer than bulk_width blocks of data left. Encrypt
+ // them one by one until there is less than a full block
+ // remaining, being careful to save both the encrypted counter
+ // and the counter.
- __ BIND(NEXT);
-
- // Encrypt a single byte, and loop.
- // We expect this to be a rare event.
- __ ldrb(rscratch1, Address(in, offset));
- __ ldrb(rscratch2, Address(saved_encrypted_ctr, used));
- __ eor(rscratch1, rscratch1, rscratch2);
- __ strb(rscratch1, Address(out, offset));
- __ add(offset, offset, 1);
- __ add(used, used, 1);
- __ subw(len, len,1);
- __ cbnzw(len, L_CTR_loop);
- }
+ Label inner_loop;
+ __ bind(inner_loop);
+ // Counter to encrypt is in v0
+ __ aesecb_encrypt(noreg, noreg, keylen);
+ __ st1(v0, __ T16B, saved_encrypted_ctr);
- __ bind(DONE);
- __ strw(used, Address(used_ptr));
- __ mov(r0, saved_len);
+ // Do we have a remaining full block?
- __ leave(); // required for proper stackwalking of RuntimeStub frame
- __ ret(lr);
+ __ mov(used, 0);
+ __ cmp(len, block_size);
+ __ br(__ LO, NEXT);
- // Bulk encryption
+ // Yes, we have a full block
+ __ ldrq(v1, Address(in, offset));
+ __ eor(v1, __ T16B, v1, v0);
+ __ strq(v1, Address(out, offset));
+ __ mov(used, block_size);
+ __ add(offset, offset, block_size);
- __ BIND (CTR_large_block);
- assert(bulk_width == 4 || bulk_width == 8, "must be");
+ __ subw(len, len, block_size);
+ __ cbzw(len, DONE);
- if (bulk_width == 8) {
- __ sub(sp, sp, 4 * 16);
- __ st1(v12, v13, v14, v15, __ T16B, Address(sp));
+ // Increment the counter, store it back
+ __ orr(v0, __ T16B, v16, v16);
+ __ rev64(v16, __ T16B, v16);
+ be_add_128_64(v16, v16, v4, /*tmp*/v5);
+ __ rev64(v16, __ T16B, v16);
+ __ st1(v16, __ T16B, counter); // Save the incremented counter back
+
+ __ b(inner_loop);
}
- __ sub(sp, sp, 4 * 16);
- __ st1(v8, v9, v10, v11, __ T16B, Address(sp));
- RegSet saved_regs = (RegSet::of(in, out, offset)
- + RegSet::of(saved_encrypted_ctr, used_ptr, len));
- __ push(saved_regs, sp);
- __ andr(len, len, -16 * bulk_width); // 8/4 encryptions, 16 bytes per encryption
- __ add(in, in, offset);
- __ add(out, out, offset);
- // Keys should already be loaded into the correct registers
+ __ BIND(NEXT);
+
+ // Encrypt a single byte, and loop.
+ // We expect this to be a rare event.
+ __ ldrb(rscratch1, Address(in, offset));
+ __ ldrb(rscratch2, Address(saved_encrypted_ctr, used));
+ __ eor(rscratch1, rscratch1, rscratch2);
+ __ strb(rscratch1, Address(out, offset));
+ __ add(offset, offset, 1);
+ __ add(used, used, 1);
+ __ subw(len, len,1);
+ __ cbnzw(len, L_CTR_loop);
+ }
- __ ld1(v0, __ T16B, counter); // v0 contains the first counter
- __ rev32(v16, __ T16B, v0); // v16 contains byte-reversed counter
+ __ bind(DONE);
+ __ strw(used, Address(used_ptr));
+ __ mov(r0, saved_len);
- // AES/CTR loop
- {
- Label L_CTR_loop;
- __ BIND(L_CTR_loop);
+ __ leave(); // required for proper stackwalking of RuntimeStub frame
+ __ ret(lr);
- // Setup the counters
- __ movi(v8, __ T4S, 0);
- __ movi(v9, __ T4S, 1);
- __ ins(v8, __ S, v9, 3, 3); // v8 contains { 0, 0, 0, 1 }
+ // Bulk encryption
- for (FloatRegister f = v0; f < v0 + bulk_width; f++) {
- __ rev32(f, __ T16B, v16);
- __ addv(v16, __ T4S, v16, v8);
- }
+ __ BIND (CTR_large_block);
+ assert(bulk_width == 4 || bulk_width == 8, "must be");
- __ ld1(v8, v9, v10, v11, __ T16B, __ post(in, 4 * 16));
+ if (bulk_width == 8) {
+ __ sub(sp, sp, 4 * 16);
+ __ st1(v12, v13, v14, v15, __ T16B, Address(sp));
+ }
+ __ sub(sp, sp, 4 * 16);
+ __ st1(v8, v9, v10, v11, __ T16B, Address(sp));
+ RegSet saved_regs = (RegSet::of(in, out, offset)
+ + RegSet::of(saved_encrypted_ctr, used_ptr, len));
+ __ push(saved_regs, sp);
+ __ andr(len, len, -16 * bulk_width); // 8/4 encryptions, 16 bytes per encryption
+ __ add(in, in, offset);
+ __ add(out, out, offset);
- // Encrypt the counters
- __ aesecb_encrypt(noreg, noreg, keylen, v0, bulk_width);
+ // Keys should already be loaded into the correct registers
- if (bulk_width == 8) {
- __ ld1(v12, v13, v14, v15, __ T16B, __ post(in, 4 * 16));
- }
+ __ ld1(v0, __ T16B, counter); // v0 contains the first counter
+ __ rev64(v16, __ T16B, v0); // v16 contains byte-reversed counter
- // XOR the encrypted counters with the inputs
- for (int i = 0; i < bulk_width; i++) {
- __ eor(v0 + i, __ T16B, v0 + i, v8 + i);
- }
+ // AES/CTR loop
+ {
+ Label L_CTR_loop;
+ __ BIND(L_CTR_loop);
- // Write the encrypted data
- __ st1(v0, v1, v2, v3, __ T16B, __ post(out, 4 * 16));
- if (bulk_width == 8) {
- __ st1(v4, v5, v6, v7, __ T16B, __ post(out, 4 * 16));
- }
+ // Setup the counters
+ __ movi(v8, __ T4S, 0);
+ __ movi(v9, __ T4S, 1);
+ __ ins(v8, __ S, v9, 2, 2); // v8 contains { 0, 1 }
- __ subw(len, len, 16 * bulk_width);
- __ cbnzw(len, L_CTR_loop);
+ for (FloatRegister f = v0; f < v0 + bulk_width; f++) {
+ __ rev64(f, __ T16B, v16);
+ be_add_128_64(v16, v16, v8, /*tmp*/v9);
}
- // Save the counter back where it goes
- __ rev32(v16, __ T16B, v16);
- __ st1(v16, __ T16B, counter);
+ __ ld1(v8, v9, v10, v11, __ T16B, __ post(in, 4 * 16));
- __ pop(saved_regs, sp);
+ // Encrypt the counters
+ __ aesecb_encrypt(noreg, noreg, keylen, v0, bulk_width);
- __ ld1(v8, v9, v10, v11, __ T16B, __ post(sp, 4 * 16));
if (bulk_width == 8) {
- __ ld1(v12, v13, v14, v15, __ T16B, __ post(sp, 4 * 16));
+ __ ld1(v12, v13, v14, v15, __ T16B, __ post(in, 4 * 16));
}
- __ andr(rscratch1, len, -16 * bulk_width);
- __ sub(len, len, rscratch1);
- __ add(offset, offset, rscratch1);
- __ mov(used, 16);
- __ strw(used, Address(used_ptr));
- __ b(large_block_return);
+ // XOR the encrypted counters with the inputs
+ for (int i = 0; i < bulk_width; i++) {
+ __ eor(v0 + i, __ T16B, v0 + i, v8 + i);
+ }
- return start;
+ // Write the encrypted data
+ __ st1(v0, v1, v2, v3, __ T16B, __ post(out, 4 * 16));
+ if (bulk_width == 8) {
+ __ st1(v4, v5, v6, v7, __ T16B, __ post(out, 4 * 16));
+ }
+
+ __ subw(len, len, 16 * bulk_width);
+ __ cbnzw(len, L_CTR_loop);
}
+ // Save the counter back where it goes
+ __ rev64(v16, __ T16B, v16);
+ __ st1(v16, __ T16B, counter);
+
+ __ pop(saved_regs, sp);
+
+ __ ld1(v8, v9, v10, v11, __ T16B, __ post(sp, 4 * 16));
+ if (bulk_width == 8) {
+ __ ld1(v12, v13, v14, v15, __ T16B, __ post(sp, 4 * 16));
+ }
+
+ __ andr(rscratch1, len, -16 * bulk_width);
+ __ sub(len, len, rscratch1);
+ __ add(offset, offset, rscratch1);
+ __ mov(used, 16);
+ __ strw(used, Address(used_ptr));
+ __ b(large_block_return);
+
+ return start;
+ }
+
// Arguments:
diff --git a/hotspot/test/compiler/codegen/aes/CTR_Wraparound.java b/hotspot/test/compiler/codegen/aes/CTR_Wraparound.java
new file mode 100644
index 000000000..f578b432c
--- /dev/null
+++ b/hotspot/test/compiler/codegen/aes/CTR_Wraparound.java
@@ -0,0 +1,169 @@
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.lang.reflect.Executable;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.concurrent.Callable;
+
+/**
+ * @test
+ * @bug 8308682
+ * @summary Check for 128-bit AES/CTR wraparound
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox /compiler/testlibrary
+ * @build CTR_Wraparound
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:.
+ * -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * CTR_Wraparound 32
+ * @run main/othervm -Xbootclasspath/a:.
+ * -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * CTR_Wraparound 1009
+ * @run main/othervm -Xbootclasspath/a:.
+ * -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * CTR_Wraparound 2048
+ */
+
+public class CTR_Wraparound extends CompilerWhiteBoxTest {
+ private static final String ALGO = "AES/CTR/NoPadding";
+ private static final int LOOPS = 100000;
+ private int length;
+ private int maxOffset;
+
+ public CTR_Wraparound(int len,int offset){
+ super(new CTR_WraparoundTestCase());
+ length = len;
+ maxOffset = offset;
+ }
+
+ public static class CTR_WraparoundTestCase implements TestCase {
+
+ public String name() {
+ return "CTR_WraparoundTestCase";
+ }
+
+ public Executable getExecutable(){
+ try {
+ return Class.forName("com.sun.crypto.provider.CounterMode").getDeclaredMethod("implCrypt", byte[].class, int.class, int.class, byte[].class, int.class);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Test bug, method unavailable. " + e);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Test bug, class unavailable. " + e);
+ }
+ }
+
+ public Callable<Integer> getCallable() {
+ return null;
+ }
+
+ public boolean isOsr() {
+ return false;
+ }
+
+ }
+
+ private static boolean isServerVM(String VMName) { return VMName.toLowerCase().contains("server");}
+
+
+
+ protected static boolean checkIntrinsicForCompilationLevel(Executable method, int compLevel) {
+ boolean intrinsicEnabled = Boolean.valueOf(getVMOption("UseAESCTRIntrinsics"));
+ boolean intrinsicAvailable = WHITE_BOX.isIntrinsicAvailable(method,
+ compLevel);
+ if(intrinsicAvailable && intrinsicEnabled){
+ return true;
+ }
+ return false;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int length = Integer.parseInt(args[0]);
+ int maxOffset = 60;
+ if (args.length > 1) {
+ maxOffset = Integer.parseInt(args[1]);
+ System.out.println("InitialOffset = " + maxOffset);
+ }
+ new CTR_Wraparound(length,maxOffset).test();
+ }
+
+ @Override
+ protected void test() throws Exception {
+
+ String VMName = System.getProperty("java.vm.name");
+ Executable intrinsicMethod = testCase.getExecutable();
+ boolean isIntrinsicEnabled = false;
+ if (isServerVM(VMName)) {
+ if (TIERED_COMPILATION) {
+ isIntrinsicEnabled = checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE);
+ }
+ isIntrinsicEnabled = checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_FULL_OPTIMIZATION);
+ } else {
+ isIntrinsicEnabled = checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE);
+ }
+ if(!isIntrinsicEnabled){
+ return;
+ }
+
+
+ long SEED = Long.getLong("jdk.test.lib.random.seed", new Random().nextLong());
+ Random random = new Random(SEED);
+
+ byte[] keyBytes = new byte[32];
+ Arrays.fill(keyBytes, (byte)0xff);
+ SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
+
+ byte[] ivBytes = new byte[16];
+
+ Arrays.fill(ivBytes, (byte)0xff);
+
+ byte[][] plaintext = new byte[maxOffset][];
+ byte[][] ciphertext = new byte[maxOffset][];
+
+ for (int offset = 0; offset < maxOffset; offset++) {
+ ivBytes[ivBytes.length - 1] = (byte)-offset;
+ IvParameterSpec iv = new IvParameterSpec(ivBytes);
+
+ Cipher encryptCipher = Cipher.getInstance(ALGO);
+ Cipher decryptCipher = Cipher.getInstance(ALGO);
+
+ encryptCipher.init(Cipher.ENCRYPT_MODE, key, iv);
+ decryptCipher.init(Cipher.DECRYPT_MODE, key, iv);
+
+ plaintext[offset] = new byte[length];
+ ciphertext[offset] = new byte[length];
+ random.nextBytes(plaintext[offset]);
+
+ byte[] decrypted = new byte[length];
+
+ encryptCipher.doFinal(plaintext[offset], 0, length, ciphertext[offset]);
+ decryptCipher.doFinal(ciphertext[offset], 0, length, decrypted);
+
+ if (!Arrays.equals(plaintext[offset], decrypted)) {
+ throw new Exception("mismatch in setup at offset " + offset);
+ }
+ }
+
+ for (int offset = 0; offset < maxOffset; offset++) {
+ ivBytes[ivBytes.length - 1] = (byte)-offset;
+ IvParameterSpec iv = new IvParameterSpec(ivBytes);
+
+ Cipher encryptCipher = Cipher.getInstance(ALGO);
+
+ encryptCipher.init(Cipher.ENCRYPT_MODE, key, iv);
+
+ byte[] encrypted = new byte[length];
+
+ for (int i = 0; i < LOOPS; i++) {
+ encryptCipher.doFinal(plaintext[offset], 0, length, encrypted);
+ if (!Arrays.equals(ciphertext[offset], encrypted)) {
+ throw new Exception("array mismatch at offset " + offset
+ + " with length " + length);
+ }
+ }
+ }
+ }
+}
--
2.19.1

View File

@ -0,0 +1,366 @@
From 941ebd7303bce4242121cc2173d5fd6dcff2226a Mon Sep 17 00:00:00 2001
Subject: 8312065: Socket.connect does not timeout when profiling
---
jdk/src/aix/native/java/net/aix_close.c | 56 +++++++++---------
jdk/src/solaris/native/java/net/bsd_close.c | 57 ++++++++++---------
jdk/src/solaris/native/java/net/linux_close.c | 57 ++++++++++---------
3 files changed, 86 insertions(+), 84 deletions(-)
diff --git a/jdk/src/aix/native/java/net/aix_close.c b/jdk/src/aix/native/java/net/aix_close.c
index 90d57b42f..3402293c6 100644
--- a/jdk/src/aix/native/java/net/aix_close.c
+++ b/jdk/src/aix/native/java/net/aix_close.c
@@ -53,8 +53,8 @@
#include <sys/uio.h>
#include <unistd.h>
#include <errno.h>
-
#include <sys/poll.h>
+#include "jvm.h"
/*
* Stack allocated by thread when doing blocking operation
@@ -376,61 +376,61 @@ int NET_SocketClose(int fd) {
/************** Basic I/O operations here ***************/
/*
- * Macro to perform a blocking IO operation. Restarts
- * automatically if interrupted by signal (other than
- * our wakeup signal)
+ * Macro to perform a blocking IO operation.
+ * If interrupted by signal (other than our wakeup signal), and if RETRY is true,
+ * then restarts automatically
*/
-#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
- int ret; \
- threadEntry_t self; \
- fdEntry_t *fdEntry = getFdEntry(FD); \
- if (fdEntry == NULL) { \
- errno = EBADF; \
- return -1; \
- } \
- do { \
- startOp(fdEntry, &self); \
- ret = FUNC; \
- endOp(fdEntry, &self); \
- } while (ret == -1 && errno == EINTR); \
- return ret; \
+#define BLOCKING_IO_RETURN_INT(FD, FUNC, RETRY) { \
+ int ret; \
+ threadEntry_t self; \
+ fdEntry_t *fdEntry = getFdEntry(FD); \
+ if (fdEntry == NULL) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ do { \
+ startOp(fdEntry, &self); \
+ ret = FUNC; \
+ endOp(fdEntry, &self); \
+ } while ((RETRY) && ret == -1 && errno == EINTR); \
+ return ret; \
}
int NET_Read(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0), JNI_TRUE);
}
int NET_NonBlockingRead(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT(s, recv(s, buf, len, MSG_NONBLOCK));
+ BLOCKING_IO_RETURN_INT(s, recv(s, buf, len, MSG_NONBLOCK), JNI_TRUE);
}
int NET_ReadV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
+ BLOCKING_IO_RETURN_INT( s, readv(s, vector, count), JNI_TRUE);
}
int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen) {
socklen_t socklen = *fromlen;
- BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
+ BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen), JNI_TRUE);
*fromlen = socklen;
}
int NET_Send(int s, void *msg, int len, unsigned int flags) {
- BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
+ BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags), JNI_TRUE);
}
int NET_WriteV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
+ BLOCKING_IO_RETURN_INT( s, writev(s, vector, count), JNI_TRUE);
}
int NET_SendTo(int s, const void *msg, int len, unsigned int
flags, const struct sockaddr *to, int tolen) {
- BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
+ BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen), JNI_TRUE);
}
int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
socklen_t socklen = *addrlen;
- BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen) );
+ BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen), JNI_TRUE);
*addrlen = socklen;
}
@@ -490,13 +490,13 @@ int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
#ifndef USE_SELECT
int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
- BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
+ BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout), JNI_FALSE);
}
#else
int NET_Select(int s, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout) {
BLOCKING_IO_RETURN_INT( s-1,
- select(s, readfds, writefds, exceptfds, timeout) );
+ select(s, readfds, writefds, exceptfds, timeout), JNI_FALSE);
}
#endif
diff --git a/jdk/src/solaris/native/java/net/bsd_close.c b/jdk/src/solaris/native/java/net/bsd_close.c
index 89a20707c..37a6e5688 100644
--- a/jdk/src/solaris/native/java/net/bsd_close.c
+++ b/jdk/src/solaris/native/java/net/bsd_close.c
@@ -39,6 +39,7 @@
#include <unistd.h>
#include <errno.h>
#include <sys/poll.h>
+#include "jvm.h"
/*
* Stack allocated by thread when doing blocking operation
@@ -347,55 +348,55 @@ int NET_SocketClose(int fd) {
/************** Basic I/O operations here ***************/
/*
- * Macro to perform a blocking IO operation. Restarts
- * automatically if interrupted by signal (other than
- * our wakeup signal)
+ * Macro to perform a blocking IO operation.
+ * If interrupted by signal (other than our wakeup signal), and if RETRY is true,
+ * then restarts automatically
*/
-#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
- int ret; \
- threadEntry_t self; \
- fdEntry_t *fdEntry = getFdEntry(FD); \
- if (fdEntry == NULL) { \
- errno = EBADF; \
- return -1; \
- } \
- do { \
- startOp(fdEntry, &self); \
- ret = FUNC; \
- endOp(fdEntry, &self); \
- } while (ret == -1 && errno == EINTR); \
- return ret; \
+#define BLOCKING_IO_RETURN_INT(FD, FUNC, RETRY) { \
+ int ret; \
+ threadEntry_t self; \
+ fdEntry_t *fdEntry = getFdEntry(FD); \
+ if (fdEntry == NULL) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ do { \
+ startOp(fdEntry, &self); \
+ ret = FUNC; \
+ endOp(fdEntry, &self); \
+ } while ((RETRY) && ret == -1 && errno == EINTR); \
+ return ret; \
}
int NET_Read(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0), JNI_TRUE);
}
int NET_NonBlockingRead(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT));
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT), JNI_TRUE);
}
int NET_ReadV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
+ BLOCKING_IO_RETURN_INT( s, readv(s, vector, count), JNI_TRUE);
}
int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen) {
/* casting int *fromlen -> socklen_t* Both are ints */
- BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen) );
+ BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen), JNI_TRUE);
}
int NET_Send(int s, void *msg, int len, unsigned int flags) {
- BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
+ BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags), JNI_TRUE);
}
int NET_WriteV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
+ BLOCKING_IO_RETURN_INT( s, writev(s, vector, count), JNI_TRUE);
}
int NET_SendTo(int s, const void *msg, int len, unsigned int
flags, const struct sockaddr *to, int tolen) {
- BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
+ BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen), JNI_TRUE);
}
int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
@@ -403,22 +404,22 @@ int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
int error = accept(s, addr, &len);
if (error != -1)
*addrlen = (int)len;
- BLOCKING_IO_RETURN_INT( s, error );
+ BLOCKING_IO_RETURN_INT( s, error, JNI_TRUE);
}
int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
- BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
+ BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen), JNI_TRUE);
}
#ifndef USE_SELECT
int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
- BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
+ BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout), JNI_FALSE);
}
#else
int NET_Select(int s, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout) {
BLOCKING_IO_RETURN_INT( s-1,
- select(s, readfds, writefds, exceptfds, timeout) );
+ select(s, readfds, writefds, exceptfds, timeout), JNI_FALSE);
}
#endif
diff --git a/jdk/src/solaris/native/java/net/linux_close.c b/jdk/src/solaris/native/java/net/linux_close.c
index f4c53a0d0..2a31b1591 100644
--- a/jdk/src/solaris/native/java/net/linux_close.c
+++ b/jdk/src/solaris/native/java/net/linux_close.c
@@ -37,6 +37,7 @@
#include <unistd.h>
#include <errno.h>
#include <sys/poll.h>
+#include "jvm.h"
/*
* Stack allocated by thread when doing blocking operation
@@ -343,77 +344,77 @@ int NET_SocketClose(int fd) {
/************** Basic I/O operations here ***************/
/*
- * Macro to perform a blocking IO operation. Restarts
- * automatically if interrupted by signal (other than
- * our wakeup signal)
+ * Macro to perform a blocking IO operation.
+ * If interrupted by signal (other than our wakeup signal), and if RETRY is true,
+ * then restarts automatically
*/
-#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
- int ret; \
- threadEntry_t self; \
- fdEntry_t *fdEntry = getFdEntry(FD); \
- if (fdEntry == NULL) { \
- errno = EBADF; \
- return -1; \
- } \
- do { \
- startOp(fdEntry, &self); \
- ret = FUNC; \
- endOp(fdEntry, &self); \
- } while (ret == -1 && errno == EINTR); \
- return ret; \
+#define BLOCKING_IO_RETURN_INT(FD, FUNC, RETRY) { \
+ int ret; \
+ threadEntry_t self; \
+ fdEntry_t *fdEntry = getFdEntry(FD); \
+ if (fdEntry == NULL) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ do { \
+ startOp(fdEntry, &self); \
+ ret = FUNC; \
+ endOp(fdEntry, &self); \
+ } while ((RETRY) && ret == -1 && errno == EINTR); \
+ return ret; \
}
int NET_Read(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0), JNI_TRUE);
}
int NET_NonBlockingRead(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT) );
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT), JNI_TRUE);
}
int NET_ReadV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
+ BLOCKING_IO_RETURN_INT( s, readv(s, vector, count), JNI_TRUE);
}
int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen) {
socklen_t socklen = *fromlen;
- BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
+ BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen), JNI_TRUE);
*fromlen = socklen;
}
int NET_Send(int s, void *msg, int len, unsigned int flags) {
- BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
+ BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags), JNI_TRUE);
}
int NET_WriteV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
+ BLOCKING_IO_RETURN_INT( s, writev(s, vector, count), JNI_TRUE);
}
int NET_SendTo(int s, const void *msg, int len, unsigned int
flags, const struct sockaddr *to, int tolen) {
- BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
+ BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen), JNI_TRUE);
}
int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
socklen_t socklen = *addrlen;
- BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen) );
+ BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen), JNI_TRUE);
*addrlen = socklen;
}
int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
- BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
+ BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen), JNI_TRUE);
}
#ifndef USE_SELECT
int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
- BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
+ BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout), JNI_FALSE);
}
#else
int NET_Select(int s, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout) {
BLOCKING_IO_RETURN_INT( s-1,
- select(s, readfds, writefds, exceptfds, timeout) );
+ select(s, readfds, writefds, exceptfds, timeout), JNI_FALSE);
}
#endif
--
2.22.0

View File

@ -0,0 +1,96 @@
From c8190e59dbdcb9f52af521994523bae6b893716b Mon Sep 17 00:00:00 2001
Subject: 8312200: Fix Parse::catch_call_exceptions memory leak
---
hotspot/src/share/vm/opto/doCall.cpp | 35 ++++++++++++++--------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp
index 1b2b77c71..f41e6d386 100644
--- a/hotspot/src/share/vm/opto/doCall.cpp
+++ b/hotspot/src/share/vm/opto/doCall.cpp
@@ -698,24 +698,25 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
Node* i_o = this->i_o();
// Add a CatchNode.
- GrowableArray<int>* bcis = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, -1);
- GrowableArray<const Type*>* extypes = new (C->node_arena()) GrowableArray<const Type*>(C->node_arena(), 8, 0, NULL);
- GrowableArray<int>* saw_unloaded = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, 0);
+ Arena tmp_mem(mtCompiler);
+ GrowableArray<int> bcis(&tmp_mem, 8, 0, -1);
+ GrowableArray<const Type*> extypes(&tmp_mem, 8, 0, NULL);
+ GrowableArray<int> saw_unloaded(&tmp_mem, 8, 0, -1);
bool default_handler = false;
for (; !handlers.is_done(); handlers.next()) {
- ciExceptionHandler* h = handlers.handler();
- int h_bci = h->handler_bci();
- ciInstanceKlass* h_klass = h->is_catch_all() ? env()->Throwable_klass() : h->catch_klass();
+ ciExceptionHandler* h = handlers.handler();
+ int h_bci = h->handler_bci();
+ ciInstanceKlass* h_klass = h->is_catch_all() ? env()->Throwable_klass() : h->catch_klass();
// Do not introduce unloaded exception types into the graph:
if (!h_klass->is_loaded()) {
- if (saw_unloaded->contains(h_bci)) {
+ if (saw_unloaded.contains(h_bci)) {
/* We've already seen an unloaded exception with h_bci,
so don't duplicate. Duplication will cause the CatchNode to be
unnecessarily large. See 4713716. */
continue;
} else {
- saw_unloaded->append(h_bci);
+ saw_unloaded.append(h_bci);
}
}
const Type* h_extype = TypeOopPtr::make_from_klass(h_klass);
@@ -723,19 +724,19 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
h_extype = h_extype->join(TypeInstPtr::NOTNULL);
assert(!h_extype->empty(), "sanity");
// Note: It's OK if the BCIs repeat themselves.
- bcis->append(h_bci);
- extypes->append(h_extype);
+ bcis.append(h_bci);
+ extypes.append(h_extype);
if (h_bci == -1) {
default_handler = true;
}
}
if (!default_handler) {
- bcis->append(-1);
- extypes->append(TypeOopPtr::make_from_klass(env()->Throwable_klass())->is_instptr());
+ bcis.append(-1);
+ extypes.append(TypeOopPtr::make_from_klass(env()->Throwable_klass())->is_instptr());
}
- int len = bcis->length();
+ int len = bcis.length();
CatchNode *cn = new (C) CatchNode(control(), i_o, len+1);
Node *catch_ = _gvn.transform(cn);
@@ -746,18 +747,18 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
PreserveJVMState pjvms(this);
// Locals are just copied from before the call.
// Get control from the CatchNode.
- int handler_bci = bcis->at(i);
+ int handler_bci = bcis.at(i);
Node* ctrl = _gvn.transform( new (C) CatchProjNode(catch_, i+1,handler_bci));
// This handler cannot happen?
if (ctrl == top()) continue;
set_control(ctrl);
// Create exception oop
- const TypeInstPtr* extype = extypes->at(i)->is_instptr();
- Node *ex_oop = _gvn.transform(new (C) CreateExNode(extypes->at(i), ctrl, i_o));
+ const TypeInstPtr* extype = extypes.at(i)->is_instptr();
+ Node *ex_oop = _gvn.transform(new (C) CreateExNode(extypes.at(i), ctrl, i_o));
// Handle unloaded exception classes.
- if (saw_unloaded->contains(handler_bci)) {
+ if (saw_unloaded.contains(handler_bci)) {
// An unloaded exception type is coming here. Do an uncommon trap.
#ifndef PRODUCT
// We do not expect the same handler bci to take both cold unloaded
--
2.22.0

View File

@ -0,0 +1,226 @@
From ca014e842f05da9d929152c7e5f7cd56d30629e5 Mon Sep 17 00:00:00 2001
Subject: 8313626: C2 crash due to unexpected exception control flow
---
hotspot/src/share/vm/opto/doCall.cpp | 4 +
.../compiler/MissingSafepointOnTryCatch.jasm | 112 ++++++++++++++++++
.../TestMissingSafepointOnTryCatch.java | 66 +++++++++++
3 files changed, 182 insertions(+)
create mode 100644 jdk/test/jdk/jfr/event/compiler/MissingSafepointOnTryCatch.jasm
create mode 100644 jdk/test/jdk/jfr/event/compiler/TestMissingSafepointOnTryCatch.java
diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp
index 1b2b77c71..7a7aba359 100644
--- a/hotspot/src/share/vm/opto/doCall.cpp
+++ b/hotspot/src/share/vm/opto/doCall.cpp
@@ -892,6 +892,8 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
tty->print_cr(" Catching every inline exception bci:%d -> handler_bci:%d", bci(), handler_bci);
}
#endif
+ // If this is a backwards branch in the bytecodes, add safepoint
+ maybe_add_safepoint(handler_bci);
merge_exception(handler_bci); // jump to handler
return; // No more handling to be done here!
}
@@ -925,6 +927,8 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
tty->cr();
}
#endif
+ // If this is a backwards branch in the bytecodes, add safepoint
+ maybe_add_safepoint(handler_bci);
merge_exception(handler_bci);
}
set_control(not_subtype_ctrl);
diff --git a/jdk/test/jdk/jfr/event/compiler/MissingSafepointOnTryCatch.jasm b/jdk/test/jdk/jfr/event/compiler/MissingSafepointOnTryCatch.jasm
new file mode 100644
index 000000000..413736e59
--- /dev/null
+++ b/jdk/test/jdk/jfr/event/compiler/MissingSafepointOnTryCatch.jasm
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2023, 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.
+ */
+
+public class MissingSafepointOnTryCatch version 52:0 {
+
+ static Method m:"()V" {
+ return;
+ }
+
+ static Method test1:"()V" stack 1 {
+ try t;
+ invokestatic m:"()V";
+ return;
+
+ catch t java/lang/Throwable;
+ stack_map class java/lang/Throwable;
+ athrow;
+ endtry t;
+ }
+
+ static Method test2:"()V" stack 1 {
+ try t0;
+ try t1;
+ invokestatic m:"()V";
+ endtry t1;
+ return;
+
+ catch t1 java/lang/Exception;
+ stack_map class java/lang/Exception;
+ return;
+
+ catch t0 java/lang/Throwable;
+ stack_map class java/lang/Throwable;
+ athrow;
+ endtry t0;
+ }
+
+ public static Method th:"()V"
+ throws java/lang/Exception
+ stack 2 locals 0
+ {
+ new class java/lang/Exception;
+ dup;
+ invokespecial Method java/lang/Exception."<init>":"()V";
+ athrow;
+ }
+
+ static Method test3:"()V" stack 1 locals 2 {
+ try t;
+ invokestatic m:"()V";
+ iconst_1;
+ istore_0;
+ iconst_0;
+ istore_1;
+ return;
+ catch t java/lang/Throwable;
+ stack_map class java/lang/Throwable;
+ invokestatic th:"()V";
+ return;
+ endtry t;
+ }
+
+ static Method test4:"()V" stack 2 locals 2 {
+ try t;
+ invokestatic m:"()V";
+ iconst_1;
+ istore_0;
+ iconst_0;
+ istore_1;
+ return;
+ catch t java/lang/Throwable;
+ stack_map class java/lang/Throwable;
+ iconst_1;
+ istore_0;
+ invokestatic th:"()V";
+ return;
+ endtry t;
+ }
+
+ static Method testInfinite:"()V" stack 1 {
+ try t;
+ invokestatic th:"()V";
+ return;
+
+ catch t java/lang/Throwable;
+ stack_map class java/lang/Throwable;
+ athrow;
+ endtry t;
+ }
+
+} // end Class MissingSafepointOnTryCatch
diff --git a/jdk/test/jdk/jfr/event/compiler/TestMissingSafepointOnTryCatch.java b/jdk/test/jdk/jfr/event/compiler/TestMissingSafepointOnTryCatch.java
new file mode 100644
index 000000000..fa579b7d4
--- /dev/null
+++ b/jdk/test/jdk/jfr/event/compiler/TestMissingSafepointOnTryCatch.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023, 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 8313626
+ * @library /lib /
+ * @summary assert(false) failed: malformed control flow to missing safepoint on backedge of a try-catch
+ * @compile MissingSafepointOnTryCatch.jasm
+ * @run main/othervm -XX:CompileCommand=quiet
+ * -XX:CompileCommand=compileonly,MissingSafepointOnTryCatch::test*
+ * -XX:CompileCommand=dontinline,MissingSafepointOnTryCatch::m
+ * -XX:CompileCommand=inline,MissingSafepointOnTryCatch::th
+ * -XX:-TieredCompilation -Xcomp TestMissingSafepointOnTryCatch
+ */
+
+import jdk.test.lib.Utils;
+
+public class TestMissingSafepointOnTryCatch {
+
+ public static void infiniteLoop() {
+ try {
+ Thread thread = new Thread() {
+ public void run() {
+ MissingSafepointOnTryCatch.testInfinite();
+ }
+ };
+ thread.setDaemon(true);
+ thread.start();
+ Thread.sleep(Utils.adjustTimeout(500));
+ } catch (Exception e) {}
+ }
+
+ public static void main(String[] args) {
+ try {
+ // to make sure java/lang/Exception class is resolved
+ MissingSafepointOnTryCatch.th();
+ } catch (Exception e) {}
+ MissingSafepointOnTryCatch.test1();
+ MissingSafepointOnTryCatch.test2();
+ MissingSafepointOnTryCatch.test3();
+ MissingSafepointOnTryCatch.test4();
+ infiniteLoop();
+ }
+}
--
2.22.0

View File

@ -0,0 +1,127 @@
From 11bd45aac555a00c705c8bf480a179bb063b1c44 Mon Sep 17 00:00:00 2001
Subject: 8314236: Overflow in Collections.rotate
---
.../share/classes/java/util/Collections.java | 9 +-
.../java/util/Collections/RotateHuge.java | 85 +++++++++++++++++++
2 files changed, 90 insertions(+), 4 deletions(-)
create mode 100644 jdk/test/java/util/Collections/RotateHuge.java
diff --git a/jdk/src/share/classes/java/util/Collections.java b/jdk/src/share/classes/java/util/Collections.java
index 3ab4c5ec0..9aa373841 100644
--- a/jdk/src/share/classes/java/util/Collections.java
+++ b/jdk/src/share/classes/java/util/Collections.java
@@ -789,15 +789,16 @@ public class Collections {
if (distance == 0)
return;
- for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
+ int bound = size - distance;
+ for (int cycleStart = 0, nMoved = 0; nMoved < size; cycleStart++) {
T displaced = list.get(cycleStart);
int i = cycleStart;
do {
- i += distance;
- if (i >= size)
+ if (i >= bound)
i -= size;
+ i += distance;
displaced = list.set(i, displaced);
- nMoved ++;
+ nMoved++;
} while (i != cycleStart);
}
}
diff --git a/jdk/test/java/util/Collections/RotateHuge.java b/jdk/test/java/util/Collections/RotateHuge.java
new file mode 100644
index 000000000..a6f8f739c
--- /dev/null
+++ b/jdk/test/java/util/Collections/RotateHuge.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2023, 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 8314236
+ * @summary Overflow in Collections.rotate
+ */
+
+import com.sun.crypto.provider.Preconditions;
+
+import java.util.AbstractList;
+import java.util.Collections;
+import java.util.List;
+import java.util.RandomAccess;
+
+public class RotateHuge {
+
+ private static final class MockList extends AbstractList<Object>
+ implements RandomAccess {
+ private final int size;
+
+ public MockList(final int size) {
+ if (size < 0)
+ throw new IllegalArgumentException("Illegal size: " + size);
+ this.size = size;
+ }
+
+ @Override
+ public Object get(final int index) {
+ Preconditions.checkIndex(index, size, null);
+ return null;
+ }
+
+ @Override
+ public Object set(final int index, final Object element) {
+ Preconditions.checkIndex(index, size, null);
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+ }
+
+ public static void main(final String[] args) {
+ testRotate((1 << 30) + 1, -(1 << 30) - 2);
+ testRotate((1 << 30) + 1, 1 << 30);
+ testRotate(Integer.MAX_VALUE, Integer.MIN_VALUE);
+ testRotate(Integer.MAX_VALUE, Integer.MIN_VALUE + 3);
+ testRotate(Integer.MAX_VALUE, 2);
+ testRotate(Integer.MAX_VALUE, Integer.MAX_VALUE - 1);
+ }
+
+ /*
+ * This test covers only index computations.
+ * Correctness of elements rotation is not checked.
+ */
+ private static void testRotate(final int size, final int distance) {
+ final List<Object> list = new MockList(size);
+ Collections.rotate(list, distance);
+ }
+}
--
2.22.0

View File

@ -0,0 +1,219 @@
From 69b1d2f90f27a9158bc16d549dd0afc7a4e955a8 Mon Sep 17 00:00:00 2001
From: d30023828 <douyiwang@huawei.com>
Date: Sat, 28 Jan 2023 15:47:20 +0800
Subject: [PATCH 1/6] Add CMS's trim test cases and fix failure
DTS/AR: DTS2022120810426
Summary: <CDS> : Add CMS's trim test cases and fix failure
LLT: NA
Patch Type: huawei
Bug url: NA
---
hotspot/test/gc/TestTrimNative.java | 77 ++++++++++++++++++++++-------
1 file changed, 58 insertions(+), 19 deletions(-)
diff --git a/hotspot/test/gc/TestTrimNative.java b/hotspot/test/gc/TestTrimNative.java
index 58d540527..e0ac7734b 100644
--- a/hotspot/test/gc/TestTrimNative.java
+++ b/hotspot/test/gc/TestTrimNative.java
@@ -41,7 +41,7 @@ package gc;
/*
* @test id=fullgc-serial
* @summary Test that GCTrimNativeHeap works with Serial
- * @requires vm.gc=="Serial"
+ * @requires vm.gc=="Serial" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
@@ -51,17 +51,27 @@ package gc;
/*
* @test id=fullgc-parallel
* @summary Test that GCTrimNativeHeap works with Parallel
- * @requires vm.gc=="Parallel"
+ * @requires vm.gc=="Parallel" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
* @run driver gc.TestTrimNative test-fullgc parallel
*/
+ /*
+ * @test id=fullgc-concMarkSweep
+ * @summary Test that GCTrimNativeHeap works with concMarkSweep
+ * @requires vm.gc=="ConcMarkSweep" | vm.gc=="null"
+ * @requires os.family=="linux"
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @run driver gc.TestTrimNative test-fullgc concMarkSweep
+ */
+
/*
* @test id=fullgc-g1
* @summary Test that GCTrimNativeHeap works with G1
- * @requires vm.gc=="G1"
+ * @requires vm.gc=="G1" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
@@ -75,17 +85,27 @@ package gc;
/*
* @test id=auto-parallel
* @summary Test that GCTrimNativeHeap works with Parallel
- * @requires vm.gc=="Parallel"
+ * @requires vm.gc=="Parallel" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
* @run driver gc.TestTrimNative test-auto parallel
*/
+ /*
+ * @test id=auto-concMarkSweep
+ * @summary Test that GCTrimNativeHeap works with concMarkSweep
+ * @requires vm.gc=="ConcMarkSweep" | vm.gc == "null"
+ * @requires os.family=="linux"
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @run driver gc.TestTrimNative test-auto concMarkSweep
+ */
+
/*
* @test id=auto-g1
* @summary Test that GCTrimNativeHeap works with G1
- * @requires vm.gc=="G1"
+ * @requires vm.gc=="G1" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
@@ -100,17 +120,27 @@ package gc;
/*
* @test id=auto-high-interval-parallel
* @summary Test that a high GCTrimNativeHeapInterval effectively disables automatic trimming
- * @requires vm.gc=="Parallel"
+ * @requires vm.gc=="Parallel" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
* @run driver gc.TestTrimNative test-auto-high-interval parallel
*/
+/*
+ * @test id=auto-high-interval-concMarkSweep
+ * @summary Test that a high GCTrimNativeHeapInterval effectively disables automatic trimming
+ * @requires vm.gc=="ConcMarkSweep" | vm.gc == "null"
+ * @requires os.family=="linux"
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @run driver gc.TestTrimNative test-auto-high-interval concMarkSweep
+ */
+
/*
* @test id=auto-high-interval-g1
* @summary Test that a high GCTrimNativeHeapInterval effectively disables automatic trimming
- * @requires vm.gc=="G1"
+ * @requires vm.gc=="G1" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
@@ -124,17 +154,27 @@ package gc;
/*
* @test id=auto-zero-interval-parallel
* @summary Test that a GCTrimNativeHeapInterval=0 disables periodic trimming
- * @requires vm.gc=="Parallel"
+ * @requires vm.gc=="Parallel" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
* @run driver gc.TestTrimNative test-auto-zero-interval parallel
*/
+/*
+ * @test id=auto-zero-interval-concMarkSweep
+ * @summary Test that a GCTrimNativeHeapInterval=0 disables periodic trimming
+ * @requires vm.gc=="ConcMarkSweep" | vm.gc == "null"
+ * @requires os.family=="linux"
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @run driver gc.TestTrimNative test-auto-zero-interval concMarkSweep
+ */
+
/*
* @test id=auto-zero-interval-g1
* @summary Test that a GCTrimNativeHeapInterval=0 disables periodic trimming
- * @requires vm.gc=="G1"
+ * @requires vm.gc=="G1" | vm.gc == "null"
* @requires os.family=="linux"
* @modules java.base/jdk.internal.misc
* @library /testlibrary
@@ -196,20 +236,19 @@ public class TestTrimNative {
}
enum GC {
- serial, parallel, g1, shenandoah, z;
+ serial, parallel, g1, concMarkSweep;
String getSwitchName() {
String s = name();
return "-XX:+Use" + s.substring(0, 1).toUpperCase() + s.substring(1) + "GC";
}
- boolean isZ() { return this == GC.z; }
boolean isSerial() { return this == GC.serial; }
boolean isParallel() { return this == GC.parallel; }
boolean isG1() { return this == GC.g1; }
- boolean isShenandoah() { return this == GC.shenandoah; }
+ boolean isConcMarkSweep() { return this == GC.concMarkSweep; }
}
static private boolean usesNativeTrimmer(GC gc) {
- return gc.isG1() || gc.isParallel() || gc.isZ();
+ return gc.isG1() || gc.isParallel() || gc.isConcMarkSweep();
}
static private final OutputAnalyzer runTestWithOptions(String[] extraOptions, String[] testArgs) throws Exception {
@@ -234,7 +273,7 @@ public class TestTrimNative {
/**
* Given JVM output, look for a log line that describes a successful negative trim in the megabyte range
* like this:
- * "[2.053s][debug][gc,trim] Trim native heap (retain size: 5120K): RSS+Swap: 271M->223M (-49112K), 2.834ms"
+ * "Trim native heap (retain size: 5120K): RSS+Swap: 271M->223M (-49112K), 2.834ms"
* (Note: we use the "properXXX" print routines, therefore units can differ)
* Check that the sum of all trim log lines comes to a total RSS reduction in the MB range
* @param output
@@ -244,7 +283,7 @@ public class TestTrimNative {
private final static void parseOutputAndLookForNegativeTrim(OutputAnalyzer output, int minExpected, int maxExpected) {
output.reportDiagnosticSummary();
List<String> lines = output.asLines();
- Pattern pat = Pattern.compile(".*\\[gc,trim\\] Trim native heap.*RSS\\+Swap: (\\d+)([KMB])->(\\d+)([KMB]).*");
+ Pattern pat = Pattern.compile(".*Trim native heap.*RSS\\+Swap: (\\d+)([KMB])->(\\d+)([KMB]).*");
int numTrimsFound = 0;
long rssReductionTotal = 0;
for (String line : lines) {
@@ -270,7 +309,7 @@ public class TestTrimNative {
// This is very fuzzy. We malloced X, free'd X, trimmed, measured the combined effect of all reductions.
// This does not take into effect mallocs or frees that may happen concurrently. But we expect to see *some*
// reduction somewhere. Test with a fudge factor.
- float fudge = 0.8f;
+ float fudge = 0.25f;
long expectedMinimalReduction = (long) (totalAllocationsSize * fudge);
if (rssReductionTotal < expectedMinimalReduction) {
throw new RuntimeException("We did not see the expected RSS reduction in the UL log. Expected (with fudge)" +
@@ -293,8 +332,8 @@ public class TestTrimNative {
// started and shut down properly.
if (usesNativeTrimmer(gc)) {
output.shouldContain("NativeTrimmer started");
- output.shouldContain("NativeTrimmer paused");
- output.shouldContain("NativeTrimmer unpaused");
+ //Only debug version JDK contains this item: output.shouldContain("NativeTrimmer paused");
+ //Only debug version JDK contains this item: output.shouldContain("NativeTrimmer unpaused");
output.shouldContain("NativeTrimmer stopped");
} else {
output.shouldNotContain("NativeTrimmer");
@@ -432,4 +471,4 @@ public class TestTrimNative {
}
-}
\ No newline at end of file
+}
--
2.22.0

View File

@ -0,0 +1,135 @@
diff --git a/jdk/test/java/awt/FontClass/CaptchaTest.java b/jdk/test/java/awt/FontClass/CaptchaTest.java
new file mode 100644
index 000000000..7f2ed1275
--- /dev/null
+++ b/jdk/test/java/awt/FontClass/CaptchaTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2023 Xiaotao NAN. All rights reserved.
+ */
+import java.awt.Graphics2D;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.Random;
+
+/*
+ * @test
+ * @summary Check if the captcha can be successfully generated
+ * @author XiaotaoNAN
+ * I8ME2N(https://gitee.com/openeuler/bishengjdk-8/issues/I8ME2N?from=project-issue)
+ */
+
+public class CaptchaTest {
+
+ /**
+ * Check if the captcha can be successfully generated.
+ * @param n the number of digits int the captcha.
+ * @param fontName the font name.
+ * @throws IOException
+ */
+ public static String captchaTest(int n,String fontName) throws IOException {
+ int width = 100, height = 50;
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = image.createGraphics();
+ g.setColor(Color.LIGHT_GRAY);
+ g.fillRect(0, 0, width, height);
+ String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ Random random = new Random();
+ StringBuilder sbuffer = new StringBuilder();
+ for (int i = 0; i < n; i++) {
+ int index = random.nextInt(chars.length());
+ char c = chars.charAt(index);
+ sbuffer.append(c);
+ g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
+ g.setFont(new Font(fontName, Font.BOLD, 25));
+ g.drawString(Character.toString(c), 20 + i * 15, 25);
+ }
+ image.flush();
+ g.dispose();
+ return sbuffer.toString();
+ }
+
+ public static void main(String[] args) throws IOException {
+ String captcha = captchaTest(4,"Times New Roman");
+ System.out.println(captcha);
+ }
+
+}
diff --git a/jdk/test/java/security/Provider/SunJCEValidator.java b/jdk/test/java/security/Provider/SunJCEValidator.java
index 314abb380..e6b9f18ad 100644
--- a/jdk/test/java/security/Provider/SunJCEValidator.java
+++ b/jdk/test/java/security/Provider/SunJCEValidator.java
@@ -37,10 +37,10 @@
*- @TestCaseType:Function test
*- @RequirementID:AR.SR.IREQ02758058.001.001
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
- *- @Condition:JDK8u302及以后
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异以openJDK8u302为准
- * -#step:比较openJDK8u302 SunJceProvider与此特性修改后的SunJceProvider所提供的service是否一致
- *- @Expect:正常运行
+ *- @Condition:JDK8u302 and later
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302)
+ * -#step:Compare whether the service provided by openJDK8u302 SunJceProvider is consistent with the modified SunJceProvider with this feature
+ *- @Expect:Normal Running
*- @Priority:Level 1
*/
diff --git a/jdk/test/java/security/Provider/SunJSSEValidator.java b/jdk/test/java/security/Provider/SunJSSEValidator.java
index 5817c3b7f..0cf0663a4 100644
--- a/jdk/test/java/security/Provider/SunJSSEValidator.java
+++ b/jdk/test/java/security/Provider/SunJSSEValidator.java
@@ -37,10 +37,10 @@
*- @TestCaseType:Function test
*- @RequirementID:AR.SR.IREQ02758058.001.001
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
- *- @Condition:JDK8u302及以后
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异以openJDK8u302为准
- * -#step:比较openJDK8u302 SunJSSEProvider与此特性修改后的SunJSSEProvider所提供的service是否一致
- *- @Expect:正常运行
+ *- @Condition:JDK8u302 and later
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302)
+ * -#step:Compare whether the service provided by openJDK8u302 SunJSSEProvider is consistent with the modified SunJSSEProvider with this feature
+ *- @Expect:Normal Running
*- @Priority:Level 1
*/
diff --git a/jdk/test/java/security/Provider/SunRsaSignValidator.java b/jdk/test/java/security/Provider/SunRsaSignValidator.java
index 66fb33a44..ddcf6107b 100644
--- a/jdk/test/java/security/Provider/SunRsaSignValidator.java
+++ b/jdk/test/java/security/Provider/SunRsaSignValidator.java
@@ -37,10 +37,10 @@
*- @TestCaseType:Function test
*- @RequirementID:AR.SR.IREQ02758058.001.001
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
- *- @Condition:JDK8u302及以后
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异以openJDK8u302为准
- * -#step:比较openJDK8u302 SunRsaSignProvider与此特性修改后的SunRsaSignProvider所提供的service是否一致
- *- @Expect:正常运行
+ *- @Condition:JDK8u302 and later
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302).
+ * -#step:Compare whether the service provided by openJDK8u302 SunRsaSignProvider is consistent with the modified SunRsaSignProvider with this feature.
+ *- @Expect:Normal Running.
*- @Priority:Level 1
*/
diff --git a/jdk/test/java/security/Provider/SunValidator.java b/jdk/test/java/security/Provider/SunValidator.java
index 3f4b81222..b1fc38303 100644
--- a/jdk/test/java/security/Provider/SunValidator.java
+++ b/jdk/test/java/security/Provider/SunValidator.java
@@ -37,10 +37,10 @@
*- @TestCaseType:Function test
*- @RequirementID:AR.SR.IREQ02758058.001.001
*- @RequirementName: java.security.Provider.getService() is synchronized and became scalability bottleneck
- *- @Condition:JDK8u302及以后
- *- @Brief:测试相应provider更改底层架构以后所提供的service是否与原先有差异以openJDK8u302为准
- * -#step:比较openJDK8u302 SunProvider与此特性修改后的SunProvider所提供的service是否一致
- *- @Expect:正常运行
+ *- @Condition:JDK8u302 and later
+ *- @Brief:Check whether the service provided by the corresponding provider after changing the underlying architecture is different from the original one (subject to openJDK8u302).
+ * -#step:Compare whether the service provided by openJDK8u302 SunProvider is consistent with the modified SunProvider with this feature.
+ *- @Expect:Normal Running.
*- @Priority:Level 1
*/

17639
Add-Problemlist.patch Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More