8303150: DCmd framework unnecessarily creates a DCmd instance on registration

Reviewed-by: fparain, stuefe, kevinw
This commit is contained in:
David Holmes 2023-03-16 21:00:21 +00:00
parent 2e987d798a
commit a487a270dc
12 changed files with 45 additions and 68 deletions

View File

@ -45,18 +45,6 @@ ClassLoaderHierarchyDCmd::ClassLoaderHierarchyDCmd(outputStream* output, bool he
_dcmdparser.add_dcmd_option(&_fold); _dcmdparser.add_dcmd_option(&_fold);
} }
int ClassLoaderHierarchyDCmd::num_arguments() {
ResourceMark rm;
ClassLoaderHierarchyDCmd* dcmd = new ClassLoaderHierarchyDCmd(nullptr, false);
if (dcmd != nullptr) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
// Helper class for drawing the branches to the left of a node. // Helper class for drawing the branches to the left of a node.
class BranchTracker : public StackObj { class BranchTracker : public StackObj {
// "<x>" // "<x>"

View File

@ -51,7 +51,7 @@ public:
"monitor", nullptr}; "monitor", nullptr};
return p; return p;
} }
static int num_arguments(); static int num_arguments() { return 3; }
virtual void execute(DCmdSource source, TRAPS); virtual void execute(DCmdSource source, TRAPS);
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -447,16 +447,6 @@ void JfrConfigureFlightRecorderDCmd::print_help(const char* name) const {
out->print_cr(""); out->print_cr("");
} }
int JfrConfigureFlightRecorderDCmd::num_arguments() {
ResourceMark rm;
JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
}
return 0;
}
void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) { void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -177,7 +177,7 @@ class JfrConfigureFlightRecorderDCmd : public DCmdWithParser {
JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", NULL}; JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", NULL};
return p; return p;
} }
static int num_arguments(); static int num_arguments() { return 9; }
virtual void execute(DCmdSource source, TRAPS); virtual void execute(DCmdSource source, TRAPS);
virtual void print_help(const char* name) const; virtual void print_help(const char* name) const;
}; };

View File

