From b594b509befef9cbbac1763358cbe78fc35668f9 Mon Sep 17 00:00:00 2001
Date: Mon, 11 May 2026 10:51:51 +0800
Subject: 8314029: Add file name parameter to Compiler.perfmap
src/hotspot/share/code/codeCache.cpp | 14 ++++++----
src/hotspot/share/code/codeCache.hpp | 2 +-
.../share/services/diagnosticCommand.cpp | 9 +++++-
.../share/services/diagnosticCommand.hpp | 7 +++--
src/jdk.jcmd/share/man/jcmd.1 | 12 +++++++-
.../dcmd/compiler/PerfMapTest.java | 28 +++++++++++++------
6 files changed, 53 insertions(+), 19 deletions(-)
@@ -1821,16 +1821,20 @@ void CodeCache::log_state(outputStream* st) {
}
#ifdef LINUX
-void CodeCache::write_perf_map() {
+void CodeCache::write_perf_map(const char* filename) {
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- // Perf expects to find the map file at /tmp/perf-<pid>.map.
+ // Perf expects to find the map file at /tmp/perf-<pid>.map
+ // if the file name is not specified.
char fname[32];
- jio_snprintf(fname, sizeof(fname), "/tmp/perf-%d.map", os::current_process_id());
+ if (filename == nullptr) {
+ jio_snprintf(fname, sizeof(fname), "/tmp/perf-%d.map", os::current_process_id());
+ filename = fname;
+ }
- fileStream fs(fname, "w");
+ fileStream fs(filename, "w");
if (!fs.is_open()) {
- log_warning(codecache)("Failed to create %s for perf map", fname);
+ log_warning(codecache)("Failed to create %s for perf map", filename);
return;
}
@@ -237,7 +237,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();)
+ LINUX_ONLY(static void write_perf_map(const char* filename = nullptr);)
static const char* get_code_heap_name(CodeBlobType code_blob_type) { return (heap_available(code_blob_type) ? get_code_heap(code_blob_type)->name() : "Unused"); }
static void report_codemem_full(CodeBlobType code_blob_type, bool print);
@@ -974,8 +974,15 @@ void CodeCacheDCmd::execute(DCmdSource source, TRAPS) {
}
#ifdef LINUX
+PerfMapDCmd::PerfMapDCmd(outputStream* output, bool heap) :
+ DCmdWithParser(output, heap),
+ _filename("filename", "Name of the map file", "STRING", false)
+{
+ _dcmdparser.add_dcmd_argument(&_filename);
+}
+
void PerfMapDCmd::execute(DCmdSource source, TRAPS) {
- CodeCache::write_perf_map();
+ CodeCache::write_perf_map(_filename.value());
}
#endif // LINUX
@@ -647,9 +647,12 @@ public:
};
#ifdef LINUX
-class PerfMapDCmd : public DCmd {
+class PerfMapDCmd : public DCmdWithParser {
+protected:
+ DCmdArgument<char*> _filename;
public:
- PerfMapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+ static int num_arguments() { return 1; }
+ PerfMapDCmd(outputStream* output, bool heap);
static const char* name() {
return "Compiler.perfmap";
}
@@ -178,11 +178,21 @@ Prints all compiled methods in code cache that are alive.
Impact: Medium
.RE
.TP
-\f[V]Compiler.perfmap\f[R] (Linux only)
+\f[V]Compiler.perfmap\f[R] [\f[I]arguments\f[R]] (Linux only)
Write map file for Linux perf tool.
.RS
.PP
Impact: Low
+.PP
+\f[I]arguments\f[R]:
+.IP \[bu] 2
+\f[V]filename\f[R]: (Optional) Name of the map file (STRING, no default
+value)
+.PP
+If \f[V]filename\f[R] is not specified, a default file name is chosen
+using the pid of the target JVM process.
+For example, if the pid is \f[V]12345\f[R], then the default
+\f[V]filename\f[R] will be \f[V]/tmp/perf-12345.map\f[R].
.RE
.TP
\f[V]Compiler.queue\f[R]
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2023, 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
@@ -46,6 +46,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -58,15 +59,12 @@ public class PerfMapTest {
static final Pattern LINE_PATTERN =
Pattern.compile("^((?:0x)?\\p{XDigit}+)\\s+((?:0x)?\\p{XDigit}+)\\s+(.*)$");
- public void run(CommandExecutor executor) {
- OutputAnalyzer output = executor.execute("Compiler.perfmap");
+ public void run(CommandExecutor executor, String cmd, Path path) {
+ OutputAnalyzer output = executor.execute(cmd);
output.stderrShouldBeEmpty();
output.stdoutShouldBeEmpty();
- final long pid = ProcessHandle.current().pid();
- final Path path = Paths.get(String.format("/tmp/perf-%d.map", pid));
-
Assert.assertTrue(Files.exists(path));
// Sanity check the file contents
@@ -81,7 +79,19 @@ public class PerfMapTest {
}
@Test
- public void jmx() {
- run(new JMXExecutor());
+ public void defaultMapFile() {
+ final long pid = ProcessHandle.current().pid();
+ final Path path = Paths.get(String.format("/tmp/perf-%d.map", pid));
+ run(new JMXExecutor(), "Compiler.perfmap", path);
+ }
+
+ @Test
+ public void specifiedMapFile() {
+ String test_dir = System.getProperty("test.dir", ".");
+ Path path = null;
+ do {
+ path = Paths.get(String.format("%s/%s.map", test_dir, UUID.randomUUID().toString()));
+ } while(Files.exists(path));
+ run(new JMXExecutor(), "Compiler.perfmap " + path.toString(), path);
}
}
--
2.17.1