File: | jdk/src/hotspot/share/services/diagnosticCommand.cpp |
Warning: | line 223, column 7 Value stored to 'factory' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 2011, 2021, 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" |
26 | #include "jvm.h" |
27 | #include "classfile/classLoaderHierarchyDCmd.hpp" |
28 | #include "classfile/classLoaderStats.hpp" |
29 | #include "classfile/javaClasses.hpp" |
30 | #include "classfile/systemDictionary.hpp" |
31 | #include "classfile/vmClasses.hpp" |
32 | #include "code/codeCache.hpp" |
33 | #include "compiler/compileBroker.hpp" |
34 | #include "compiler/directivesParser.hpp" |
35 | #include "gc/shared/gcVMOperations.hpp" |
36 | #include "memory/metaspace/metaspaceDCmd.hpp" |
37 | #include "memory/resourceArea.hpp" |
38 | #include "memory/universe.hpp" |
39 | #include "oops/instanceKlass.hpp" |
40 | #include "oops/objArrayOop.inline.hpp" |
41 | #include "oops/oop.inline.hpp" |
42 | #include "oops/typeArrayOop.inline.hpp" |
43 | #include "runtime/fieldDescriptor.inline.hpp" |
44 | #include "runtime/flags/jvmFlag.hpp" |
45 | #include "runtime/handles.inline.hpp" |
46 | #include "runtime/interfaceSupport.inline.hpp" |
47 | #include "runtime/javaCalls.hpp" |
48 | #include "runtime/jniHandles.hpp" |
49 | #include "runtime/os.hpp" |
50 | #include "runtime/vmOperations.hpp" |
51 | #include "runtime/vm_version.hpp" |
52 | #include "services/diagnosticArgument.hpp" |
53 | #include "services/diagnosticCommand.hpp" |
54 | #include "services/diagnosticFramework.hpp" |
55 | #include "services/heapDumper.hpp" |
56 | #include "services/management.hpp" |
57 | #include "services/writeableFlags.hpp" |
58 | #include "utilities/debug.hpp" |
59 | #include "utilities/events.hpp" |
60 | #include "utilities/formatBuffer.hpp" |
61 | #include "utilities/macros.hpp" |
62 | #ifdef LINUX1 |
63 | #include "trimCHeapDCmd.hpp" |
64 | #endif |
65 | |
66 | static void loadAgentModule(TRAPSJavaThread* __the_thread__) { |
67 | ResourceMark rm(THREAD__the_thread__); |
68 | HandleMark hm(THREAD__the_thread__); |
69 | |
70 | JavaValue result(T_OBJECT); |
71 | Handle h_module_name = java_lang_String::create_from_str("jdk.management.agent", CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
72 | JavaCalls::call_static(&result, |
73 | vmClasses::module_Modules_klass(), |
74 | vmSymbols::loadModule_name(), |
75 | vmSymbols::loadModule_signature(), |
76 | h_module_name, |
77 | THREAD__the_thread__); |
78 | } |
79 | |
80 | void DCmdRegistrant::register_dcmds(){ |
81 | // Registration of the diagnostic commands |
82 | // First argument specifies which interfaces will export the command |
83 | // Second argument specifies if the command is enabled |
84 | // Third argument specifies if the command is hidden |
85 | uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI |
86 | | DCmd_Source_MBean; |
87 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(full_export, true, false)); |
88 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(full_export, true, false)); |
89 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(full_export, true, false)); |
90 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(full_export, true, false)); |
91 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(full_export, true, false)); |
92 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SetVMFlagDCmd>(full_export, true, false)); |
93 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false)); |
94 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false)); |
95 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMInfoDCmd>(full_export, true, false)); |
96 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false)); |
97 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false)); |
98 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false)); |
99 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<FinalizerInfoDCmd>(full_export, true, false)); |
100 | #if INCLUDE_SERVICES1 |
101 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); |
102 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false)); |
103 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemDictionaryDCmd>(full_export, true, false)); |
104 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHierarchyDCmd>(full_export, true, false)); |
105 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false)); |
106 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false)); |
107 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<metaspace::MetaspaceDCmd>(full_export, true, false)); |
108 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<EventLogDCmd>(full_export, true, false)); |
109 | #if INCLUDE_JVMTI1 // Both JVMTI and SERVICES have to be enabled to have this dcmd |
110 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIAgentLoadDCmd>(full_export, true, false)); |
111 | #endif // INCLUDE_JVMTI |
112 | #endif // INCLUDE_SERVICES |
113 | #if INCLUDE_JVMTI1 |
114 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIDataDumpDCmd>(full_export, true, false)); |
115 | #endif // INCLUDE_JVMTI |
116 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false)); |
117 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false)); |
118 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderHierarchyDCmd>(full_export, true, false)); |
119 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompileQueueDCmd>(full_export, true, false)); |
120 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeListDCmd>(full_export, true, false)); |
121 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeCacheDCmd>(full_export, true, false)); |
122 | #ifdef LINUX1 |
123 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PerfMapDCmd>(full_export, true, false)); |
124 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false)); |
125 | #endif // LINUX |
126 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TouchedMethodsDCmd>(full_export, true, false)); |
127 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeHeapAnalyticsDCmd>(full_export, true, false)); |
128 | |
129 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesPrintDCmd>(full_export, true, false)); |
130 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesAddDCmd>(full_export, true, false)); |
131 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesRemoveDCmd>(full_export, true, false)); |
132 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesClearDCmd>(full_export, true, false)); |
133 | |
134 | // Enhanced JMX Agent Support |
135 | // These commands won't be exported via the DiagnosticCommandMBean until an |
136 | // appropriate permission is created for them |
137 | uint32_t jmx_agent_export_flags = DCmd_Source_Internal | DCmd_Source_AttachAPI; |
138 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(jmx_agent_export_flags, true,false)); |
139 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(jmx_agent_export_flags, true,false)); |
140 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(jmx_agent_export_flags, true,false)); |
141 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStatusDCmd>(jmx_agent_export_flags, true,false)); |
142 | |
143 | // Debug on cmd (only makes sense with JVMTI since the agentlib needs it). |
144 | #if INCLUDE_JVMTI1 |
145 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DebugOnCmdStartDCmd>(full_export, true, true)); |
146 | #endif // INCLUDE_JVMTI |
147 | |
148 | #if INCLUDE_CDS1 |
149 | DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DumpSharedArchiveDCmd>(full_export, true, false)); |
150 | #endif // INCLUDE_CDS |
151 | } |
152 | |
153 | #ifndef HAVE_EXTRA_DCMD |
154 | void DCmdRegistrant::register_dcmds_ext(){ |
155 | // Do nothing here |
156 | } |
157 | #endif |
158 | |
159 | |
160 | HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), |
161 | _all("-all", "Show help for all commands", "BOOLEAN", false, "false"), |
162 | _cmd("command name", "The name of the command for which we want help", |
163 | "STRING", false) { |
164 | _dcmdparser.add_dcmd_option(&_all); |
165 | _dcmdparser.add_dcmd_argument(&_cmd); |
166 | }; |
167 | |
168 | |
169 | static int compare_strings(const char** s1, const char** s2) { |
170 | return ::strcmp(*s1, *s2); |
171 | } |
172 | |
173 | void HelpDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
174 | if (_all.value()) { |
175 | GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(source); |
176 | cmd_list->sort(compare_strings); |
177 | for (int i = 0; i < cmd_list->length(); i++) { |
178 | DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i), |
179 | strlen(cmd_list->at(i))); |
180 | output()->print_cr("%s%s", factory->name(), |
181 | factory->is_enabled() ? "" : " [disabled]"); |
182 | output()->print_cr("\t%s", factory->description()); |
183 | output()->cr(); |
184 | factory = factory->next(); |
185 | } |
186 | } else if (_cmd.has_value()) { |
187 | DCmd* cmd = NULL__null; |
188 | DCmdFactory* factory = DCmdFactory::factory(source, _cmd.value(), |
189 | strlen(_cmd.value())); |
190 | if (factory != NULL__null) { |
191 | output()->print_cr("%s%s", factory->name(), |
192 | factory->is_enabled() ? "" : " [disabled]"); |
193 | output()->print_cr("%s", factory->description()); |
194 | output()->print_cr("\nImpact: %s", factory->impact()); |
195 | JavaPermission p = factory->permission(); |
196 | if(p._class != NULL__null) { |
197 | if(p._action != NULL__null) { |
198 | output()->print_cr("\nPermission: %s(%s, %s)", |
199 | p._class, p._name == NULL__null ? "null" : p._name, p._action); |
200 | } else { |
201 | output()->print_cr("\nPermission: %s(%s)", |
202 | p._class, p._name == NULL__null ? "null" : p._name); |
203 | } |
204 | } |
205 | output()->cr(); |
206 | cmd = factory->create_resource_instance(output()); |
207 | if (cmd != NULL__null) { |
208 | DCmdMark mark(cmd); |
209 | cmd->print_help(factory->name()); |
210 | } |
211 | } else { |
212 | output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value()); |
213 | } |
214 | } else { |
215 | output()->print_cr("The following commands are available:"); |
216 | GrowableArray<const char *>* cmd_list = DCmdFactory::DCmd_list(source); |
217 | cmd_list->sort(compare_strings); |
218 | for (int i = 0; i < cmd_list->length(); i++) { |
219 | DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i), |
220 | strlen(cmd_list->at(i))); |
221 | output()->print_cr("%s%s", factory->name(), |
222 | factory->is_enabled() ? "" : " [disabled]"); |
223 | factory = factory->_next; |
Value stored to 'factory' is never read | |
224 | } |
225 | output()->print_cr("\nFor more information about a specific command use 'help <command>'."); |
226 | } |
227 | } |
228 | |
229 | void VersionDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
230 | output()->print_cr("%s version %s", VM_Version::vm_name(), |
231 | VM_Version::vm_release()); |
232 | JDK_Version jdk_version = JDK_Version::current(); |
233 | if (jdk_version.patch_version() > 0) { |
234 | output()->print_cr("JDK %d.%d.%d.%d", jdk_version.major_version(), |
235 | jdk_version.minor_version(), jdk_version.security_version(), |
236 | jdk_version.patch_version()); |
237 | } else { |
238 | output()->print_cr("JDK %d.%d.%d", jdk_version.major_version(), |
239 | jdk_version.minor_version(), jdk_version.security_version()); |
240 | } |
241 | } |
242 | |
243 | PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) : |
244 | DCmdWithParser(output, heap), |
245 | _all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") { |
246 | _dcmdparser.add_dcmd_option(&_all); |
247 | } |
248 | |
249 | void PrintVMFlagsDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
250 | if (_all.value()) { |
251 | JVMFlag::printFlags(output(), true); |
252 | } else { |
253 | JVMFlag::printSetFlags(output()); |
254 | } |
255 | } |
256 | |
257 | SetVMFlagDCmd::SetVMFlagDCmd(outputStream* output, bool heap) : |
258 | DCmdWithParser(output, heap), |
259 | _flag("flag name", "The name of the flag we want to set", |
260 | "STRING", true), |
261 | _value("string value", "The value we want to set", "STRING", false) { |
262 | _dcmdparser.add_dcmd_argument(&_flag); |
263 | _dcmdparser.add_dcmd_argument(&_value); |
264 | } |
265 | |
266 | void SetVMFlagDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
267 | const char* val = NULL__null; |
268 | if (_value.value() != NULL__null) { |
269 | val = _value.value(); |
270 | } |
271 | |
272 | FormatBuffer<80> err_msg("%s", ""); |
273 | int ret = WriteableFlags::set_flag(_flag.value(), val, JVMFlagOrigin::MANAGEMENT, err_msg); |
274 | |
275 | if (ret != JVMFlag::SUCCESS) { |
276 | output()->print_cr("%s", err_msg.buffer()); |
277 | } |
278 | } |
279 | |
280 | void JVMTIDataDumpDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
281 | if (JvmtiExport::should_post_data_dump()) { |
282 | JvmtiExport::post_data_dump(); |
283 | } |
284 | } |
285 | |
286 | #if INCLUDE_SERVICES1 |
287 | #if INCLUDE_JVMTI1 |
288 | JVMTIAgentLoadDCmd::JVMTIAgentLoadDCmd(outputStream* output, bool heap) : |
289 | DCmdWithParser(output, heap), |
290 | _libpath("library path", "Absolute path of the JVMTI agent to load.", |
291 | "STRING", true), |
292 | _option("agent option", "Option string to pass the agent.", "STRING", false) { |
293 | _dcmdparser.add_dcmd_argument(&_libpath); |
294 | _dcmdparser.add_dcmd_argument(&_option); |
295 | } |
296 | |
297 | void JVMTIAgentLoadDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
298 | |
299 | if (_libpath.value() == NULL__null) { |
300 | output()->print_cr("JVMTI.agent_load dcmd needs library path."); |
301 | return; |
302 | } |
303 | |
304 | char *suffix = strrchr(_libpath.value(), '.'); |
305 | bool is_java_agent = (suffix != NULL__null) && (strncmp(".jar", suffix, 4) == 0); |
306 | |
307 | if (is_java_agent) { |
308 | if (_option.value() == NULL__null) { |
309 | JvmtiExport::load_agent_library("instrument", "false", |
310 | _libpath.value(), output()); |
311 | } else { |
312 | size_t opt_len = strlen(_libpath.value()) + strlen(_option.value()) + 2; |
313 | if (opt_len > 4096) { |
314 | output()->print_cr("JVMTI agent attach failed: Options is too long."); |
315 | return; |
316 | } |
317 | |
318 | char *opt = (char *)os::malloc(opt_len, mtInternal); |
319 | if (opt == NULL__null) { |
320 | output()->print_cr("JVMTI agent attach failed: " |
321 | "Could not allocate " SIZE_FORMAT"%" "l" "u" " bytes for argument.", |
322 | opt_len); |
323 | return; |
324 | } |
325 | |
326 | jio_snprintf(opt, opt_len, "%s=%s", _libpath.value(), _option.value()); |
327 | JvmtiExport::load_agent_library("instrument", "false", opt, output()); |
328 | |
329 | os::free(opt); |
330 | } |
331 | } else { |
332 | JvmtiExport::load_agent_library(_libpath.value(), "true", |
333 | _option.value(), output()); |
334 | } |
335 | } |
336 | |
337 | #endif // INCLUDE_JVMTI |
338 | #endif // INCLUDE_SERVICES |
339 | |
340 | void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
341 | // load VMSupport |
342 | Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport(); |
343 | Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
344 | InstanceKlass* ik = InstanceKlass::cast(k); |
345 | if (ik->should_be_initialized()) { |
346 | ik->initialize(THREAD__the_thread__); |
347 | } |
348 | if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { |
349 | java_lang_Throwable::print(PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->pending_exception()), output()); |
350 | output()->cr(); |
351 | CLEAR_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_exception( )); |
352 | return; |
353 | } |
354 | |
355 | // invoke the serializePropertiesToByteArray method |
356 | JavaValue result(T_OBJECT); |
357 | JavaCallArguments args; |
358 | |
359 | Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature(); |
360 | JavaCalls::call_static(&result, |
361 | ik, |
362 | vmSymbols::serializePropertiesToByteArray_name(), |
363 | signature, |
364 | &args, |
365 | THREAD__the_thread__); |
366 | if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { |
367 | java_lang_Throwable::print(PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->pending_exception()), output()); |
368 | output()->cr(); |
369 | CLEAR_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_exception( )); |
370 | return; |
371 | } |
372 | |
373 | // The result should be a [B |
374 | oop res = result.get_oop(); |
375 | assert(res->is_typeArray(), "just checking")do { if (!(res->is_typeArray())) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/diagnosticCommand.cpp" , 375, "assert(" "res->is_typeArray()" ") failed", "just checking" ); ::breakpoint(); } } while (0); |
376 | assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking")do { if (!(TypeArrayKlass::cast(res->klass())->element_type () == T_BYTE)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/diagnosticCommand.cpp" , 376, "assert(" "TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE" ") failed", "just checking"); ::breakpoint(); } } while (0); |
377 | |
378 | // copy the bytes to the output stream |
379 | typeArrayOop ba = typeArrayOop(res); |
380 | jbyte* addr = typeArrayOop(res)->byte_at_addr(0); |
381 | output()->print_raw((const char*)addr, ba->length()); |
382 | } |
383 | |
384 | VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) : |
385 | DCmdWithParser(output, heap), |
386 | _date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") { |
387 | _dcmdparser.add_dcmd_option(&_date); |
388 | } |
389 | |
390 | void VMUptimeDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
391 | if (_date.value()) { |
392 | output()->date_stamp(true, "", ": "); |
393 | } |
394 | output()->time_stamp().update_to(tty->time_stamp().ticks()); |
395 | output()->stamp(); |
396 | output()->print_cr(" s"); |
397 | } |
398 | |
399 | void VMInfoDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
400 | VMError::print_vm_info(_output); |
401 | } |
402 | |
403 | void SystemGCDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
404 | Universe::heap()->collect(GCCause::_dcmd_gc_run); |
405 | } |
406 | |
407 | void RunFinalizationDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
408 | Klass* k = vmClasses::System_klass(); |
409 | JavaValue result(T_VOID); |
410 | JavaCalls::call_static(&result, k, |
411 | vmSymbols::run_finalization_name(), |
412 | vmSymbols::void_method_signature(), CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
413 | } |
414 | |
415 | void HeapInfoDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
416 | MutexLocker hl(THREAD__the_thread__, Heap_lock); |
417 | Universe::heap()->print_on(output()); |
418 | } |
419 | |
420 | void FinalizerInfoDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
421 | ResourceMark rm(THREAD__the_thread__); |
422 | |
423 | if (!InstanceKlass::is_finalization_enabled()) { |
424 | output()->print_cr("Finalization is disabled"); |
425 | return; |
426 | } |
427 | |
428 | Klass* k = SystemDictionary::resolve_or_fail( |
429 | vmSymbols::finalizer_histogram_klass(), true, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
430 | |
431 | JavaValue result(T_ARRAY); |
432 | |
433 | // We are calling lang.ref.FinalizerHistogram.getFinalizerHistogram() method |
434 | // and expect it to return array of FinalizerHistogramEntry as Object[] |
435 | |
436 | JavaCalls::call_static(&result, k, |
437 | vmSymbols::get_finalizer_histogram_name(), |
438 | vmSymbols::void_finalizer_histogram_entry_array_signature(), CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
439 | |
440 | objArrayOop result_oop = (objArrayOop) result.get_oop(); |
441 | if (result_oop->length() == 0) { |
442 | output()->print_cr("No instances waiting for finalization found"); |
443 | return; |
444 | } |
445 | |
446 | oop foop = result_oop->obj_at(0); |
447 | InstanceKlass* ik = InstanceKlass::cast(foop->klass()); |
448 | |
449 | fieldDescriptor count_fd, name_fd; |
450 | |
451 | Klass* count_res = ik->find_field( |
452 | vmSymbols::finalizer_histogram_entry_count_field(), vmSymbols::int_signature(), &count_fd); |
453 | |
454 | Klass* name_res = ik->find_field( |
455 | vmSymbols::finalizer_histogram_entry_name_field(), vmSymbols::string_signature(), &name_fd); |
456 | |
457 | assert(count_res != NULL && name_res != NULL, "Unexpected layout of FinalizerHistogramEntry")do { if (!(count_res != __null && name_res != __null) ) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/diagnosticCommand.cpp" , 457, "assert(" "count_res != __null && name_res != __null" ") failed", "Unexpected layout of FinalizerHistogramEntry"); ::breakpoint(); } } while (0); |
458 | |
459 | output()->print_cr("Unreachable instances waiting for finalization"); |
460 | output()->print_cr("#instances class name"); |
461 | output()->print_cr("-----------------------"); |
462 | |
463 | for (int i = 0; i < result_oop->length(); ++i) { |
464 | oop element_oop = result_oop->obj_at(i); |
465 | oop str_oop = element_oop->obj_field(name_fd.offset()); |
466 | char *name = java_lang_String::as_utf8_string(str_oop); |
467 | int count = element_oop->int_field(count_fd.offset()); |
468 | output()->print_cr("%10d %s", count, name); |
469 | } |
470 | } |
471 | |
472 | #if INCLUDE_SERVICES1 // Heap dumping/inspection supported |
473 | HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) : |
474 | DCmdWithParser(output, heap), |
475 | _filename("filename","Name of the dump file", "STRING",true), |
476 | _all("-all", "Dump all objects, including unreachable objects", |
477 | "BOOLEAN", false, "false"), |
478 | _gzip("-gz", "If specified, the heap dump is written in gzipped format " |
479 | "using the given compression level. 1 (recommended) is the fastest, " |
480 | "9 the strongest compression.", "INT", false, "1"), |
481 | _overwrite("-overwrite", "If specified, the dump file will be overwritten if it exists", |
482 | "BOOLEAN", false, "false") { |
483 | _dcmdparser.add_dcmd_option(&_all); |
484 | _dcmdparser.add_dcmd_argument(&_filename); |
485 | _dcmdparser.add_dcmd_option(&_gzip); |
486 | _dcmdparser.add_dcmd_option(&_overwrite); |
487 | } |
488 | |
489 | void HeapDumpDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
490 | jlong level = -1; // -1 means no compression. |
491 | |
492 | if (_gzip.is_set()) { |
493 | level = _gzip.value(); |
494 | |
495 | if (level < 1 || level > 9) { |
496 | output()->print_cr("Compression level out of range (1-9): " JLONG_FORMAT"%" "l" "d", level); |
497 | return; |
498 | } |
499 | } |
500 | |
501 | // Request a full GC before heap dump if _all is false |
502 | // This helps reduces the amount of unreachable objects in the dump |
503 | // and makes it easier to browse. |
504 | HeapDumper dumper(!_all.value() /* request GC if _all is false*/); |
505 | dumper.dump(_filename.value(), output(), (int) level, _overwrite.value()); |
506 | } |
507 | |
508 | ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) : |
509 | DCmdWithParser(output, heap), |
510 | _all("-all", "Inspect all objects, including unreachable objects", |
511 | "BOOLEAN", false, "false"), |
512 | _parallel_thread_num("-parallel", |
513 | "Number of parallel threads to use for heap inspection. " |
514 | "0 (the default) means let the VM determine the number of threads to use. " |
515 | "1 means use one thread (disable parallelism). " |
516 | "For any other value the VM will try to use the specified number of " |
517 | "threads, but might use fewer.", |
518 | "INT", false, "0") { |
519 | _dcmdparser.add_dcmd_option(&_all); |
520 | _dcmdparser.add_dcmd_option(&_parallel_thread_num); |
521 | } |
522 | |
523 | void ClassHistogramDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
524 | jlong num = _parallel_thread_num.value(); |
525 | if (num < 0) { |
526 | output()->print_cr("Parallel thread number out of range (>=0): " JLONG_FORMAT"%" "l" "d", num); |
527 | return; |
528 | } |
529 | uint parallel_thread_num = num == 0 |
530 | ? MAX2<uint>(1, (uint)os::initial_active_processor_count() * 3 / 8) |
531 | : num; |
532 | VM_GC_HeapInspection heapop(output(), |
533 | !_all.value(), /* request full gc if false */ |
534 | parallel_thread_num); |
535 | VMThread::execute(&heapop); |
536 | } |
537 | |
538 | #endif // INCLUDE_SERVICES |
539 | |
540 | ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) : |
541 | DCmdWithParser(output, heap), |
542 | _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false"), |
543 | _extended("-e", "print extended thread information", "BOOLEAN", false, "false") { |
544 | _dcmdparser.add_dcmd_option(&_locks); |
545 | _dcmdparser.add_dcmd_option(&_extended); |
546 | } |
547 | |
548 | void ThreadDumpDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
549 | // thread stacks and JNI global handles |
550 | VM_PrintThreads op1(output(), _locks.value(), _extended.value(), true /* print JNI handle info */); |
551 | VMThread::execute(&op1); |
552 | |
553 | // Deadlock detection |
554 | VM_FindDeadlocks op2(output()); |
555 | VMThread::execute(&op2); |
556 | } |
557 | |
558 | // Enhanced JMX Agent support |
559 | |
560 | JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated) : |
561 | |
562 | DCmdWithParser(output, heap_allocated), |
563 | |
564 | _config_file |
565 | ("config.file", |
566 | "set com.sun.management.config.file", "STRING", false), |
567 | |
568 | _jmxremote_host |
569 | ("jmxremote.host", |
570 | "set com.sun.management.jmxremote.host", "STRING", false), |
571 | |
572 | _jmxremote_port |
573 | ("jmxremote.port", |
574 | "set com.sun.management.jmxremote.port", "STRING", false), |
575 | |
576 | _jmxremote_rmi_port |
577 | ("jmxremote.rmi.port", |
578 | "set com.sun.management.jmxremote.rmi.port", "STRING", false), |
579 | |
580 | _jmxremote_ssl |
581 | ("jmxremote.ssl", |
582 | "set com.sun.management.jmxremote.ssl", "STRING", false), |
583 | |
584 | _jmxremote_registry_ssl |
585 | ("jmxremote.registry.ssl", |
586 | "set com.sun.management.jmxremote.registry.ssl", "STRING", false), |
587 | |
588 | _jmxremote_authenticate |
589 | ("jmxremote.authenticate", |
590 | "set com.sun.management.jmxremote.authenticate", "STRING", false), |
591 | |
592 | _jmxremote_password_file |
593 | ("jmxremote.password.file", |
594 | "set com.sun.management.jmxremote.password.file", "STRING", false), |
595 | |
596 | _jmxremote_access_file |
597 | ("jmxremote.access.file", |
598 | "set com.sun.management.jmxremote.access.file", "STRING", false), |
599 | |
600 | _jmxremote_login_config |
601 | ("jmxremote.login.config", |
602 | "set com.sun.management.jmxremote.login.config", "STRING", false), |
603 | |
604 | _jmxremote_ssl_enabled_cipher_suites |
605 | ("jmxremote.ssl.enabled.cipher.suites", |
606 | "set com.sun.management.jmxremote.ssl.enabled.cipher.suite", "STRING", false), |
607 | |
608 | _jmxremote_ssl_enabled_protocols |
609 | ("jmxremote.ssl.enabled.protocols", |
610 | "set com.sun.management.jmxremote.ssl.enabled.protocols", "STRING", false), |
611 | |
612 | _jmxremote_ssl_need_client_auth |
613 | ("jmxremote.ssl.need.client.auth", |
614 | "set com.sun.management.jmxremote.need.client.auth", "STRING", false), |
615 | |
616 | _jmxremote_ssl_config_file |
617 | ("jmxremote.ssl.config.file", |
618 | "set com.sun.management.jmxremote.ssl.config.file", "STRING", false), |
619 | |
620 | // JDP Protocol support |
621 | _jmxremote_autodiscovery |
622 | ("jmxremote.autodiscovery", |
623 | "set com.sun.management.jmxremote.autodiscovery", "STRING", false), |
624 | |
625 | _jdp_port |
626 | ("jdp.port", |
627 | "set com.sun.management.jdp.port", "INT", false), |
628 | |
629 | _jdp_address |
630 | ("jdp.address", |
631 | "set com.sun.management.jdp.address", "STRING", false), |
632 | |
633 | _jdp_source_addr |
634 | ("jdp.source_addr", |
635 | "set com.sun.management.jdp.source_addr", "STRING", false), |
636 | |
637 | _jdp_ttl |
638 | ("jdp.ttl", |
639 | "set com.sun.management.jdp.ttl", "INT", false), |
640 | |
641 | _jdp_pause |
642 | ("jdp.pause", |
643 | "set com.sun.management.jdp.pause", "INT", false), |
644 | |
645 | _jdp_name |
646 | ("jdp.name", |
647 | "set com.sun.management.jdp.name", "STRING", false) |
648 | |
649 | { |
650 | _dcmdparser.add_dcmd_option(&_config_file); |
651 | _dcmdparser.add_dcmd_option(&_jmxremote_host); |
652 | _dcmdparser.add_dcmd_option(&_jmxremote_port); |
653 | _dcmdparser.add_dcmd_option(&_jmxremote_rmi_port); |
654 | _dcmdparser.add_dcmd_option(&_jmxremote_ssl); |
655 | _dcmdparser.add_dcmd_option(&_jmxremote_registry_ssl); |
656 | _dcmdparser.add_dcmd_option(&_jmxremote_authenticate); |
657 | _dcmdparser.add_dcmd_option(&_jmxremote_password_file); |
658 | _dcmdparser.add_dcmd_option(&_jmxremote_access_file); |
659 | _dcmdparser.add_dcmd_option(&_jmxremote_login_config); |
660 | _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_cipher_suites); |
661 | _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_protocols); |
662 | _dcmdparser.add_dcmd_option(&_jmxremote_ssl_need_client_auth); |
663 | _dcmdparser.add_dcmd_option(&_jmxremote_ssl_config_file); |
664 | _dcmdparser.add_dcmd_option(&_jmxremote_autodiscovery); |
665 | _dcmdparser.add_dcmd_option(&_jdp_port); |
666 | _dcmdparser.add_dcmd_option(&_jdp_address); |
667 | _dcmdparser.add_dcmd_option(&_jdp_source_addr); |
668 | _dcmdparser.add_dcmd_option(&_jdp_ttl); |
669 | _dcmdparser.add_dcmd_option(&_jdp_pause); |
670 | _dcmdparser.add_dcmd_option(&_jdp_name); |
671 | } |
672 | |
673 | void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
674 | ResourceMark rm(THREAD__the_thread__); |
675 | HandleMark hm(THREAD__the_thread__); |
676 | |
677 | // Load and initialize the jdk.internal.agent.Agent class |
678 | // invoke startRemoteManagementAgent(string) method to start |
679 | // the remote management server. |
680 | // throw java.lang.NoSuchMethodError if the method doesn't exist |
681 | |
682 | loadAgentModule(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
683 | Handle loader = Handle(THREAD__the_thread__, SystemDictionary::java_system_loader()); |
684 | Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
685 | |
686 | JavaValue result(T_VOID); |
687 | |
688 | // Pass all command line arguments to java as key=value,... |
689 | // All checks are done on java side |
690 | |
691 | int len = 0; |
692 | stringStream options; |
693 | char comma[2] = {0,0}; |
694 | |
695 | // Leave default values on Agent.class side and pass only |
696 | // agruments explicitly set by user. All arguments passed |
697 | // to jcmd override properties with the same name set by |
698 | // command line with -D or by managmenent.properties |
699 | // file. |
700 | #define PUT_OPTION(a) \ |
701 | do { \ |
702 | if ( (a).is_set() ){ \ |
703 | if ( *((a).type()) == 'I' ) { \ |
704 | options.print("%scom.sun.management.%s=" JLONG_FORMAT"%" "l" "d", comma, (a).name(), (jlong)((a).value())); \ |
705 | } else { \ |
706 | options.print("%scom.sun.management.%s=%s", comma, (a).name(), (char*)((a).value())); \ |
707 | } \ |
708 | comma[0] = ','; \ |
709 | }\ |
710 | } while(0); |
711 | |
712 | |
713 | PUT_OPTION(_config_file); |
714 | PUT_OPTION(_jmxremote_host); |
715 | PUT_OPTION(_jmxremote_port); |
716 | PUT_OPTION(_jmxremote_rmi_port); |
717 | PUT_OPTION(_jmxremote_ssl); |
718 | PUT_OPTION(_jmxremote_registry_ssl); |
719 | PUT_OPTION(_jmxremote_authenticate); |
720 | PUT_OPTION(_jmxremote_password_file); |
721 | PUT_OPTION(_jmxremote_access_file); |
722 | PUT_OPTION(_jmxremote_login_config); |
723 | PUT_OPTION(_jmxremote_ssl_enabled_cipher_suites); |
724 | PUT_OPTION(_jmxremote_ssl_enabled_protocols); |
725 | PUT_OPTION(_jmxremote_ssl_need_client_auth); |
726 | PUT_OPTION(_jmxremote_ssl_config_file); |
727 | PUT_OPTION(_jmxremote_autodiscovery); |
728 | PUT_OPTION(_jdp_port); |
729 | PUT_OPTION(_jdp_address); |
730 | PUT_OPTION(_jdp_source_addr); |
731 | PUT_OPTION(_jdp_ttl); |
732 | PUT_OPTION(_jdp_pause); |
733 | PUT_OPTION(_jdp_name); |
734 | |
735 | #undef PUT_OPTION |
736 | |
737 | Handle str = java_lang_String::create_from_str(options.as_string(), CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
738 | JavaCalls::call_static(&result, k, vmSymbols::startRemoteAgent_name(), vmSymbols::string_void_signature(), str, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
739 | } |
740 | |
741 | JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) : |
742 | DCmd(output, heap_allocated) { |
743 | // do nothing |
744 | } |
745 | |
746 | void JMXStartLocalDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
747 | ResourceMark rm(THREAD__the_thread__); |
748 | HandleMark hm(THREAD__the_thread__); |
749 | |
750 | // Load and initialize the jdk.internal.agent.Agent class |
751 | // invoke startLocalManagementAgent(void) method to start |
752 | // the local management server |
753 | // throw java.lang.NoSuchMethodError if method doesn't exist |
754 | |
755 | loadAgentModule(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
756 | Handle loader = Handle(THREAD__the_thread__, SystemDictionary::java_system_loader()); |
757 | Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
758 | |
759 | JavaValue result(T_VOID); |
760 | JavaCalls::call_static(&result, k, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
761 | } |
762 | |
763 | void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
764 | ResourceMark rm(THREAD__the_thread__); |
765 | HandleMark hm(THREAD__the_thread__); |
766 | |
767 | // Load and initialize the jdk.internal.agent.Agent class |
768 | // invoke stopRemoteManagementAgent method to stop the |
769 | // management server |
770 | // throw java.lang.NoSuchMethodError if method doesn't exist |
771 | |
772 | loadAgentModule(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
773 | Handle loader = Handle(THREAD__the_thread__, SystemDictionary::java_system_loader()); |
774 | Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
775 | |
776 | JavaValue result(T_VOID); |
777 | JavaCalls::call_static(&result, k, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
778 | } |
779 | |
780 | JMXStatusDCmd::JMXStatusDCmd(outputStream *output, bool heap_allocated) : |
781 | DCmd(output, heap_allocated) { |
782 | // do nothing |
783 | } |
784 | |
785 | void JMXStatusDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
786 | ResourceMark rm(THREAD__the_thread__); |
787 | HandleMark hm(THREAD__the_thread__); |
788 | |
789 | // Load and initialize the jdk.internal.agent.Agent class |
790 | // invoke getManagementAgentStatus() method to generate the status info |
791 | // throw java.lang.NoSuchMethodError if method doesn't exist |
792 | |
793 | loadAgentModule(CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
794 | Handle loader = Handle(THREAD__the_thread__, SystemDictionary::java_system_loader()); |
795 | Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
796 | |
797 | JavaValue result(T_OBJECT); |
798 | JavaCalls::call_static(&result, k, vmSymbols::getAgentStatus_name(), vmSymbols::void_string_signature(), CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
799 | |
800 | jvalue* jv = (jvalue*) result.get_value_addr(); |
801 | oop str = cast_to_oop(jv->l); |
802 | if (str != NULL__null) { |
803 | char* out = java_lang_String::as_utf8_string(str); |
804 | if (out) { |
805 | output()->print_cr("%s", out); |
806 | return; |
807 | } |
808 | } |
809 | output()->print_cr("Error obtaining management agent status"); |
810 | } |
811 | |
812 | VMDynamicLibrariesDCmd::VMDynamicLibrariesDCmd(outputStream *output, bool heap_allocated) : |
813 | DCmd(output, heap_allocated) { |
814 | // do nothing |
815 | } |
816 | |
817 | void VMDynamicLibrariesDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
818 | os::print_dll_info(output()); |
819 | output()->cr(); |
820 | } |
821 | |
822 | void CompileQueueDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
823 | VM_PrintCompileQueue printCompileQueueOp(output()); |
824 | VMThread::execute(&printCompileQueueOp); |
825 | } |
826 | |
827 | void CodeListDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
828 | CodeCache::print_codelist(output()); |
829 | } |
830 | |
831 | void CodeCacheDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
832 | CodeCache::print_layout(output()); |
833 | } |
834 | |
835 | #ifdef LINUX1 |
836 | void PerfMapDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
837 | CodeCache::write_perf_map(); |
838 | } |
839 | #endif // LINUX |
840 | |
841 | //---< BEGIN >--- CodeHeap State Analytics. |
842 | CodeHeapAnalyticsDCmd::CodeHeapAnalyticsDCmd(outputStream* output, bool heap) : |
843 | DCmdWithParser(output, heap), |
844 | _function("function", "Function to be performed (aggregate, UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames, discard", "STRING", false, "all"), |
845 | _granularity("granularity", "Detail level - smaller value -> more detail", "INT", false, "4096") { |
846 | _dcmdparser.add_dcmd_argument(&_function); |
847 | _dcmdparser.add_dcmd_argument(&_granularity); |
848 | } |
849 | |
850 | void CodeHeapAnalyticsDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
851 | jlong granularity = _granularity.value(); |
852 | if (granularity < 1) { |
853 | Exceptions::fthrow(THREAD_AND_LOCATION__the_thread__, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/diagnosticCommand.cpp" , 853, vmSymbols::java_lang_IllegalArgumentException(), |
854 | "Invalid granularity value " JLONG_FORMAT"%" "l" "d" ". Should be positive.\n", granularity); |
855 | return; |
856 | } |
857 | |
858 | CompileBroker::print_heapinfo(output(), _function.value(), granularity); |
859 | } |
860 | //---< END >--- CodeHeap State Analytics. |
861 | |
862 | EventLogDCmd::EventLogDCmd(outputStream* output, bool heap) : |
863 | DCmdWithParser(output, heap), |
864 | _log("log", "Name of log to be printed. If omitted, all logs are printed.", "STRING", false, NULL__null), |
865 | _max("max", "Maximum number of events to be printed (newest first). If omitted, all events are printed.", "STRING", false, NULL__null) |
866 | { |
867 | _dcmdparser.add_dcmd_option(&_log); |
868 | _dcmdparser.add_dcmd_option(&_max); |
869 | } |
870 | |
871 | void EventLogDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
872 | const char* max_value = _max.value(); |
873 | long max = -1; |
874 | if (max_value != NULL__null) { |
875 | char* endptr = NULL__null; |
876 | max = ::strtol(max_value, &endptr, 10); |
877 | if (max == 0 && max_value == endptr) { |
878 | output()->print_cr("Invalid max option: \"%s\".", max_value); |
879 | return; |
880 | } |
881 | } |
882 | const char* log_name = _log.value(); |
883 | if (log_name != NULL__null) { |
884 | Events::print_one(output(), log_name, max); |
885 | } else { |
886 | Events::print_all(output(), max); |
887 | } |
888 | } |
889 | |
890 | void CompilerDirectivesPrintDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
891 | DirectivesStack::print(output()); |
892 | } |
893 | |
894 | CompilerDirectivesAddDCmd::CompilerDirectivesAddDCmd(outputStream* output, bool heap) : |
895 | DCmdWithParser(output, heap), |
896 | _filename("filename","Name of the directives file", "STRING",true) { |
897 | _dcmdparser.add_dcmd_argument(&_filename); |
898 | } |
899 | |
900 | void CompilerDirectivesAddDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
901 | DirectivesParser::parse_from_file(_filename.value(), output()); |
902 | } |
903 | |
904 | void CompilerDirectivesRemoveDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
905 | DirectivesStack::pop(1); |
906 | } |
907 | |
908 | void CompilerDirectivesClearDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
909 | DirectivesStack::clear(); |
910 | } |
911 | #if INCLUDE_SERVICES1 |
912 | ClassHierarchyDCmd::ClassHierarchyDCmd(outputStream* output, bool heap) : |
913 | DCmdWithParser(output, heap), |
914 | _print_interfaces("-i", "Inherited interfaces should be printed.", "BOOLEAN", false, "false"), |
915 | _print_subclasses("-s", "If a classname is specified, print its subclasses " |
916 | "in addition to its superclasses. Without this option only the " |
917 | "superclasses will be printed.", "BOOLEAN", false, "false"), |
918 | _classname("classname", "Name of class whose hierarchy should be printed. " |
919 | "If not specified, all class hierarchies are printed.", |
920 | "STRING", false) { |
921 | _dcmdparser.add_dcmd_option(&_print_interfaces); |
922 | _dcmdparser.add_dcmd_option(&_print_subclasses); |
923 | _dcmdparser.add_dcmd_argument(&_classname); |
924 | } |
925 | |
926 | void ClassHierarchyDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
927 | VM_PrintClassHierarchy printClassHierarchyOp(output(), _print_interfaces.value(), |
928 | _print_subclasses.value(), _classname.value()); |
929 | VMThread::execute(&printClassHierarchyOp); |
930 | } |
931 | #endif |
932 | |
933 | class VM_DumpTouchedMethods : public VM_Operation { |
934 | private: |
935 | outputStream* _out; |
936 | public: |
937 | VM_DumpTouchedMethods(outputStream* out) { |
938 | _out = out; |
939 | } |
940 | |
941 | virtual VMOp_Type type() const { return VMOp_DumpTouchedMethods; } |
942 | |
943 | virtual void doit() { |
944 | Method::print_touched_methods(_out); |
945 | } |
946 | }; |
947 | |
948 | void TouchedMethodsDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
949 | if (!LogTouchedMethods) { |
950 | output()->print_cr("VM.print_touched_methods command requires -XX:+LogTouchedMethods"); |
951 | return; |
952 | } |
953 | VM_DumpTouchedMethods dumper(output()); |
954 | VMThread::execute(&dumper); |
955 | } |
956 | |
957 | #if INCLUDE_CDS1 |
958 | DumpSharedArchiveDCmd::DumpSharedArchiveDCmd(outputStream* output, bool heap) : |
959 | DCmdWithParser(output, heap), |
960 | _suboption("subcmd", "static_dump | dynamic_dump", "STRING", true), |
961 | _filename("filename", "Name of shared archive to be dumped", "STRING", false) |
962 | { |
963 | _dcmdparser.add_dcmd_argument(&_suboption); |
964 | _dcmdparser.add_dcmd_argument(&_filename); |
965 | } |
966 | |
967 | void DumpSharedArchiveDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
968 | jboolean is_static; |
969 | const char* scmd = _suboption.value(); |
970 | const char* file = _filename.value(); |
971 | |
972 | if (strcmp(scmd, "static_dump") == 0) { |
973 | is_static = JNI_TRUE1; |
974 | output()->print("Static dump: "); |
975 | } else if (strcmp(scmd, "dynamic_dump") == 0) { |
976 | is_static = JNI_FALSE0; |
977 | output()->print("Dynamic dump: "); |
978 | if (!UseSharedSpaces) { |
979 | output()->print_cr("Dynamic dump is unsupported when base CDS archive is not loaded"); |
980 | return; |
981 | } |
982 | if (!RecordDynamicDumpInfo) { |
983 | output()->print_cr("Dump dynamic should run with -XX:+RecordDynamicDumpInfo"); |
984 | return; |
985 | } |
986 | } else { |
987 | output()->print_cr("Invalid command for VM.cds, valid input is static_dump or dynamic_dump"); |
988 | return; |
989 | } |
990 | |
991 | // call CDS.dumpSharedArchive |
992 | Handle fileh; |
993 | if (file != NULL__null) { |
994 | fileh = java_lang_String::create_from_str(_filename.value(), CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
995 | } |
996 | Symbol* cds_name = vmSymbols::jdk_internal_misc_CDS(); |
997 | Klass* cds_klass = SystemDictionary::resolve_or_fail(cds_name, true /*throw error*/, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
998 | JavaValue result(T_OBJECT); |
999 | JavaCallArguments args; |
1000 | args.push_int(is_static); |
1001 | args.push_oop(fileh); |
1002 | JavaCalls::call_static(&result, |
1003 | cds_klass, |
1004 | vmSymbols::dumpSharedArchive(), |
1005 | vmSymbols::dumpSharedArchive_signature(), |
1006 | &args, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception ())) return ; (void)(0); |
1007 | if (!HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) { |
1008 | assert(result.get_type() == T_OBJECT, "Sanity check")do { if (!(result.get_type() == T_OBJECT)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/diagnosticCommand.cpp" , 1008, "assert(" "result.get_type() == T_OBJECT" ") failed", "Sanity check"); ::breakpoint(); } } while (0); |
1009 | // result contains the archive name |
1010 | char* archive_name = java_lang_String::as_utf8_string(result.get_oop()); |
1011 | output()->print_cr("%s", archive_name); |
1012 | } |
1013 | } |
1014 | #endif // INCLUDE_CDS |
1015 | |
1016 | #if INCLUDE_JVMTI1 |
1017 | extern "C" typedef char const* (JNICALL *debugInit_startDebuggingViaCommandPtr)(JNIEnv* env, jthread thread, char const** transport_name, |
1018 | char const** address, jboolean* first_start); |
1019 | static debugInit_startDebuggingViaCommandPtr dvc_start_ptr = NULL__null; |
1020 | |
1021 | void DebugOnCmdStartDCmd::execute(DCmdSource source, TRAPSJavaThread* __the_thread__) { |
1022 | char const* transport = NULL__null; |
1023 | char const* addr = NULL__null; |
1024 | jboolean is_first_start = JNI_FALSE0; |
1025 | JavaThread* thread = THREAD__the_thread__; |
1026 | jthread jt = JNIHandles::make_local(thread->threadObj()); |
1027 | ThreadToNativeFromVM ttn(thread); |
1028 | const char *error = "Could not find jdwp agent."; |
1029 | |
1030 | if (!dvc_start_ptr) { |
1031 | for (AgentLibrary* agent = Arguments::agents(); agent != NULL__null; agent = agent->next()) { |
1032 | if ((strcmp("jdwp", agent->name()) == 0) && (dvc_start_ptr == NULL__null)) { |
1033 | char const* func = "debugInit_startDebuggingViaCommand"; |
1034 | dvc_start_ptr = (debugInit_startDebuggingViaCommandPtr) os::find_agent_function(agent, false, &func, 1); |
1035 | } |
1036 | } |
1037 | } |
1038 | |
1039 | if (dvc_start_ptr) { |
1040 | error = dvc_start_ptr(thread->jni_environment(), jt, &transport, &addr, &is_first_start); |
1041 | } |
1042 | |
1043 | if (error != NULL__null) { |
1044 | output()->print_cr("Debugging has not been started: %s", error); |
1045 | } else { |
1046 | output()->print_cr(is_first_start ? "Debugging has been started." : "Debugging is already active."); |
1047 | output()->print_cr("Transport : %s", transport ? transport : "#unknown"); |
1048 | output()->print_cr("Address : %s", addr ? addr : "#unknown"); |
1049 | } |
1050 | } |
1051 | #endif // INCLUDE_JVMTI |