Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JDK-8317683: Add JIT memory statistics #16076

Closed
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/hotspot/share/compiler/compilationMemoryStatistic.cpp
Original file line number Diff line number Diff line change
@@ -358,8 +358,8 @@ void CompilationMemoryStatistic::on_end_compilation() {
fmn.make_permanent();

const DirectiveSet* directive = th->task()->directive();
assert(directive->CollectMemStatOption || directive->PrintMemStatOption, "Only call if memstat is active for this method");
const bool print = directive->PrintMemStatOption;
assert(directive->should_collect_memstat(), "Only call if memstat is enabled");
const bool print = directive->should_print_memstat();

if (print) {
char buf[1024];
6 changes: 5 additions & 1 deletion src/hotspot/share/compiler/compilerDirectives.cpp
Original file line number Diff line number Diff line change
@@ -203,7 +203,11 @@ bool DirectiveSet::is_c2(CompilerDirectives* directive) const {
}

bool DirectiveSet::should_collect_memstat() const {
return CollectMemStatOption || PrintMemStatOption;
return MemStatOption > 0;
}

bool DirectiveSet::should_print_memstat() const {
return MemStatOption == (uintx)MemStatAction::print;
}

// In the list of Control/disabled intrinsics, the ID of the control intrinsics can separated:
4 changes: 2 additions & 2 deletions src/hotspot/share/compiler/compilerDirectives.hpp
Original file line number Diff line number Diff line change
@@ -40,12 +40,11 @@
cflags(Exclude, bool, false, Unknown) \
cflags(BreakAtExecute, bool, false, BreakAtExecute) \
cflags(BreakAtCompile, bool, false, BreakAtCompile) \
cflags(CollectMemStat, bool, false, CollectMemStat) \
cflags(Log, bool, LogCompilation, Unknown) \
cflags(MemStat, uintx, 0, MemStat) \
cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \
cflags(PrintCompilation, bool, PrintCompilation, PrintCompilation) \
cflags(PrintInlining, bool, PrintInlining, PrintInlining) \
cflags(PrintMemStat, bool, false, PrintMemStat) \
cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods) \
cflags(BackgroundCompilation, bool, BackgroundCompilation, BackgroundCompilation) \
cflags(ReplayInline, bool, false, ReplayInline) \
@@ -134,6 +133,7 @@ class DirectiveSet : public CHeapObj<mtCompiler> {
bool is_c1(CompilerDirectives* directive) const;
bool is_c2(CompilerDirectives* directive) const;
bool should_collect_memstat() const;
bool should_print_memstat() const;

typedef enum {
#define enum_of_flags(name, type, dvalue, cc_flag) name##Index,
38 changes: 33 additions & 5 deletions src/hotspot/share/compiler/compilerOracle.cpp
Original file line number Diff line number Diff line change
@@ -101,6 +101,7 @@ class TypedMethodOptionMatcher;

static TypedMethodOptionMatcher* option_list = nullptr;
static bool any_set = false;
static bool print_final_memstat_report = false;

// A filter for quick lookup if an option is set
static bool option_filter[static_cast<int>(CompileCommand::Unknown) + 1] = { 0 };
@@ -325,6 +326,7 @@ static void register_command(TypedMethodOptionMatcher* matcher,
tty->print("CompileCommand: %s ", option2name(option));
matcher->print();
}

return;
}

@@ -457,11 +459,11 @@ bool CompilerOracle::should_print_methods() {

// Tells whether there are any methods to collect memory statistics for
bool CompilerOracle::should_collect_memstat() {
return has_command(CompileCommand::PrintMemStat) || has_command(CompileCommand::CollectMemStat);
return has_command(CompileCommand::MemStat);
}

bool CompilerOracle::should_print_memstat() {
return has_command(CompileCommand::PrintMemStat);
bool CompilerOracle::should_print_final_memstat_report() {
return print_final_memstat_report;
}

bool CompilerOracle::should_log(const methodHandle& method) {
@@ -632,6 +634,22 @@ void skip_comma(char* &line) {
}
}

static bool parseEnumValueAsUintx(enum CompileCommand option, const char* line, uintx& value, int& bytes_read, char* errorbuf, const int buf_size) {
if (option == CompileCommand::MemStat) {
if (strncasecmp(line, "collect", 7) == 0) {
value = (uintx)MemStatAction::collect;
} else if (strncasecmp(line, "print", 5) == 0) {
value = (uintx)MemStatAction::print;
print_final_memstat_report = true;
} else {
jio_snprintf(errorbuf, buf_size, "MemStat: invalid value expected 'collect' or 'print' (omitting value means 'collect')");
}
return true; // handled
}
return false;
#undef HANDLE_VALUE
}

static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
TypedMethodOptionMatcher* matcher, enum CompileCommand option, char* errorbuf, const int buf_size) {
int bytes_read = 0;
@@ -651,7 +669,13 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
}
} else if (type == OptionType::Uintx) {
uintx value;
if (sscanf(line, "" UINTX_FORMAT "%n", &value, &bytes_read) == 1) {
// Is it a named enum?
bool success = parseEnumValueAsUintx(option, line, value, bytes_read, errorbuf, buf_size);
if (!success) {
// Is it a raw number?
success = (sscanf(line, "" UINTX_FORMAT "%n", &value, &bytes_read) == 1);
}
if (success) {
total_bytes_read += bytes_read;
line += bytes_read;
register_command(matcher, option, value);
@@ -923,10 +947,14 @@ bool CompilerOracle::parse_from_line(char* line) {
}
skip_whitespace(line);
if (*line == '\0') {
// if this is a bool option this implies true
if (option2type(option) == OptionType::Bool) {
// if this is a bool option this implies true
register_command(matcher, option, true);
return true;
} else if (option == CompileCommand::MemStat) {
// MemStat default action is to collect data but to not print
register_command(matcher, option, (uintx)MemStatAction::collect);
return true;
} else {
jio_snprintf(error_buf, sizeof(error_buf), " Option '%s' is not followed by a value", option2name(option));
print_parse_error(error_buf, original.get());
9 changes: 6 additions & 3 deletions src/hotspot/share/compiler/compilerOracle.hpp
Original file line number Diff line number Diff line change
@@ -57,12 +57,11 @@ class methodHandle;
option(Break, "break", Bool) \
option(BreakAtExecute, "BreakAtExecute", Bool) \
option(BreakAtCompile, "BreakAtCompile", Bool) \
option(CollectMemStat, "CollectMemStat", Bool) \
option(MemStat, "MemStat", Uintx) \
option(PrintAssembly, "PrintAssembly", Bool) \
option(PrintCompilation, "PrintCompilation", Bool) \
option(PrintInlining, "PrintInlining", Bool) \
option(PrintIntrinsics, "PrintIntrinsics", Bool) \
option(PrintMemStat, "PrintMemStat", Bool) \
option(PrintNMethods, "PrintNMethods", Bool) \
option(PrintOptoAssembly, "PrintOptoAssembly", Bool) \
option(PrintDebugInfo, "PrintDebugInfo", Bool) \
@@ -115,6 +114,10 @@ enum class OptionType {
Unknown
};

enum class MemStatAction {
collect = 1, print = 2
};

class CompilerOracle : AllStatic {
private:
static bool _quiet;
@@ -155,7 +158,7 @@ class CompilerOracle : AllStatic {

// Tells whether there are any methods to (collect|collect+print) memory statistics for
static bool should_collect_memstat();
static bool should_print_memstat();
static bool should_print_final_memstat_report();

// Tags the method as blackhole candidate, if possible.
static void tag_blackhole_if_possible(const methodHandle& method);
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/java.cpp
Original file line number Diff line number Diff line change
@@ -342,7 +342,7 @@ void print_statistics() {
MetaspaceUtils::print_basic_report(tty, 0);
}

if (CompilerOracle::should_print_memstat()) {
if (CompilerOracle::should_print_final_memstat_report()) {
CompilationMemoryStatistic::print_all_by_size(tty, false, 0);
}

Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ private static void test(String include, String exclude) throws Exception {
options.add("-Xcomp");
options.add("-XX:-Inline");
options.add("-XX:CompileCommand=compileonly," + getTestClass() + "::*");
options.add("-XX:CompileCommand=PrintMemStat," + getTestMethod(include));
options.add("-XX:CompileCommand=MemStat," + getTestMethod(include) + ",print");
options.add(getTestClass());

OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
Original file line number Diff line number Diff line change
@@ -36,7 +36,19 @@
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @run main/othervm -XX:CompileCommand=CollectMemStat,*.* CompilerMemoryStatisticTest
* @run main/othervm -XX:CompileCommand=memstat,*.* CompilerMemoryStatisticTest
*/

/*
* @test CompilerMemoryStatisticTest
* @summary Test Compiler.memory
* @requires vm.compiler1.enabled
* @requires vm.compiler2.enabled
*
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @run main/othervm -XX:CompileCommand=memstat,*.*,collect CompilerMemoryStatisticTest
*/

public class CompilerMemoryStatisticTest {