提交 d70602ec 编写于 作者: F fparain

7120511: Add diagnostic commands

Reviewed-by: acorn, phh, dcubed, sspitsyn
上级 7279047c
...@@ -296,6 +296,7 @@ ...@@ -296,6 +296,7 @@
template(finalize_method_name, "finalize") \ template(finalize_method_name, "finalize") \
template(reference_lock_name, "lock") \ template(reference_lock_name, "lock") \
template(reference_discovered_name, "discovered") \ template(reference_discovered_name, "discovered") \
template(run_finalization_name, "runFinalization") \
template(run_finalizers_on_exit_name, "runFinalizersOnExit") \ template(run_finalizers_on_exit_name, "runFinalizersOnExit") \
template(uncaughtException_name, "uncaughtException") \ template(uncaughtException_name, "uncaughtException") \
template(dispatchUncaughtException_name, "dispatchUncaughtException") \ template(dispatchUncaughtException_name, "dispatchUncaughtException") \
......
...@@ -2323,7 +2323,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, ...@@ -2323,7 +2323,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
#ifndef PRODUCT #ifndef PRODUCT
// -Xprintflags // -Xprintflags
} else if (match_option(option, "-Xprintflags", &tail)) { } else if (match_option(option, "-Xprintflags", &tail)) {
CommandLineFlags::printFlags(); CommandLineFlags::printFlags(tty, false);
vm_exit(0); vm_exit(0);
#endif #endif
// -D // -D
...@@ -2971,13 +2971,13 @@ jint Arguments::parse(const JavaVMInitArgs* args) { ...@@ -2971,13 +2971,13 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
IgnoreUnrecognizedVMOptions = false; IgnoreUnrecognizedVMOptions = false;
} }
if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) { if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) {
CommandLineFlags::printFlags(); CommandLineFlags::printFlags(tty, false);
vm_exit(0); vm_exit(0);
} }
#ifndef PRODUCT #ifndef PRODUCT
if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) { if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) {
CommandLineFlags::printFlags(true); CommandLineFlags::printFlags(tty, true);
vm_exit(0); vm_exit(0);
} }
#endif #endif
...@@ -3170,7 +3170,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) { ...@@ -3170,7 +3170,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
#endif #endif
if (PrintCommandLineFlags) { if (PrintCommandLineFlags) {
CommandLineFlags::printSetFlags(); CommandLineFlags::printSetFlags(tty);
} }
// Apply CPU specific policy for the BiasedLocking // Apply CPU specific policy for the BiasedLocking
......
...@@ -488,7 +488,7 @@ extern "C" { ...@@ -488,7 +488,7 @@ extern "C" {
} }
} }
void CommandLineFlags::printSetFlags() { void CommandLineFlags::printSetFlags(outputStream* out) {
// Print which flags were set on the command line // Print which flags were set on the command line
// note: this method is called before the thread structure is in place // note: this method is called before the thread structure is in place
// which means resource allocation cannot be used. // which means resource allocation cannot be used.
...@@ -507,11 +507,11 @@ void CommandLineFlags::printSetFlags() { ...@@ -507,11 +507,11 @@ void CommandLineFlags::printSetFlags() {
// Print // Print
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if (array[i]->origin /* naked field! */) { if (array[i]->origin /* naked field! */) {
array[i]->print_as_flag(tty); array[i]->print_as_flag(out);
tty->print(" "); out->print(" ");
} }
} }
tty->cr(); out->cr();
FREE_C_HEAP_ARRAY(Flag*, array); FREE_C_HEAP_ARRAY(Flag*, array);
} }
...@@ -524,7 +524,7 @@ void CommandLineFlags::verify() { ...@@ -524,7 +524,7 @@ void CommandLineFlags::verify() {
#endif // PRODUCT #endif // PRODUCT
void CommandLineFlags::printFlags(bool withComments) { void CommandLineFlags::printFlags(outputStream* out, bool withComments) {
// Print the flags sorted by name // Print the flags sorted by name
// note: this method is called before the thread structure is in place // note: this method is called before the thread structure is in place
// which means resource allocation cannot be used. // which means resource allocation cannot be used.
...@@ -541,10 +541,10 @@ void CommandLineFlags::printFlags(bool withComments) { ...@@ -541,10 +541,10 @@ void CommandLineFlags::printFlags(bool withComments) {
qsort(array, length, sizeof(Flag*), compare_flags); qsort(array, length, sizeof(Flag*), compare_flags);
// Print // Print
tty->print_cr("[Global flags]"); out->print_cr("[Global flags]");
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if (array[i]->is_unlocked()) { if (array[i]->is_unlocked()) {
array[i]->print_on(tty, withComments); array[i]->print_on(out, withComments);
} }
} }
FREE_C_HEAP_ARRAY(Flag*, array); FREE_C_HEAP_ARRAY(Flag*, array);
......
...@@ -326,9 +326,9 @@ class CommandLineFlags { ...@@ -326,9 +326,9 @@ class CommandLineFlags {
// Returns false if name is not a command line flag. // Returns false if name is not a command line flag.
static bool wasSetOnCmdline(const char* name, bool* value); static bool wasSetOnCmdline(const char* name, bool* value);
static void printSetFlags(); static void printSetFlags(outputStream* out);
static void printFlags(bool withComments = false ); static void printFlags(outputStream* out, bool withComments);
static void verify() PRODUCT_RETURN; static void verify() PRODUCT_RETURN;
}; };
......
...@@ -140,7 +140,7 @@ jint init_globals() { ...@@ -140,7 +140,7 @@ jint init_globals() {
// All the flags that get adjusted by VM_Version_init and os::init_2 // All the flags that get adjusted by VM_Version_init and os::init_2
// have been set so dump the flags now. // have been set so dump the flags now.
if (PrintFlagsFinal) { if (PrintFlagsFinal) {
CommandLineFlags::printFlags(); CommandLineFlags::printFlags(tty, false);
} }
return JNI_OK; return JNI_OK;
......
...@@ -99,6 +99,7 @@ static jint get_properties(AttachOperation* op, outputStream* out, Symbol* seria ...@@ -99,6 +99,7 @@ static jint get_properties(AttachOperation* op, outputStream* out, Symbol* seria
} }
// Implementation of "properties" command. // Implementation of "properties" command.
// See also: PrintSystemPropertiesDCmd class
static jint get_system_properties(AttachOperation* op, outputStream* out) { static jint get_system_properties(AttachOperation* op, outputStream* out) {
return get_properties(op, out, vmSymbols::serializePropertiesToByteArray_name()); return get_properties(op, out, vmSymbols::serializePropertiesToByteArray_name());
} }
...@@ -127,6 +128,7 @@ static jint data_dump(AttachOperation* op, outputStream* out) { ...@@ -127,6 +128,7 @@ static jint data_dump(AttachOperation* op, outputStream* out) {
} }
// Implementation of "threaddump" command - essentially a remote ctrl-break // Implementation of "threaddump" command - essentially a remote ctrl-break
// See also: ThreadDumpDCmd class
// //
static jint thread_dump(AttachOperation* op, outputStream* out) { static jint thread_dump(AttachOperation* op, outputStream* out) {
bool print_concurrent_locks = false; bool print_concurrent_locks = false;
...@@ -158,6 +160,7 @@ static jint jcmd(AttachOperation* op, outputStream* out) { ...@@ -158,6 +160,7 @@ static jint jcmd(AttachOperation* op, outputStream* out) {
DCmd::parse_and_execute(out, op->arg(0), ' ', THREAD); DCmd::parse_and_execute(out, op->arg(0), ' ', THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, out); java_lang_Throwable::print(PENDING_EXCEPTION, out);
out->cr();
CLEAR_PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION;
// The exception has been printed on the output stream // The exception has been printed on the output stream
// If the JVM returns JNI_ERR, the attachAPI throws a generic I/O // If the JVM returns JNI_ERR, the attachAPI throws a generic I/O
...@@ -169,6 +172,7 @@ static jint jcmd(AttachOperation* op, outputStream* out) { ...@@ -169,6 +172,7 @@ static jint jcmd(AttachOperation* op, outputStream* out) {
#ifndef SERVICES_KERNEL // Heap dumping not supported #ifndef SERVICES_KERNEL // Heap dumping not supported
// Implementation of "dumpheap" command. // Implementation of "dumpheap" command.
// See also: HeapDumpDCmd class
// //
// Input arguments :- // Input arguments :-
// arg0: Name of the dump file // arg0: Name of the dump file
...@@ -211,6 +215,7 @@ jint dump_heap(AttachOperation* op, outputStream* out) { ...@@ -211,6 +215,7 @@ jint dump_heap(AttachOperation* op, outputStream* out) {
#endif // SERVICES_KERNEL #endif // SERVICES_KERNEL
// Implementation of "inspectheap" command // Implementation of "inspectheap" command
// See also: ClassHistogramDCmd class
// //
// Input arguments :- // Input arguments :-
// arg0: "-live" or "-all" // arg0: "-live" or "-all"
...@@ -354,6 +359,7 @@ static jint set_flag(AttachOperation* op, outputStream* out) { ...@@ -354,6 +359,7 @@ static jint set_flag(AttachOperation* op, outputStream* out) {
} }
// Implementation of "printflag" command // Implementation of "printflag" command
// See also: PrintVMFlagsDCmd class
static jint print_flag(AttachOperation* op, outputStream* out) { static jint print_flag(AttachOperation* op, outputStream* out) {
const char* name = NULL; const char* name = NULL;
if ((name = op->arg(0)) == NULL) { if ((name = op->arg(0)) == NULL) {
......
...@@ -23,11 +23,15 @@ ...@@ -23,11 +23,15 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "runtime/javaCalls.hpp"
#include "services/diagnosticArgument.hpp" #include "services/diagnosticArgument.hpp"
#include "services/diagnosticCommand.hpp" #include "services/diagnosticCommand.hpp"
#include "services/diagnosticFramework.hpp" #include "services/diagnosticFramework.hpp"
#include "services/heapDumper.hpp"
#include "services/management.hpp"
HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap), HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
_all("-all", "Show help for all commands", "BOOLEAN", false, "false"), _all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
_cmd("command name", "The name of the command for which we want help", _cmd("command name", "The name of the command for which we want help",
"STRING", false) { "STRING", false) {
...@@ -35,14 +39,6 @@ HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap), ...@@ -35,14 +39,6 @@ HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap),
_dcmdparser.add_dcmd_argument(&_cmd); _dcmdparser.add_dcmd_argument(&_cmd);
}; };
void HelpDCmd::parse(CmdLine* line, char delim, TRAPS) {
_dcmdparser.parse(line, delim, CHECK);
}
void HelpDCmd::print_help(outputStream* out) {
_dcmdparser.print_help(out, name());
}
void HelpDCmd::execute(TRAPS) { void HelpDCmd::execute(TRAPS) {
if (_all.value()) { if (_all.value()) {
GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(); GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list();
...@@ -66,10 +62,11 @@ void HelpDCmd::execute(TRAPS) { ...@@ -66,10 +62,11 @@ void HelpDCmd::execute(TRAPS) {
factory->is_enabled() ? "" : " [disabled]"); factory->is_enabled() ? "" : " [disabled]");
output()->print_cr(factory->description()); output()->print_cr(factory->description());
output()->print_cr("\nImpact: %s", factory->impact()); output()->print_cr("\nImpact: %s", factory->impact());
output()->cr();
cmd = factory->create_resource_instance(output()); cmd = factory->create_resource_instance(output());
if (cmd != NULL) { if (cmd != NULL) {
DCmdMark mark(cmd); DCmdMark mark(cmd);
cmd->print_help(output()); cmd->print_help(factory->name());
} }
} else { } else {
output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value()); output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value());
...@@ -90,14 +87,6 @@ void HelpDCmd::execute(TRAPS) { ...@@ -90,14 +87,6 @@ void HelpDCmd::execute(TRAPS) {
} }
} }
void HelpDCmd::reset(TRAPS) {
_dcmdparser.reset(CHECK);
}
void HelpDCmd::cleanup() {
_dcmdparser.cleanup();
}
int HelpDCmd::num_arguments() { int HelpDCmd::num_arguments() {
ResourceMark rm; ResourceMark rm;
HelpDCmd* dcmd = new HelpDCmd(NULL, false); HelpDCmd* dcmd = new HelpDCmd(NULL, false);
...@@ -109,14 +98,6 @@ int HelpDCmd::num_arguments() { ...@@ -109,14 +98,6 @@ int HelpDCmd::num_arguments() {
} }
} }
GrowableArray<const char*>* HelpDCmd::argument_name_array() {
return _dcmdparser.argument_name_array();
}
GrowableArray<DCmdArgumentInfo*>* HelpDCmd::argument_info_array() {
return _dcmdparser.argument_info_array();
}
void VersionDCmd::execute(TRAPS) { void VersionDCmd::execute(TRAPS) {
output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(), output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(),
Abstract_VM_Version::vm_release()); Abstract_VM_Version::vm_release());
...@@ -129,3 +110,210 @@ void VersionDCmd::execute(TRAPS) { ...@@ -129,3 +110,210 @@ void VersionDCmd::execute(TRAPS) {
jdk_version.minor_version()); jdk_version.minor_version());
} }
} }
PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_all);
}
void PrintVMFlagsDCmd::execute(TRAPS) {
if (_all.value()) {
CommandLineFlags::printFlags(output(), true);
} else {
CommandLineFlags::printSetFlags(output());
}
}
int PrintVMFlagsDCmd::num_arguments() {
ResourceMark rm;
PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
void PrintSystemPropertiesDCmd::execute(TRAPS) {
// load sun.misc.VMSupport
Symbol* klass = vmSymbols::sun_misc_VMSupport();
klassOop k = SystemDictionary::resolve_or_fail(klass, true, CHECK);
instanceKlassHandle ik (THREAD, k);
if (ik->should_be_initialized()) {
ik->initialize(THREAD);
}
if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, output());
output()->cr();
CLEAR_PENDING_EXCEPTION;
return;
}
// invoke the serializePropertiesToByteArray method
JavaValue result(T_OBJECT);
JavaCallArguments args;
Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature();
JavaCalls::call_static(&result,
ik,
vmSymbols::serializePropertiesToByteArray_name(),
signature,
&args,
THREAD);
if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, output());
output()->cr();
CLEAR_PENDING_EXCEPTION;
return;
}
// The result should be a [B
oop res = (oop)result.get_jobject();
assert(res->is_typeArray(), "just checking");
assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking");
// copy the bytes to the output stream
typeArrayOop ba = typeArrayOop(res);
jbyte* addr = typeArrayOop(res)->byte_at_addr(0);
output()->print_raw((const char*)addr, ba->length());
}
VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_date);
}
void VMUptimeDCmd::execute(TRAPS) {
if (_date.value()) {
output()->date_stamp(true, "", ": ");
}
output()->time_stamp().update_to(tty->time_stamp().ticks());
output()->stamp();
output()->print_cr(" s");
}
int VMUptimeDCmd::num_arguments() {
ResourceMark rm;
VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
void SystemGCDCmd::execute(TRAPS) {
Universe::heap()->collect(GCCause::_java_lang_system_gc);
}
void RunFinalizationDCmd::execute(TRAPS) {
klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
true, CHECK);
instanceKlassHandle klass(THREAD, k);
JavaValue result(T_VOID);
JavaCalls::call_static(&result, klass,
vmSymbols::run_finalization_name(),
vmSymbols::void_method_signature(), CHECK);
}
#ifndef SERVICES_KERNEL // Heap dumping not supported
HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_filename("filename","Name of the dump file", "STRING",true),
_all("-all", "Dump all objects, including unreachable objects",
"BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_all);
_dcmdparser.add_dcmd_argument(&_filename);
}
void HeapDumpDCmd::execute(TRAPS) {
// Request a full GC before heap dump if _all is false
// This helps reduces the amount of unreachable objects in the dump
// and makes it easier to browse.
HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
int res = dumper.dump(_filename.value());
if (res == 0) {
output()->print_cr("Heap dump file created");
} else {
// heap dump failed
ResourceMark rm;
char* error = dumper.error_as_C_string();
if (error == NULL) {
output()->print_cr("Dump failed - reason unknown");
} else {
output()->print_cr("%s", error);
}
}
}
int HeapDumpDCmd::num_arguments() {
ResourceMark rm;
HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
#endif // SERVICES_KERNEL
ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_all("-all", "Inspect all objects, including unreachable objects",
"BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_all);
}
void ClassHistogramDCmd::execute(TRAPS) {
VM_GC_HeapInspection heapop(output(),
!_all.value() /* request full gc if false */,
true /* need_prologue */);
VMThread::execute(&heapop);
}
int ClassHistogramDCmd::num_arguments() {
ResourceMark rm;
ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_locks);
}
void ThreadDumpDCmd::execute(TRAPS) {
// thread stacks
VM_PrintThreads op1(output(), _locks.value());
VMThread::execute(&op1);
// JNI global handles
VM_PrintJNI op2(output());
VMThread::execute(&op2);
// Deadlock detection
VM_FindDeadlocks op3(output());
VMThread::execute(&op3);
}
int ThreadDumpDCmd::num_arguments() {
ResourceMark rm;
ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
...@@ -35,9 +35,8 @@ ...@@ -35,9 +35,8 @@
#include "services/diagnosticCommand.hpp" #include "services/diagnosticCommand.hpp"
#include "services/diagnosticFramework.hpp" #include "services/diagnosticFramework.hpp"
class HelpDCmd : public DCmd { class HelpDCmd : public DCmdWithParser {
protected: protected:
DCmdParser _dcmdparser;
DCmdArgument<bool> _all; DCmdArgument<bool> _all;
DCmdArgument<char*> _cmd; DCmdArgument<char*> _cmd;
public: public:
...@@ -50,13 +49,7 @@ public: ...@@ -50,13 +49,7 @@ public:
} }
static const char* impact() { return "Low: "; } static const char* impact() { return "Low: "; }
static int num_arguments(); static int num_arguments();
virtual void parse(CmdLine* line, char delim, TRAPS);
virtual void execute(TRAPS); virtual void execute(TRAPS);
virtual void reset(TRAPS);
virtual void cleanup();
virtual void print_help(outputStream* out);
virtual GrowableArray<const char*>* argument_name_array();
virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array();
}; };
class VersionDCmd : public DCmd { class VersionDCmd : public DCmd {
...@@ -68,9 +61,156 @@ public: ...@@ -68,9 +61,156 @@ public:
} }
static const char* impact() { return "Low: "; } static const char* impact() { return "Low: "; }
static int num_arguments() { return 0; } static int num_arguments() { return 0; }
virtual void parse(CmdLine* line, char delim, TRAPS) { }
virtual void execute(TRAPS); virtual void execute(TRAPS);
virtual void print_help(outputStream* out) { } };
class CommandLineDCmd : public DCmd {
public:
CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "VM.command_line"; }
static const char* description() {
return "Print the command line used to start this VM instance.";
}
static const char* impact() { return "Low: "; }
static int num_arguments() { return 0; }
virtual void execute(TRAPS) {
Arguments::print_on(_output);
}
};
// See also: get_system_properties in attachListener.cpp
class PrintSystemPropertiesDCmd : public DCmd {
public:
PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "VM.system_properties"; }
static const char* description() {
return "Print system properties.";
}
static const char* impact() {
return "Low: ";
}
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
};
// See also: print_flag in attachListener.cpp
class PrintVMFlagsDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _all;
public:
PrintVMFlagsDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.flags"; }
static const char* description() {
return "Print VM flag options and their current values.";
}
static const char* impact() {
return "Low: ";
}
static int num_arguments();
virtual void execute(TRAPS);
};
class VMUptimeDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _date;
public:
VMUptimeDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.uptime"; }
static const char* description() {
return "Print VM uptime.";
}
static const char* impact() {
return "Low: ";
}
static int num_arguments();
virtual void execute(TRAPS);
};
class SystemGCDCmd : public DCmd {
public:
SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "GC.run"; }
static const char* description() {
return "Call java.lang.System.gc().";
}
static const char* impact() {
return "Medium: Depends on Java heap size and content.";
}
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
};
class RunFinalizationDCmd : public DCmd {
public:
RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "GC.run_finalization"; }
static const char* description() {
return "Call java.lang.System.runFinalization().";
}
static const char* impact() {
return "Medium: Depends on Java content.";
}
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
};
#ifndef SERVICES_KERNEL // Heap dumping not supported
// See also: dump_heap in attachListener.cpp
class HeapDumpDCmd : public DCmdWithParser {
protected:
DCmdArgument<char*> _filename;
DCmdArgument<bool> _all;
public:
HeapDumpDCmd(outputStream* output, bool heap);
static const char* name() {
return "GC.heap_dump";
}
static const char* description() {
return "Generate a HPROF format dump of the Java heap.";
}
static const char* impact() {
return "High: Depends on Java heap size and content. "
"Request a full GC unless the '-all' option is specified.";
}
static int num_arguments();
virtual void execute(TRAPS);
};
#endif // SERVICES_KERNEL
// See also: inspeactheap in attachListener.cpp
class ClassHistogramDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _all;
public:
ClassHistogramDCmd(outputStream* output, bool heap);
static const char* name() {
return "GC.class_histogram";
}
static const char* description() {
return "Provide statistics about the Java heap usage.";
}
static const char* impact() {
return "High: Depends on Java heap size and content.";
}
static int num_arguments();
virtual void execute(TRAPS);
};
// See also: thread_dump in attachListener.cpp
class ThreadDumpDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _locks;
public:
ThreadDumpDCmd(outputStream* output, bool heap);
static const char* name() { return "Thread.print"; }
static const char* description() {
return "Print all threads with stacktraces.";
}
static const char* impact() {
return "Medium: Depends on the number of threads.";
}
static int num_arguments();
virtual void execute(TRAPS);
}; };
#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
...@@ -226,7 +226,7 @@ void DCmdParser::check(TRAPS) { ...@@ -226,7 +226,7 @@ void DCmdParser::check(TRAPS) {
} }
void DCmdParser::print_help(outputStream* out, const char* cmd_name) { void DCmdParser::print_help(outputStream* out, const char* cmd_name) {
out->print("\nSyntax : %s %s", cmd_name, _options == NULL ? "" : "[options]"); out->print("Syntax : %s %s", cmd_name, _options == NULL ? "" : "[options]");
GenDCmdArgument* arg = _arguments_list; GenDCmdArgument* arg = _arguments_list;
while (arg != NULL) { while (arg != NULL) {
if (arg->is_mandatory()) { if (arg->is_mandatory()) {
...@@ -373,6 +373,30 @@ void DCmd::parse_and_execute(outputStream* out, const char* cmdline, ...@@ -373,6 +373,30 @@ void DCmd::parse_and_execute(outputStream* out, const char* cmdline,
} }
} }
void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) {
_dcmdparser.parse(line, delim, CHECK);
}
void DCmdWithParser::print_help(const char* name) {
_dcmdparser.print_help(output(), name);
}
void DCmdWithParser::reset(TRAPS) {
_dcmdparser.reset(CHECK);
}
void DCmdWithParser::cleanup() {
_dcmdparser.cleanup();
}
GrowableArray<const char*>* DCmdWithParser::argument_name_array() {
return _dcmdparser.argument_name_array();
}
GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() {
return _dcmdparser.argument_info_array();
}
Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true); Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
DCmdFactory* DCmdFactory::factory(const char* name, size_t len) { DCmdFactory* DCmdFactory::factory(const char* name, size_t len) {
......
...@@ -241,8 +241,17 @@ public: ...@@ -241,8 +241,17 @@ public:
static int num_arguments() { return 0; } static int num_arguments() { return 0; }
outputStream* output() { return _output; } outputStream* output() { return _output; }
bool is_heap_allocated() { return _is_heap_allocated; } bool is_heap_allocated() { return _is_heap_allocated; }
virtual void print_help(outputStream* out) { }; virtual void print_help(const char* name) {
virtual void parse(CmdLine* line, char delim, TRAPS) { } output()->print_cr("Syntax: %s", name);
}
virtual void parse(CmdLine* line, char delim, TRAPS) {
DCmdArgIter iter(line->args_addr(), line->args_len(), delim);
bool has_arg = iter.next(CHECK);
if (has_arg) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unknown argument in diagnostic command");
}
}
virtual void execute(TRAPS) { } virtual void execute(TRAPS) { }
virtual void reset(TRAPS) { } virtual void reset(TRAPS) { }
virtual void cleanup() { } virtual void cleanup() { }
...@@ -262,6 +271,25 @@ public: ...@@ -262,6 +271,25 @@ public:
char delim, TRAPS); char delim, TRAPS);
}; };
class DCmdWithParser : public DCmd {
protected:
DCmdParser _dcmdparser;
public:
DCmdWithParser (outputStream *output, bool heap=false) : DCmd(output, heap) { }
static const char* name() { return "No Name";}
static const char* description() { return "No Help";}
static const char* disabled_message() { return "Diagnostic command currently disabled"; }
static const char* impact() { return "Low: No impact"; }
static int num_arguments() { return 0; }
virtual void parse(CmdLine *line, char delim, TRAPS);
virtual void execute(TRAPS) { }
virtual void reset(TRAPS);
virtual void cleanup();
virtual void print_help(const char* name);
virtual GrowableArray<const char*>* argument_name_array();
virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array();
};
class DCmdMark : public StackObj { class DCmdMark : public StackObj {
DCmd* _ref; DCmd* _ref;
public: public:
......
...@@ -118,8 +118,22 @@ void Management::init() { ...@@ -118,8 +118,22 @@ void Management::init() {
#endif // SERVICES_KERNEL #endif // SERVICES_KERNEL
_optional_support.isThreadAllocatedMemorySupported = 1; _optional_support.isThreadAllocatedMemorySupported = 1;
// Registration of the diagnostic commands
// First boolean argument specifies if the command is enabled
// Second boolean argument specifies if the command is hidden
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
#ifndef SERVICES_KERNEL // Heap dumping not supported
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
#endif // SERVICES_KERNEL
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
} }
void Management::initialize(TRAPS) { void Management::initialize(TRAPS) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册