8314029: Add file name parameter to Compiler.perfmap

Reviewed-by: cjplummer, eastigeevich
This commit is contained in:
Yi-Fan Tsai 2023-12-18 15:20:59 +00:00 committed by Paul Hohensee
parent c0a3b76958
commit a5122d7f6c
6 changed files with 53 additions and 19 deletions

View File

@ -1819,16 +1819,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;
}

View File

@ -227,7 +227,7 @@ class CodeCache : AllStatic {
static void print_trace(const char* event, CodeBlob* cb, uint 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);

View File

@ -851,8 +851,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

View File

@ -577,9 +577,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";
}

View File

@ -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]

View File

@ -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);
}
}