diff --git a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp index 6778f6b862d..f89090fbb5c 100644 --- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp +++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp @@ -45,18 +45,6 @@ ClassLoaderHierarchyDCmd::ClassLoaderHierarchyDCmd(outputStream* output, bool he _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. class BranchTracker : public StackObj { // "" diff --git a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp index 1d4fe861335..26c765443c9 100644 --- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp +++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp @@ -51,7 +51,7 @@ public: "monitor", nullptr}; return p; } - static int num_arguments(); + static int num_arguments() { return 3; } virtual void execute(DCmdSource source, TRAPS); }; diff --git a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp index b9834adc8b0..e086b18f8fd 100644 --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp @@ -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. * * 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(""); } -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) { DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); diff --git a/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp b/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp index df6f586b266..8d2ae20281c 100644 --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp @@ -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. * * 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}; return p; } - static int num_arguments(); + static int num_arguments() { return 9; } virtual void execute(DCmdSource source, TRAPS); virtual void print_help(const char* name) const; }; diff --git a/src/hotspot/share/logging/logDiagnosticCommand.cpp b/src/hotspot/share/logging/logDiagnosticCommand.cpp index 75ac32d6537..dfd45d61188 100644 --- a/src/hotspot/share/logging/logDiagnosticCommand.cpp +++ b/src/hotspot/share/logging/logDiagnosticCommand.cpp @@ -45,17 +45,6 @@ LogDiagnosticCommand::LogDiagnosticCommand(outputStream* output, bool heap_alloc _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() { uint32_t full_visibility = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean; DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_visibility, true, false)); diff --git a/src/hotspot/share/logging/logDiagnosticCommand.hpp b/src/hotspot/share/logging/logDiagnosticCommand.hpp index bc7f18951ae..089bcdc48af 100644 --- a/src/hotspot/share/logging/logDiagnosticCommand.hpp +++ b/src/hotspot/share/logging/logDiagnosticCommand.hpp @@ -49,7 +49,7 @@ class LogDiagnosticCommand : public DCmdWithParser { LogDiagnosticCommand(outputStream* output, bool heap_allocated); void execute(DCmdSource source, TRAPS); static void registerCommand(); - static int num_arguments(); + static int num_arguments() { return 7; } static const char* name() { return "VM.log"; diff --git a/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp b/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp index 36a7ba3ae93..db6d3631450 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp @@ -58,17 +58,6 @@ MetaspaceDCmd::MetaspaceDCmd(outputStream* output, bool heap) : _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) { // Parse scale value. const char* scale_value = _scale.value(); diff --git a/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp b/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp index e3490a26880..453b6721202 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp @@ -57,7 +57,7 @@ public: "monitor", nullptr}; return p; } - static int num_arguments(); + static int num_arguments() { return 8; } virtual void execute(DCmdSource source, TRAPS); }; diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index 5de1fb1b716..4e913fb64bf 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -1073,17 +1073,6 @@ ThreadDumpToFileDCmd::ThreadDumpToFileDCmd(outputStream* output, bool heap) : _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) { bool json = (_format.value() != nullptr) && (strcmp(_format.value(), "json") == 0); char* path = _filepath.value(); diff --git a/src/hotspot/share/services/diagnosticCommand.hpp b/src/hotspot/share/services/diagnosticCommand.hpp index eb2e1898c3a..9349b4e7a08 100644 --- a/src/hotspot/share/services/diagnosticCommand.hpp +++ b/src/hotspot/share/services/diagnosticCommand.hpp @@ -44,6 +44,7 @@ protected: DCmdArgument _all; DCmdArgument _cmd; public: + static int num_arguments() { return 2; } HelpDCmd(outputStream* output, bool heap); static const char* name() { return "help"; } static const char* description() { @@ -113,6 +114,7 @@ class PrintVMFlagsDCmd : public DCmdWithParser { protected: DCmdArgument _all; public: + static int num_arguments() { return 1; } PrintVMFlagsDCmd(outputStream* output, bool heap); static const char* name() { return "VM.flags"; } static const char* description() { @@ -135,6 +137,7 @@ protected: DCmdArgument _value; public: + static int num_arguments() { return 2; } SetVMFlagDCmd(outputStream* output, bool heap); static const char* name() { return "VM.set_flag"; } static const char* description() { @@ -176,6 +179,7 @@ protected: DCmdArgument _libpath; DCmdArgument _option; public: + static int num_arguments() { return 2; } JVMTIAgentLoadDCmd(outputStream* output, bool heap); static const char* name() { return "JVMTI.agent_load"; } static const char* description() { @@ -216,6 +220,7 @@ class VMUptimeDCmd : public DCmdWithParser { protected: DCmdArgument _date; public: + static int num_arguments() { return 1; } VMUptimeDCmd(outputStream* output, bool heap); static const char* name() { return "VM.uptime"; } static const char* description() { @@ -316,6 +321,7 @@ protected: DCmdArgument _gzip; DCmdArgument _overwrite; public: + static int num_arguments() { return 4; } HeapDumpDCmd(outputStream* output, bool heap); static const char* name() { return "GC.heap_dump"; @@ -342,6 +348,7 @@ protected: DCmdArgument _all; DCmdArgument _parallel_thread_num; public: + static int num_arguments() { return 2; } ClassHistogramDCmd(outputStream* output, bool heap); static const char* name() { return "GC.class_histogram"; @@ -366,6 +373,7 @@ protected: DCmdArgument _print_subclasses; // true if subclasses of the specified classname should be printed. DCmdArgument _classname; // Optional single class name whose hierarchy should be printed. public: + static int num_arguments() { return 3; } ClassHierarchyDCmd(outputStream* output, bool heap); static const char* name() { return "VM.class_hierarchy"; @@ -392,6 +400,7 @@ protected: DCmdArgument _suboption; // option of VM.cds DCmdArgument _filename; // file name, optional public: + static int num_arguments() { return 2; } DumpSharedArchiveDCmd(outputStream* output, bool heap); static const char* name() { return "VM.cds"; @@ -407,7 +416,6 @@ public: "monitor", nullptr}; return p; } - static int num_arguments(); virtual void execute(DCmdSource source, TRAPS); }; #endif // INCLUDE_CDS @@ -418,6 +426,7 @@ protected: DCmdArgument _locks; DCmdArgument _extended; public: + static int num_arguments() { return 2; } ThreadDumpDCmd(outputStream* output, bool heap); static const char* name() { return "Thread.print"; } static const char* description() { @@ -469,6 +478,8 @@ class JMXStartRemoteDCmd : public DCmdWithParser { DCmdArgument _jdp_name; public: + static int num_arguments() { return 21; } + JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); static const char *name() { @@ -632,6 +643,7 @@ protected: DCmdArgument _function; DCmdArgument _granularity; public: + static int num_arguments() { return 2; } CodeHeapAnalyticsDCmd(outputStream* output, bool heap); static const char* name() { return "Compiler.CodeHeap_Analytics"; @@ -696,6 +708,7 @@ class CompilerDirectivesAddDCmd : public DCmdWithParser { protected: DCmdArgument _filename; public: + static int num_arguments() { return 1; } CompilerDirectivesAddDCmd(outputStream* output, bool heap); static const char* name() { return "Compiler.directives_add"; @@ -781,6 +794,7 @@ class SymboltableDCmd : public DCmdWithParser { protected: DCmdArgument _verbose; public: + static int num_arguments() { return 1; } SymboltableDCmd(outputStream* output, bool heap); static const char* name() { return "VM.symboltable"; @@ -803,6 +817,7 @@ class StringtableDCmd : public DCmdWithParser { protected: DCmdArgument _verbose; public: + static int num_arguments() { return 1; } StringtableDCmd(outputStream* output, bool heap); static const char* name() { return "VM.stringtable"; @@ -825,6 +840,7 @@ class SystemDictionaryDCmd : public DCmdWithParser { protected: DCmdArgument _verbose; public: + static int num_arguments() { return 1; } SystemDictionaryDCmd(outputStream* output, bool heap); static const char* name() { return "VM.systemdictionary"; @@ -847,6 +863,7 @@ class ClassesDCmd : public DCmdWithParser { protected: DCmdArgument _verbose; public: + static int num_arguments() { return 1; } ClassesDCmd(outputStream* output, bool heap); static const char* name() { return "VM.classes"; @@ -891,6 +908,7 @@ protected: DCmdArgument _log; DCmdArgument _max; public: + static int num_arguments() { return 2; } EventLogDCmd(outputStream* output, bool heap); static const char* name() { return "VM.events"; @@ -917,6 +935,7 @@ protected: DCmdArgument _format; DCmdArgument _filepath; public: + static int num_arguments() { return 3; } ThreadDumpToFileDCmd(outputStream *output, bool heap); static const char *name() { return "Thread.dump_to_file"; @@ -931,7 +950,6 @@ public: JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; return p; } - static int num_arguments(); virtual void execute(DCmdSource source, TRAPS); }; diff --git a/src/hotspot/share/services/diagnosticFramework.hpp b/src/hotspot/share/services/diagnosticFramework.hpp index 3fdb89bf74d..8313954aaec 100644 --- a/src/hotspot/share/services/diagnosticFramework.hpp +++ b/src/hotspot/share/services/diagnosticFramework.hpp @@ -276,9 +276,7 @@ public: return p; } // num_arguments() is used by the DCmdFactoryImpl::get_num_arguments() template functions. - // - For subclasses of DCmdWithParser, it's calculated by DCmdParser::num_arguments(). - // - Other subclasses of DCmd have zero arguments by default. You can change this - // by defining your own version of MyDCmd::num_arguments(). + // All subclasses should override this to report the actual number of arguments. static int num_arguments() { return 0; } outputStream* output() const { return _output; } bool is_heap_allocated() const { return _is_heap_allocated; } @@ -439,13 +437,14 @@ public: } private: +#ifdef ASSERT template ::value)> - static int get_num_arguments() { + static int get_parsed_num_arguments() { return T::num_arguments(); } template ::value)> - static int get_num_arguments() { + static int get_parsed_num_arguments() { ResourceMark rm; DCmdClass* dcmd = new DCmdClass(nullptr, false); if (dcmd != nullptr) { @@ -455,6 +454,20 @@ private: return 0; } } +#endif + + template ::value)> + static int get_num_arguments() { + int n_args = T::num_arguments(); +#ifdef ASSERT + int n_parsed_args = get_parsed_num_arguments(); + 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 diff --git a/src/hotspot/share/services/nmtDCmd.hpp b/src/hotspot/share/services/nmtDCmd.hpp index 254ddbbef4e..9a06abb9144 100644 --- a/src/hotspot/share/services/nmtDCmd.hpp +++ b/src/hotspot/share/services/nmtDCmd.hpp @@ -44,6 +44,7 @@ class NMTDCmd: public DCmdWithParser { DCmdArgument _scale; public: + static int num_arguments() { return 7; } NMTDCmd(outputStream* output, bool heap); static const char* name() { return "VM.native_memory"; } static const char* description() {