--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Jan 05 17:16:13 2012 -0500
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Mon Jan 09 10:27:24 2012 +0100
@@ -23,11 +23,15 @@
*/
#include "precompiled.hpp"
+#include "gc_implementation/shared/vmGCOperations.hpp"
+#include "runtime/javaCalls.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticCommand.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"),
_cmd("command name", "The name of the command for which we want help",
"STRING", false) {
@@ -35,14 +39,6 @@
_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) {
if (_all.value()) {
GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list();
@@ -66,10 +62,11 @@
factory->is_enabled() ? "" : " [disabled]");
output()->print_cr(factory->description());
output()->print_cr("\nImpact: %s", factory->impact());
+ output()->cr();
cmd = factory->create_resource_instance(output());
if (cmd != NULL) {
DCmdMark mark(cmd);
- cmd->print_help(output());
+ cmd->print_help(factory->name());
}
} else {
output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value());
@@ -90,14 +87,6 @@
}
}
-void HelpDCmd::reset(TRAPS) {
- _dcmdparser.reset(CHECK);
-}
-
-void HelpDCmd::cleanup() {
- _dcmdparser.cleanup();
-}
-
int HelpDCmd::num_arguments() {
ResourceMark rm;
HelpDCmd* dcmd = new HelpDCmd(NULL, false);
@@ -109,14 +98,6 @@
}
}
-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) {
output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(),
Abstract_VM_Version::vm_release());
@@ -129,3 +110,210 @@
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;
+ }
+}