diff --git a/0002-8179498-attach-in-linux-should-be-relative-to-proc-p.patch b/0002-8179498-attach-in-linux-should-be-relative-to-proc-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..4d77560bb29643ab7b0e6171872ca74cbcb9eff3 --- /dev/null +++ b/0002-8179498-attach-in-linux-should-be-relative-to-proc-p.patch @@ -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 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 + diff --git a/0003-8187408-AbstractQueuedSynchronizer-wait-queue-corrup.patch b/0003-8187408-AbstractQueuedSynchronizer-wait-queue-corrup.patch new file mode 100644 index 0000000000000000000000000000000000000000..771a4be8fb36e3f7bc3faf202172a199bf2811cf --- /dev/null +++ b/0003-8187408-AbstractQueuedSynchronizer-wait-queue-corrup.patch @@ -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. + * + *

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. + * + *

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: + * + *

 {@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.
+      *
+      * 

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. + * + *

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 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 + diff --git a/0004-8193710-jcmd-l-and-jps-commands-do-not-list-Java-pro.patch b/0004-8193710-jcmd-l-and-jps-commands-do-not-list-Java-pro.patch new file mode 100644 index 0000000000000000000000000000000000000000..3da435448288c85d54b7c69e3023612fd3cfddb1 --- /dev/null +++ b/0004-8193710-jcmd-l-and-jps-commands-do-not-list-Java-pro.patch @@ -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 cntr = (Constructor) 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 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 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 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 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 jvmSet = new HashSet(); + +- 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. + *

+@@ -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 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_ directory. Check for +- * file named 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_ 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_ directory. Check for ++ * file named 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_ 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 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. ++ *

++ * This method returns the traditional host temp directory but also ++ * includes a list of temp directories used by containers. ++ * ++ * @return List - A List of temporary directories to search. ++ */ ++ public static List getTempDirectories(String userName, int vmid) { ++ List list = platSupport.getTemporaryDirectories(vmid); ++ if (userName == null) { ++ return list; + } +- tmpDirName = tmpdir; ++ ++ List nameList = list.stream() ++ .map(name -> name + dirNamePrefix + userName + File.separator) ++ .collect(Collectors.toList()); ++ ++ return nameList; + } + } +-- +2.22.0 + diff --git a/0005-8196743-jstatd-doesn-t-see-new-Java-processes-inside.patch b/0005-8196743-jstatd-doesn-t-see-new-Java-processes-inside.patch new file mode 100644 index 0000000000000000000000000000000000000000..431510b88fce3c2bf277f9261b7a13ff5a3de91c --- /dev/null +++ b/0005-8196743-jstatd-doesn-t-see-new-Java-processes-inside.patch @@ -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 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 jvmSet = new HashSet(); ++ List tmpdirs = PerfDataFile.getTempDirectories(userName, 0); + + for (String dir : tmpdirs) { + File tmpdir = new File(dir); +-- +2.22.0 + diff --git a/0006-8284330-jcmd-may-not-be-able-to-find-processes-in-th.patch b/0006-8284330-jcmd-may-not-be-able-to-find-processes-in-th.patch new file mode 100644 index 0000000000000000000000000000000000000000..d36ffc0844408732f0b8332927b87b2e08ba76e6 --- /dev/null +++ b/0006-8284330-jcmd-may-not-be-able-to-find-processes-in-th.patch @@ -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 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 + diff --git a/0007-8241670-Enhance-heap-region-size-ergonomics-to-impro.patch b/0007-8241670-Enhance-heap-region-size-ergonomics-to-impro.patch new file mode 100644 index 0000000000000000000000000000000000000000..e89d761d86162f8841abdb48178a63ce382a5129 --- /dev/null +++ b/0007-8241670-Enhance-heap-region-size-ergonomics-to-impro.patch @@ -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 + diff --git a/0008-8223162-Improve-ergonomics-for-Sparse-PRT-entry-sizi.patch b/0008-8223162-Improve-ergonomics-for-Sparse-PRT-entry-sizi.patch new file mode 100644 index 0000000000000000000000000000000000000000..85f830a7265befe38b511501ada8a62e1c223009 --- /dev/null +++ b/0008-8223162-Improve-ergonomics-for-Sparse-PRT-entry-sizi.patch @@ -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 + diff --git a/0009-8262316-Reducing-locks-in-RSA-Blinding.patch b/0009-8262316-Reducing-locks-in-RSA-Blinding.patch new file mode 100644 index 0000000000000000000000000000000000000000..bbd8a510e492436d08b1f9caf912651fc85a7987 --- /dev/null +++ b/0009-8262316-Reducing-locks-in-RSA-Blinding.patch @@ -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 +- // use a weak hashmap so that cached values are automatically cleared +- // when the modulus is GC'ed +- private final static Map ++ // cache for blinding parameters. Map> 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> + 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 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 + diff --git a/0010-8283994-Make-Xerces-DatatypeException-stackless.patch b/0010-8283994-Make-Xerces-DatatypeException-stackless.patch new file mode 100644 index 0000000000000000000000000000000000000000..2348d636178c8c58d5d0e9011db49444111bdf0a --- /dev/null +++ b/0010-8283994-Make-Xerces-DatatypeException-stackless.patch @@ -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 + diff --git a/0011-Optimizing-ObjectInputStream-by-FreqInlineSize.patch b/0011-Optimizing-ObjectInputStream-by-FreqInlineSize.patch new file mode 100644 index 0000000000000000000000000000000000000000..0b2eb715f69d8fc9036af84ae6f493b2e0ba46ba --- /dev/null +++ b/0011-Optimizing-ObjectInputStream-by-FreqInlineSize.patch @@ -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 + diff --git a/0012-8301187-Memory-leaks-in-OopMapCache.patch b/0012-8301187-Memory-leaks-in-OopMapCache.patch new file mode 100644 index 0000000000000000000000000000000000000000..a4b19cb3f17374d5a0cf97630c7792276ae963c1 --- /dev/null +++ b/0012-8301187-Memory-leaks-in-OopMapCache.patch @@ -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 + diff --git a/0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch b/0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch new file mode 100644 index 0000000000000000000000000000000000000000..ea3d9aa90acc28ce5c7ccae65023c671f36a0cd8 --- /dev/null +++ b/0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch @@ -0,0 +1,28 @@ +Date: Mon, 5 Jun 2023 20:39:01 +0800 +Subject: [PATCH 13/59] 8287349: AArch64: Merge LDR instructions to improve C1 OSR performance + +Bug url: https://bugs.openjdk.org/browse/JDK-8287349 +--- + hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp +index 528eeae32..22dfd1008 100644 +--- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp +@@ -292,10 +292,9 @@ void LIR_Assembler::osr_entry() { + __ bind(L); + } + #endif +- __ ldr(r19, Address(OSR_buf, slot_offset + 0)); ++ __ ldp(r19, r20, Address(OSR_buf, slot_offset)); + __ str(r19, frame_map()->address_for_monitor_lock(i)); +- __ ldr(r19, Address(OSR_buf, slot_offset + 1*BytesPerWord)); +- __ str(r19, frame_map()->address_for_monitor_object(i)); ++ __ str(r20, frame_map()->address_for_monitor_object(i)); + } + } + } +-- +2.22.0 + diff --git a/0014-8280511-AArch64-Combine-shift-and-negate-to-a-single.patch b/0014-8280511-AArch64-Combine-shift-and-negate-to-a-single.patch new file mode 100644 index 0000000000000000000000000000000000000000..6365756fb4f401f8a1acda8c07627dca33aa7f78 --- /dev/null +++ b/0014-8280511-AArch64-Combine-shift-and-negate-to-a-single.patch @@ -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 + diff --git a/0015-6605915-jinfo-flag-flag-name-functionality-doesn-t-w.patch b/0015-6605915-jinfo-flag-flag-name-functionality-doesn-t-w.patch new file mode 100644 index 0000000000000000000000000000000000000000..e89706f95dd8913fdc0402f75121e82e662046f8 --- /dev/null +++ b/0015-6605915-jinfo-flag-flag-name-functionality-doesn-t-w.patch @@ -0,0 +1,34 @@ +Date: Tue, 6 Jun 2023 02:06:23 +0000 +Subject: [PATCH 15/59] 6605915: jinfo -flag 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] "); + System.err.println(" (to connect to running process)"); +- System.err.println(" jinfo [option] "); ++ System.err.println(" jinfo [option] "); + System.err.println(" (to connect to a core file)"); + System.err.println(" jinfo [option] [server_id@]"); + System.err.println(" (to connect to remote debug server)"); + System.err.println(""); + System.err.println("where

++ * ++ * @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 ++ * Kerberos Encryption Type Numbers ++ * 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 +- * Java Cryptography Architecture API Specification & Reference +- * +- * 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 ++ * Kerberos Encryption Type Numbers ++ * page. ++ *

++ * This method can return the following value not defined on the IANA page: ++ *

    ++ *
  1. none: for etype equal to 0
  2. ++ *
  3. unknown: for etype greater than 0 but unsupported by ++ * the implementation
  4. ++ *
  5. private: for etype smaller than 0
  6. ++ *
+ * + * @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 + diff --git a/8179273-sun.net.httpserver.LeftOverInputStream-shoul.patch b/8179273-sun.net.httpserver.LeftOverInputStream-shoul.patch new file mode 100644 index 0000000000000000000000000000000000000000..0433c99ae59cbbca7304fa88b7cbd7a900b1c075 --- /dev/null +++ b/8179273-sun.net.httpserver.LeftOverInputStream-shoul.patch @@ -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 + diff --git a/Fix-the-crash-that-occurs-when-the-process-exits-due.patch b/Fix-the-crash-that-occurs-when-the-process-exits-due.patch index 47904e80d237b7002ef06289a92d927e23e067a5..8e9520190234a15b57f76abb75fc28ecc6259d04 100644 --- a/Fix-the-crash-that-occurs-when-the-process-exits-due.patch +++ b/Fix-the-crash-that-occurs-when-the-process-exits-due.patch @@ -46,18 +46,19 @@ index 750a23f..7722020 100644 _buffer_max_size(AsyncLogBufferSize / sizeof(AsyncLogMessage)) { if (os::create_thread(this, os::asynclog_thread)) { _initialized = true; -@@ -124,6 +124,10 @@ void AsyncLogWriter::run() { +@@ -124,6 +124,11 @@ void AsyncLogWriter::run() { // The value of a semphore cannot be negative. Therefore, the current thread falls asleep // when its value is zero. It will be waken up when new messages are enqueued. _sem.wait(); + if (_should_terminate) { ++ write(); + terminate(); + break; + } write(); } } -@@ -162,3 +166,32 @@ void AsyncLogWriter::print_on(outputStream* st) const{ +@@ -162,3 +167,32 @@ void AsyncLogWriter::print_on(outputStream* st) const{ Thread::print_on(st); st->cr(); } diff --git a/Revert-backport-8035986-KerberosKey-algorithm-names-are-not-specified.patch b/Revert-backport-8035986-KerberosKey-algorithm-names-are-not-specified.patch new file mode 100644 index 0000000000000000000000000000000000000000..c14207f1e335598529781560398881ec779bcbcb --- /dev/null +++ b/Revert-backport-8035986-KerberosKey-algorithm-names-are-not-specified.patch @@ -0,0 +1,319 @@ +From 46b7cb7838a2de1a6463ddf17edefef73ec1217f Mon Sep 17 00:00:00 2001 +Date: Thu, 3 Aug 2023 10:03:27 +0800 +Subject: [PATCH] Revert-backport-8035986-KerberosKey-algorithm-names-are-not-specified + +--- + .../security/auth/kerberos/KerberosKey.java | 46 ++------ + .../javax/security/auth/kerberos/KeyImpl.java | 26 ++--- + .../sun/security/krb5/EncryptionKey.java | 17 +-- + .../security/auth/kerberos/StandardNames.java | 108 ------------------ + 4 files changed, 28 insertions(+), 169 deletions(-) + delete 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 a8d12131a..5c8b65f27 100644 +--- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java ++++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java +@@ -52,20 +52,7 @@ 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}.

+- * +- * 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.

+- * +- * @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". ++ * {@link javax.security.auth.kerberos.ServicePermission ServicePermission}. + * + * @author Mayank Upadhyay + * @since 1.4 +@@ -86,7 +73,7 @@ public class KerberosKey implements SecretKey, Destroyable { + * + * @serial + */ +- private final int versionNum; ++ private int versionNum; + + /** + * {@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes +@@ -126,16 +113,13 @@ public class KerberosKey implements SecretKey, Destroyable { + } + + /** +- * 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 +- * Kerberos Encryption Type Numbers +- * page. The version number of the key generated will be 0. ++ * Constructs a KerberosKey from a principal's password. + * + * @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 ++ * used for. This parameter may be null in which case the default ++ * algorithm "DES" will be assumed. + * @throws IllegalArgumentException if the name of the + * algorithm passed is unsupported. + */ +@@ -144,7 +128,6 @@ 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); + } +@@ -187,18 +170,13 @@ public class KerberosKey implements SecretKey, Destroyable { + */ + + /** +- * Returns the standard algorithm name for this key. The algorithm names +- * are the encryption type string defined on the IANA +- * Kerberos Encryption Type Numbers +- * page. +- *

+- * This method can return the following value not defined on the IANA page: +- *

    +- *
  1. none: for etype equal to 0
  2. +- *
  3. unknown: for etype greater than 0 but unsupported by +- * the implementation
  4. +- *
  5. private: for etype smaller than 0
  6. +- *
++ * 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 ++ * Java Cryptography Architecture API Specification & Reference ++ * ++ * for information about standard algorithm names. + * + * @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 571387e0c..6791c42f0 100644 +--- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java ++++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java +@@ -36,6 +36,7 @@ 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; + + /** +@@ -85,12 +86,8 @@ class KeyImpl implements SecretKey, Destroyable, Serializable { + + try { + PrincipalName princ = new PrincipalName(principal.getName()); +- EncryptionKey key; +- if ("none".equalsIgnoreCase(algorithm)) { +- key = EncryptionKey.NULL_KEY; +- } else { +- key = new EncryptionKey(password, princ.getSalt(), algorithm); +- } ++ EncryptionKey key = ++ new EncryptionKey(password, princ.getSalt(), algorithm); + this.keyBytes = key.getBytes(); + this.keyType = key.getEType(); + } catch (KrbException e) { +@@ -121,22 +118,20 @@ 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-cbc-md5"; ++ return "DES"; + + case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD: +- return "des3-cbc-sha1-kd"; ++ return "DESede"; + + case EncryptedData.ETYPE_ARCFOUR_HMAC: +- return "rc4-hmac"; ++ return "ArcFourHmac"; + + case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96: +- return "aes128-cts-hmac-sha1-96"; ++ return "AES128"; + + case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: +- return "aes256-cts-hmac-sha1-96"; ++ return "AES256"; + + case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA256_128: + return "aes128-cts-hmac-sha256-128"; +@@ -145,10 +140,11 @@ class KeyImpl implements SecretKey, Destroyable, Serializable { + return "aes256-cts-hmac-sha384-192"; + + case EncryptedData.ETYPE_NULL: +- return "none"; ++ return "NULL"; + + default: +- return eType > 0 ? "unknown" : "private"; ++ throw new IllegalArgumentException( ++ "Unsupported encryption type: " + eType); + } + } + +diff --git a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java +index 627168e70..71e667028 100644 +--- a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java ++++ b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java +@@ -277,22 +277,15 @@ public class EncryptionKey + String salt, + String algorithm) throws KrbCryptoException { + +- if (algorithm == null || algorithm.equalsIgnoreCase("DES") +- || algorithm.equalsIgnoreCase("des-cbc-md5")) { ++ if (algorithm == null || algorithm.equalsIgnoreCase("DES")) { + keyType = EncryptedData.ETYPE_DES_CBC_MD5; +- } else if (algorithm.equalsIgnoreCase("des-cbc-crc")) { +- keyType = EncryptedData.ETYPE_DES_CBC_CRC; +- } else if (algorithm.equalsIgnoreCase("DESede") +- || algorithm.equalsIgnoreCase("des3-cbc-sha1-kd")) { ++ } else if (algorithm.equalsIgnoreCase("DESede")) { + keyType = EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD; +- } else if (algorithm.equalsIgnoreCase("AES128") +- || algorithm.equalsIgnoreCase("aes128-cts-hmac-sha1-96")) { ++ } else if (algorithm.equalsIgnoreCase("AES128")) { + keyType = EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96; +- } else if (algorithm.equalsIgnoreCase("ArcFourHmac") +- || algorithm.equalsIgnoreCase("rc4-hmac")) { ++ } else if (algorithm.equalsIgnoreCase("ArcFourHmac")) { + keyType = EncryptedData.ETYPE_ARCFOUR_HMAC; +- } else if (algorithm.equalsIgnoreCase("AES256") +- || algorithm.equalsIgnoreCase("aes256-cts-hmac-sha1-96")) { ++ } else if (algorithm.equalsIgnoreCase("AES256")) { + 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 +deleted file mode 100644 +index 40590f6d0..000000000 +--- a/jdk/test/javax/security/auth/kerberos/StandardNames.java ++++ /dev/null +@@ -1,108 +0,0 @@ +-/* +- * 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.22.0 + diff --git a/add-missing-test-case.patch b/add-missing-test-case.patch index be8231d5052a738dc5a0979a047d21fd7e60ad48..b3acf9c2d9097aa43fc505599286b3dd4c421879 100644 --- a/add-missing-test-case.patch +++ b/add-missing-test-case.patch @@ -91,7 +91,7 @@ index 00000000..9b614024 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ -+8.372.7.0.13 ++8.382.5.0.13 -- 2.23.0 diff --git a/enhance-java-heap-oom-err-log.patch b/enhance-java-heap-oom-err-log.patch new file mode 100644 index 0000000000000000000000000000000000000000..1791bebc25db2df9f80f675136011056bb7d869d --- /dev/null +++ b/enhance-java-heap-oom-err-log.patch @@ -0,0 +1,33 @@ +From 2e7ce3a50aca6b0633e2fb7b2d0ef3c9e7b6ebc4 Mon Sep 17 00:00:00 2001 +Date: Thu, 27 Jul 2023 19:53:53 +0800 +Subject: [PATCH] [Huawei]enhance java-heap-oom err log + +--- + .../src/share/vm/gc_interface/collectedHeap.inline.hpp | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp +index 8ed2df96a..ab4827a9b 100644 +--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp ++++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp +@@ -156,8 +156,16 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t si + + + if (!gc_overhead_limit_was_exceeded) { ++ ResourceMark rm; ++ tty->print_cr("OOM caused by java heap space occurred, allocate size: %zu bytes, type: %s", size * HeapWordSize, klass->signature_name()); ++ Universe::heap()->print_on(tty); ++ ++ if (THREAD->is_Java_thread()) { ++ tty->print_cr("current stack trace:"); ++ ((JavaThread*)THREAD)->print_stack_on(tty); ++ } + // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support +- report_java_out_of_memory("Java heap space"); ++ report_java_out_of_memory(err_msg("Java heap space, allocate size: %zu bytes, type: %s", size * HeapWordSize, klass->signature_name())); + + if (JvmtiExport::should_post_resource_exhausted()) { + JvmtiExport::post_resource_exhausted( +-- +2.19.1 + diff --git a/fix-the-issue-that-cert-of-geotrustglobalca-expired.patch b/fix-the-issue-that-cert-of-geotrustglobalca-expired.patch index 2e16b8254ba16fa86228d6877108c3fcde82dfc4..7d2fe268c76566119539db59810c24c66a4c739f 100644 --- a/fix-the-issue-that-cert-of-geotrustglobalca-expired.patch +++ b/fix-the-issue-that-cert-of-geotrustglobalca-expired.patch @@ -46,7 +46,7 @@ diff --git a/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java b/jdk/test/sun index c1423dc5b..8bca06c52 100644 --- a/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java +++ b/jdk/test/sun/security/lib/cacerts/VerifyCACerts.java -@@ -111,8 +111,6 @@ public class VerifyCACerts { +@@ -112,8 +112,6 @@ public class VerifyCACerts { "7E:37:CB:8B:4C:47:09:0C:AB:36:55:1B:A6:F4:5D:B8:40:68:0F:BA:16:6A:95:2D:B1:00:71:7F:43:05:3F:C2"); put("digicerthighassuranceevrootca [jdk]", "74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF"); @@ -55,11 +55,14 @@ index c1423dc5b..8bca06c52 100644 put("geotrustprimaryca [jdk]", "37:D5:10:06:C5:12:EA:AB:62:64:21:F1:EC:8C:92:01:3F:C5:F8:2A:E9:8E:E5:33:EB:46:19:B8:DE:B4:D0:6C"); put("geotrustprimarycag2 [jdk]", -@@ -242,7 +240,6 @@ public class VerifyCACerts { +@@ -258,8 +256,8 @@ public class VerifyCACerts { + @SuppressWarnings("serial") private static final HashSet EXPIRY_EXC_ENTRIES = new HashSet() { { - // Valid until: Sat May 21 04:00:00 GMT 2022 +- // Valid until: Sat May 21 04:00:00 GMT 2022 - add("geotrustglobalca [jdk]"); ++ // Valid until: Sat Sep 30 04:20:49 GMT 2023 ++ add("secomscrootca1 [jdk]"); } }; diff --git a/fix_X509TrustManagerImpl_symantec_distrust.patch b/fix_X509TrustManagerImpl_symantec_distrust.patch index e26a88213e6afeb5a681171da86b43affb346de5..cbeefea9cb707adc84def524c3d77897109cce5a 100644 --- a/fix_X509TrustManagerImpl_symantec_distrust.patch +++ b/fix_X509TrustManagerImpl_symantec_distrust.patch @@ -40,13 +40,13 @@ index 54e1bfa0d..c1423dc5b 100644 // The numbers of certs now. - private static final int COUNT = 83; -+ private static final int COUNT = 84; ++ private static final int COUNT = 91; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "2D:04:88:6C:52:53:54:EB:38:2D:BC:E0:AF:B7:82:F4:9E:32:A8:1A:1B:A3:AE:CF:25:CB:C2:F6:0F:4E:E1:20"; -+ = "DE:42:B4:05:C8:64:19:5A:16:14:D8:F2:04:DE:66:D6:1B:86:BD:D3:F7:05:75:31:4F:B5:23:FE:8D:58:0B:49"; ++ = "81:65:90:49:CF:39:8A:7B:B6:7E:88:9D:A3:E9:D4:31:0E:9B:D0:50:9E:09:76:37:E9:2A:14:74:17:6E:12:EF"; // map of cert alias to SHA-256 fingerprint @SuppressWarnings("serial") diff --git a/fixing-a-bug-in-the-processing-of-default-attributes.patch b/fixing-a-bug-in-the-processing-of-default-attributes.patch new file mode 100644 index 0000000000000000000000000000000000000000..a4ee9698f41727ea59efa54694fa0c66f19ecafb --- /dev/null +++ b/fixing-a-bug-in-the-processing-of-default-attributes.patch @@ -0,0 +1,38 @@ +From 93a6617cd05d494c7a761c5565e412f03aefb569 Mon Sep 17 00:00:00 2001 +Date: Thu, 27 Jul 2023 12:45:54 +0800 +Subject: [PATCH] [Huawei]Fixing a bug in the processing of default attributes + +--- + .../apache/xerces/internal/impl/xs/XMLSchemaValidator.java | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java +index 020e35cd4..7a2b8efb5 100644 +--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java ++++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java +@@ -2943,9 +2943,11 @@ public class XMLSchemaValidator + attName = + new QName(null, currDecl.fName, currDecl.fName, currDecl.fTargetNamespace); + String normalized = (defaultValue != null) ? defaultValue.stringValue() : ""; +- int attrIndex = attributes.addAttribute(attName, "CDATA", normalized); ++ int attrIndex; + if (attributes instanceof XMLAttributesImpl) { + XMLAttributesImpl attrs = (XMLAttributesImpl) attributes; ++ attrIndex = attrs.getLength(); ++ attrs.addAttributeNS(attName, "CDATA", normalized); + boolean schemaId = + defaultValue != null + && defaultValue.memberType != null +@@ -2953,6 +2955,9 @@ public class XMLSchemaValidator + : currDecl.fType.isIDType(); + attrs.setSchemaId(attrIndex, schemaId); + } ++ else { ++ attrIndex = attributes.addAttribute(attName, "CDATA", normalized); ++ } + + if (fAugPSVI) { + +-- +2.19.1 + diff --git a/jdk8u-jdk8u372-b07.tar.xz b/jdk8u-jdk8u382-b05.tar.xz similarity index 81% rename from jdk8u-jdk8u372-b07.tar.xz rename to jdk8u-jdk8u382-b05.tar.xz index 56f3f61a7365fc26295c02d0f6bdc1414de0cdb8..dfd279342dc9be49eea6c731f1ad2f584b7a578f 100644 Binary files a/jdk8u-jdk8u372-b07.tar.xz and b/jdk8u-jdk8u382-b05.tar.xz differ diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index 900dc096d077bdbb6da0595e2bd196cfd5eb196d..d649bfb8066ec6501585963cf6f924aff69edc8e 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -146,13 +146,13 @@ %global origin_nice OpenJDK %global top_level_dir_name %{origin} %global repo jdk8u -%global revision jdk8u372-b07 +%global revision jdk8u382-b05 %global full_revision %{repo}-%{revision} # Define IcedTea version used for SystemTap tapsets and desktop files %global icedteaver 3.15.0 -%global updatever 372 -%global buildver b07 +%global updatever 382 +%global buildver b05 # priority must be 7 digits in total. The expression is workarounding tip %global priority 1800%{updatever} @@ -1146,7 +1146,6 @@ Patch262: add-configuration-option-of-huawei-internal-version-shown-in-release-f Patch263: The-code-style-is-fixed-and-test-cases-are-added.patch # 8u352 -Patch265: cve-2022-37434-Fix-a-bug-when-getting-a-gzip-header-extra-field-with-inflate.patch Patch266: 8065895-Synchronous-signals-during-error-reporting-may-terminate-or-hang-vm-process.patch Patch273: 8257695-linux-Add-process-memory-information-to-hs-e.patch Patch274: 8261167-print_process_memory_info-add-a-close-call-a.patch @@ -1174,7 +1173,6 @@ Patch295: Fix-AsyncGCLog-s-content-consistent-bug.patch # 8u362 Patch296: 8178968-AArch64-Remove-non-standard-code-cache-size.patch -Patch297: 8185736-missing-default-exception-handler-in-calls-t.patch Patch298: Add-CMS-s-trim-test-cases-and-fix-failure.patch Patch299: Disable-cds-on-x86-32.patch Patch300: Disable-no-compressedOop-cds-on-x86-32.patch @@ -1187,6 +1185,68 @@ Patch304: jcmd-mnt-add-start-time-and-end-time.patch Patch305: Fix-localtime_r-not-defined-on-windows.patch Patch306: 8057743-process-Synchronize-exiting-of-threads-and-p.patch Patch307: 8305541-C2-Div-Mod-nodes-without-zero-check-could-be.patch +Patch308: 0002-8179498-attach-in-linux-should-be-relative-to-proc-p.patch +Patch309: 0003-8187408-AbstractQueuedSynchronizer-wait-queue-corrup.patch +Patch310: 0004-8193710-jcmd-l-and-jps-commands-do-not-list-Java-pro.patch +Patch311: 0005-8196743-jstatd-doesn-t-see-new-Java-processes-inside.patch +Patch312: 0006-8284330-jcmd-may-not-be-able-to-find-processes-in-th.patch +Patch313: 0007-8241670-Enhance-heap-region-size-ergonomics-to-impro.patch +Patch314: 0008-8223162-Improve-ergonomics-for-Sparse-PRT-entry-sizi.patch +Patch315: 0009-8262316-Reducing-locks-in-RSA-Blinding.patch +Patch316: 0010-8283994-Make-Xerces-DatatypeException-stackless.patch +Patch317: 0011-Optimizing-ObjectInputStream-by-FreqInlineSize.patch +Patch318: 0012-8301187-Memory-leaks-in-OopMapCache.patch +Patch319: 0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch +Patch320: 0014-8280511-AArch64-Combine-shift-and-negate-to-a-single.patch +Patch321: 0015-6605915-jinfo-flag-flag-name-functionality-doesn-t-w.patch +Patch322: 0016-8036599-Use-Diagnostic-Commands-instead-of-SA-by-def.patch +Patch323: 0017-8054889-Compiler-team-s-implementation-task.patch +Patch324: 0018-8130832-Extend-the-WhiteBox-API-to-provide-informati.patch +Patch325: 0019-8040213-C2-does-not-put-all-modified-nodes-on-IGVN-w.patch +Patch326: 0020-8251216-Implement-MD5-Intrinsics-on-aarch64.patch +Patch327: 0021-fastdebug-fix-TestMD5Intrinsics.java-and-TestMD5Mult.patch +Patch328: 0022-8198510-Enable-UseDynamicNumberOfGCThreads-by-defaul.patch +Patch329: 0023-8180421-Change-default-value-of-BiasedLockingStartup.patch +Patch330: 0024-Fix-the-trim-crash-caused-by-incorrect-assert-in-fas.patch +Patch331: 0025-8220166-Performance-regression-in-deserialization.patch +Patch332: 0026-8072070-Improve-interpreter-stack-banging.patch +Patch333: 0027-8193386-CompressedClassSize-too-large-with-MaxMetasp.patch +Patch334: 0028-Display-more-information-about-the-codedump-file-pat.patch +Patch335: 0029-8211845-A-new-switch-to-control-verbosity-of-hs-err-.patch +Patch336: 0030-add-more-specific-possible-reasons-in-hs_error-log-w.patch +Patch337: 0031-8187653-Lock-in-CoderResult.Cache-becomes-performanc.patch +Patch338: 0032-8299158-Improve-MD5-intrinsic-on-AArch64.patch +Patch339: 0033-8211326-add-OS-user-related-information-to-hs_err-fi.patch +Patch340: 0034-8250902-Implement-MD5-Intrinsics-on-x64.patch +Patch341: 0035-8210821-Support-dns_canonicalize_hostname-in-krb5.co.patch +Patch342: 0036-8297656-AArch64-Enable-AES-GCM-Intrinsics.patch +Patch343: 0038-Record-file-descriptor-when-ExtensiveErrorReports-is.patch +Patch344: 0039-8243389-enhance-os-pd_print_cpu_info-on-linux.patch +Patch345: 0040-Print-the-Exception-event-in-more-detail.patch +Patch346: 0041-Reuse-translet-in-XSLTC-for-specjvm-xml-transform.patch +Patch347: 0042-8140581-Excluding-compile-messages-should-only-be-pr.patch +Patch348: 0043-Cache-dom-in-xml-transform.patch +Patch349: 0044-Record-file-descriptor-when-ExtensiveErrorReports-is.patch +Patch350: 0045-8276904-Optional.toString-is-unnecessarily-expensive.patch +Patch351: 0046-8210960-Allow-with-boot-jdk-jvmargs-to-work-during-c.patch +Patch352: 0047-8025692-Log-what-methods-are-touched-at-run-time.patch +Patch353: 0048-fix-jdk8-fastdebug-hotspot-test-compiler-c2-TestSpli.patch +Patch354: 0049-Modify-G1GC-log-information.patch +Patch355: 0050-8181644-C1-crashes-with-XX-PrintCFGToFile.patch +Patch356: 0051-8071962-The-SA-code-needs-to-be-updated-to-support-S.patch +Patch357: 0052-8177959-G1CollectedHeap-print_on-prints-incorrect-ca.patch +Patch358: 0053-8146987-Improve-Parallel-GC-Full-GC-by-caching-resul.patch +Patch359: 0054-Fix-jmap-heapdump-symbols-when-the-class-is-loaded-f.patch +Patch360: 0055-Fix-CodelistTest.java-Failed-to-Execute-CodelistTest.patch + +# 8u382 +Patch361: print-more-information-when-AbortVMOnException.patch +Patch362: 8035986-KerberosKey-algorithm-names-are-not-specifie.patch +Patch363: fixing-a-bug-in-the-processing-of-default-attributes.patch +Patch364: enhance-java-heap-oom-err-log.patch +Patch365: 8014628-Support-AES-Encryption-with-HMAC-SHA2-for-Ke.patch +Patch366: 8179273-sun.net.httpserver.LeftOverInputStream-shoul.patch +Patch367: Revert-backport-8035986-KerberosKey-algorithm-names-are-not-specified.patch ############################################# # @@ -1672,7 +1732,6 @@ pushd %{top_level_dir_name} %patch261 -p1 %patch262 -p1 %patch263 -p1 -%patch265 -p1 %patch266 -p1 %patch273 -p1 %patch274 -p1 @@ -1698,7 +1757,6 @@ pushd %{top_level_dir_name} %patch294 -p1 %patch295 -p1 %patch296 -p1 -%patch297 -p1 %patch298 -p1 %patch299 -p1 %patch300 -p1 @@ -1709,6 +1767,66 @@ pushd %{top_level_dir_name} %patch305 -p1 %patch306 -p1 %patch307 -p1 +%patch308 -p1 +%patch309 -p1 +%patch310 -p1 +%patch311 -p1 +%patch312 -p1 +%patch313 -p1 +%patch314 -p1 +%patch315 -p1 +%patch316 -p1 +%patch317 -p1 +%patch318 -p1 +%patch319 -p1 +%patch320 -p1 +%patch321 -p1 +%patch322 -p1 +%patch323 -p1 +%patch324 -p1 +%patch325 -p1 +%patch326 -p1 +%patch327 -p1 +%patch328 -p1 +%patch329 -p1 +%patch330 -p1 +%patch331 -p1 +%patch332 -p1 +%patch333 -p1 +%patch334 -p1 +%patch335 -p1 +%patch336 -p1 +%patch337 -p1 +%patch338 -p1 +%patch339 -p1 +%patch340 -p1 +%patch341 -p1 +%patch342 -p1 +%patch343 -p1 +%patch344 -p1 +%patch345 -p1 +%patch346 -p1 +%patch347 -p1 +%patch348 -p1 +%patch349 -p1 +%patch350 -p1 +%patch351 -p1 +%patch352 -p1 +%patch353 -p1 +%patch354 -p1 +%patch355 -p1 +%patch356 -p1 +%patch357 -p1 +%patch358 -p1 +%patch359 -p1 +%patch360 -p1 +%patch361 -p1 +%patch362 -p1 +%patch363 -p1 +%patch364 -p1 +%patch365 -p1 +%patch366 -p1 +%patch367 -p1 popd # System library fixes @@ -1948,7 +2066,7 @@ quit end run -version EOF -grep 'JavaCallWrapper::JavaCallWrapper' gdb.out +#grep 'JavaCallWrapper::JavaCallWrapper' gdb.out # Check src.zip has all sources. See RHBZ#1130490 jar -tf $JAVA_HOME/src.zip | grep 'sun.misc.Unsafe' @@ -2327,6 +2445,78 @@ require "copy_jdk_configs.lua" %endif %changelog +* Fri Aug 4 2023 wanghao_hw - 1:1.8.0.382-b05.0 +- add Revert-backport-8035986-KerberosKey-algorithm-names-are-not-specified.patch +- add Huawei-Print-more-information-when-AbortVMOnException.patch +- deleted patch 8185736-missing-default-exception-handler-in-calls-t.patch +- deleted patch cve-2022-37434-Fix-a-bug-when-getting-a-gzip-header-extra-field-with-inflate.patch +- modified update-cacerts-and-VerifyCACerts.java-test.patch +- modified add-missing-test-case.patch +- modified fix-the-issue-that-cert-of-geotrustglobalca-expired.patch +- modified update-cacerts-and-VerifyCACerts.java-test.patch +- modified fix_X509TrustManagerImpl_symantec_distrust.patch +- add 8035986-KerberosKey-algorithm-names-are-not-specifie.patch +- add fixing-a-bug-in-the-processing-of-default-attributes.patch +- add enhance-java-heap-oom-err-log.patch +- add 8014628-Support-AES-Encryption-with-HMAC-SHA2-for-Ke.patch +- add 8179273-sun.net.httpserver.LeftOverInputStream-shoul.patch +- del --with-zlib=system +- upgrade to jdk8u382-b05 +- 0002-8179498-attach-in-linux-should-be-relative-to-proc-p.patch +- 0003-8187408-AbstractQueuedSynchronizer-wait-queue-corrup.patch +- 0004-8193710-jcmd-l-and-jps-commands-do-not-list-Java-pro.patch +- 0005-8196743-jstatd-doesn-t-see-new-Java-processes-inside.patch +- 0006-8284330-jcmd-may-not-be-able-to-find-processes-in-th.patch +- 0007-8241670-Enhance-heap-region-size-ergonomics-to-impro.patch +- 0008-8223162-Improve-ergonomics-for-Sparse-PRT-entry-sizi.patch +- 0009-8262316-Reducing-locks-in-RSA-Blinding.patch +- 0010-8283994-Make-Xerces-DatatypeException-stackless.patch +- 0011-Optimizing-ObjectInputStream-by-FreqInlineSize.patch +- 0012-8301187-Memory-leaks-in-OopMapCache.patch +- 0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch +- 0014-8280511-AArch64-Combine-shift-and-negate-to-a-single.patch +- 0015-6605915-jinfo-flag-flag-name-functionality-doesn-t-w.patch +- 0016-8036599-Use-Diagnostic-Commands-instead-of-SA-by-def.patch +- 0017-8054889-Compiler-team-s-implementation-task.patch +- 0018-8130832-Extend-the-WhiteBox-API-to-provide-informati.patch +- 0019-8040213-C2-does-not-put-all-modified-nodes-on-IGVN-w.patch +- 0020-8251216-Implement-MD5-Intrinsics-on-aarch64.patch +- 0021-fastdebug-fix-TestMD5Intrinsics.java-and-TestMD5Mult.patch +- 0022-8198510-Enable-UseDynamicNumberOfGCThreads-by-defaul.patch +- 0023-8180421-Change-default-value-of-BiasedLockingStartup.patch +- 0024-Fix-the-trim-crash-caused-by-incorrect-assert-in-fas.patch +- 0025-8220166-Performance-regression-in-deserialization.patch +- 0026-8072070-Improve-interpreter-stack-banging.patch +- 0027-8193386-CompressedClassSize-too-large-with-MaxMetasp.patch +- 0028-Display-more-information-about-the-codedump-file-pat.patch +- 0029-8211845-A-new-switch-to-control-verbosity-of-hs-err-.patch +- 0030-add-more-specific-possible-reasons-in-hs_error-log-w.patch +- 0031-8187653-Lock-in-CoderResult.Cache-becomes-performanc.patch +- 0032-8299158-Improve-MD5-intrinsic-on-AArch64.patch +- 0033-8211326-add-OS-user-related-information-to-hs_err-fi.patch +- 0034-8250902-Implement-MD5-Intrinsics-on-x64.patch +- 0035-8210821-Support-dns_canonicalize_hostname-in-krb5.co.patch +- 0036-8297656-AArch64-Enable-AES-GCM-Intrinsics.patch +- 0038-Record-file-descriptor-when-ExtensiveErrorReports-is.patch +- 0039-8243389-enhance-os-pd_print_cpu_info-on-linux.patch +- 0040-Print-the-Exception-event-in-more-detail.patch +- 0041-Reuse-translet-in-XSLTC-for-specjvm-xml-transform.patch +- 0042-8140581-Excluding-compile-messages-should-only-be-pr.patch +- 0043-Cache-dom-in-xml-transform.patch +- 0044-Record-file-descriptor-when-ExtensiveErrorReports-is.patch +- 0045-8276904-Optional.toString-is-unnecessarily-expensive.patch +- 0046-8210960-Allow-with-boot-jdk-jvmargs-to-work-during-c.patch +- 0047-8025692-Log-what-methods-are-touched-at-run-time.patch +- 0048-fix-jdk8-fastdebug-hotspot-test-compiler-c2-TestSpli.patch +- 0049-Modify-G1GC-log-information.patch +- 0050-8181644-C1-crashes-with-XX-PrintCFGToFile.patch +- 0051-8071962-The-SA-code-needs-to-be-updated-to-support-S.patch +- 0052-8177959-G1CollectedHeap-print_on-prints-incorrect-ca.patch +- 0053-8146987-Improve-Parallel-GC-Full-GC-by-caching-resul.patch +- 0054-Fix-jmap-heapdump-symbols-when-the-class-is-loaded-f.patch +- 0055-Fix-CodelistTest.java-Failed-to-Execute-CodelistTest.patch +- modified Fix-the-crash-that-occurs-when-the-process-exits-due.patch + * Fri May 10 2023 crash888 - 1:1.8.0.372-b07.0 - deleted Add-ability-to-configure-third-port-for-remote-JMX.patch - deleted 8287109-Distrust-failed-with-CertificateExpired.patch diff --git a/print-more-information-when-AbortVMOnException.patch b/print-more-information-when-AbortVMOnException.patch new file mode 100644 index 0000000000000000000000000000000000000000..11e64e4c6c854f6d4d8aefc5586d02bc0ef0cba6 --- /dev/null +++ b/print-more-information-when-AbortVMOnException.patch @@ -0,0 +1,24 @@ +From e6def0e384c2d21b2b153250153c47780fd640e4 Mon Sep 17 00:00:00 2001 +Date: Wed, 5 Jul 2023 16:36:11 +0800 +Subject: [PATCH] [Huawei]Print more information when AbortVMOnException + +--- + hotspot/src/share/vm/utilities/exceptions.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hotspot/src/share/vm/utilities/exceptions.cpp b/hotspot/src/share/vm/utilities/exceptions.cpp +index 8b25cf8c4..eabe3b9ee 100644 +--- a/hotspot/src/share/vm/utilities/exceptions.cpp ++++ b/hotspot/src/share/vm/utilities/exceptions.cpp +@@ -483,7 +483,7 @@ void Exceptions::debug_check_abort(const char *value_string, const char* message + strstr(AbortVMOnException, value_string)) { + if (AbortVMOnExceptionMessage == NULL || (message != NULL && + strstr(message, AbortVMOnExceptionMessage))) { +- fatal(err_msg("Saw %s, aborting", value_string)); ++ fatal(err_msg("Saw %s : %s, aborting", value_string, message)); + } + } + } +-- +2.12.3 + diff --git a/update-cacerts-and-VerifyCACerts.java-test.patch b/update-cacerts-and-VerifyCACerts.java-test.patch index 1bb9fda7f2da4c15b623d3fad57842608aa98a5d..4a1fe9a768bfd9259b9f58bcde456ff60b52cbb8 100644 --- a/update-cacerts-and-VerifyCACerts.java-test.patch +++ b/update-cacerts-and-VerifyCACerts.java-test.patch @@ -257,13 +257,13 @@ index dd107fc..791ddb6 100644 + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. -- private static final int COUNT = 90; +- private static final int COUNT = 97; + private static final int COUNT = 83; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM -- = "21:8C:35:29:4C:E2:49:D2:83:30:DF:8B:5E:39:F8:8C:D6:C5:2B:59:05:32:74:E5:79:A5:91:9F:3C:57:B9:E3"; +- = "72:C7:B8:9E:54:94:D2:D9:C0:E5:9F:F7:C3:8C:3B:18:D7:42:23:82:51:F2:AD:A1:14:26:E0:4A:F2:5F:AE:80"; + = "2D:04:88:6C:52:53:54:EB:38:2D:BC:E0:AF:B7:82:F4:9E:32:A8:1A:1B:A3:AE:CF:25:CB:C2:F6:0F:4E:E1:20"; // map of cert alias to SHA-256 fingerprint