Mercurial > hg > graal-compiler
comparison src/share/vm/services/diagnosticCommand.cpp @ 4773:4f25538b54c9
7120511: Add diagnostic commands
Reviewed-by: acorn, phh, dcubed, sspitsyn
author | fparain |
---|---|
date | Mon, 09 Jan 2012 10:27:24 +0100 |
parents | 3b688d6ff3d0 |
children | a42c07c38c47 |
comparison
equal
deleted
inserted
replaced
4754:66259eca2bf7 | 4773:4f25538b54c9 |
---|---|
21 * questions. | 21 * questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/shared/vmGCOperations.hpp" | |
27 #include "runtime/javaCalls.hpp" | |
26 #include "services/diagnosticArgument.hpp" | 28 #include "services/diagnosticArgument.hpp" |
27 #include "services/diagnosticCommand.hpp" | 29 #include "services/diagnosticCommand.hpp" |
28 #include "services/diagnosticFramework.hpp" | 30 #include "services/diagnosticFramework.hpp" |
29 | 31 #include "services/heapDumper.hpp" |
30 HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap), | 32 #include "services/management.hpp" |
33 | |
34 HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), | |
31 _all("-all", "Show help for all commands", "BOOLEAN", false, "false"), | 35 _all("-all", "Show help for all commands", "BOOLEAN", false, "false"), |
32 _cmd("command name", "The name of the command for which we want help", | 36 _cmd("command name", "The name of the command for which we want help", |
33 "STRING", false) { | 37 "STRING", false) { |
34 _dcmdparser.add_dcmd_option(&_all); | 38 _dcmdparser.add_dcmd_option(&_all); |
35 _dcmdparser.add_dcmd_argument(&_cmd); | 39 _dcmdparser.add_dcmd_argument(&_cmd); |
36 }; | 40 }; |
37 | |
38 void HelpDCmd::parse(CmdLine* line, char delim, TRAPS) { | |
39 _dcmdparser.parse(line, delim, CHECK); | |
40 } | |
41 | |
42 void HelpDCmd::print_help(outputStream* out) { | |
43 _dcmdparser.print_help(out, name()); | |
44 } | |
45 | 41 |
46 void HelpDCmd::execute(TRAPS) { | 42 void HelpDCmd::execute(TRAPS) { |
47 if (_all.value()) { | 43 if (_all.value()) { |
48 GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(); | 44 GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(); |
49 for (int i = 0; i < cmd_list->length(); i++) { | 45 for (int i = 0; i < cmd_list->length(); i++) { |
64 if (factory != NULL) { | 60 if (factory != NULL) { |
65 output()->print_cr("%s%s", factory->name(), | 61 output()->print_cr("%s%s", factory->name(), |
66 factory->is_enabled() ? "" : " [disabled]"); | 62 factory->is_enabled() ? "" : " [disabled]"); |
67 output()->print_cr(factory->description()); | 63 output()->print_cr(factory->description()); |
68 output()->print_cr("\nImpact: %s", factory->impact()); | 64 output()->print_cr("\nImpact: %s", factory->impact()); |
65 output()->cr(); | |
69 cmd = factory->create_resource_instance(output()); | 66 cmd = factory->create_resource_instance(output()); |
70 if (cmd != NULL) { | 67 if (cmd != NULL) { |
71 DCmdMark mark(cmd); | 68 DCmdMark mark(cmd); |
72 cmd->print_help(output()); | 69 cmd->print_help(factory->name()); |
73 } | 70 } |
74 } else { | 71 } else { |
75 output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value()); | 72 output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value()); |
76 } | 73 } |
77 } else { | 74 } else { |
88 } | 85 } |
89 output()->print_cr("\nFor more information about a specific command use 'help <command>'."); | 86 output()->print_cr("\nFor more information about a specific command use 'help <command>'."); |
90 } | 87 } |
91 } | 88 } |
92 | 89 |
93 void HelpDCmd::reset(TRAPS) { | |
94 _dcmdparser.reset(CHECK); | |
95 } | |
96 | |
97 void HelpDCmd::cleanup() { | |
98 _dcmdparser.cleanup(); | |
99 } | |
100 | |
101 int HelpDCmd::num_arguments() { | 90 int HelpDCmd::num_arguments() { |
102 ResourceMark rm; | 91 ResourceMark rm; |
103 HelpDCmd* dcmd = new HelpDCmd(NULL, false); | 92 HelpDCmd* dcmd = new HelpDCmd(NULL, false); |
104 if (dcmd != NULL) { | 93 if (dcmd != NULL) { |
105 DCmdMark mark(dcmd); | 94 DCmdMark mark(dcmd); |
106 return dcmd->_dcmdparser.num_arguments(); | 95 return dcmd->_dcmdparser.num_arguments(); |
107 } else { | 96 } else { |
108 return 0; | 97 return 0; |
109 } | 98 } |
110 } | |
111 | |
112 GrowableArray<const char*>* HelpDCmd::argument_name_array() { | |
113 return _dcmdparser.argument_name_array(); | |
114 } | |
115 | |
116 GrowableArray<DCmdArgumentInfo*>* HelpDCmd::argument_info_array() { | |
117 return _dcmdparser.argument_info_array(); | |
118 } | 99 } |
119 | 100 |
120 void VersionDCmd::execute(TRAPS) { | 101 void VersionDCmd::execute(TRAPS) { |
121 output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(), | 102 output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(), |
122 Abstract_VM_Version::vm_release()); | 103 Abstract_VM_Version::vm_release()); |
127 } else { | 108 } else { |
128 output()->print_cr("JDK %d.%d", jdk_version.major_version(), | 109 output()->print_cr("JDK %d.%d", jdk_version.major_version(), |
129 jdk_version.minor_version()); | 110 jdk_version.minor_version()); |
130 } | 111 } |
131 } | 112 } |
113 | |
114 PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) : | |
115 DCmdWithParser(output, heap), | |
116 _all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") { | |
117 _dcmdparser.add_dcmd_option(&_all); | |
118 } | |
119 | |
120 void PrintVMFlagsDCmd::execute(TRAPS) { | |
121 if (_all.value()) { | |
122 CommandLineFlags::printFlags(output(), true); | |
123 } else { | |
124 CommandLineFlags::printSetFlags(output()); | |
125 } | |
126 } | |
127 | |
128 int PrintVMFlagsDCmd::num_arguments() { | |
129 ResourceMark rm; | |
130 PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false); | |
131 if (dcmd != NULL) { | |
132 DCmdMark mark(dcmd); | |
133 return dcmd->_dcmdparser.num_arguments(); | |
134 } else { | |
135 return 0; | |
136 } | |
137 } | |
138 | |
139 void PrintSystemPropertiesDCmd::execute(TRAPS) { | |
140 // load sun.misc.VMSupport | |
141 Symbol* klass = vmSymbols::sun_misc_VMSupport(); | |
142 klassOop k = SystemDictionary::resolve_or_fail(klass, true, CHECK); | |
143 instanceKlassHandle ik (THREAD, k); | |
144 if (ik->should_be_initialized()) { | |
145 ik->initialize(THREAD); | |
146 } | |
147 if (HAS_PENDING_EXCEPTION) { | |
148 java_lang_Throwable::print(PENDING_EXCEPTION, output()); | |
149 output()->cr(); | |
150 CLEAR_PENDING_EXCEPTION; | |
151 return; | |
152 } | |
153 | |
154 // invoke the serializePropertiesToByteArray method | |
155 JavaValue result(T_OBJECT); | |
156 JavaCallArguments args; | |
157 | |
158 Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature(); | |
159 JavaCalls::call_static(&result, | |
160 ik, | |
161 vmSymbols::serializePropertiesToByteArray_name(), | |
162 signature, | |
163 &args, | |
164 THREAD); | |
165 if (HAS_PENDING_EXCEPTION) { | |
166 java_lang_Throwable::print(PENDING_EXCEPTION, output()); | |
167 output()->cr(); | |
168 CLEAR_PENDING_EXCEPTION; | |
169 return; | |
170 } | |
171 | |
172 // The result should be a [B | |
173 oop res = (oop)result.get_jobject(); | |
174 assert(res->is_typeArray(), "just checking"); | |
175 assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking"); | |
176 | |
177 // copy the bytes to the output stream | |
178 typeArrayOop ba = typeArrayOop(res); | |
179 jbyte* addr = typeArrayOop(res)->byte_at_addr(0); | |
180 output()->print_raw((const char*)addr, ba->length()); | |
181 } | |
182 | |
183 VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) : | |
184 DCmdWithParser(output, heap), | |
185 _date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") { | |
186 _dcmdparser.add_dcmd_option(&_date); | |
187 } | |
188 | |
189 void VMUptimeDCmd::execute(TRAPS) { | |
190 if (_date.value()) { | |
191 output()->date_stamp(true, "", ": "); | |
192 } | |
193 output()->time_stamp().update_to(tty->time_stamp().ticks()); | |
194 output()->stamp(); | |
195 output()->print_cr(" s"); | |
196 } | |
197 | |
198 int VMUptimeDCmd::num_arguments() { | |
199 ResourceMark rm; | |
200 VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false); | |
201 if (dcmd != NULL) { | |
202 DCmdMark mark(dcmd); | |
203 return dcmd->_dcmdparser.num_arguments(); | |
204 } else { | |
205 return 0; | |
206 } | |
207 } | |
208 | |
209 void SystemGCDCmd::execute(TRAPS) { | |
210 Universe::heap()->collect(GCCause::_java_lang_system_gc); | |
211 } | |
212 | |
213 void RunFinalizationDCmd::execute(TRAPS) { | |
214 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), | |
215 true, CHECK); | |
216 instanceKlassHandle klass(THREAD, k); | |
217 JavaValue result(T_VOID); | |
218 JavaCalls::call_static(&result, klass, | |
219 vmSymbols::run_finalization_name(), | |
220 vmSymbols::void_method_signature(), CHECK); | |
221 } | |
222 | |
223 #ifndef SERVICES_KERNEL // Heap dumping not supported | |
224 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) : | |
225 DCmdWithParser(output, heap), | |
226 _filename("filename","Name of the dump file", "STRING",true), | |
227 _all("-all", "Dump all objects, including unreachable objects", | |
228 "BOOLEAN", false, "false") { | |
229 _dcmdparser.add_dcmd_option(&_all); | |
230 _dcmdparser.add_dcmd_argument(&_filename); | |
231 } | |
232 | |
233 void HeapDumpDCmd::execute(TRAPS) { | |
234 // Request a full GC before heap dump if _all is false | |
235 // This helps reduces the amount of unreachable objects in the dump | |
236 // and makes it easier to browse. | |
237 HeapDumper dumper(!_all.value() /* request GC if _all is false*/); | |
238 int res = dumper.dump(_filename.value()); | |
239 if (res == 0) { | |
240 output()->print_cr("Heap dump file created"); | |
241 } else { | |
242 // heap dump failed | |
243 ResourceMark rm; | |
244 char* error = dumper.error_as_C_string(); | |
245 if (error == NULL) { | |
246 output()->print_cr("Dump failed - reason unknown"); | |
247 } else { | |
248 output()->print_cr("%s", error); | |
249 } | |
250 } | |
251 } | |
252 | |
253 int HeapDumpDCmd::num_arguments() { | |
254 ResourceMark rm; | |
255 HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false); | |
256 if (dcmd != NULL) { | |
257 DCmdMark mark(dcmd); | |
258 return dcmd->_dcmdparser.num_arguments(); | |
259 } else { | |
260 return 0; | |
261 } | |
262 } | |
263 #endif // SERVICES_KERNEL | |
264 | |
265 ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) : | |
266 DCmdWithParser(output, heap), | |
267 _all("-all", "Inspect all objects, including unreachable objects", | |
268 "BOOLEAN", false, "false") { | |
269 _dcmdparser.add_dcmd_option(&_all); | |
270 } | |
271 | |
272 void ClassHistogramDCmd::execute(TRAPS) { | |
273 VM_GC_HeapInspection heapop(output(), | |
274 !_all.value() /* request full gc if false */, | |
275 true /* need_prologue */); | |
276 VMThread::execute(&heapop); | |
277 } | |
278 | |
279 int ClassHistogramDCmd::num_arguments() { | |
280 ResourceMark rm; | |
281 ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false); | |
282 if (dcmd != NULL) { | |
283 DCmdMark mark(dcmd); | |
284 return dcmd->_dcmdparser.num_arguments(); | |
285 } else { | |
286 return 0; | |
287 } | |
288 } | |
289 | |
290 ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) : | |
291 DCmdWithParser(output, heap), | |
292 _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") { | |
293 _dcmdparser.add_dcmd_option(&_locks); | |
294 } | |
295 | |
296 void ThreadDumpDCmd::execute(TRAPS) { | |
297 // thread stacks | |
298 VM_PrintThreads op1(output(), _locks.value()); | |
299 VMThread::execute(&op1); | |
300 | |
301 // JNI global handles | |
302 VM_PrintJNI op2(output()); | |
303 VMThread::execute(&op2); | |
304 | |
305 // Deadlock detection | |
306 VM_FindDeadlocks op3(output()); | |
307 VMThread::execute(&op3); | |
308 } | |
309 | |
310 int ThreadDumpDCmd::num_arguments() { | |
311 ResourceMark rm; | |
312 ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false); | |
313 if (dcmd != NULL) { | |
314 DCmdMark mark(dcmd); | |
315 return dcmd->_dcmdparser.num_arguments(); | |
316 } else { | |
317 return 0; | |
318 } | |
319 } |