Add feature and bug fix for 8u382

This commit is contained in:
DXwangg 2023-09-26 09:10:42 +08:00
parent 8822d34627
commit 5110184ec9
26 changed files with 9112 additions and 96 deletions

View File

@ -8,9 +8,7 @@ Subject: Reuse translet in XSLTC for XML
hotspot/src/share/vm/runtime/arguments.cpp | 2 +
hotspot/src/share/vm/runtime/arguments.hpp | 3 +
.../src/share/vm/utilities/accessFlags.hpp | 1 +
.../transform/TestXmlTransletEnhance.java | 83 +++++++++++++++++++
8 files changed, 144 insertions(+), 3 deletions(-)
create mode 100644 jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java
7 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index d8e99e622..b9fde38dc 100644
@ -182,95 +180,6 @@ index bc56262d1..b20f0f740 100644
void set_has_finalizer() { atomic_set_bits(JVM_ACC_HAS_FINALIZER); }
void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); }
void set_is_cloneable() { atomic_set_bits(JVM_ACC_IS_CLONEABLE); }
diff --git a/jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java b/jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java
new file mode 100644
index 000000000..73b848de8
--- /dev/null
+++ b/jdk/test/javax/xml/jaxp/transform/TestXmlTransletEnhance.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2012-2023. All rights reserved.
+ */
+
+
+/* @test
+ * @summary a test for xml translet enhance
+ * @library /lib/testlibrary
+ * @run main TestXmlTransletEnhance
+ */
+
+import javax.xml.transform.TransformerFactory;
+import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
+import java.lang.reflect.Field;
+import static jdk.testlibrary.Asserts.assertEquals;
+
+public class TestXmlTransletEnhance {
+ static final boolean expectedResult = true;
+
+ public static void main(String[] args) throws InterruptedException {
+
+ Thread thread = new Mythread("BenchmarkThread xml ");
+ thread.start();
+ thread.join();
+ boolean ret = SharedData.getInstance().getResult();
+ assertEquals(ret, expectedResult);
+
+ }
+
+ static class Mythread extends Thread {
+ Mythread(String name){
+ super(name);
+ }
+
+ @Override
+ public void run(){
+
+ try {
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ TransformerFactoryImpl transformer = new TransformerFactoryImpl();
+ Class<?> clazz = transformer.getClass();
+
+ Field generateTransletFiled = clazz.getDeclaredField("_generateTranslet");
+ Field autoTransletFiled = clazz.getDeclaredField("_autoTranslet");
+
+ generateTransletFiled.setAccessible(true);
+ autoTransletFiled.setAccessible(true);
+
+ boolean value1 = (boolean)generateTransletFiled.get(transformer);
+ boolean value2 = (boolean)autoTransletFiled.get(transformer);
+
+ SharedData.getInstance().setResult(value1 && value2);
+
+ } catch (NoSuchFieldException| IllegalAccessException | SecurityException | IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ static class SharedData {
+ private static SharedData instance;
+ private boolean result;
+
+ private SharedData() {
+ }
+
+ public static synchronized SharedData getInstance() {
+ if (instance == null) {
+ instance = new SharedData();
+ }
+ return instance;
+ }
+
+ public synchronized boolean getResult() {
+ return result;
+ }
+
+ public synchronized void setResult(boolean result) {
+ this.result = result;
+ }
+ }
+}
--
2.22.0

View File

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

View File

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

View File

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

View File

@ -0,0 +1,66 @@
From 752494be2626cb819c92269e26f53833b2538160 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 14:46:56 +0800
Subject: Record-the-number-of-processes-to-errlog-file.patch
---
hotspot/src/os/linux/vm/os_linux.cpp | 24 ++++++++++++++++++++++++
hotspot/src/os/linux/vm/os_linux.hpp | 1 +
2 files changed, 25 insertions(+)
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 72839eb5a..a1cc85ca3 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -2256,6 +2256,10 @@ void os::print_os_info(outputStream* st) {
os::Posix::print_load_average(st);
+ if (ExtensiveErrorReports) {
+ os::Linux::print_system_process_count(st);
+ }
+
os::Linux::print_system_memory_info(st);
st->cr();
@@ -2323,6 +2327,26 @@ void os::Linux::print_libversion_info(outputStream* st) {
st->cr();
}
+void os::Linux::print_system_process_count(outputStream* st) {
+ // system process count
+ DIR *dir = opendir("/proc");
+ if (dir == NULL) {
+ return;
+ }
+
+ st->print("system process count:");
+ uint count = 0;
+ struct dirent *ptr;
+ while ((ptr = readdir(dir)) != NULL) {
+ if(ptr->d_type == DT_DIR && isdigit((ptr->d_name)[0])) {
+ count++;
+ }
+ }
+ (void) closedir(dir);
+ st->print("%u", count);
+ st->cr();
+}
+
void os::Linux::print_system_memory_info(outputStream* st) {
st->print("\n/proc/meminfo:\n");
_print_ascii_file("/proc/meminfo", st);
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index a516335d2..19dde2e58 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -124,6 +124,7 @@ class Linux {
static void print_container_info(outputStream* st);
static void print_distro_info(outputStream* st);
static void print_libversion_info(outputStream* st);
+ static void print_system_process_count(outputStream* st);
static void print_proc_sys_info(outputStream* st);
public:
--
2.22.0

View File

@ -0,0 +1,89 @@
From 2fd15967a7974d1d61cc7aa706c82733c572964d Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:14:11 +0800
Subject: The-OverWriteOldestGCLog-option-is-added-to-control
---
hotspot/src/share/vm/runtime/globals.hpp | 3 ++
hotspot/src/share/vm/utilities/ostream.cpp | 45 ++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 4f649bd45..fdd9db149 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -2571,6 +2571,9 @@ class CommandLineFlags {
"GC log file size, requires UseGCLogFileRotation. " \
"Set to 0 to only trigger rotation via jcmd") \
\
+ product(bool, OverWriteOldestGCLog, false, \
+ "Over write the oldest gclog") \
+ \
/* JVMTI heap profiling */ \
\
diagnostic(bool, TraceJVMTIObjectTagging, false, \
diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp
index f4e127145..133b5a7c0 100644
--- a/hotspot/src/share/vm/utilities/ostream.cpp
+++ b/hotspot/src/share/vm/utilities/ostream.cpp
@@ -843,6 +843,48 @@ gcLogFileStream::~gcLogFileStream() {
delete _file_lock;
}
+static uintx next_file_number(const char* filename) {
+ uintx next_num;
+ uintx index;
+ char gclog[JVM_MAXPATHLEN];
+ struct stat st;
+ long oldestTime = LONG_MAX;
+ bool normal_file_exist;
+ bool current_file_exist;
+ for (index = 0; index < NumberOfGCLogFiles; ++index) {
+ // normal gc log file
+ jio_snprintf(gclog, JVM_MAXPATHLEN, "%s.%d", filename, index);
+ normal_file_exist = (os::stat(gclog, &st) == 0);
+ if (normal_file_exist && oldestTime > st.st_mtime) {
+ oldestTime = st.st_mtime;
+ next_num = index;
+ }
+
+ // current gc log file
+ jio_snprintf(gclog, JVM_MAXPATHLEN, "%s.%d" CURRENTAPPX, filename, index);
+ current_file_exist = (os::stat(gclog, &st) == 0);
+ if (current_file_exist && oldestTime > st.st_mtime) {
+ oldestTime = st.st_mtime;
+ next_num = index;
+ }
+
+ // Stop looking if we find an unused file name
+ if (!normal_file_exist && !current_file_exist) {
+ next_num = index;
+ break;
+ }
+ }
+ // remove the existing normal file
+ char exist_file_name[JVM_MAXPATHLEN];
+ jio_snprintf(exist_file_name, JVM_MAXPATHLEN, "%s.%d", filename, next_num);
+ if (access(exist_file_name, F_OK) == 0) {
+ if (remove(exist_file_name) != 0) {
+ warning("Could not delete existing normal file %s\n", exist_file_name);
+ }
+ }
+ return next_num;
+}
+
gcLogFileStream::gcLogFileStream(const char* file_name) : _file_lock(NULL) {
_cur_file_num = 0;
_bytes_written = 0L;
@@ -857,6 +899,9 @@ gcLogFileStream::gcLogFileStream(const char* file_name) : _file_lock(NULL) {
// gc log file rotation
if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
+ if (OverWriteOldestGCLog) {
+ _cur_file_num = next_file_number(_file_name);
+ }
char tempbuf[JVM_MAXPATHLEN];
jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
_file = fopen(tempbuf, "w");
--
2.22.0

View File

@ -0,0 +1,311 @@
From fe0409dd4a7b26a623d2e0ad77be635b20f11d29 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 14:44:51 +0800
Subject: add 0010-8301749-Tracking-malloc-pooled-memory-size
---
hotspot/src/os/linux/vm/mallocInfoDcmd.cpp | 62 +++++++++++++++++++
hotspot/src/os/linux/vm/mallocInfoDcmd.hpp | 51 +++++++++++++++
hotspot/src/os/linux/vm/os_linux.cpp | 10 +++
hotspot/src/os/linux/vm/os_linux.hpp | 4 ++
.../share/vm/services/diagnosticCommand.cpp | 2 +
.../serviceability/dcmd/MallocInfoTest.java | 54 ++++++++++++++++
.../com/oracle/java/testlibrary/Platform.java | 18 +++++-
7 files changed, 199 insertions(+), 2 deletions(-)
create mode 100644 hotspot/src/os/linux/vm/mallocInfoDcmd.cpp
create mode 100644 hotspot/src/os/linux/vm/mallocInfoDcmd.hpp
create mode 100644 hotspot/test/serviceability/dcmd/MallocInfoTest.java
diff --git a/hotspot/src/os/linux/vm/mallocInfoDcmd.cpp b/hotspot/src/os/linux/vm/mallocInfoDcmd.cpp
new file mode 100644
index 000000000..4e50a8e13
--- /dev/null
+++ b/hotspot/src/os/linux/vm/mallocInfoDcmd.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "mallocInfoDcmd.hpp"
+#include "os_linux.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+
+#include <malloc.h>
+
+const char* malloc_info_unavailable = "Error: malloc_info(3) not available.";
+
+void MallocInfoDcmd::execute(DCmdSource source, TRAPS) {
+#ifdef __GLIBC__
+ char* buf;
+ size_t size;
+ FILE* stream = ::open_memstream(&buf, &size);
+ if (stream == NULL) {
+ _output->print_cr("Error: Could not call malloc_info(3)");
+ return;
+ }
+
+ int err = os::Linux::malloc_info(stream);
+ if (err == 0) {
+ fflush(stream);
+ _output->print_raw(buf);
+ _output->cr();
+ } else if (err == -1) {
+ _output->print_cr("Error: %s", strerror(errno));
+ } else if (err == -2) {
+ _output->print_cr("%s", malloc_info_unavailable);
+ } else {
+ ShouldNotReachHere();
+ }
+ ::fclose(stream);
+ ::free(buf);
+#else
+ _output->print_cr(malloc_info_unavailable);
+#endif // __GLIBC__
+}
diff --git a/hotspot/src/os/linux/vm/mallocInfoDcmd.hpp b/hotspot/src/os/linux/vm/mallocInfoDcmd.hpp
new file mode 100644
index 000000000..deb154415
--- /dev/null
+++ b/hotspot/src/os/linux/vm/mallocInfoDcmd.hpp
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef OS_LINUX_MALLOCINFODCMD_HPP
+#define OS_LINUX_MALLOCINFODCMD_HPP
+
+#include "services/diagnosticCommand.hpp"
+
+class outputStream;
+
+class MallocInfoDcmd : public DCmd {
+public:
+ MallocInfoDcmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+ static const char* name() {
+ return "System.native_heap_info";
+ }
+ static const char* description() {
+ return "Attempts to output information regarding native heap usage through malloc_info(3). If unsuccessful outputs \"Error: \" and a reason.";
+ }
+ static const char* impact() {
+ return "Low";
+ }
+ static const JavaPermission permission() {
+ JavaPermission p = { "java.lang.management.ManagementPermission", "monitor", NULL };
+ return p;
+ }
+ void execute(DCmdSource source, TRAPS);
+};
+
+#endif // OS_LINUX_MALLOCINFODCMD_HPP
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index cf3a166aa..72839eb5a 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -177,6 +177,8 @@ typedef struct glibc_mallinfo (*mallinfo_func_t)(void);
typedef struct os::Linux::glibc_mallinfo2 (*mallinfo2_func_t)(void);
static mallinfo_func_t g_mallinfo = NULL;
static mallinfo2_func_t g_mallinfo2 = NULL;
+typedef int (*malloc_info_func_t)(int options, FILE *stream);
+static malloc_info_func_t g_malloc_info = NULL;
#endif // __GLIBC__
static jlong initial_time_count=0;
@@ -5416,6 +5418,7 @@ void os::init(void) {
#ifdef __GLIBC__
g_mallinfo = CAST_TO_FN_PTR(mallinfo_func_t, dlsym(RTLD_DEFAULT, "mallinfo"));
g_mallinfo2 = CAST_TO_FN_PTR(mallinfo2_func_t, dlsym(RTLD_DEFAULT, "mallinfo2"));
+ g_malloc_info = CAST_TO_FN_PTR(malloc_info_func_t, dlsym(RTLD_DEFAULT, "malloc_info"));
#endif // __GLIBC__
// _main_thread points to the thread that created/loaded the JVM.
@@ -7072,6 +7075,13 @@ os::Linux::mallinfo_retval_t os::Linux::get_mallinfo(glibc_mallinfo2* out) {
}
return os::Linux::ok;
}
+
+int os::Linux::malloc_info(FILE* stream) {
+ if (g_malloc_info == NULL) {
+ return -2;
+ }
+ return g_malloc_info(0, stream);
+}
#endif // __GLIBC__
// Trim-native support
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index 39a2b4989..a516335d2 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -488,6 +488,10 @@ public:
// If we only have mallinfo(), values may be 32-bit truncated, which is signaled via
// "ok_but_possibly_wrapped".
static mallinfo_retval_t get_mallinfo(glibc_mallinfo2* out);
+
+ // Calls out to GNU extension malloc_info if available
+ // otherwise does nothing and returns -2.
+ static int malloc_info(FILE* stream);
#endif
static bool isbound_to_all_node() {
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
index 50050a169..416dc77ce 100644
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
@@ -39,6 +39,7 @@
#ifdef LINUX
#include "trimCHeapDCmd.hpp"
+#include "mallocInfoDcmd.hpp"
#endif
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
@@ -79,6 +80,7 @@ void DCmdRegistrant::register_dcmds(){
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TouchedMethodsDCmd>(full_export, true, false));
#ifdef LINUX
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<MallocInfoDcmd>(full_export, true, false));
#endif // LINUX
// Enhanced JMX Agent Support
diff --git a/hotspot/test/serviceability/dcmd/MallocInfoTest.java b/hotspot/test/serviceability/dcmd/MallocInfoTest.java
new file mode 100644
index 000000000..bc8ab3ef4
--- /dev/null
+++ b/hotspot/test/serviceability/dcmd/MallocInfoTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.Test;
+import com.oracle.java.testlibrary.*;
+
+/*
+ * @test
+ * @summary Test of diagnostic command System.native_heap_info
+ * @library /testlibrary
+ * @requires (os.family=="linux")
+ * @modules java.base/jdk.internal.misc
+ * java.compiler
+ * java.management
+ * jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @run testng MallocInfoTest
+ */
+public class MallocInfoTest {
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("System.native_heap_info");
+ if (!Platform.isMusl()) {
+ output.shouldNotContain("Error: ");
+ output.shouldContain("<malloc version=");
+ } else {
+ output.shouldContain("Error: malloc_info(3) not available.");
+ }
+ output.reportDiagnosticSummary();
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java
index 6a1407934..adce2ee35 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java
@@ -26,7 +26,8 @@ package com.oracle.java.testlibrary;
import java.util.regex.Pattern;
import com.oracle.java.testlibrary.Utils;
-
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
public class Platform {
private static final String osName = System.getProperty("os.name");
private static final String dataModel = System.getProperty("sun.arch.data.model");
@@ -98,7 +99,20 @@ public class Platform {
public static String getVMVersion() {
return vmVersion;
}
-
+
+ public static boolean isMusl() {
+ try {
+ ProcessBuilder pb = new ProcessBuilder("ldd", "--version");
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String l = b.readLine();
+ if (l != null && l.contains("musl")) { return true; }
+ } catch(Exception e) {
+ }
+ return false;
+ }
+
// Returns true for sparc and sparcv9.
public static boolean isSparc() {
return isArch("sparc.*");
--
2.22.0

View File

@ -0,0 +1,645 @@
From 1d8f83e9ab4a39f6f76617bbd627eec062ab00c2 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:14:53 +0800
Subject: add 6899049-G1-Clean-up-code-in-ptrQueue.-ch-pp-and-ptrQ
---
.../gc_implementation/g1/dirtyCardQueue.cpp | 65 +++++++++++++------
.../gc_implementation/g1/dirtyCardQueue.hpp | 16 ++---
.../vm/gc_implementation/g1/ptrQueue.cpp | 41 +++++++++---
.../vm/gc_implementation/g1/ptrQueue.hpp | 58 ++++++++---------
.../vm/gc_implementation/g1/satbQueue.cpp | 65 +++++++++----------
.../vm/gc_implementation/g1/satbQueue.hpp | 8 +--
hotspot/test/gc/g1/TestPtrQueueSize.java | 58 +++++++++++++++++
7 files changed, 201 insertions(+), 110 deletions(-)
create mode 100644 hotspot/test/gc/g1/TestPtrQueueSize.java
diff --git a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
index 62555c974..52b0ef0ce 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
@@ -32,6 +32,18 @@
#include "runtime/thread.inline.hpp"
#include "utilities/workgroup.hpp"
+DirtyCardQueue::DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent) :
+ // Dirty card queues are always active, so we create them with their
+ // active field set to true.
+ PtrQueue(qset, permanent, true /* active */)
+{ }
+
+DirtyCardQueue::~DirtyCardQueue() {
+ if (!is_permanent()) {
+ flush();
+ }
+}
+
bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
bool consume,
uint worker_i) {
@@ -40,7 +52,9 @@ bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
res = apply_closure_to_buffer(cl, _buf, _index, _sz,
consume,
worker_i);
- if (res && consume) _index = _sz;
+ if (res && consume) {
+ _index = _sz;
+ }
}
return res;
}
@@ -51,14 +65,18 @@ bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
bool consume,
uint worker_i) {
if (cl == NULL) return true;
- for (size_t i = index; i < sz; i += oopSize) {
- int ind = byte_index_to_index((int)i);
- jbyte* card_ptr = (jbyte*)buf[ind];
+ size_t limit = byte_index_to_index(sz);
+ for (size_t i = byte_index_to_index(index); i < limit; ++i) {
+ jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
if (card_ptr != NULL) {
// Set the entry to null, so we don't do it again (via the test
// above) if we reconsider this buffer.
- if (consume) buf[ind] = NULL;
- if (!cl->do_card_ptr(card_ptr, worker_i)) return false;
+ if (consume) {
+ buf[i] = NULL;
+ }
+ if (!cl->do_card_ptr(card_ptr, worker_i)) {
+ return false;
+ }
}
}
return true;
@@ -71,7 +89,7 @@ bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
PtrQueueSet(notify_when_complete),
_mut_process_closure(NULL),
- _shared_dirty_card_queue(this, true /*perm*/),
+ _shared_dirty_card_queue(this, true /* permanent */),
_free_ids(NULL),
_processed_buffers_mut(0), _processed_buffers_rs_thread(0)
{
@@ -83,13 +101,19 @@ uint DirtyCardQueueSet::num_par_ids() {
return (uint)os::initial_active_processor_count();
}
-void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
+void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
+ Monitor* cbl_mon,
+ Mutex* fl_lock,
int process_completed_threshold,
int max_completed_queue,
- Mutex* lock, PtrQueueSet* fl_owner) {
+ Mutex* lock,
+ DirtyCardQueueSet* fl_owner) {
_mut_process_closure = cl;
- PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
- max_completed_queue, fl_owner);
+ PtrQueueSet::initialize(cbl_mon,
+ fl_lock,
+ process_completed_threshold,
+ max_completed_queue,
+ fl_owner);
set_buffer_size(G1UpdateBufferSize);
_shared_dirty_card_queue.set_lock(lock);
_free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
@@ -103,7 +127,7 @@ void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
bool consume,
uint worker_i) {
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
- for(JavaThread* t = Threads::first(); t; t = t->next()) {
+ for (JavaThread* t = Threads::first(); t; t = t->next()) {
bool b = t->dirty_card_queue().apply_closure(cl, consume);
guarantee(b, "Should not be interrupted.");
}
@@ -160,8 +184,7 @@ bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
}
-BufferNode*
-DirtyCardQueueSet::get_completed_buffer(int stop_at) {
+BufferNode* DirtyCardQueueSet::get_completed_buffer(int stop_at) {
BufferNode* nd = NULL;
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
@@ -178,12 +201,11 @@ DirtyCardQueueSet::get_completed_buffer(int stop_at) {
_n_completed_buffers--;
assert(_n_completed_buffers >= 0, "Invariant");
}
- debug_only(assert_completed_buffer_list_len_correct_locked());
+ DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
return nd;
}
-bool DirtyCardQueueSet::
-apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl,
+bool DirtyCardQueueSet::apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl,
uint worker_i,
BufferNode* nd) {
if (nd != NULL) {
@@ -259,7 +281,7 @@ void DirtyCardQueueSet::clear() {
}
_n_completed_buffers = 0;
_completed_buffers_tail = NULL;
- debug_only(assert_completed_buffer_list_len_correct_locked());
+ DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
}
while (buffers_to_delete != NULL) {
BufferNode* nd = buffers_to_delete;
@@ -291,10 +313,11 @@ void DirtyCardQueueSet::concatenate_logs() {
for (JavaThread* t = Threads::first(); t; t = t->next()) {
DirtyCardQueue& dcq = t->dirty_card_queue();
if (dcq.size() != 0) {
- void **buf = t->dirty_card_queue().get_buf();
+ void **buf = dcq.get_buf();
// We must NULL out the unused entries, then enqueue.
- for (size_t i = 0; i < t->dirty_card_queue().get_index(); i += oopSize) {
- buf[PtrQueue::byte_index_to_index((int)i)] = NULL;
+ size_t limit = dcq.byte_index_to_index(dcq.get_index());
+ for (size_t i = 0; i < limit; ++i) {
+ buf[i] = NULL;
}
enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
dcq.reinitialize();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
index 986c0ea3c..250145937 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
@@ -29,6 +29,7 @@
#include "memory/allocation.hpp"
class FreeIdSet;
+class DirtyCardQueueSet;
// A closure class for processing card table entries. Note that we don't
// require these closure objects to be stack-allocated.
@@ -42,14 +43,11 @@ public:
// A ptrQueue whose elements are "oops", pointers to object heads.
class DirtyCardQueue: public PtrQueue {
public:
- DirtyCardQueue(PtrQueueSet* qset_, bool perm = false) :
- // Dirty card queues are always active, so we create them with their
- // active field set to true.
- PtrQueue(qset_, perm, true /* active */) { }
+ DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent = false);
// Flush before destroying; queue may be used to capture pending work while
// doing something else, with auto-flush on completion.
- ~DirtyCardQueue() { if (!is_permanent()) flush(); }
+ ~DirtyCardQueue();
// Process queue entries and release resources.
void flush() { flush_impl(); }
@@ -72,7 +70,6 @@ public:
bool consume = true,
uint worker_i = 0);
void **get_buf() { return _buf;}
- void set_buf(void **buf) {_buf = buf;}
size_t get_index() { return _index;}
void reinitialize() { _buf = 0; _sz = 0; _index = 0;}
};
@@ -101,10 +98,13 @@ class DirtyCardQueueSet: public PtrQueueSet {
public:
DirtyCardQueueSet(bool notify_when_complete = true);
- void initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
+ void initialize(CardTableEntryClosure* cl,
+ Monitor* cbl_mon,
+ Mutex* fl_lock,
int process_completed_threshold,
int max_completed_queue,
- Mutex* lock, PtrQueueSet* fl_owner = NULL);
+ Mutex* lock,
+ DirtyCardQueueSet* fl_owner = NULL);
// The number of parallel ids that can be claimed to allow collector or
// mutator threads to do card-processing work.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
index 2845d5186..c92b081c3 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
@@ -30,24 +30,25 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.inline.hpp"
-PtrQueue::PtrQueue(PtrQueueSet* qset, bool perm, bool active) :
+PtrQueue::PtrQueue(PtrQueueSet* qset, bool permanent, bool active) :
_qset(qset), _buf(NULL), _index(0), _sz(0), _active(active),
- _perm(perm), _lock(NULL)
+ _permanent(permanent), _lock(NULL)
{}
PtrQueue::~PtrQueue() {
- assert(_perm || (_buf == NULL), "queue must be flushed before delete");
+ assert(_permanent || (_buf == NULL), "queue must be flushed before delete");
}
void PtrQueue::flush_impl() {
- if (!_perm && _buf != NULL) {
+ if (!_permanent && _buf != NULL) {
if (_index == _sz) {
// No work to do.
qset()->deallocate_buffer(_buf);
} else {
// We must NULL out the unused entries, then enqueue.
- for (size_t i = 0; i < _index; i += oopSize) {
- _buf[byte_index_to_index((int)i)] = NULL;
+ size_t limit = byte_index_to_index(_index);
+ for (size_t i = 0; i < limit; ++i) {
+ _buf[i] = NULL;
}
qset()->enqueue_complete_buffer(_buf);
}
@@ -66,8 +67,8 @@ void PtrQueue::enqueue_known_active(void* ptr) {
}
assert(_index > 0, "postcondition");
- _index -= oopSize;
- _buf[byte_index_to_index((int)_index)] = ptr;
+ _index -= sizeof(void*);
+ _buf[byte_index_to_index(_index)] = ptr;
assert(0 <= _index && _index <= _sz, "Invariant.");
}
@@ -100,6 +101,26 @@ PtrQueueSet::PtrQueueSet(bool notify_when_complete) :
_fl_owner = this;
}
+PtrQueueSet::~PtrQueueSet() {
+ // There are presently only a couple (derived) instances ever
+ // created, and they are permanent, so no harm currently done by
+ // doing nothing here.
+}
+
+void PtrQueueSet::initialize(Monitor* cbl_mon,
+ Mutex* fl_lock,
+ int process_completed_threshold,
+ int max_completed_queue,
+ PtrQueueSet *fl_owner) {
+ _max_completed_queue = max_completed_queue;
+ _process_completed_threshold = process_completed_threshold;
+ _completed_queue_padding = 0;
+ assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?");
+ _cbl_mon = cbl_mon;
+ _fl_lock = fl_lock;
+ _fl_owner = (fl_owner != NULL) ? fl_owner : this;
+}
+
void** PtrQueueSet::allocate_buffer() {
assert(_sz > 0, "Didn't set a buffer size.");
MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
@@ -234,7 +255,7 @@ void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index) {
if (_notify_when_complete)
_cbl_mon->notify();
}
- debug_only(assert_completed_buffer_list_len_correct_locked());
+ DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
}
int PtrQueueSet::completed_buffers_list_length() {
@@ -259,7 +280,7 @@ void PtrQueueSet::assert_completed_buffer_list_len_correct_locked() {
void PtrQueueSet::set_buffer_size(size_t sz) {
assert(_sz == 0 && sz > 0, "Should be called only once.");
- _sz = sz * oopSize;
+ _sz = sz * sizeof(void*);
}
// Merge lists of buffers. Notify the processing threads.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp
index 27404f0a9..9c969b2ad 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp
@@ -40,44 +40,49 @@ class PtrQueueSet;
class PtrQueue VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
-protected:
+ // Noncopyable - not defined.
+ PtrQueue(const PtrQueue&);
+ PtrQueue& operator=(const PtrQueue&);
+
// The ptr queue set to which this queue belongs.
- PtrQueueSet* _qset;
+ PtrQueueSet* const _qset;
// Whether updates should be logged.
bool _active;
+ // If true, the queue is permanent, and doesn't need to deallocate
+ // its buffer in the destructor (since that obtains a lock which may not
+ // be legally locked by then.
+ const bool _permanent;
+
+protected:
// The buffer.
void** _buf;
- // The index at which an object was last enqueued. Starts at "_sz"
+ // The (byte) index at which an object was last enqueued. Starts at "_sz"
// (indicating an empty buffer) and goes towards zero.
size_t _index;
- // The size of the buffer.
+ // The (byte) size of the buffer.
size_t _sz;
- // If true, the queue is permanent, and doesn't need to deallocate
- // its buffer in the destructor (since that obtains a lock which may not
- // be legally locked by then.
- bool _perm;
-
// If there is a lock associated with this buffer, this is that lock.
Mutex* _lock;
PtrQueueSet* qset() { return _qset; }
- bool is_permanent() const { return _perm; }
+ bool is_permanent() const { return _permanent; }
// Process queue entries and release resources, if not permanent.
void flush_impl();
-public:
// Initialize this queue to contain a null buffer, and be part of the
// given PtrQueueSet.
- PtrQueue(PtrQueueSet* qset, bool perm = false, bool active = false);
+ PtrQueue(PtrQueueSet* qset, bool permanent = false, bool active = false);
// Requires queue flushed or permanent.
~PtrQueue();
+public:
+
// Associate a lock with a ptr queue.
void set_lock(Mutex* lock) { _lock = lock; }
@@ -129,13 +134,9 @@ public:
bool is_active() { return _active; }
- static int byte_index_to_index(int ind) {
- assert((ind % oopSize) == 0, "Invariant.");
- return ind / oopSize;
- }
-
- static int index_to_byte_index(int byte_ind) {
- return byte_ind * oopSize;
+ static size_t byte_index_to_index(size_t ind) {
+ assert((ind % sizeof(void*)) == 0, "Invariant.");
+ return ind / sizeof(void*);
}
// To support compiler.
@@ -246,26 +247,21 @@ protected:
return false;
}
-public:
// Create an empty ptr queue set.
PtrQueueSet(bool notify_when_complete = false);
+ ~PtrQueueSet();
// Because of init-order concerns, we can't pass these as constructor
// arguments.
- void initialize(Monitor* cbl_mon, Mutex* fl_lock,
+ void initialize(Monitor* cbl_mon,
+ Mutex* fl_lock,
int process_completed_threshold,
int max_completed_queue,
- PtrQueueSet *fl_owner = NULL) {
- _max_completed_queue = max_completed_queue;
- _process_completed_threshold = process_completed_threshold;
- _completed_queue_padding = 0;
- assert(cbl_mon != NULL && fl_lock != NULL, "Init order issue?");
- _cbl_mon = cbl_mon;
- _fl_lock = fl_lock;
- _fl_owner = (fl_owner != NULL) ? fl_owner : this;
- }
+ PtrQueueSet *fl_owner = NULL);
+
+public:
- // Return an empty oop array of size _sz (required to be non-zero).
+ // Return an empty array of size _sz (required to be non-zero).
void** allocate_buffer();
// Return an empty buffer to the free list. The "buf" argument is
diff --git a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp
index d423c69ac..8c70b6795 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp
@@ -35,6 +35,15 @@
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+ObjPtrQueue::ObjPtrQueue(SATBMarkQueueSet* qset, bool permanent) :
+ // SATB queues are only active during marking cycles. We create
+ // them with their active field set to false. If a thread is
+ // created during a cycle and its SATB queue needs to be activated
+ // before the thread starts running, we'll need to set its active
+ // field to true. This is done in JavaThread::initialize_queues().
+ PtrQueue(qset, permanent, false /* active */)
+{ }
+
void ObjPtrQueue::flush() {
// Filter now to possibly save work later. If filtering empties the
// buffer then flush_impl can deallocate the buffer.
@@ -101,7 +110,6 @@ inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
void ObjPtrQueue::filter() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
void** buf = _buf;
- size_t sz = _sz;
if (buf == NULL) {
// nothing to do
@@ -109,43 +117,37 @@ void ObjPtrQueue::filter() {
}
// Used for sanity checking at the end of the loop.
- debug_only(size_t entries = 0; size_t retained = 0;)
+ DEBUG_ONLY(size_t entries = 0; size_t retained = 0;)
- size_t i = sz;
- size_t new_index = sz;
+ assert(_index <= _sz, "invariant");
+ void** limit = &buf[byte_index_to_index(_index)];
+ void** src = &buf[byte_index_to_index(_sz)];
+ void** dst = src;
- while (i > _index) {
- assert(i > 0, "we should have at least one more entry to process");
- i -= oopSize;
- debug_only(entries += 1;)
- void** p = &buf[byte_index_to_index((int) i)];
- void* entry = *p;
+ while (limit < src) {
+ DEBUG_ONLY(entries += 1;)
+ --src;
+ void* entry = *src;
// NULL the entry so that unused parts of the buffer contain NULLs
// at the end. If we are going to retain it we will copy it to its
// final place. If we have retained all entries we have visited so
// far, we'll just end up copying it to the same place.
- *p = NULL;
+ *src = NULL;
if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) {
- assert(new_index > 0, "we should not have already filled up the buffer");
- new_index -= oopSize;
- assert(new_index >= i,
- "new_index should never be below i, as we alwaysr compact 'up'");
- void** new_p = &buf[byte_index_to_index((int) new_index)];
- assert(new_p >= p, "the destination location should never be below "
- "the source as we always compact 'up'");
- assert(*new_p == NULL,
- "we should have already cleared the destination location");
- *new_p = entry;
- debug_only(retained += 1;)
+ --dst;
+ assert(*dst == NULL, "filtering destination should be clear");
+ *dst = entry;
+ DEBUG_ONLY(retained += 1;);
}
}
+ size_t new_index = pointer_delta(dst, buf, 1);
#ifdef ASSERT
- size_t entries_calc = (sz - _index) / oopSize;
+ size_t entries_calc = (_sz - _index) / sizeof(void*);
assert(entries == entries_calc, "the number of entries we counted "
"should match the number of entries we calculated");
- size_t retained_calc = (sz - new_index) / oopSize;
+ size_t retained_calc = (_sz - new_index) / sizeof(void*);
assert(retained == retained_calc, "the number of retained entries we counted "
"should match the number of retained entries we calculated");
#endif // ASSERT
@@ -172,11 +174,8 @@ bool ObjPtrQueue::should_enqueue_buffer() {
filter();
- size_t sz = _sz;
- size_t all_entries = sz / oopSize;
- size_t retained_entries = (sz - _index) / oopSize;
- size_t perc = retained_entries * 100 / all_entries;
- bool should_enqueue = perc > (size_t) G1SATBBufferEnqueueingThresholdPercent;
+ size_t percent_used = ((_sz - _index) * 100) / _sz;
+ bool should_enqueue = percent_used > G1SATBBufferEnqueueingThresholdPercent;
return should_enqueue;
}
@@ -187,8 +186,8 @@ void ObjPtrQueue::apply_closure_and_empty(SATBBufferClosure* cl) {
assert(_index % sizeof(void*) == 0, "invariant");
assert(_sz % sizeof(void*) == 0, "invariant");
assert(_index <= _sz, "invariant");
- cl->do_buffer(_buf + byte_index_to_index((int)_index),
- byte_index_to_index((int)(_sz - _index)));
+ cl->do_buffer(_buf + byte_index_to_index(_index),
+ byte_index_to_index(_sz - _index));
_index = _sz;
}
}
@@ -214,7 +213,7 @@ void ObjPtrQueue::print(const char* name,
SATBMarkQueueSet::SATBMarkQueueSet() :
PtrQueueSet(),
- _shared_satb_queue(this, true /*perm*/) { }
+ _shared_satb_queue(this, true /* permanent */) { }
void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
int process_completed_threshold,
@@ -301,7 +300,7 @@ bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl)
// Filtering can result in non-full completed buffers; see
// should_enqueue_buffer.
assert(_sz % sizeof(void*) == 0, "invariant");
- size_t limit = ObjPtrQueue::byte_index_to_index((int)_sz);
+ size_t limit = ObjPtrQueue::byte_index_to_index(_sz);
for (size_t i = 0; i < limit; ++i) {
if (buf[i] != NULL) {
// Found the end of the block of NULLs; process the remainder.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp
index 594895919..6651210a3 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp
@@ -50,13 +50,7 @@ private:
void filter();
public:
- ObjPtrQueue(PtrQueueSet* qset, bool perm = false) :
- // SATB queues are only active during marking cycles. We create
- // them with their active field set to false. If a thread is
- // created during a cycle and its SATB queue needs to be activated
- // before the thread starts running, we'll need to set its active
- // field to true. This is done in JavaThread::initialize_queues().
- PtrQueue(qset, perm, false /* active */) { }
+ ObjPtrQueue(SATBMarkQueueSet* qset, bool permanent = false);
// Process queue entries and free resources.
void flush();
diff --git a/hotspot/test/gc/g1/TestPtrQueueSize.java b/hotspot/test/gc/g1/TestPtrQueueSize.java
new file mode 100644
index 000000000..f46c95bec
--- /dev/null
+++ b/hotspot/test/gc/g1/TestPtrQueueSize.java
@@ -0,0 +1,58 @@
+/*
+ * 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 TestPtrQueueSize.java
+* @key gc
+* @bug 6899049
+* @summary Test size of PtrQueue; used by dirtyCardQueue and satbQueue
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+ public class TestPtrQueueSize {
+ public static void main(String[] args) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+ "-XX:G1SATBBufferSize=716M",
+ "-Xms1024m",
+ "-Xmx4096m",
+ SystemGCTest.class.getName());
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ System.out.println("Output:\n" + output.getOutput());
+
+ output.shouldHaveExitValue(0);
+ }
+
+ static class SystemGCTest {
+ public static void main(String [] args) {
+ for (int i = 0; i < 500; ++i) {
+ byte[] bArray = new byte[1024*1024];
+ }
+ }
+ }
+ }
\ No newline at end of file
--
2.22.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
From b6a24b666a1c7536e35afaba4057cc8eac6fe48f Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:25:03 +0800
Subject: add 8146431-j.u.z.ZipFile.getEntry-throws-AIOOBE
---
jdk/src/share/classes/java/util/zip/ZipFile.java | 2 +-
jdk/test/java/util/zip/ZipFile/TestZipFile.java | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 38b642bdc..36135a9c0 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -1313,7 +1313,7 @@ class ZipFile implements ZipConstants, Closeable {
idx = getEntryNext(idx);
}
/* If not addSlash, or slash is already there, we are done */
- if (!addSlash || name[name.length - 1] == '/') {
+ if (!addSlash || name.length == 0 || name[name.length - 1] == '/') {
return -1;
}
// Add a slash to the hash code
diff --git a/jdk/test/java/util/zip/ZipFile/TestZipFile.java b/jdk/test/java/util/zip/ZipFile/TestZipFile.java
index 30bae3bb9..773f47558 100644
--- a/jdk/test/java/util/zip/ZipFile/TestZipFile.java
+++ b/jdk/test/java/util/zip/ZipFile/TestZipFile.java
@@ -24,7 +24,7 @@
/*
* @test
- * @bug 8142508
+ * @bug 8142508 8146431
* @summary Tests various ZipFile apis
* @run main/manual TestZipFile
*/
@@ -230,6 +230,13 @@ public class TestZipFile {
}
static void doTest0(Zip zip, ZipFile zf) throws Throwable {
+ // (0) check zero-length entry name, no AIOOBE
+ try {
+ check(zf.getEntry("") == null);;
+ } catch (Throwable t) {
+ unexpected(t);
+ }
+
List<ZipEntry> list = new ArrayList(zip.entries.keySet());
// (1) check entry list, in expected order
if (!check(Arrays.equals(
--
2.22.0

View File

@ -0,0 +1,79 @@
From 40b88d64b144bd1b94b2a887c132ec88b3a9a39d Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:26:13 +0800
Subject: add 8147940-Modify-testcase-this-test-does-not-assume-th
---
...stG1TraceEagerReclaimHumongousObjects.java | 45 +------------------
1 file changed, 1 insertion(+), 44 deletions(-)
diff --git a/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java
index e653554c9..aca54daf6 100644
--- a/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java
+++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -36,36 +36,6 @@ import java.util.LinkedList;
public class TestG1TraceEagerReclaimHumongousObjects {
public static void main(String[] args) throws Exception {
- testGCLogs();
- testHumongousObjectGCLogs();
- }
-
- private static void testGCLogs() throws Exception {
-
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
- "-Xms128M",
- "-Xmx128M",
- "-Xmn16M",
- "-XX:G1HeapRegionSize=1M",
- "-XX:+PrintGC",
- "-XX:+UnlockExperimentalVMOptions",
- "-XX:G1LogLevel=finest",
- "-XX:+G1TraceEagerReclaimHumongousObjects",
- GCTest.class.getName());
-
- OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
- // As G1EagerReclaimHumongousObjects is set(default), below logs should be displayed.
- // And GCTest doesn't have humongous objects, so values should be zero.
- output.shouldContain("[Humongous Reclaim");
- output.shouldContain("[Humongous Total: 0]");
- output.shouldContain("[Humongous Candidate: 0]");
- output.shouldContain("[Humongous Reclaimed: 0]");
-
- output.shouldHaveExitValue(0);
- }
-
- private static void testHumongousObjectGCLogs() throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
"-Xms128M",
"-Xmx128M",
@@ -92,19 +62,6 @@ public class TestG1TraceEagerReclaimHumongousObjects {
output.shouldHaveExitValue(0);
}
- static class GCTest {
- private static byte[] garbage;
-
- public static void main(String [] args) {
- System.out.println("Creating garbage");
- // create 128MB of garbage. This should result in at least one GC
- for (int i = 0; i < 1024; i++) {
- garbage = new byte[128 * 1024];
- }
- System.out.println("Done");
- }
- }
-
static class GCWithHumongousObjectTest {
public static final int M = 1024*1024;
--
2.22.0

View File

@ -0,0 +1,45 @@
From 8e3e20eef3f18d023ffc327a9fae30c34de84773 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:24:45 +0800
Subject: add 8170831-ZipFile-implementation-no-longer-caches-the
---
jdk/src/share/classes/java/util/zip/ZipFile.java | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index b6a6c2a48..38b642bdc 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -342,7 +342,9 @@ class ZipFile implements ZipConstants, Closeable {
ZipFileInputStream in = null;
synchronized (this) {
ensureOpen();
- if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
+ if (Objects.equals(lastEntryName, entry.name)) {
+ pos = lastEntryPos;
+ } else if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
pos = zsrc.getEntryPos(zc.getBytesUTF8(entry.name), false);
} else {
pos = zsrc.getEntryPos(zc.getBytes(entry.name), false);
@@ -533,6 +535,9 @@ class ZipFile implements ZipConstants, Closeable {
Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
}
+ private String lastEntryName;
+ private int lastEntryPos;
+
/* Checks ensureOpen() before invoke this method */
private ZipEntry getZipEntry(String name, int pos) {
byte[] cen = zsrc.cen;
@@ -566,6 +571,8 @@ class ZipFile implements ZipConstants, Closeable {
e.comment = zc.toString(cen, start, clen);
}
}
+ lastEntryName = e.name;
+ lastEntryPos = pos;
return e;
}
--
2.22.0

View File

@ -0,0 +1,100 @@
From 64123e7422fb9441c8999aaa1ddfdf639295fea1 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:26:33 +0800
Subject: add 8191924-Adjust-DelegatingClassLoader-s-metadata-spac
---
hotspot/src/share/vm/memory/metaspace.cpp | 31 ++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index 07259e649..d65a81267 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -1206,7 +1206,10 @@ class SpaceManager : public CHeapObj<mtClass> {
Mutex* const _lock;
// Type of metadata allocated.
- Metaspace::MetadataType _mdtype;
+ const Metaspace::MetadataType _mdtype;
+
+ // Type of metaspace
+ const Metaspace::MetaspaceType _space_type;
// List of chunks in use by this SpaceManager. Allocations
// are done from the current chunk. The list is used for deallocating
@@ -1218,6 +1221,10 @@ class SpaceManager : public CHeapObj<mtClass> {
// If class space manager, small chunks are unlimited
static uint const _small_chunk_limit;
+ // Maximum number of specialize chunks to allocate for anonymous and delegating
+ // metadata space to a SpaceManager
+ static uint const _anon_and_delegating_metadata_specialize_chunk_limit;
+
// Sum of all space in allocated chunks
size_t _allocated_blocks_words;
@@ -1270,6 +1277,7 @@ class SpaceManager : public CHeapObj<mtClass> {
public:
SpaceManager(Metaspace::MetadataType mdtype,
+ Metaspace::MetaspaceType space_type,
Mutex* lock);
~SpaceManager();
@@ -1385,6 +1393,7 @@ class SpaceManager : public CHeapObj<mtClass> {
};
uint const SpaceManager::_small_chunk_limit = 4;
+uint const SpaceManager::_anon_and_delegating_metadata_specialize_chunk_limit = 4;
const char* SpaceManager::_expand_lock_name =
"SpaceManager chunk allocation lock";
@@ -3409,6 +3418,20 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) {
// once a medium chunk has been allocated, no more small
// chunks will be allocated.
size_t chunk_word_size;
+
+ // Special case for anonymous metadata space.
+ // Anonymous metadata space is usually small, with majority within 1K - 2K range and
+ // rarely about 4K (64-bits JVM).
+ // Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation
+ // from SpecializeChunk up to _anon_or_delegating_metadata_specialize_chunk_limit (4)
+ // reduces space waste from 60+% to around 30%.
+ if ((_space_type == Metaspace::AnonymousMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) &&
+ _mdtype == Metaspace::NonClassType &&
+ sum_count_in_chunks_in_use(SpecializedIndex) < _anon_and_delegating_metadata_specialize_chunk_limit &&
+ word_size + Metachunk::overhead() <= SpecializedChunk) {
+ return SpecializedChunk;
+ }
+
if (chunks_in_use(MediumIndex) == NULL &&
sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
chunk_word_size = (size_t) small_chunk_size();
@@ -3517,8 +3540,10 @@ void SpaceManager::print_on(outputStream* st) const {
}
SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
+ Metaspace::MetaspaceType space_type,
Mutex* lock) :
_mdtype(mdtype),
+ _space_type(space_type),
_allocated_blocks_words(0),
_allocated_chunks_words(0),
_allocated_chunks_count(0),
@@ -4926,11 +4951,11 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
verify_global_initialization();
// Allocate SpaceManager for metadata objects.
- _vsm = new SpaceManager(NonClassType, lock);
+ _vsm = new SpaceManager(NonClassType, type, lock);
if (using_class_space()) {
// Allocate SpaceManager for classes.
- _class_vsm = new SpaceManager(ClassType, lock);
+ _class_vsm = new SpaceManager(ClassType, type, lock);
} else {
_class_vsm = NULL;
}
--
2.22.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,274 @@
From 131462b71b86d97bd7dadf7a099d4395d9057423 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:16:36 +0800
Subject: add 8226530-ZipFile-reads-wrong-entry-size-from-ZIP64-en
---
.../share/classes/java/util/zip/ZipEntry.java | 41 +++--
.../share/classes/java/util/zip/ZipFile.java | 2 +-
.../classes/java/util/zip/ZipInputStream.java | 4 +-
.../java/util/zip/ZipFile/Zip64SizeTest.java | 147 ++++++++++++++++++
4 files changed, 179 insertions(+), 15 deletions(-)
create mode 100644 jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java
diff --git a/jdk/src/share/classes/java/util/zip/ZipEntry.java b/jdk/src/share/classes/java/util/zip/ZipEntry.java
index aa93bcb36..4a15428ac 100644
--- a/jdk/src/share/classes/java/util/zip/ZipEntry.java
+++ b/jdk/src/share/classes/java/util/zip/ZipEntry.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -440,7 +440,7 @@ class ZipEntry implements ZipConstants, Cloneable {
* @see #getExtra()
*/
public void setExtra(byte[] extra) {
- setExtra0(extra, false);
+ setExtra0(extra, false, true);
}
/**
@@ -450,8 +450,11 @@ class ZipEntry implements ZipConstants, Cloneable {
* the extra field data bytes
* @param doZIP64
* if true, set size and csize from ZIP64 fields if present
+ * @param isLOC
+ * true if setting the extra field for a LOC, false if for
+ * a CEN
*/
- void setExtra0(byte[] extra, boolean doZIP64) {
+ void setExtra0(byte[] extra, boolean doZIP64, boolean isLOC) {
if (extra != null) {
if (extra.length > 0xFFFF) {
throw new IllegalArgumentException("invalid extra field length");
@@ -468,15 +471,29 @@ class ZipEntry implements ZipConstants, Cloneable {
switch (tag) {
case EXTID_ZIP64:
if (doZIP64) {
- // LOC extra zip64 entry MUST include BOTH original
- // and compressed file size fields.
- // If invalid zip64 extra fields, simply skip. Even
- // it's rare, it's possible the entry size happens to
- // be the magic value and it "accidently" has some
- // bytes in extra match the id.
- if (sz >= 16) {
- size = get64(extra, off);
- csize = get64(extra, off + 8);
+ if (isLOC) {
+ // LOC extra zip64 entry MUST include BOTH original
+ // and compressed file size fields.
+ // If invalid zip64 extra fields, simply skip. Even
+ // it's rare, it's possible the entry size happens to
+ // be the magic value and it "accidently" has some
+ // bytes in extra match the id.
+ if (sz >= 16) {
+ size = get64(extra, off);
+ csize = get64(extra, off + 8);
+ }
+ } else {
+ // CEN extra zip64
+ if (size == ZIP64_MAGICVAL) {
+ if (off + 8 > len) // invalid zip64 extra
+ break; // fields, just skip
+ size = get64(extra, off);
+ }
+ if (csize == ZIP64_MAGICVAL) {
+ if (off + 16 > len) // invalid zip64 extra
+ break; // fields, just skip
+ csize = get64(extra, off + 8);
+ }
}
}
break;
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 5d9b0de97..9e854e84d 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -556,7 +556,7 @@ class ZipFile implements ZipConstants, Closeable {
e.method = CENHOW(cen, pos);
if (elen != 0) {
int start = pos + CENHDR + nlen;
- e.setExtra0(Arrays.copyOfRange(cen, start, start + elen), true);
+ e.setExtra0(Arrays.copyOfRange(cen, start, start + elen), true, false);
}
if (clen != 0) {
int start = pos + CENHDR + nlen + elen;
diff --git a/jdk/src/share/classes/java/util/zip/ZipInputStream.java b/jdk/src/share/classes/java/util/zip/ZipInputStream.java
index 98526ef82..398dd70ad 100644
--- a/jdk/src/share/classes/java/util/zip/ZipInputStream.java
+++ b/jdk/src/share/classes/java/util/zip/ZipInputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -320,7 +320,7 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
byte[] extra = new byte[len];
readFully(extra, 0, len);
e.setExtra0(extra,
- e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL);
+ e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL, true);
}
return e;
}
diff --git a/jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java b/jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java
new file mode 100644
index 000000000..be701e480
--- /dev/null
+++ b/jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @test
+ * @bug 8226530
+ * @summary ZIP File System tests that leverage DirectoryStream
+ * @modules java.base
+ * @compile Zip64SizeTest.java
+ * @run testng Zip64SizeTest
+ */
+public class Zip64SizeTest {
+
+ private static final int BUFFER_SIZE = 2048;
+ // ZIP file to create
+ private static final String ZIP_FILE_NAME = "Zip64SizeTest.zip";
+ // File that will be created with a size greater than 0xFFFFFFFF
+ private static final String LARGE_FILE_NAME = "LargeZipEntry.txt";
+ // File that will be created with a size less than 0xFFFFFFFF
+ private static final String SMALL_FILE_NAME = "SmallZipEntry.txt";
+ // List of files to be added to the ZIP file
+ private static final List<String> ZIP_ENTRIES = List.of(LARGE_FILE_NAME,
+ SMALL_FILE_NAME);
+ private static final long LARGE_FILE_SIZE = 5L * 1024L * 1024L * 1024L; // 5GB
+ private static final long SMALL_FILE_SIZE = 0x100000L; // 1024L x 1024L;
+
+ /**
+ * Validate that if the size of a ZIP entry exceeds 0xFFFFFFFF, that the
+ * correct size is returned from the ZIP64 Extended information.
+ * @throws IOException
+ */
+ @Test
+ private static void validateZipEntrySizes() throws IOException {
+ createFiles();
+ createZipFile();
+ System.out.println("Validating Zip Entry Sizes");
+ try (ZipFile zip = new ZipFile(ZIP_FILE_NAME)) {
+ ZipEntry ze = zip.getEntry(LARGE_FILE_NAME);
+ System.out.printf("Entry: %s, size= %s%n", ze.getName(), ze.getSize());
+ assertTrue(ze.getSize() == LARGE_FILE_SIZE);
+ ze = zip.getEntry(SMALL_FILE_NAME);
+ System.out.printf("Entry: %s, size= %s%n", ze.getName(), ze.getSize());
+ assertTrue(ze.getSize() == SMALL_FILE_SIZE);
+
+ }
+ }
+
+ /**
+ * Delete the files created for use by the test
+ * @throws IOException if an error occurs deleting the files
+ */
+ private static void deleteFiles() throws IOException {
+ Files.deleteIfExists(Path.of(ZIP_FILE_NAME));
+ Files.deleteIfExists(Path.of(LARGE_FILE_NAME));
+ Files.deleteIfExists(Path.of(SMALL_FILE_NAME));
+ }
+
+ /**
+ * Create the ZIP file adding an entry whose size exceeds 0xFFFFFFFF
+ * @throws IOException if an error occurs creating the ZIP File
+ */
+ private static void createZipFile() throws IOException {
+ try (FileOutputStream fos = new FileOutputStream(ZIP_FILE_NAME);
+ ZipOutputStream zos = new ZipOutputStream(fos)) {
+ System.out.printf("Creating Zip file: %s%n", ZIP_FILE_NAME);
+ for (String srcFile : ZIP_ENTRIES) {
+ System.out.printf("...Adding Entry: %s%n", srcFile);
+ File fileToZip = new File(srcFile);
+ try (FileInputStream fis = new FileInputStream(fileToZip)) {
+ ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
+ zipEntry.setSize(fileToZip.length());
+ zos.putNextEntry(zipEntry);
+ byte[] bytes = new byte[BUFFER_SIZE];
+ int length;
+ while ((length = fis.read(bytes)) >= 0) {
+ zos.write(bytes, 0, length);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Create the files that will be added to the ZIP file
+ * @throws IOException if there is a problem creating the files
+ */
+ private static void createFiles() throws IOException {
+ try (RandomAccessFile largeFile = new RandomAccessFile(LARGE_FILE_NAME, "rw");
+ RandomAccessFile smallFile = new RandomAccessFile(SMALL_FILE_NAME, "rw")) {
+ System.out.printf("Creating %s%n", LARGE_FILE_NAME);
+ largeFile.setLength(LARGE_FILE_SIZE);
+ System.out.printf("Creating %s%n", SMALL_FILE_NAME);
+ smallFile.setLength(SMALL_FILE_SIZE);
+ }
+ }
+
+ /**
+ * Make sure the needed test files do not exist prior to executing the test
+ * @throws IOException
+ */
+ @BeforeMethod
+ public void setUp() throws IOException {
+ deleteFiles();
+ }
+
+ /**
+ * Remove the files created for the test
+ * @throws IOException
+ */
+ @AfterMethod
+ public void tearDown() throws IOException {
+ deleteFiles();
+ }
+}
\ No newline at end of file
--
2.22.0

View File

@ -0,0 +1,54 @@
From 6430afa36959aa740f47d64427f06c755ea1549f Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:25:27 +0800
Subject: add 8226530-test-case-fixed
---
jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java b/jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java
index be701e480..c466ffa07 100644
--- a/jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java
+++ b/jdk/test/java/util/zip/ZipFile/Zip64SizeTest.java
@@ -26,7 +26,8 @@ import org.testng.annotations.Test;
import java.io.*;
import java.nio.file.Files;
-import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -52,7 +53,7 @@ public class Zip64SizeTest {
// File that will be created with a size less than 0xFFFFFFFF
private static final String SMALL_FILE_NAME = "SmallZipEntry.txt";
// List of files to be added to the ZIP file
- private static final List<String> ZIP_ENTRIES = List.of(LARGE_FILE_NAME,
+ private static final List<String> ZIP_ENTRIES = Arrays.asList(LARGE_FILE_NAME,
SMALL_FILE_NAME);
private static final long LARGE_FILE_SIZE = 5L * 1024L * 1024L * 1024L; // 5GB
private static final long SMALL_FILE_SIZE = 0x100000L; // 1024L x 1024L;
@@ -83,9 +84,9 @@ public class Zip64SizeTest {
* @throws IOException if an error occurs deleting the files
*/
private static void deleteFiles() throws IOException {
- Files.deleteIfExists(Path.of(ZIP_FILE_NAME));
- Files.deleteIfExists(Path.of(LARGE_FILE_NAME));
- Files.deleteIfExists(Path.of(SMALL_FILE_NAME));
+ Files.deleteIfExists(Paths.get(ZIP_FILE_NAME));
+ Files.deleteIfExists(Paths.get(LARGE_FILE_NAME));
+ Files.deleteIfExists(Paths.get(SMALL_FILE_NAME));
}
/**
@@ -144,4 +145,4 @@ public class Zip64SizeTest {
public void tearDown() throws IOException {
deleteFiles();
}
-}
\ No newline at end of file
+}
--
2.22.0

View File

@ -0,0 +1,23 @@
From 627e452a58f0c8fc5504ec2ccd3de69924ab1484 Mon Sep 17 00:00:00 2001
Date: Fri, 22 Sep 2023 14:45:50 +0800
Subject: add 8227041-runtime-memory-RunUnitTestsConcurrently
---
hotspot/src/share/vm/memory/metaspace.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index d65a81267..0569500c1 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -5432,7 +5432,6 @@ class TestMetaspaceAuxTest : AllStatic {
static void test() {
test_reserved();
test_committed();
- test_virtual_space_list_large_chunk();
}
};
--
2.22.0

View File

@ -0,0 +1,70 @@
From be90711b32cb79822222d31f258ff4e0f45a616c Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:24:07 +0800
Subject: add 8242842-Avoid-reallocating-name-when-checking-for-tr
---
.../share/classes/java/util/zip/ZipFile.java | 25 ++++++++++++-------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 9e854e84d..b6a6c2a48 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -1049,7 +1049,7 @@ class ZipFile implements ZipConstants, Closeable {
return h;
}
- private static final int hash_append(int hash, byte b) {
+ private static final int hashAppend(int hash, byte b) {
return hash * 31 + b;
}
@@ -1267,11 +1267,13 @@ class ZipFile implements ZipConstants, Closeable {
}
int hsh = hashN(name, 0, name.length);
int idx = table[(hsh & 0x7fffffff) % tablelen];
+ boolean appendSlash = false;
/*
* This while loop is an optimization where a double lookup
- * for name and name+/ is being performed. The name char
- * array has enough room at the end to try again with a
- * slash appended if the first table lookup does not succeed.
+ * for name and name+/ is being performed. The name byte
+ * array will be updated with an added slash only if the first
+ * table lookup fails and there is a matching hash value for
+ * name+/.
*/
while(true) {
/*
@@ -1282,6 +1284,11 @@ class ZipFile implements ZipConstants, Closeable {
if (getEntryHash(idx) == hsh) {
// The CEN name must match the specfied one
int pos = getEntryPos(idx);
+ if (appendSlash) {
+ name = Arrays.copyOf(name, name.length + 1);
+ name[name.length - 1] = '/';
+ appendSlash = false;
+ }
if (name.length == CENNAM(cen, pos)) {
boolean matched = true;
int nameoff = pos + CENHDR;
@@ -1302,11 +1309,11 @@ class ZipFile implements ZipConstants, Closeable {
if (!addSlash || name[name.length - 1] == '/') {
return -1;
}
- /* Add slash and try once more */
- name = Arrays.copyOf(name, name.length + 1);
- name[name.length - 1] = '/';
- hsh = hash_append(hsh, (byte)'/');
- //idx = table[hsh % tablelen];
+ // Add a slash to the hash code
+ hsh = hashAppend(hsh, (byte)'/');
+ // If we find a match on the new hash code, we need to append a
+ // slash when comparing
+ appendSlash = true;
idx = table[(hsh & 0x7fffffff) % tablelen];
addSlash = false;
}
--
2.22.0

View File

@ -0,0 +1,28 @@
From 7965b56b3269b8e553ce929a466466990c9d0c07 Mon Sep 17 00:00:00 2001
Date: Fri, 22 Sep 2023 14:45:16 +0800
Subject: add Adapting-IOException-of-Zip-to-ZipException
---
jdk/src/share/classes/java/util/zip/ZipFile.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 36135a9c0..e603e83d3 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -970,7 +970,11 @@ class ZipFile implements ZipConstants, Closeable {
return src;
}
}
- src = new Source(key, toDelete);
+ try {
+ src = new Source(key, toDelete);
+ } catch (IOException exception) {
+ throw new ZipException(exception.getMessage());
+ }
synchronized (files) {
if (files.containsKey(key)) { // someone else put in first
--
2.22.0

View File

@ -0,0 +1,26 @@
From 32657f9ef4e781254fb918adef8802d9998ef083 Mon Sep 17 00:00:00 2001
Date: Fri, 22 Sep 2023 14:44:01 +0800
Subject: add Do-not-collect_class-when-DynamicCDS-dump
---
hotspot/src/share/vm/classfile/dictionary.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp
index 530c3fdfb..79aaa99e5 100644
--- a/hotspot/src/share/vm/classfile/dictionary.cpp
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp
@@ -209,7 +209,9 @@ void Dictionary::remove_classes_in_error_state(void f(Klass*)) {
_current_class_entry = NULL;
}
free_entry(probe);
- f(ik);
+ if (DumpSharedSpaces) {
+ f(ik);
+ }
ResourceMark rm;
tty->print_cr("Preload Warning: Removed error class: %s", ik->external_name());
continue;
--
2.22.0

View File

@ -0,0 +1,153 @@
From c4fd69c76c41b7b6168f1071d50143566f7d269e Mon Sep 17 00:00:00 2001
Date: Fri, 22 Sep 2023 14:48:33 +0800
Subject: [PATCH] add Fix-aarch64-runtime-thread-signal-transfer-bug
---
.../src/cpu/aarch64/vm/vm_version_aarch64.hpp | 7 ++
hotspot/src/os/linux/vm/os_linux.cpp | 3 +
.../linux_aarch64/vm/thread_linux_aarch64.cpp | 69 +++++++++++++++++++
.../linux_aarch64/vm/thread_linux_aarch64.hpp | 2 +
4 files changed, 82 insertions(+), 5 deletions(-)
diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
index 7f3a53262..9dfc3465e 100644
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
@@ -63,6 +63,7 @@ public:
CPU_BROADCOM = 'B',
CPU_CAVIUM = 'C',
CPU_DEC = 'D',
+ CPU_HISILICON = 'H',
CPU_INFINEON = 'I',
CPU_MOTOROLA = 'M',
CPU_NVIDIA = 'N',
@@ -93,6 +94,12 @@ public:
static int cpu_variant() { return _variant; }
static int cpu_revision() { return _revision; }
static int cpu_cpuFeatures() { return _cpuFeatures; }
+ static bool is_hisi_enabled() {
+ if (_cpu == CPU_HISILICON && (_model == 0xd01 || _model == 0xd02)) {
+ return true;
+ }
+ return false;
+ }
static ByteSize dczid_el0_offset() { return byte_offset_of(PsrInfo, dczid_el0); }
static ByteSize ctr_el0_offset() { return byte_offset_of(PsrInfo, ctr_el0); }
static bool is_zva_enabled() {
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 197b5c193..3ed8cde6b 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -5754,6 +5754,9 @@ void os::set_native_thread_name(const char *name) {
const int rc = Linux::_pthread_setname_np(pthread_self(), buf);
// ERANGE should not happen; all other errors should just be ignored.
assert(rc != ERANGE, "pthread_setname_np failed");
+#ifdef AARCH64
+ ((JavaThread*)Thread::current())->os_linux_aarch64_options(name);
+#endif
}
}
diff --git a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp
index 87e42318a..bc4b03561 100644
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/thread.inline.hpp"
+#include "runtime/arguments.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
@@ -39,6 +40,74 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
return pd_get_top_frame(fr_addr, ucontext, isInJava);
}
+inline unsigned int stringHash(const char* str) {
+ unsigned int seed = 13;
+ unsigned int hash = 0;
+ while(*str) {
+ hash = hash * seed + (*str++);
+ }
+
+ return (hash & 0x7fffffff);
+}
+
+void JavaThread::os_linux_aarch64_options(const char *name) {
+ if (name == NULL || strlen(name) < 20) {
+ return;
+ }
+
+ char firstStr[16] ;
+ char secondStr[20];
+ memcpy(firstStr, name, 15);
+ firstStr[15] = '\0';
+
+ if (stringHash(firstStr) != 1216735539) {
+ return;
+ }
+
+ int i = 0;
+ for (int j = 16; (name[j] != '\0') && name[j] != ' ' && i < 20; i++, j++) {
+ secondStr[i] = name[j];
+ }
+ secondStr[i] = '\0';
+
+ if (VM_Version::is_hisi_enabled()) {
+ if (stringHash(firstStr) == 1216735539) {
+#ifdef COMPILER2
+ const static intx tTypeProfileMajorReceiverPercent = TypeProfileMajorReceiverPercent;
+ const static intx tLoopUnrollLimit = LoopUnrollLimit;
+ if (stringHash(secondStr) == 2046673384) {
+ // makes specjvm compiler.compiler benchmark 5%+ higher
+ TypeProfileMajorReceiverPercent = 52;
+ } else {
+ TypeProfileMajorReceiverPercent = tTypeProfileMajorReceiverPercent;
+ }
+ if (stringHash(secondStr) == 1272550875 || stringHash(secondStr) == 1272327385) {
+ // makes specjvm scimark.sor.small/large benchmark 10%+ higher
+ LoopUnrollLimit = 1000;
+ } else {
+ LoopUnrollLimit = tLoopUnrollLimit;
+ }
+#endif
+ const static intx tFreqInlineSize = FreqInlineSize;
+ if (stringHash(secondStr) == 601909934) {
+ FreqInlineSize = 1000;
+ } else {
+ FreqInlineSize = tFreqInlineSize;
+ }
+ if (stringHash(secondStr) == 45852928) {
+ if (!UseFastSerializer) {
+ UseFastSerializer = true;
+ }
+ } else if (UseFastSerializer) {
+ UseFastSerializer = false;
+ }
+ if (stringHash(secondStr) == 21805) {
+ Arguments::set_transletEnhance(true);
+ }
+ }
+ }
+}
+
bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
assert(this->is_Java_thread(), "must be JavaThread");
JavaThread* jt = (JavaThread *)this;
diff --git a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp
index a2f0135c2..251e523df 100644
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp
@@ -66,6 +66,8 @@
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
bool isInJava);
+ void os_linux_aarch64_options(const char *name);
+
bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
private:
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
--
2.22.0

View File

@ -0,0 +1,60 @@
From fccc34c57f171463e871d8beeb4f97a67abc03da Mon Sep 17 00:00:00 2001
Date: Fri, 22 Sep 2023 14:44:32 +0800
Subject: add add-Count-instance-klass-when-loading-from-jsa-file
---
hotspot/src/share/vm/classfile/classLoaderData.cpp | 5 ++++-
hotspot/src/share/vm/oops/instanceKlass.cpp | 1 -
hotspot/src/share/vm/oops/instanceKlass.hpp | 1 +
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp
index 12b7e5036..ba86a0ebc 100644
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp
@@ -64,6 +64,7 @@
#include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
+#include "oops/instanceKlass.hpp"
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
@@ -304,7 +305,9 @@ void ClassLoaderData::add_class(Klass* k) {
k->set_next_link(old_value);
// link the new item into the list
_klasses = k;
-
+ if(k->oop_is_instance()){
+ InstanceKlass::inc_instance_classes();
+ }
if (TraceClassLoaderData && Verbose && k->class_loader_data() != NULL) {
ResourceMark rm;
tty->print_cr("[TraceClassLoaderData] Adding k: " PTR_FORMAT " %s to CLD: "
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 993778270..00aea4377 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -232,7 +232,6 @@ InstanceKlass* InstanceKlass::allocate_instance_klass(
// including classes in the bootstrap (NULL) class loader.
loader_data->add_class(ik);
- Atomic::inc(&_total_instanceKlass_count);
return ik;
}
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 6e36fa4ce..973480341 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -175,6 +175,7 @@ class InstanceKlass: public Klass {
initialization_error // error happened during initialization
};
+ static void inc_instance_classes() { Atomic::inc(&_total_instanceKlass_count); }
static int number_of_instance_classes() { return _total_instanceKlass_count; }
private:
--
2.22.0

View File

@ -0,0 +1,227 @@
From eb4284c06d643ec1204a922ccc06970331055bc4 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:23:38 +0800
Subject: add fix-lock_fd-no-close-and-improve-KAEProvider
---
hotspot/src/share/vm/memory/filemap.cpp | 21 +++++++++++++++++++
hotspot/src/share/vm/memory/filemap.hpp | 2 ++
.../src/share/vm/memory/metaspaceShared.cpp | 4 ++++
hotspot/src/share/vm/prims/unsafe.cpp | 1 +
.../security/openssl/KAESM4Cipher.java | 6 ++++--
.../security/openssl/kae_keyagreement_dh.c | 6 ++++--
.../security/openssl/kae_keyagreement_ecdh.c | 7 ++++---
.../security/openssl/kae_symmetric_cipher.c | 11 ++++++----
8 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp
index 0d217078a..166fe2b80 100644
--- a/hotspot/src/share/vm/memory/filemap.cpp
+++ b/hotspot/src/share/vm/memory/filemap.cpp
@@ -181,6 +181,18 @@ FileMapInfo::~FileMapInfo() {
_file_open = false;
_fd = -1;
}
+
+ if (DumpSharedSpaces && UseAppCDS && AppCDSLockFile != NULL) {
+ // delete appcds.lock
+ if (_lock_file_open) {
+ if (::close(_lock_fd) < 0) {
+ fail_stop("Unable to close the lock file.");
+ }
+ _lock_file_open = false;
+ _lock_fd = -1;
+ }
+ remove(_appcds_file_lock_path);
+ }
}
void FileMapInfo::populate_header(size_t alignment) {
@@ -606,6 +618,8 @@ void FileMapInfo::open_for_write() {
"2. You have the permission.\n 3. Make sure no other process using the same lock file.\n");
fail_stop("Failed to create appcds lock file, the lock path is: %s.", _appcds_file_lock_path);
}
+ _lock_fd = lock_fd;
+ _lock_file_open = true;
tty->print_cr("You are using file lock %s in concurrent mode", AppCDSLockFile);
}
#endif
@@ -772,6 +786,13 @@ void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) {
void FileMapInfo::close() {
if (UseAppCDS && AppCDSLockFile != NULL) {
+ if (_lock_file_open) {
+ if (::close(_lock_fd) < 0) {
+ fail_stop("Unable to close the lock file.");
+ }
+ _lock_file_open = false;
+ _lock_fd = -1;
+ }
// delete appcds.lock
remove(_appcds_file_lock_path);
}
diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp
index debfb5049..f6cf43a64 100644
--- a/hotspot/src/share/vm/memory/filemap.hpp
+++ b/hotspot/src/share/vm/memory/filemap.hpp
@@ -74,6 +74,8 @@ private:
bool _is_mapped;
int _fd;
size_t _file_offset;
+ int _lock_fd;
+ bool _lock_file_open;
private:
static SharedClassPathEntry* _classpath_entry_table;
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp
index e6bd39d85..eea79cc09 100644
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp
@@ -829,6 +829,10 @@ int MetaspaceShared::preload_and_dump(const char * class_list_path,
TempNewSymbol class_name_symbol = SymbolTable::new_permanent_symbol(class_name, THREAD);
guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
+ // If preload_and_dump has anonymous class failed ,pls del this class_name in classlist
+ if (TraceClassLoading) {
+ tty->print_cr("preload_and_dump start: %s", class_name);
+ }
Handle loader = UseAppCDS ? SystemDictionary::java_system_loader() : Handle();
Klass* klass = SystemDictionary::resolve_or_null(class_name_symbol,
loader,
diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp
index fa3e46782..d6c33dd33 100644
--- a/hotspot/src/share/vm/prims/unsafe.cpp
+++ b/hotspot/src/share/vm/prims/unsafe.cpp
@@ -1042,6 +1042,7 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
if (DumpSharedSpaces) {
tty->print_cr("failed: must not create anonymous classes when dumping.");
+ tty->print_cr("Please delete the last class_name prefixed with \"preload_and_dump start\" from -XX:SharedClassListFile to avoid anonymous classes.");
JVM_Halt(0);
}
diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java
index cca619e1a..830f058e3 100644
--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java
+++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java
@@ -356,8 +356,10 @@ abstract class KAESM4Cipher extends KAESymmetricCipherBase {
throw new InvalidAlgorithmParameterException("Wrong IV length: iv is null ");
}
if (mode == Mode.CTR) {
- if (ivBytes.length < 8) {
- throw new InvalidAlgorithmParameterException("Wrong IV length: CTR mode requires IV of at least: 8 bytes.");
+ // For compatibility, SM4 CTR allows 8 < IV < blockSize, the remaining bytes will be filled with 0 in engineInit
+ if (ivBytes.length < 8 || ivBytes.length > blockSize) {
+ throw new InvalidAlgorithmParameterException("Wrong IV length: CTR mode requires IV of at least" +
+ "8 bytes, and no greater than " + blockSize + "bytes");
}
return;
}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c
index d8d2ee7cb..74af15a51 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c
@@ -117,7 +117,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyAgreeme
KAE_ThrowRuntimeException(env, "GetByteArrayFromBigNum failed in nativeComputeKey.");
goto cleanup;
}
- KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyAgreement_nativeGenerateSecret finished!");
+ KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyAgreement_nativeComputeKey finished!");
cleanup:
if (dh != NULL)
@@ -130,8 +130,10 @@ cleanup:
KAE_ReleaseBigNumFromByteArray(p_bn);
if (g_bn != NULL)
KAE_ReleaseBigNumFromByteArray(g_bn);
- if (secret != NULL)
+ if (secret != NULL) {
+ memset(secret, 0, pSizeInByte);
free(secret);
+ }
if (computeKeyRetBn != NULL)
BN_free(computeKeyRetBn);
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c
index 5fc4d68fd..877a915f0 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c
@@ -30,7 +30,7 @@
#include "org_openeuler_security_openssl_KAEECDHKeyAgreement.h"
static void FreeGenerateSecretParam(BIGNUM* s, BIGNUM* wX, BIGNUM* wY,
- EC_POINT* pub, EC_KEY* eckey, EC_GROUP* group, unsigned char* shareKey)
+ EC_POINT* pub, EC_KEY* eckey, EC_GROUP* group, unsigned char* shareKey, int shareKeyLen)
{
KAE_ReleaseBigNumFromByteArray(s);
KAE_ReleaseBigNumFromByteArray(wX);
@@ -45,6 +45,7 @@ static void FreeGenerateSecretParam(BIGNUM* s, BIGNUM* wX, BIGNUM* wY,
EC_GROUP_free(group);
}
if (shareKey != NULL) {
+ memset(shareKey, 0, shareKeyLen);
free(shareKey);
}
}
@@ -106,10 +107,10 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEECDHKeyAgree
goto cleanup;
}
(*env)->SetByteArrayRegion(env, javaBytes, 0, expectSecretLen, (jbyte*)shareKey);
- FreeGenerateSecretParam(s, wX, wY, pub, eckey, group, shareKey);
+ FreeGenerateSecretParam(s, wX, wY, pub, eckey, group, shareKey, expectSecretLen);
return javaBytes;
cleanup:
- FreeGenerateSecretParam(s, wX, wY, pub, eckey, group, shareKey);
+ FreeGenerateSecretParam(s, wX, wY, pub, eckey, group, shareKey, expectSecretLen);
return NULL;
}
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
index 43f6326b2..ec8894f1a 100644
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
@@ -119,13 +119,15 @@ static const EVP_CIPHER* EVPGetAesCipherByName(JNIEnv* env, const char* algo)
}
}
-void FreeMemoryFromInit(JNIEnv* env, jbyteArray iv, jbyte* ivBytes, jbyteArray key, jbyte* keyBytes)
+void FreeMemoryFromInit(JNIEnv* env, jbyteArray iv, jbyte* ivBytes, jbyteArray key, jbyte* keyBytes,
+ int keyLength)
{
if (ivBytes != NULL) {
(*env)->ReleaseByteArrayElements(env, iv, ivBytes, 0);
}
if (keyBytes != NULL) {
- (*env)->ReleaseByteArrayElements(env, key, keyBytes, 0);
+ memset(keyBytes, 0, keyLength);
+ (*env)->ReleaseByteArrayElements(env, key, keyBytes, JNI_ABORT);
}
}
@@ -143,6 +145,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
jbyte* ivBytes = NULL;
const EVP_CIPHER* cipher = NULL;
ENGINE* kaeEngine = NULL;
+ int keyLength = (*env)->GetArrayLength(env, key);
const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0);
if (StartsWith("aes", algo)) {
@@ -180,14 +183,14 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0);
- FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes);
+ FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength);
return (jlong)ctx;
cleanup:
if (ctx != NULL) {
EVP_CIPHER_CTX_free(ctx);
}
- FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes);
+ FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength);
return 0;
}
--
2.22.0

View File

@ -0,0 +1,43 @@
From d0212dc187a9693da07ce2fce0ea0935eebf0457 Mon Sep 17 00:00:00 2001
Date: Fri, 22 Sep 2023 14:46:23 +0800
Subject: add fix-windows-build-Dynamic-CDS-failure
---
hotspot/make/windows/makefiles/vm.make | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make
index 77a56ad54..fd5e5d224 100644
--- a/hotspot/make/windows/makefiles/vm.make
+++ b/hotspot/make/windows/makefiles/vm.make
@@ -149,6 +149,7 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/code
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/interpreter
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/ci
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/classfile
+VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/cds
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/gc_implementation/parallelScavenge
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/gc_implementation/shared
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/gc_implementation/parNew
@@ -234,6 +235,9 @@ arguments.obj: $(WorkSpace)\src\share\vm\runtime\arguments.cpp
{$(COMMONSRC)\share\vm\classfile}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+{$(COMMONSRC)\share\vm\cds}.cpp.obj::
+ $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
{$(COMMONSRC)\share\vm\gc_implementation\parallelScavenge}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
@@ -317,6 +321,9 @@ arguments.obj: $(WorkSpace)\src\share\vm\runtime\arguments.cpp
{$(ALTSRC)\share\vm\classfile}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+{$(ALTSRC)\share\vm\cds}.cpp.obj::
+ $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
{$(ALTSRC)\share\vm\gc_implementation\parallelScavenge}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
--
2.22.0

View File

@ -0,0 +1,306 @@
From b35f73bec878c712e9fed512361b5fa424dc3fda Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:15:17 +0800
Subject: add make-Appcds-jsa-rw-region-deterministic
---
.../share/vm/classfile/classFileParser.hpp | 1 +
.../share/vm/classfile/classLoaderData.hpp | 2 +-
.../src/share/vm/classfile/defaultMethods.cpp | 6 +++-
hotspot/src/share/vm/classfile/dictionary.cpp | 6 +++-
hotspot/src/share/vm/classfile/dictionary.hpp | 2 +-
.../share/vm/classfile/systemDictionary.cpp | 24 ++++++++++++++--
.../share/vm/classfile/systemDictionary.hpp | 2 +-
.../src/share/vm/memory/metaspaceShared.cpp | 28 +++++++++++--------
hotspot/src/share/vm/runtime/mutex.cpp | 2 +-
hotspot/src/share/vm/runtime/os.cpp | 5 +++-
hotspot/src/share/vm/runtime/os.hpp | 2 +-
hotspot/src/share/vm/runtime/synchronizer.cpp | 2 +-
12 files changed, 59 insertions(+), 23 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index 1900f0abf..dda7c92d9 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -42,6 +42,7 @@ class FieldLayoutInfo;
// The bytes describing the class file structure is read from a Stream object
class ClassFileParser VALUE_OBJ_CLASS_SPEC {
+ friend class SystemDictionary;
private:
bool _need_verify;
bool _relax_verify;
diff --git a/hotspot/src/share/vm/classfile/classLoaderData.hpp b/hotspot/src/share/vm/classfile/classLoaderData.hpp
index 7155257ed..0bb2e1000 100644
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp
@@ -211,7 +211,6 @@ class ClassLoaderData : public CHeapObj<mtClass> {
JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
void set_next(ClassLoaderData* next) { _next = next; }
- ClassLoaderData* next() const { return _next; }
ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies);
~ClassLoaderData();
@@ -238,6 +237,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void clear_claimed() { _claimed = 0; }
bool claimed() const { return _claimed == 1; }
bool claim();
+ ClassLoaderData* next() const { return _next; }
bool is_alive(BoolObjectClosure* is_alive_closure) const;
diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp
index 196622aed..0becb35ed 100644
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp
@@ -909,7 +909,11 @@ static void switchover_constant_pool(BytecodeConstantPool* bpool,
if (new_methods->length() > 0) {
ConstantPool* cp = bpool->create_constant_pool(CHECK);
if (cp != klass->constants()) {
- klass->class_loader_data()->add_to_deallocate_list(klass->constants());
+ ClassLoaderData* loader_data = klass->class_loader_data();
+ while (DumpSharedSpaces && loader_data->next() != NULL) {
+ loader_data = loader_data->next();
+ }
+ loader_data->add_to_deallocate_list(klass->constants());
klass->set_constants(cp);
cp->set_pool_holder(klass);
diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp
index d41372ecc..530c3fdfb 100644
--- a/hotspot/src/share/vm/classfile/dictionary.cpp
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp
@@ -196,7 +196,7 @@ void Dictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
_pd_cache_table->roots_oops_do(strong, weak);
}
-void Dictionary::remove_classes_in_error_state() {
+void Dictionary::remove_classes_in_error_state(void f(Klass*)) {
assert(DynamicDumpSharedSpaces || DumpSharedSpaces, "supported only when dumping");
DictionaryEntry* probe = NULL;
for (int index = 0; index < table_size(); index++) {
@@ -209,6 +209,7 @@ void Dictionary::remove_classes_in_error_state() {
_current_class_entry = NULL;
}
free_entry(probe);
+ f(ik);
ResourceMark rm;
tty->print_cr("Preload Warning: Removed error class: %s", ik->external_name());
continue;
@@ -420,6 +421,9 @@ void Dictionary::add_protection_domain(int index, unsigned int hash,
instanceKlassHandle klass,
ClassLoaderData* loader_data, Handle protection_domain,
TRAPS) {
+ if (DumpSharedSpaces) {
+ return;
+ }
Symbol* klass_name = klass->name();
DictionaryEntry* entry = get_entry(index, hash, klass_name, loader_data);
diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp
index 9ed0defb8..8a88fa2e4 100644
--- a/hotspot/src/share/vm/classfile/dictionary.hpp
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp
@@ -103,7 +103,7 @@ public:
void methods_do(void f(Method*));
void unlink(BoolObjectClosure* is_alive);
- void remove_classes_in_error_state();
+ void remove_classes_in_error_state(void f(Klass*));
// Classes loaded by the bootstrap loader are always strongly reachable.
// If we're not doing class unloading, all classes are strongly reachable.
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
index 9089a762d..c8f66e830 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
@@ -1170,6 +1170,26 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
parsed_name,
verify,
THREAD);
+ if (DumpSharedSpaces && k.is_null()) {
+ if (loader_data) {
+ ClassLoaderData* cld = loader_data;
+ while (cld->next() != NULL)
+ cld = cld->next();
+ ConstantPool* cp = parser._cp;
+ if (cp) {
+ cld->add_to_deallocate_list(cp);
+ }
+ Array<Method*>* m = parser._methods;
+ if (m) {
+ for (int i = 0; i < m->length(); i++) {
+ Method* method = m->at(i);
+ if (method != NULL) {
+ cld->add_to_deallocate_list(method);
+ }
+ }
+ }
+ }
+ }
const char* pkg = "java/";
size_t pkglen = strlen(pkg);
if (!HAS_PENDING_EXCEPTION &&
@@ -2036,8 +2056,8 @@ void SystemDictionary::methods_do(void f(Method*)) {
invoke_method_table()->methods_do(f);
}
-void SystemDictionary::remove_classes_in_error_state() {
- dictionary()->remove_classes_in_error_state();
+void SystemDictionary::remove_classes_in_error_state(void f(Klass*)) {
+ dictionary()->remove_classes_in_error_state(f);
}
// ----------------------------------------------------------------------------
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp
index cfc15c20e..e39c1de62 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp
@@ -347,7 +347,7 @@ public:
static bool do_unloading(BoolObjectClosure* is_alive, bool clean_alive = true);
// Used by DumpSharedSpaces only to remove classes that failed verification
- static void remove_classes_in_error_state();
+ static void remove_classes_in_error_state(void f(Klass*));
static int calculate_systemdictionary_size(int loadedclasses);
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp
index b31d0a3fb..e6bd39d85 100644
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp
@@ -216,6 +216,10 @@ static void patch_deallocate_meta_vtables(void** vtbl_list, void* new_vtable_sta
((ConstantPool*)m)->remove_unshareable_info();
*(void**)m = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, m);
}
+ else if (m->is_method()) {
+ ((Method*)m)->remove_unshareable_info();
+ *(void**)m = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, m);
+ }
}
}
}
@@ -442,6 +446,7 @@ public:
_md_vs.initialize(md_rs, SharedMiscDataSize);
_mc_vs.initialize(mc_rs, SharedMiscCodeSize);
_class_promote_order = class_promote_order;
+ _global_klass_objects = new GrowableArray<Klass*>(1000);
}
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
@@ -465,13 +470,6 @@ void VM_PopulateDumpSharedSpace::doit() {
SystemDictionary::invoke_method_table()->number_of_entries() == 0,
"invoke method table is not saved");
- // At this point, many classes have been loaded.
- // Gather systemDictionary classes in a global array and do everything to
- // that so we don't have to walk the SystemDictionary again.
- _global_klass_objects = new GrowableArray<Klass*>(1000);
- Universe::basic_type_classes_do(collect_classes);
- SystemDictionary::classes_do(collect_classes);
-
tty->print_cr("Number of classes %d", _global_klass_objects->length());
{
int num_type_array = 0, num_obj_array = 0, num_inst = 0;
@@ -702,7 +700,7 @@ void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
// record error message, remove error state, and continue to dump jsa file
tty->print_cr("Please remove the unverifiable classes from your class list and try again");
- SystemDictionary::remove_classes_in_error_state();
+ SystemDictionary::remove_classes_in_error_state(collect_classes);
}
// Copy the dependencies from C_HEAP-alloced GrowableArrays to RO-alloced
@@ -785,6 +783,9 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
// Rewrite and link classes
tty->print_cr("Rewriting and linking classes ...");
+ // Create here because link_and_cleanup_shared_classes need the _global_klass_objects
+ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+ VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
// Link any classes which got missed. This would happen if we have loaded classes that
// were not explicitly specified in the classlist. E.g., if an interface implemented by class K
// fails verification, all other interfaces that were not specified in the classlist but
@@ -792,10 +793,13 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
link_and_cleanup_shared_classes(CATCH);
tty->print_cr("Rewriting and linking classes: done");
- // Create and dump the shared spaces. Everything so far is loaded
- // with the null class loader.
- ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
- VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
+ // At this point, many classes have been loaded.
+ // Gather systemDictionary classes in a global array and do everything to
+ // that so we don't have to walk the SystemDictionary again.
+ Universe::basic_type_classes_do(collect_classes);
+ SystemDictionary::classes_do(collect_classes);
+
+ // Dump the shared spaces.
VMThread::execute(&op);
// Since various initialization steps have been undone by this process,
diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp
index 92bd50662..b1159d02e 100644
--- a/hotspot/src/share/vm/runtime/mutex.cpp
+++ b/hotspot/src/share/vm/runtime/mutex.cpp
@@ -276,7 +276,7 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
// Useful for spin loops as the compiler can't optimize it away.
static inline jint MarsagliaXORV (jint x) {
- if (x == 0) x = 1|os::random() ;
+ if (x == 0) x = 1|os::random(DumpSharedSpaces) ;
x ^= x << 6;
x ^= ((unsigned)x) >> 21;
x ^= x << 7 ;
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index 43d66e85e..ff35e8b3a 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -770,7 +770,7 @@ void os::init_random(long initval) {
}
-long os::random() {
+long os::random(bool skip) {
/* standard, well-known linear congruential random generator with
* next_rand = (16807*seed) mod (2**31-1)
* see
@@ -801,6 +801,9 @@ long os::random() {
lo &= m;
++lo;
}
+ if (skip) {
+ return lo;
+ }
return (_rand_seed = lo);
}
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index 988977b17..07beeed8c 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -800,7 +800,7 @@ class os: AllStatic {
static int sigexitnum_pd();
// random number generation
- static long random(); // return 32bit pseudorandom number
+ static long random(bool skip = false); // return 32bit pseudorandom number
static void init_random(long initval); // initialize random sequence
// Structured OS Exception support
diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp
index 8400bff11..e83ecd1d2 100644
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp
@@ -1657,7 +1657,7 @@ void ObjectSynchronizer::deflate_idle_monitors() {
// TODO: Add objectMonitor leak detection.
// Audit/inventory the objectMonitors -- make sure they're all accounted for.
- GVars.stwRandom = os::random() ;
+ GVars.stwRandom = os::random(DumpSharedSpaces) ;
GVars.stwCycle ++ ;
}
--
2.22.0

View File

@ -925,7 +925,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r
Name: java-%{javaver}-%{origin}
Version: %{javaver}.%{updatever}.%{buildver}
Release: 7
Release: 10
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
@ -1254,6 +1254,30 @@ 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
Patch368: 8283441-C2-segmentation-fault-in-ciMethodBlocks-make.patch
Patch369: add-0010-8301749-Tracking-malloc-pooled-memory-size.patch
Patch370: 8213397-Stack-dump-should-show-more-clearly-when-a-t.patch
Patch371: Record-the-number-of-processes-to-errlog-file.patch.patch
Patch372: 8254723-Add-diagnostic-command-to-write-Linux-perf-m.patch
Patch373: The-OverWriteOldestGCLog-option-is-added-to-control.patch
Patch374: add-6899049-G1-Clean-up-code-in-ptrQueue.-ch-pp-and-.patch
Patch375: add-make-Appcds-jsa-rw-region-deterministic.patch
Patch376: add-8142508-To-bring-j.u.z.ZipFile-s-native-implemen.patch
Patch377: add-8198423-Improve-metaspace-chunk-allocation.patch
Patch378: add-8226530-ZipFile-reads-wrong-entry-size-from-ZIP6.patch
Patch379: add-fix-lock_fd-no-close-and-improve-KAEProvider.patch
Patch380: add-8242842-Avoid-reallocating-name-when-checking-fo.patch
Patch381: add-8170831-ZipFile-implementation-no-longer-caches-.patch
Patch382: add-8146431-j.u.z.ZipFile.getEntry-throws-AIOOBE.patch
Patch383: add-8226530-test-case-fixed.patch
Patch384: add-8147940-Modify-testcase-this-test-does-not-assum.patch
Patch385: add-8191924-Adjust-DelegatingClassLoader-s-metadata-.patch
Patch386: add-Do-not-collect_class-when-DynamicCDS-dump.patch
Patch387: add-add-Count-instance-klass-when-loading-from-jsa-f.patch
Patch388: add-Adapting-IOException-of-Zip-to-ZipException.patch
Patch389: add-8227041-runtime-memory-RunUnitTestsConcurrently.patch
Patch390: add-fix-windows-build-Dynamic-CDS-failure.patch
Patch391: add-Fix-aarch64-runtime-thread-signal-transfer-bug.patch
Patch392: 8295068-SSLEngine-throws-NPE-parsing-CertificateRequ.patch
#############################################
#
@ -1836,6 +1860,31 @@ pushd %{top_level_dir_name}
%patch366 -p1
%patch367 -p1
%patch368 -p1
%patch369 -p1
%patch370 -p1
%patch371 -p1
%patch372 -p1
%patch373 -p1
%patch374 -p1
%patch375 -p1
%patch376 -p1
%patch377 -p1
%patch378 -p1
%patch379 -p1
%patch380 -p1
%patch381 -p1
%patch382 -p1
%patch383 -p1
%patch384 -p1
%patch385 -p1
%patch386 -p1
%patch387 -p1
%patch388 -p1
%patch389 -p1
%patch390 -p1
%patch391 -p1
%patch392 -p1
%ifarch riscv64
%patch2000 -p1
%endif
@ -2480,12 +2529,44 @@ cjc.mainProgram(arg)
%endif
%changelog
* Mon Sep 11 2023 misaka00251 <liuxin@iscas.ac.cn> - 1:1.8.0.382-b05.7
- Fix openjfx binding issues
* Mon Sep 25 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.382-b05.10
- del useless code
* Tue Sep 5 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.382-b05.6
* Fri Sep 22 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.382-b05.9
- add add-0010-8301749-Tracking-malloc-pooled-memory-size.patch
- add 8213397-Stack-dump-should-show-more-clearly-when-a-t.patch
- add Record-the-number-of-processes-to-errlog-file.patch.patch
- add 8254723-Add-diagnostic-command-to-write-Linux-perf-m.patch
- add The-OverWriteOldestGCLog-option-is-added-to-control.patch
- add add-6899049-G1-Clean-up-code-in-ptrQueue.-ch-pp-and-.patch
- add add-make-Appcds-jsa-rw-region-deterministic.patch
- add add-8142508-To-bring-j.u.z.ZipFile-s-native-implemen.patch
- add add-8198423-Improve-metaspace-chunk-allocation.patch
- add add-8226530-ZipFile-reads-wrong-entry-size-from-ZIP6.patch
- add add-fix-lock_fd-no-close-and-improve-KAEProvider.patch
- add add-8242842-Avoid-reallocating-name-when-checking-fo.patch
- add add-8170831-ZipFile-implementation-no-longer-caches-.patch
- add add-8146431-j.u.z.ZipFile.getEntry-throws-AIOOBE.patch
- add add-8226530-test-case-fixed.patch
- add add-8147940-Modify-testcase-this-test-does-not-assum.patch
- add add-8191924-Adjust-DelegatingClassLoader-s-metadata-.patch
- add add-Do-not-collect_class-when-DynamicCDS-dump.patch
- add add-add-Count-instance-klass-when-loading-from-jsa-f.patch
- add add-Adapting-IOException-of-Zip-to-ZipException.patch
- add add-8227041-runtime-memory-RunUnitTestsConcurrently.patch
- add add-fix-windows-build-Dynamic-CDS-failure.patch
- add add-Fix-aarch64-runtime-thread-signal-transfer-bug.patch
- add 8295068-SSLEngine-throws-NPE-parsing-CertificateRequ.patch
* Mon Sep 11 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.382-b05.8
- Fix openjfx bingding issues
* Wed Sep 6 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.382-b05.7
- del 0013-8287349-AArch64-Merge-LDR-instructions-to-improve-C1.patch
* Fri Sep 1 2023 noah <hedongbo@huawei.com> - 1:1.8.0.382-b05.6
- removed cjc backward comaptiblity, to fix when both rpm 4.16 and 4.17 are in transaction
* Wed Aug 30 2023 kuenking111 <wangkun49@huawei.com> - 1:1.8.0.382-b05.5
- del 0022-8198510-Enable-UseDynamicNumberOfGCThreads-by-defaul.patch