Mercurial > hg > truffle
annotate src/share/vm/services/diagnosticCommand.cpp @ 5763:a3d71693e0ce
removed bytecode disassembly from CodeCacheRuntime into separate BytecodeDisassembler class
removed VM call for doing bytecode disassembly
added support for explicitly excluding classes from JaCoCo (put '// JaCoCo Exclude' somewhere in the source file)
added node intrinsics to MaterializeNode
added snippets for the UnsignedMath classes
each file opened by CFGPrinter now includes a unique id in its name to avoid a race of multiple threads writing to the same file
the IdealGraphPrinter uses the new BytecodeDisassembler mechanism
teh UnsignedMath class is exclude from JaCoCo processing as it is used in snippets
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 04 Jul 2012 21:57:49 +0200 |
parents | a42c07c38c47 |
children | 645162d94294 |
rev | line source |
---|---|
4133 | 1 /* |
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 #include "precompiled.hpp" | |
4773 | 26 #include "gc_implementation/shared/vmGCOperations.hpp" |
27 #include "runtime/javaCalls.hpp" | |
4133 | 28 #include "services/diagnosticArgument.hpp" |
29 #include "services/diagnosticCommand.hpp" | |
30 #include "services/diagnosticFramework.hpp" | |
4773 | 31 #include "services/heapDumper.hpp" |
32 #include "services/management.hpp" | |
4133 | 33 |
4851
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
34 void DCmdRegistrant::register_dcmds(){ |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
35 // Registration of the diagnostic commands |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
36 // First boolean argument specifies if the command is enabled |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
37 // Second boolean argument specifies if the command is hidden |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
38 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
39 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
40 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
41 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
42 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
43 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
44 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
45 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
46 #ifndef SERVICES_KERNEL // Heap dumping not supported |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
47 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
48 #endif // SERVICES_KERNEL |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
49 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
50 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false)); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
51 |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
52 } |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
53 |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
54 #ifndef HAVE_EXTRA_DCMD |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
55 void DCmdRegistrant::register_dcmds_ext(){ |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
56 // Do nothing here |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
57 } |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
58 #endif |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
59 |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
60 |
4773 | 61 HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), |
4133 | 62 _all("-all", "Show help for all commands", "BOOLEAN", false, "false"), |
63 _cmd("command name", "The name of the command for which we want help", | |
64 "STRING", false) { | |
65 _dcmdparser.add_dcmd_option(&_all); | |
66 _dcmdparser.add_dcmd_argument(&_cmd); | |
67 }; | |
68 | |
69 void HelpDCmd::execute(TRAPS) { | |
70 if (_all.value()) { | |
71 GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(); | |
72 for (int i = 0; i < cmd_list->length(); i++) { | |
73 DCmdFactory* factory = DCmdFactory::factory(cmd_list->at(i), | |
74 strlen(cmd_list->at(i))); | |
75 if (!factory->is_hidden()) { | |
76 output()->print_cr("%s%s", factory->name(), | |
77 factory->is_enabled() ? "" : " [disabled]"); | |
78 output()->print_cr("\t%s", factory->description()); | |
79 output()->cr(); | |
80 } | |
81 factory = factory->next(); | |
82 } | |
83 } else if (_cmd.has_value()) { | |
84 DCmd* cmd = NULL; | |
85 DCmdFactory* factory = DCmdFactory::factory(_cmd.value(), | |
86 strlen(_cmd.value())); | |
87 if (factory != NULL) { | |
88 output()->print_cr("%s%s", factory->name(), | |
89 factory->is_enabled() ? "" : " [disabled]"); | |
90 output()->print_cr(factory->description()); | |
91 output()->print_cr("\nImpact: %s", factory->impact()); | |
4773 | 92 output()->cr(); |
4133 | 93 cmd = factory->create_resource_instance(output()); |
94 if (cmd != NULL) { | |
95 DCmdMark mark(cmd); | |
4773 | 96 cmd->print_help(factory->name()); |
4133 | 97 } |
98 } else { | |
99 output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value()); | |
100 } | |
101 } else { | |
102 output()->print_cr("The following commands are available:"); | |
103 GrowableArray<const char *>* cmd_list = DCmdFactory::DCmd_list(); | |
104 for (int i = 0; i < cmd_list->length(); i++) { | |
105 DCmdFactory* factory = DCmdFactory::factory(cmd_list->at(i), | |
106 strlen(cmd_list->at(i))); | |
107 if (!factory->is_hidden()) { | |
108 output()->print_cr("%s%s", factory->name(), | |
109 factory->is_enabled() ? "" : " [disabled]"); | |
110 } | |
111 factory = factory->_next; | |
112 } | |
113 output()->print_cr("\nFor more information about a specific command use 'help <command>'."); | |
114 } | |
115 } | |
116 | |
117 int HelpDCmd::num_arguments() { | |
118 ResourceMark rm; | |
119 HelpDCmd* dcmd = new HelpDCmd(NULL, false); | |
120 if (dcmd != NULL) { | |
121 DCmdMark mark(dcmd); | |
122 return dcmd->_dcmdparser.num_arguments(); | |
123 } else { | |
124 return 0; | |
125 } | |
126 } | |
127 | |
128 void VersionDCmd::execute(TRAPS) { | |
129 output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(), | |
130 Abstract_VM_Version::vm_release()); | |
131 JDK_Version jdk_version = JDK_Version::current(); | |
132 if (jdk_version.update_version() > 0) { | |
133 output()->print_cr("JDK %d.%d_%02d", jdk_version.major_version(), | |
134 jdk_version.minor_version(), jdk_version.update_version()); | |
135 } else { | |
136 output()->print_cr("JDK %d.%d", jdk_version.major_version(), | |
137 jdk_version.minor_version()); | |
138 } | |
139 } | |
4773 | 140 |
141 PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) : | |
142 DCmdWithParser(output, heap), | |
143 _all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") { | |
144 _dcmdparser.add_dcmd_option(&_all); | |
145 } | |
146 | |
147 void PrintVMFlagsDCmd::execute(TRAPS) { | |
148 if (_all.value()) { | |
149 CommandLineFlags::printFlags(output(), true); | |
150 } else { | |
151 CommandLineFlags::printSetFlags(output()); | |
152 } | |
153 } | |
154 | |
155 int PrintVMFlagsDCmd::num_arguments() { | |
156 ResourceMark rm; | |
157 PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false); | |
158 if (dcmd != NULL) { | |
159 DCmdMark mark(dcmd); | |
160 return dcmd->_dcmdparser.num_arguments(); | |
161 } else { | |
162 return 0; | |
163 } | |
164 } | |
165 | |
166 void PrintSystemPropertiesDCmd::execute(TRAPS) { | |
167 // load sun.misc.VMSupport | |
168 Symbol* klass = vmSymbols::sun_misc_VMSupport(); | |
169 klassOop k = SystemDictionary::resolve_or_fail(klass, true, CHECK); | |
170 instanceKlassHandle ik (THREAD, k); | |
171 if (ik->should_be_initialized()) { | |
172 ik->initialize(THREAD); | |
173 } | |
174 if (HAS_PENDING_EXCEPTION) { | |
175 java_lang_Throwable::print(PENDING_EXCEPTION, output()); | |
176 output()->cr(); | |
177 CLEAR_PENDING_EXCEPTION; | |
178 return; | |
179 } | |
180 | |
181 // invoke the serializePropertiesToByteArray method | |
182 JavaValue result(T_OBJECT); | |
183 JavaCallArguments args; | |
184 | |
185 Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature(); | |
186 JavaCalls::call_static(&result, | |
187 ik, | |
188 vmSymbols::serializePropertiesToByteArray_name(), | |
189 signature, | |
190 &args, | |
191 THREAD); | |
192 if (HAS_PENDING_EXCEPTION) { | |
193 java_lang_Throwable::print(PENDING_EXCEPTION, output()); | |
194 output()->cr(); | |
195 CLEAR_PENDING_EXCEPTION; | |
196 return; | |
197 } | |
198 | |
199 // The result should be a [B | |
200 oop res = (oop)result.get_jobject(); | |
201 assert(res->is_typeArray(), "just checking"); | |
202 assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking"); | |
203 | |
204 // copy the bytes to the output stream | |
205 typeArrayOop ba = typeArrayOop(res); | |
206 jbyte* addr = typeArrayOop(res)->byte_at_addr(0); | |
207 output()->print_raw((const char*)addr, ba->length()); | |
208 } | |
209 | |
210 VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) : | |
211 DCmdWithParser(output, heap), | |
212 _date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") { | |
213 _dcmdparser.add_dcmd_option(&_date); | |
214 } | |
215 | |
216 void VMUptimeDCmd::execute(TRAPS) { | |
217 if (_date.value()) { | |
218 output()->date_stamp(true, "", ": "); | |
219 } | |
220 output()->time_stamp().update_to(tty->time_stamp().ticks()); | |
221 output()->stamp(); | |
222 output()->print_cr(" s"); | |
223 } | |
224 | |
225 int VMUptimeDCmd::num_arguments() { | |
226 ResourceMark rm; | |
227 VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false); | |
228 if (dcmd != NULL) { | |
229 DCmdMark mark(dcmd); | |
230 return dcmd->_dcmdparser.num_arguments(); | |
231 } else { | |
232 return 0; | |
233 } | |
234 } | |
235 | |
236 void SystemGCDCmd::execute(TRAPS) { | |
237 Universe::heap()->collect(GCCause::_java_lang_system_gc); | |
238 } | |
239 | |
240 void RunFinalizationDCmd::execute(TRAPS) { | |
241 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), | |
242 true, CHECK); | |
243 instanceKlassHandle klass(THREAD, k); | |
244 JavaValue result(T_VOID); | |
245 JavaCalls::call_static(&result, klass, | |
246 vmSymbols::run_finalization_name(), | |
247 vmSymbols::void_method_signature(), CHECK); | |
248 } | |
249 | |
250 #ifndef SERVICES_KERNEL // Heap dumping not supported | |
251 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) : | |
252 DCmdWithParser(output, heap), | |
253 _filename("filename","Name of the dump file", "STRING",true), | |
254 _all("-all", "Dump all objects, including unreachable objects", | |
255 "BOOLEAN", false, "false") { | |
256 _dcmdparser.add_dcmd_option(&_all); | |
257 _dcmdparser.add_dcmd_argument(&_filename); | |
258 } | |
259 | |
260 void HeapDumpDCmd::execute(TRAPS) { | |
261 // Request a full GC before heap dump if _all is false | |
262 // This helps reduces the amount of unreachable objects in the dump | |
263 // and makes it easier to browse. | |
264 HeapDumper dumper(!_all.value() /* request GC if _all is false*/); | |
265 int res = dumper.dump(_filename.value()); | |
266 if (res == 0) { | |
267 output()->print_cr("Heap dump file created"); | |
268 } else { | |
269 // heap dump failed | |
270 ResourceMark rm; | |
271 char* error = dumper.error_as_C_string(); | |
272 if (error == NULL) { | |
273 output()->print_cr("Dump failed - reason unknown"); | |
274 } else { | |
275 output()->print_cr("%s", error); | |
276 } | |
277 } | |
278 } | |
279 | |
280 int HeapDumpDCmd::num_arguments() { | |
281 ResourceMark rm; | |
282 HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false); | |
283 if (dcmd != NULL) { | |
284 DCmdMark mark(dcmd); | |
285 return dcmd->_dcmdparser.num_arguments(); | |
286 } else { | |
287 return 0; | |
288 } | |
289 } | |
290 #endif // SERVICES_KERNEL | |
291 | |
292 ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) : | |
293 DCmdWithParser(output, heap), | |
294 _all("-all", "Inspect all objects, including unreachable objects", | |
295 "BOOLEAN", false, "false") { | |
296 _dcmdparser.add_dcmd_option(&_all); | |
297 } | |
298 | |
299 void ClassHistogramDCmd::execute(TRAPS) { | |
300 VM_GC_HeapInspection heapop(output(), | |
301 !_all.value() /* request full gc if false */, | |
302 true /* need_prologue */); | |
303 VMThread::execute(&heapop); | |
304 } | |
305 | |
306 int ClassHistogramDCmd::num_arguments() { | |
307 ResourceMark rm; | |
308 ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false); | |
309 if (dcmd != NULL) { | |
310 DCmdMark mark(dcmd); | |
311 return dcmd->_dcmdparser.num_arguments(); | |
312 } else { | |
313 return 0; | |
314 } | |
315 } | |
316 | |
317 ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) : | |
318 DCmdWithParser(output, heap), | |
319 _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") { | |
320 _dcmdparser.add_dcmd_option(&_locks); | |
321 } | |
322 | |
323 void ThreadDumpDCmd::execute(TRAPS) { | |
324 // thread stacks | |
325 VM_PrintThreads op1(output(), _locks.value()); | |
326 VMThread::execute(&op1); | |
327 | |
328 // JNI global handles | |
329 VM_PrintJNI op2(output()); | |
330 VMThread::execute(&op2); | |
331 | |
332 // Deadlock detection | |
333 VM_FindDeadlocks op3(output()); | |
334 VMThread::execute(&op3); | |
335 } | |
336 | |
337 int ThreadDumpDCmd::num_arguments() { | |
338 ResourceMark rm; | |
339 ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false); | |
340 if (dcmd != NULL) { | |
341 DCmdMark mark(dcmd); | |
342 return dcmd->_dcmdparser.num_arguments(); | |
343 } else { | |
344 return 0; | |
345 } | |
346 } |