1.1 --- a/src/share/vm/services/diagnosticCommand.cpp Thu Jan 05 17:16:13 2012 -0500 1.2 +++ b/src/share/vm/services/diagnosticCommand.cpp Mon Jan 09 10:27:24 2012 +0100 1.3 @@ -23,11 +23,15 @@ 1.4 */ 1.5 1.6 #include "precompiled.hpp" 1.7 +#include "gc_implementation/shared/vmGCOperations.hpp" 1.8 +#include "runtime/javaCalls.hpp" 1.9 #include "services/diagnosticArgument.hpp" 1.10 #include "services/diagnosticCommand.hpp" 1.11 #include "services/diagnosticFramework.hpp" 1.12 +#include "services/heapDumper.hpp" 1.13 +#include "services/management.hpp" 1.14 1.15 -HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap), 1.16 +HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), 1.17 _all("-all", "Show help for all commands", "BOOLEAN", false, "false"), 1.18 _cmd("command name", "The name of the command for which we want help", 1.19 "STRING", false) { 1.20 @@ -35,14 +39,6 @@ 1.21 _dcmdparser.add_dcmd_argument(&_cmd); 1.22 }; 1.23 1.24 -void HelpDCmd::parse(CmdLine* line, char delim, TRAPS) { 1.25 - _dcmdparser.parse(line, delim, CHECK); 1.26 -} 1.27 - 1.28 -void HelpDCmd::print_help(outputStream* out) { 1.29 - _dcmdparser.print_help(out, name()); 1.30 -} 1.31 - 1.32 void HelpDCmd::execute(TRAPS) { 1.33 if (_all.value()) { 1.34 GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(); 1.35 @@ -66,10 +62,11 @@ 1.36 factory->is_enabled() ? "" : " [disabled]"); 1.37 output()->print_cr(factory->description()); 1.38 output()->print_cr("\nImpact: %s", factory->impact()); 1.39 + output()->cr(); 1.40 cmd = factory->create_resource_instance(output()); 1.41 if (cmd != NULL) { 1.42 DCmdMark mark(cmd); 1.43 - cmd->print_help(output()); 1.44 + cmd->print_help(factory->name()); 1.45 } 1.46 } else { 1.47 output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value()); 1.48 @@ -90,14 +87,6 @@ 1.49 } 1.50 } 1.51 1.52 -void HelpDCmd::reset(TRAPS) { 1.53 - _dcmdparser.reset(CHECK); 1.54 -} 1.55 - 1.56 -void HelpDCmd::cleanup() { 1.57 - _dcmdparser.cleanup(); 1.58 -} 1.59 - 1.60 int HelpDCmd::num_arguments() { 1.61 ResourceMark rm; 1.62 HelpDCmd* dcmd = new HelpDCmd(NULL, false); 1.63 @@ -109,14 +98,6 @@ 1.64 } 1.65 } 1.66 1.67 -GrowableArray<const char*>* HelpDCmd::argument_name_array() { 1.68 - return _dcmdparser.argument_name_array(); 1.69 -} 1.70 - 1.71 -GrowableArray<DCmdArgumentInfo*>* HelpDCmd::argument_info_array() { 1.72 - return _dcmdparser.argument_info_array(); 1.73 -} 1.74 - 1.75 void VersionDCmd::execute(TRAPS) { 1.76 output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(), 1.77 Abstract_VM_Version::vm_release()); 1.78 @@ -129,3 +110,210 @@ 1.79 jdk_version.minor_version()); 1.80 } 1.81 } 1.82 + 1.83 +PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) : 1.84 + DCmdWithParser(output, heap), 1.85 + _all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") { 1.86 + _dcmdparser.add_dcmd_option(&_all); 1.87 +} 1.88 + 1.89 +void PrintVMFlagsDCmd::execute(TRAPS) { 1.90 + if (_all.value()) { 1.91 + CommandLineFlags::printFlags(output(), true); 1.92 + } else { 1.93 + CommandLineFlags::printSetFlags(output()); 1.94 + } 1.95 +} 1.96 + 1.97 +int PrintVMFlagsDCmd::num_arguments() { 1.98 + ResourceMark rm; 1.99 + PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false); 1.100 + if (dcmd != NULL) { 1.101 + DCmdMark mark(dcmd); 1.102 + return dcmd->_dcmdparser.num_arguments(); 1.103 + } else { 1.104 + return 0; 1.105 + } 1.106 +} 1.107 + 1.108 +void PrintSystemPropertiesDCmd::execute(TRAPS) { 1.109 + // load sun.misc.VMSupport 1.110 + Symbol* klass = vmSymbols::sun_misc_VMSupport(); 1.111 + klassOop k = SystemDictionary::resolve_or_fail(klass, true, CHECK); 1.112 + instanceKlassHandle ik (THREAD, k); 1.113 + if (ik->should_be_initialized()) { 1.114 + ik->initialize(THREAD); 1.115 + } 1.116 + if (HAS_PENDING_EXCEPTION) { 1.117 + java_lang_Throwable::print(PENDING_EXCEPTION, output()); 1.118 + output()->cr(); 1.119 + CLEAR_PENDING_EXCEPTION; 1.120 + return; 1.121 + } 1.122 + 1.123 + // invoke the serializePropertiesToByteArray method 1.124 + JavaValue result(T_OBJECT); 1.125 + JavaCallArguments args; 1.126 + 1.127 + Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature(); 1.128 + JavaCalls::call_static(&result, 1.129 + ik, 1.130 + vmSymbols::serializePropertiesToByteArray_name(), 1.131 + signature, 1.132 + &args, 1.133 + THREAD); 1.134 + if (HAS_PENDING_EXCEPTION) { 1.135 + java_lang_Throwable::print(PENDING_EXCEPTION, output()); 1.136 + output()->cr(); 1.137 + CLEAR_PENDING_EXCEPTION; 1.138 + return; 1.139 + } 1.140 + 1.141 + // The result should be a [B 1.142 + oop res = (oop)result.get_jobject(); 1.143 + assert(res->is_typeArray(), "just checking"); 1.144 + assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking"); 1.145 + 1.146 + // copy the bytes to the output stream 1.147 + typeArrayOop ba = typeArrayOop(res); 1.148 + jbyte* addr = typeArrayOop(res)->byte_at_addr(0); 1.149 + output()->print_raw((const char*)addr, ba->length()); 1.150 +} 1.151 + 1.152 +VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) : 1.153 + DCmdWithParser(output, heap), 1.154 + _date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") { 1.155 + _dcmdparser.add_dcmd_option(&_date); 1.156 +} 1.157 + 1.158 +void VMUptimeDCmd::execute(TRAPS) { 1.159 + if (_date.value()) { 1.160 + output()->date_stamp(true, "", ": "); 1.161 + } 1.162 + output()->time_stamp().update_to(tty->time_stamp().ticks()); 1.163 + output()->stamp(); 1.164 + output()->print_cr(" s"); 1.165 +} 1.166 + 1.167 +int VMUptimeDCmd::num_arguments() { 1.168 + ResourceMark rm; 1.169 + VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false); 1.170 + if (dcmd != NULL) { 1.171 + DCmdMark mark(dcmd); 1.172 + return dcmd->_dcmdparser.num_arguments(); 1.173 + } else { 1.174 + return 0; 1.175 + } 1.176 +} 1.177 + 1.178 +void SystemGCDCmd::execute(TRAPS) { 1.179 + Universe::heap()->collect(GCCause::_java_lang_system_gc); 1.180 +} 1.181 + 1.182 +void RunFinalizationDCmd::execute(TRAPS) { 1.183 + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), 1.184 + true, CHECK); 1.185 + instanceKlassHandle klass(THREAD, k); 1.186 + JavaValue result(T_VOID); 1.187 + JavaCalls::call_static(&result, klass, 1.188 + vmSymbols::run_finalization_name(), 1.189 + vmSymbols::void_method_signature(), CHECK); 1.190 +} 1.191 + 1.192 +#ifndef SERVICES_KERNEL // Heap dumping not supported 1.193 +HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) : 1.194 + DCmdWithParser(output, heap), 1.195 + _filename("filename","Name of the dump file", "STRING",true), 1.196 + _all("-all", "Dump all objects, including unreachable objects", 1.197 + "BOOLEAN", false, "false") { 1.198 + _dcmdparser.add_dcmd_option(&_all); 1.199 + _dcmdparser.add_dcmd_argument(&_filename); 1.200 +} 1.201 + 1.202 +void HeapDumpDCmd::execute(TRAPS) { 1.203 + // Request a full GC before heap dump if _all is false 1.204 + // This helps reduces the amount of unreachable objects in the dump 1.205 + // and makes it easier to browse. 1.206 + HeapDumper dumper(!_all.value() /* request GC if _all is false*/); 1.207 + int res = dumper.dump(_filename.value()); 1.208 + if (res == 0) { 1.209 + output()->print_cr("Heap dump file created"); 1.210 + } else { 1.211 + // heap dump failed 1.212 + ResourceMark rm; 1.213 + char* error = dumper.error_as_C_string(); 1.214 + if (error == NULL) { 1.215 + output()->print_cr("Dump failed - reason unknown"); 1.216 + } else { 1.217 + output()->print_cr("%s", error); 1.218 + } 1.219 + } 1.220 +} 1.221 + 1.222 +int HeapDumpDCmd::num_arguments() { 1.223 + ResourceMark rm; 1.224 + HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false); 1.225 + if (dcmd != NULL) { 1.226 + DCmdMark mark(dcmd); 1.227 + return dcmd->_dcmdparser.num_arguments(); 1.228 + } else { 1.229 + return 0; 1.230 + } 1.231 +} 1.232 +#endif // SERVICES_KERNEL 1.233 + 1.234 +ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) : 1.235 + DCmdWithParser(output, heap), 1.236 + _all("-all", "Inspect all objects, including unreachable objects", 1.237 + "BOOLEAN", false, "false") { 1.238 + _dcmdparser.add_dcmd_option(&_all); 1.239 +} 1.240 + 1.241 +void ClassHistogramDCmd::execute(TRAPS) { 1.242 + VM_GC_HeapInspection heapop(output(), 1.243 + !_all.value() /* request full gc if false */, 1.244 + true /* need_prologue */); 1.245 + VMThread::execute(&heapop); 1.246 +} 1.247 + 1.248 +int ClassHistogramDCmd::num_arguments() { 1.249 + ResourceMark rm; 1.250 + ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false); 1.251 + if (dcmd != NULL) { 1.252 + DCmdMark mark(dcmd); 1.253 + return dcmd->_dcmdparser.num_arguments(); 1.254 + } else { 1.255 + return 0; 1.256 + } 1.257 +} 1.258 + 1.259 +ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) : 1.260 + DCmdWithParser(output, heap), 1.261 + _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") { 1.262 + _dcmdparser.add_dcmd_option(&_locks); 1.263 +} 1.264 + 1.265 +void ThreadDumpDCmd::execute(TRAPS) { 1.266 + // thread stacks 1.267 + VM_PrintThreads op1(output(), _locks.value()); 1.268 + VMThread::execute(&op1); 1.269 + 1.270 + // JNI global handles 1.271 + VM_PrintJNI op2(output()); 1.272 + VMThread::execute(&op2); 1.273 + 1.274 + // Deadlock detection 1.275 + VM_FindDeadlocks op3(output()); 1.276 + VMThread::execute(&op3); 1.277 +} 1.278 + 1.279 +int ThreadDumpDCmd::num_arguments() { 1.280 + ResourceMark rm; 1.281 + ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false); 1.282 + if (dcmd != NULL) { 1.283 + DCmdMark mark(dcmd); 1.284 + return dcmd->_dcmdparser.num_arguments(); 1.285 + } else { 1.286 + return 0; 1.287 + } 1.288 +}