1 Star 0 Fork 81

lyn/openjdk-1.8.0

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
8254723-Add-diagnostic-command-to-write-Linux-perf-m.patch 10.14 KB
一键复制 编辑 原始数据 按行查看 历史
DXwangg 提交于 2023-09-26 09:10 . Add feature and bug fix for 8u382
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
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/lyn1001/openjdk-1.8.0.git
git@gitee.com:lyn1001/openjdk-1.8.0.git
lyn1001
openjdk-1.8.0
openjdk-1.8.0
master

搜索帮助