@ -45,17 +45,6 @@ LogDiagnosticCommand::LogDiagnosticCommand(outputStream* output, bool heap_alloc
_dcmdparser.add_dcmd_option(&_rotate); _dcmdparser.add_dcmd_option(&_rotate);
} }
int LogDiagnosticCommand::num_arguments() {
ResourceMark rm;
LogDiagnosticCommand* dcmd = new LogDiagnosticCommand(nullptr, false);
if (dcmd != nullptr) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
void LogDiagnosticCommand::registerCommand() { void LogDiagnosticCommand::registerCommand() {
uint32_t full_visibility = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean; uint32_t full_visibility = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<LogDiagnosticCommand>(full_visibility, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<LogDiagnosticCommand>(full_visibility, true, false));

View File

@ -49,7 +49,7 @@ class LogDiagnosticCommand : public DCmdWithParser {
LogDiagnosticCommand(outputStream* output, bool heap_allocated); LogDiagnosticCommand(outputStream* output, bool heap_allocated);
void execute(DCmdSource source, TRAPS); void execute(DCmdSource source, TRAPS);
static void registerCommand(); static void registerCommand();
static int num_arguments(); static int num_arguments() { return 7; }
static const char* name() { static const char* name() {
return "VM.log"; return "VM.log";

View File

@ -58,17 +58,6 @@ MetaspaceDCmd::MetaspaceDCmd(outputStream* output, bool heap) :
_dcmdparser.add_dcmd_option(&_scale); _dcmdparser.add_dcmd_option(&_scale);
} }
int MetaspaceDCmd::num_arguments() {
ResourceMark rm;
MetaspaceDCmd* dcmd = new MetaspaceDCmd(nullptr, false);
if (dcmd != nullptr) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
void MetaspaceDCmd::execute(DCmdSource source, TRAPS) { void MetaspaceDCmd::execute(DCmdSource source, TRAPS) {
// Parse scale value. // Parse scale value.
const char* scale_value = _scale.value(); const char* scale_value = _scale.value();

View File

@ -57,7 +57,7 @@ public:
"monitor", nullptr}; "monitor", nullptr};
return p; return p;
} }
static int num_arguments(); static int num_arguments() { return 8; }
virtual void execute(DCmdSource source, TRAPS); virtual void execute(DCmdSource source, TRAPS);
}; };

View File

@ -1073,17 +1073,6 @@ ThreadDumpToFileDCmd::ThreadDumpToFileDCmd(outputStream* output, bool heap) :
_dcmdparser.add_dcmd_argument(&_filepath); _dcmdparser.add_dcmd_argument(&_filepath);
} }
int ThreadDumpToFileDCmd::num_arguments() {
ResourceMark rm;
ThreadDumpToFileDCmd* dcmd = new ThreadDumpToFileDCmd(nullptr, false);
if (dcmd != nullptr) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
void ThreadDumpToFileDCmd::execute(DCmdSource source, TRAPS) { void ThreadDumpToFileDCmd::execute(DCmdSource source, TRAPS) {
bool json = (_format.value() != nullptr) && (strcmp(_format.value(), "json") == 0); bool json = (_format.value() != nullptr) && (strcmp(_format.value(), "json") == 0);
char* path = _filepath.value(); char* path = _filepath.value();

View File

@ -44,6 +44,7 @@ protected:
DCmdArgument<bool> _all; DCmdArgument<bool> _all;
DCmdArgument<char*> _cmd; DCmdArgument<char*> _cmd;
public: public:
static int num_arguments() { return 2; }
HelpDCmd(outputStream* output, bool heap); HelpDCmd(outputStream* output, bool heap);
static const char* name() { return "help"; } static const char* name() { return "help"; }
static const char* description() { static const char* description() {
@ -113,6 +114,7 @@ class PrintVMFlagsDCmd : public DCmdWithParser {
protected: protected:
DCmdArgument<bool> _all; DCmdArgument<bool> _all;
public: public:
static int num_arguments() { return 1; }
PrintVMFlagsDCmd(outputStream* output, bool heap); PrintVMFlagsDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.flags"; } static const char* name() { return "VM.flags"; }
static const char* description() { static const char* description() {
@ -135,6 +137,7 @@ protected:
DCmdArgument<char*> _value; DCmdArgument<char*> _value;
public: public:
static int num_arguments() { return 2; }
SetVMFlagDCmd(outputStream* output, bool heap); SetVMFlagDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.set_flag"; } static const char* name() { return "VM.set_flag"; }
static const char* description() { static const char* description() {
@ -176,6 +179,7 @@ protected:
DCmdArgument<char*> _libpath; DCmdArgument<char*> _libpath;
DCmdArgument<char*> _option; DCmdArgument<char*> _option;
public: public:
static int num_arguments() { return 2; }
JVMTIAgentLoadDCmd(outputStream* output, bool heap); JVMTIAgentLoadDCmd(outputStream* output, bool heap);
static const char* name() { return "JVMTI.agent_load"; } static const char* name() { return "JVMTI.agent_load"; }
static const char* description() { static const char* description() {
@ -216,6 +220,7 @@ class VMUptimeDCmd : public DCmdWithParser {
protected: protected:
DCmdArgument<bool> _date; DCmdArgument<bool> _date;
public: public:
static int num_arguments() { return 1; }
VMUptimeDCmd(outputStream* output, bool heap); VMUptimeDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.uptime"; } static const char* name() { return "VM.uptime"; }
static const char* description() { static const char* description() {
@ -316,6 +321,7 @@ protected:
DCmdArgument<jlong> _gzip; DCmdArgument<jlong> _gzip;
DCmdArgument<bool> _overwrite; DCmdArgument<bool> _overwrite;
public: public:
static int num_arguments() { return 4; }
HeapDumpDCmd(outputStream* output, bool heap); HeapDumpDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "GC.heap_dump"; return "GC.heap_dump";
@ -342,6 +348,7 @@ protected:
DCmdArgument<bool> _all; DCmdArgument<bool> _all;
DCmdArgument<jlong> _parallel_thread_num; DCmdArgument<jlong> _parallel_thread_num;
public: public:
static int num_arguments() { return 2; }
ClassHistogramDCmd(outputStream* output, bool heap); ClassHistogramDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "GC.class_histogram"; return "GC.class_histogram";
@ -366,6 +373,7 @@ protected:
DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed. DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed.
DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed. DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed.
public: public:
static int num_arguments() { return 3; }
ClassHierarchyDCmd(outputStream* output, bool heap); ClassHierarchyDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "VM.class_hierarchy"; return "VM.class_hierarchy";
@ -392,6 +400,7 @@ protected:
DCmdArgument<char*> _suboption; // option of VM.cds DCmdArgument<char*> _suboption; // option of VM.cds
DCmdArgument<char*> _filename; // file name, optional DCmdArgument<char*> _filename; // file name, optional
public: public:
static int num_arguments() { return 2; }
DumpSharedArchiveDCmd(outputStream* output, bool heap); DumpSharedArchiveDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "VM.cds"; return "VM.cds";
@ -407,7 +416,6 @@ public:
"monitor", nullptr}; "monitor", nullptr};
return p; return p;
} }
static int num_arguments();
virtual void execute(DCmdSource source, TRAPS); virtual void execute(DCmdSource source, TRAPS);
}; };
#endif // INCLUDE_CDS #endif // INCLUDE_CDS
@ -418,6 +426,7 @@ protected:
DCmdArgument<bool> _locks; DCmdArgument<bool> _locks;
DCmdArgument<bool> _extended; DCmdArgument<bool> _extended;
public: public:
static int num_arguments() { return 2; }
ThreadDumpDCmd(outputStream* output, bool heap); ThreadDumpDCmd(outputStream* output, bool heap);
static const char* name() { return "Thread.print"; } static const char* name() { return "Thread.print"; }
static const char* description() { static const char* description() {
@ -469,6 +478,8 @@ class JMXStartRemoteDCmd : public DCmdWithParser {
DCmdArgument<char *> _jdp_name; DCmdArgument<char *> _jdp_name;
public: public:
static int num_arguments() { return 21; }
JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
static const char *name() { static const char *name() {
@ -632,6 +643,7 @@ protected:
DCmdArgument<char*> _function; DCmdArgument<char*> _function;
DCmdArgument<jlong> _granularity; DCmdArgument<jlong> _granularity;
public: public:
static int num_arguments() { return 2; }
CodeHeapAnalyticsDCmd(outputStream* output, bool heap); CodeHeapAnalyticsDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "Compiler.CodeHeap_Analytics"; return "Compiler.CodeHeap_Analytics";
@ -696,6 +708,7 @@ class CompilerDirectivesAddDCmd : public DCmdWithParser {
protected: protected:
DCmdArgument<char*> _filename; DCmdArgument<char*> _filename;
public: public:
static int num_arguments() { return 1; }
CompilerDirectivesAddDCmd(outputStream* output, bool heap); CompilerDirectivesAddDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "Compiler.directives_add"; return "Compiler.directives_add";
@ -781,6 +794,7 @@ class SymboltableDCmd : public DCmdWithParser {
protected: protected:
DCmdArgument<bool> _verbose; DCmdArgument<bool> _verbose;
public: public:
static int num_arguments() { return 1; }
SymboltableDCmd(outputStream* output, bool heap); SymboltableDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "VM.symboltable"; return "VM.symboltable";
@ -803,6 +817,7 @@ class StringtableDCmd : public DCmdWithParser {
protected: protected:
DCmdArgument<bool> _verbose; DCmdArgument<bool> _verbose;
public: public:
static int num_arguments() { return 1; }
StringtableDCmd(outputStream* output, bool heap); StringtableDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "VM.stringtable"; return "VM.stringtable";
@ -825,6 +840,7 @@ class SystemDictionaryDCmd : public DCmdWithParser {
protected: protected:
DCmdArgument<bool> _verbose; DCmdArgument<bool> _verbose;
public: public:
static int num_arguments() { return 1; }
SystemDictionaryDCmd(outputStream* output, bool heap); SystemDictionaryDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "VM.systemdictionary"; return "VM.systemdictionary";
@ -847,6 +863,7 @@ class ClassesDCmd : public DCmdWithParser {
protected: protected:
DCmdArgument<bool> _verbose; DCmdArgument<bool> _verbose;
public: public:
static int num_arguments() { return 1; }
ClassesDCmd(outputStream* output, bool heap); ClassesDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "VM.classes"; return "VM.classes";
@ -891,6 +908,7 @@ protected:
DCmdArgument<char*> _log; DCmdArgument<char*> _log;
DCmdArgument<char*> _max; DCmdArgument<char*> _max;
public: public:
static int num_arguments() { return 2; }
EventLogDCmd(outputStream* output, bool heap); EventLogDCmd(outputStream* output, bool heap);
static const char* name() { static const char* name() {
return "VM.events"; return "VM.events";
@ -917,6 +935,7 @@ protected:
DCmdArgument<char*> _format; DCmdArgument<char*> _format;
DCmdArgument<char*> _filepath; DCmdArgument<char*> _filepath;
public: public:
static int num_arguments() { return 3; }
ThreadDumpToFileDCmd(outputStream *output, bool heap); ThreadDumpToFileDCmd(outputStream *output, bool heap);
static const char *name() { static const char *name() {
return "Thread.dump_to_file"; return "Thread.dump_to_file";
@ -931,7 +950,6 @@ public:
JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
return p; return p;
} }
static int num_arguments();
virtual void execute(DCmdSource source, TRAPS); virtual void execute(DCmdSource source, TRAPS);
}; };

View File

@ -276,9 +276,7 @@ public:
return p; return p;
} }
// num_arguments() is used by the DCmdFactoryImpl::get_num_arguments() template functions. // num_arguments() is used by the DCmdFactoryImpl::get_num_arguments() template functions.
// - For subclasses of DCmdWithParser, it's calculated by DCmdParser::num_arguments(). // All subclasses should override this to report the actual number of arguments.
// - Other subclasses of DCmd have zero arguments by default. You can change this
// by defining your own version of MyDCmd::num_arguments().
static int num_arguments() { return 0; } static int num_arguments() { return 0; }
outputStream* output() const { return _output; } outputStream* output() const { return _output; }
bool is_heap_allocated() const { return _is_heap_allocated; } bool is_heap_allocated() const { return _is_heap_allocated; }
@ -439,13 +437,14 @@ public:
} }
private: private:
#ifdef ASSERT
template <typename T, ENABLE_IF(!std::is_base_of<DCmdWithParser, T>::value)> template <typename T, ENABLE_IF(!std::is_base_of<DCmdWithParser, T>::value)>
static int get_num_arguments() { static int get_parsed_num_arguments() {
return T::num_arguments(); return T::num_arguments();
} }
template <typename T, ENABLE_IF(std::is_base_of<DCmdWithParser, T>::value)> template <typename T, ENABLE_IF(std::is_base_of<DCmdWithParser, T>::value)>
static int get_num_arguments() { static int get_parsed_num_arguments() {
ResourceMark rm; ResourceMark rm;
DCmdClass* dcmd = new DCmdClass(nullptr, false); DCmdClass* dcmd = new DCmdClass(nullptr, false);
if (dcmd != nullptr) { if (dcmd != nullptr) {
@ -455,6 +454,20 @@ private:
return 0; return 0;
} }
} }
#endif
template <typename T, ENABLE_IF(std::is_convertible<T, DCmd>::value)>
static int get_num_arguments() {
int n_args = T::num_arguments();
#ifdef ASSERT
int n_parsed_args = get_parsed_num_arguments<T>();
assert(n_args == n_parsed_args,
"static argument count %d does not match parsed argument count %d",
n_args, n_parsed_args);
#endif
return n_args;
}
}; };
#endif // SHARE_SERVICES_DIAGNOSTICFRAMEWORK_HPP #endif // SHARE_SERVICES_DIAGNOSTICFRAMEWORK_HPP

View File

@ -44,6 +44,7 @@ class NMTDCmd: public DCmdWithParser {
DCmdArgument<char*> _scale; DCmdArgument<char*> _scale;
public: public:
static int num_arguments() { return 7; }
NMTDCmd(outputStream* output, bool heap); NMTDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.native_memory"; } static const char* name() { return "VM.native_memory"; }
static const char* description() { static const char* description() {