1 /*
2 * Copyright (c) 2011, 2025, 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 #ifndef SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP
26 #define SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP
27
28 #include "classfile/stringTable.hpp"
29 #include "classfile/symbolTable.hpp"
30 #include "classfile/systemDictionary.hpp"
31 #include "classfile/vmSymbols.hpp"
32 #include "oops/method.hpp"
33 #include "runtime/arguments.hpp"
34 #include "runtime/os.hpp"
35 #include "runtime/vmThread.hpp"
36 #include "services/diagnosticArgument.hpp"
37 #include "services/diagnosticCommand.hpp"
38 #include "services/diagnosticFramework.hpp"
39 #include "utilities/macros.hpp"
40 #include "utilities/ostream.hpp"
41
42 class HelpDCmd : public DCmdWithParser {
43 protected:
44 DCmdArgument<bool> _all;
45 DCmdArgument<char*> _cmd;
46 public:
47 static int num_arguments() { return 2; }
48 HelpDCmd(outputStream* output, bool heap);
49 static const char* name() { return "help"; }
50 static const char* description() {
51 return "For more information about a specific command use 'help <command>'. "
52 "With no argument this will show a list of available commands. "
53 "'help all' will show help for all commands.";
54 }
55 static const char* impact() { return "Low"; }
56 virtual void execute(DCmdSource source, TRAPS);
57 };
58
59 class VersionDCmd : public DCmd {
60 public:
61 VersionDCmd(outputStream* output, bool heap) : DCmd(output,heap) { }
62 static const char* name() { return "VM.version"; }
63 static const char* description() {
64 return "Print JVM version information.";
65 }
66 static const char* impact() { return "Low"; }
67 virtual void execute(DCmdSource source, TRAPS);
68 };
69
70 class CommandLineDCmd : public DCmd {
71 public:
72 CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
73 static const char* name() { return "VM.command_line"; }
74 static const char* description() {
75 return "Print the command line used to start this VM instance.";
76 }
77 static const char* impact() { return "Low"; }
78 virtual void execute(DCmdSource source, TRAPS) {
79 Arguments::print_on(_output);
80 }
81 };
82
83 // See also: get_system_properties in attachListener.cpp
84 class PrintSystemPropertiesDCmd : public DCmd {
85 public:
86 PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
87 static const char* name() { return "VM.system_properties"; }
88 static const char* description() {
89 return "Print system properties.";
90 }
91 static const char* impact() {
92 return "Low";
93 }
94 virtual void execute(DCmdSource source, TRAPS);
95 };
96
97 class PrintSecurityPropertiesDCmd : public DCmd {
98 public:
99 PrintSecurityPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
100 static const char* name() { return "VM.security_properties"; }
101 static const char* description() { return "Print java.security.Security properties."; }
102 static const char* impact() { return "Low"; }
103 virtual void execute(DCmdSource source, TRAPS);
104 };
105
106 // See also: print_flag in attachListener.cpp
107 class PrintVMFlagsDCmd : public DCmdWithParser {
108 protected:
109 DCmdArgument<bool> _all;
110 public:
111 static int num_arguments() { return 1; }
112 PrintVMFlagsDCmd(outputStream* output, bool heap);
113 static const char* name() { return "VM.flags"; }
114 static const char* description() {
115 return "Print VM flag options and their current values.";
116 }
117 static const char* impact() {
118 return "Low";
119 }
120 virtual void execute(DCmdSource source, TRAPS);
121 };
122
123 class SetVMFlagDCmd : public DCmdWithParser {
124 protected:
125 DCmdArgument<char*> _flag;
126 DCmdArgument<char*> _value;
127
128 public:
129 static int num_arguments() { return 2; }
130 SetVMFlagDCmd(outputStream* output, bool heap);
131 static const char* name() { return "VM.set_flag"; }
132 static const char* description() {
133 return "Sets VM flag option using the provided value.";
134 }
135 static const char* impact() {
136 return "Low";
137 }
138 virtual void execute(DCmdSource source, TRAPS);
139 };
140
141 class JVMTIDataDumpDCmd : public DCmd {
142 public:
143 JVMTIDataDumpDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
144 static const char* name() { return "JVMTI.data_dump"; }
145 static const char* description() {
146 return "Signal the JVM to do a data-dump request for JVMTI.";
147 }
148 static const char* impact() {
149 return "High";
150 }
151 virtual void execute(DCmdSource source, TRAPS);
152 };
153
154 #if INCLUDE_SERVICES
155 #if INCLUDE_JVMTI
156 class JVMTIAgentLoadDCmd : public DCmdWithParser {
157 protected:
158 DCmdArgument<char*> _libpath;
159 DCmdArgument<char*> _option;
160 public:
161 static int num_arguments() { return 2; }
162 JVMTIAgentLoadDCmd(outputStream* output, bool heap);
163 static const char* name() { return "JVMTI.agent_load"; }
164 static const char* description() {
165 return "Load JVMTI native agent.";
166 }
167 static const char* impact() { return "Low"; }
168 virtual void execute(DCmdSource source, TRAPS);
169 };
170 #endif // INCLUDE_JVMTI
171 #endif // INCLUDE_SERVICES
172
173 class VMDynamicLibrariesDCmd : public DCmd {
174 public:
175 VMDynamicLibrariesDCmd(outputStream* output, bool heap);
176 static const char* name() {
177 return "VM.dynlibs";
178 }
179 static const char* description() {
180 return "Print loaded dynamic libraries.";
181 }
182 static const char* impact() {
183 return "Low";
184 }
185 virtual void execute(DCmdSource source, TRAPS);
186 };
187
188 class VMUptimeDCmd : public DCmdWithParser {
189 protected:
190 DCmdArgument<bool> _date;
191 public:
192 static int num_arguments() { return 1; }
193 VMUptimeDCmd(outputStream* output, bool heap);
194 static const char* name() { return "VM.uptime"; }
195 static const char* description() {
196 return "Print VM uptime.";
197 }
198 static const char* impact() {
199 return "Low";
200 }
201 virtual void execute(DCmdSource source, TRAPS);
202 };
203
204 class VMInfoDCmd : public DCmd {
205 public:
206 VMInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
207 static const char* name() { return "VM.info"; }
208 static const char* description() {
209 return "Print information about JVM environment and status.";
210 }
211 static const char* impact() { return "Low"; }
212 virtual void execute(DCmdSource source, TRAPS);
213 };
214
215 class SystemGCDCmd : public DCmd {
216 public:
217 SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
218 static const char* name() { return "GC.run"; }
219 static const char* description() {
220 return "Call java.lang.System.gc().";
221 }
222 static const char* impact() {
223 return "Medium: Depends on Java heap size and content.";
224 }
225 virtual void execute(DCmdSource source, TRAPS);
226 };
227
228 class RunFinalizationDCmd : public DCmd {
229 public:
230 RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
231 static const char* name() { return "GC.run_finalization"; }
232 static const char* description() {
233 return "Call java.lang.System.runFinalization().";
234 }
235 static const char* impact() {
236 return "Medium: Depends on Java content.";
237 }
238 virtual void execute(DCmdSource source, TRAPS);
239 };
240
241 class HeapInfoDCmd : public DCmd {
242 public:
243 HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
244 static const char* name() { return "GC.heap_info"; }
245 static const char* description() {
246 return "Provide generic Java heap information.";
247 }
248 static const char* impact() {
249 return "Medium";
250 }
251
252 virtual void execute(DCmdSource source, TRAPS);
253 };
254
255 class FinalizerInfoDCmd : public DCmd {
256 public:
257 FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
258 static const char* name() { return "GC.finalizer_info"; }
259 static const char* description() {
260 return "Provide information about Java finalization queue.";
261 }
262 static const char* impact() {
263 return "Medium";
264 }
265
266 virtual void execute(DCmdSource source, TRAPS);
267 };
268
269 #if INCLUDE_SERVICES // Heap dumping supported
270 // See also: dump_heap in attachListener.cpp
271 class HeapDumpDCmd : public DCmdWithParser {
272 protected:
273 DCmdArgument<char*> _filename;
274 DCmdArgument<bool> _all;
275 DCmdArgument<jlong> _gzip;
276 DCmdArgument<bool> _overwrite;
277 DCmdArgument<jlong> _parallel;
278 public:
279 static int num_arguments() { return 5; }
280 HeapDumpDCmd(outputStream* output, bool heap);
281 static const char* name() {
282 return "GC.heap_dump";
283 }
284 static const char* description() {
285 return "Generate a HPROF format dump of the Java heap.";
286 }
287 static const char* impact() {
288 return "High: Depends on Java heap size and content. "
289 "Request a full GC unless the '-all' option is specified.";
290 }
291 virtual void execute(DCmdSource source, TRAPS);
292 };
293 #endif // INCLUDE_SERVICES
294
295 // See also: inspectheap in attachListener.cpp
296 class ClassHistogramDCmd : public DCmdWithParser {
297 protected:
298 DCmdArgument<bool> _all;
299 DCmdArgument<jlong> _parallel_thread_num;
300 public:
301 static int num_arguments() { return 2; }
302 ClassHistogramDCmd(outputStream* output, bool heap);
303 static const char* name() {
304 return "GC.class_histogram";
305 }
306 static const char* description() {
307 return "Provide statistics about the Java heap usage.";
308 }
309 static const char* impact() {
310 return "High: Depends on Java heap size and content.";
311 }
312 virtual void execute(DCmdSource source, TRAPS);
313 };
314
315 class ClassHierarchyDCmd : public DCmdWithParser {
316 protected:
317 DCmdArgument<bool> _print_interfaces; // true if inherited interfaces should be printed.
318 DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed.
319 DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed.
320 public:
321 static int num_arguments() { return 3; }
322 ClassHierarchyDCmd(outputStream* output, bool heap);
323 static const char* name() {
324 return "VM.class_hierarchy";
325 }
326 static const char* description() {
327 return "Print a list of all loaded classes, indented to show the class hierarchy. "
328 "The name of each class is followed by the ClassLoaderData* of its ClassLoader, "
329 "or \"null\" if loaded by the bootstrap class loader.";
330 }
331 static const char* impact() {
332 return "Medium: Depends on number of loaded classes.";
333 }
334 virtual void execute(DCmdSource source, TRAPS);
335 };
336
337 #if INCLUDE_CDS
338 class AOTEndRecordingDCmd : public DCmd {
339 public:
340 AOTEndRecordingDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
341 static const char* name() { return "AOT.end_recording"; }
342 static const char* description() {
343 return "End AOT recording.";
344 }
345 static const char* impact() {
346 return "Medium: Pause time depends on number of loaded classes";
347 }
348 virtual void execute(DCmdSource source, TRAPS);
349 };
350 #endif // INCLUDE_CDS
351
352 #if INCLUDE_CDS
353 class DumpSharedArchiveDCmd: public DCmdWithParser {
354 protected:
355 DCmdArgument<char*> _suboption; // option of VM.cds
356 DCmdArgument<char*> _filename; // file name, optional
357 public:
358 static int num_arguments() { return 2; }
359 DumpSharedArchiveDCmd(outputStream* output, bool heap);
360 static const char* name() {
361 return "VM.cds";
362 }
363 static const char* description() {
364 return "Dump a static or dynamic shared archive including all shareable classes";
365 }
366 static const char* impact() {
367 return "Medium: Pause time depends on number of loaded classes";
368 }
369 virtual void execute(DCmdSource source, TRAPS);
370 };
371 #endif // INCLUDE_CDS
372
373 // See also: thread_dump in attachListener.cpp
374 class ThreadDumpDCmd : public DCmdWithParser {
375 protected:
376 DCmdArgument<bool> _locks;
377 DCmdArgument<bool> _extended;
378 public:
379 static int num_arguments() { return 2; }
380 ThreadDumpDCmd(outputStream* output, bool heap);
381 static const char* name() { return "Thread.print"; }
382 static const char* description() {
383 return "Print all platform threads, and mounted virtual threads, "
384 "with stack traces. The Thread.dump_to_file command will "
385 "print all threads to a file.";
386 }
387 static const char* impact() {
388 return "Medium: Depends on the number of threads.";
389 }
390 virtual void execute(DCmdSource source, TRAPS);
391 };
392
393 // Enhanced JMX Agent support
394
395 class JMXStartRemoteDCmd : public DCmdWithParser {
396
397 // Explicitly list all properties that could be
398 // passed to Agent.startRemoteManagementAgent()
399 // com.sun.management is omitted
400
401 DCmdArgument<char *> _config_file;
402 DCmdArgument<char *> _jmxremote_host;
403 DCmdArgument<char *> _jmxremote_port;
404 DCmdArgument<char *> _jmxremote_rmi_port;
405 DCmdArgument<char *> _jmxremote_ssl;
406 DCmdArgument<char *> _jmxremote_registry_ssl;
407 DCmdArgument<char *> _jmxremote_authenticate;
408 DCmdArgument<char *> _jmxremote_password_file;
409 DCmdArgument<char *> _jmxremote_access_file;
410 DCmdArgument<char *> _jmxremote_login_config;
411 DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites;
412 DCmdArgument<char *> _jmxremote_ssl_enabled_protocols;
413 DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
414 DCmdArgument<char *> _jmxremote_ssl_config_file;
415
416 // JDP support
417 // Keep autodiscovery char* not bool to pass true/false
418 // as property value to java level.
419 DCmdArgument<char *> _jmxremote_autodiscovery;
420 DCmdArgument<jlong> _jdp_port;
421 DCmdArgument<char *> _jdp_address;
422 DCmdArgument<char *> _jdp_source_addr;
423 DCmdArgument<jlong> _jdp_ttl;
424 DCmdArgument<jlong> _jdp_pause;
425 DCmdArgument<char *> _jdp_name;
426
427 public:
428 static int num_arguments() { return 21; }
429
430 JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
431
432 static const char *name() {
433 return "ManagementAgent.start";
434 }
435
436 static const char *description() {
437 return "Start remote management agent.";
438 }
439
440 virtual void execute(DCmdSource source, TRAPS);
441 };
442
443 class JMXStartLocalDCmd : public DCmd {
444
445 // Explicitly request start of local agent,
446 // it will not be started by start dcmd
447
448
449 public:
450 JMXStartLocalDCmd(outputStream *output, bool heap_allocated);
451
452 static const char *name() {
453 return "ManagementAgent.start_local";
454 }
455
456 static const char *description() {
457 return "Start local management agent.";
458 }
459
460 virtual void execute(DCmdSource source, TRAPS);
461
462 };
463
464 class JMXStopRemoteDCmd : public DCmd {
465 public:
466 JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) :
467 DCmd(output, heap_allocated) {
468 // Do Nothing
469 }
470
471 static const char *name() {
472 return "ManagementAgent.stop";
473 }
474
475 static const char *description() {
476 return "Stop remote management agent.";
477 }
478
479 virtual void execute(DCmdSource source, TRAPS);
480 };
481
482 // Print the JMX system status
483 class JMXStatusDCmd : public DCmd {
484 public:
485 JMXStatusDCmd(outputStream *output, bool heap_allocated);
486
487 static const char *name() {
488 return "ManagementAgent.status";
489 }
490
491 static const char *description() {
492 return "Print the management agent status.";
493 }
494
495 virtual void execute(DCmdSource source, TRAPS);
496
497 };
498
499 class CompileQueueDCmd : public DCmd {
500 public:
501 CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
502 static const char* name() {
503 return "Compiler.queue";
504 }
505 static const char* description() {
506 return "Print methods queued for compilation.";
507 }
508 static const char* impact() {
509 return "Low";
510 }
511 virtual void execute(DCmdSource source, TRAPS);
512 };
513
514 #ifdef LINUX
515 class PerfMapDCmd : public DCmdWithParser {
516 protected:
517 DCmdArgument<char*> _filename;
518 public:
519 static int num_arguments() { return 1; }
520 PerfMapDCmd(outputStream* output, bool heap);
521 static const char* name() {
522 return "Compiler.perfmap";
523 }
524 static const char* description() {
525 return "Write map file for Linux perf tool.";
526 }
527 static const char* impact() {
528 return "Low";
529 }
530 virtual void execute(DCmdSource source, TRAPS);
531 };
532 #endif // LINUX
533
534 class CodeListDCmd : public DCmd {
535 public:
536 CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
537 static const char* name() {
538 return "Compiler.codelist";
539 }
540 static const char* description() {
541 return "Print all compiled methods in code cache that are alive";
542 }
543 static const char* impact() {
544 return "Medium";
545 }
546 virtual void execute(DCmdSource source, TRAPS);
547 };
548
549 class CodeCacheDCmd : public DCmd {
550 public:
551 CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
552 static const char* name() {
553 return "Compiler.codecache";
554 }
555 static const char* description() {
556 return "Print code cache layout and bounds.";
557 }
558 static const char* impact() {
559 return "Low";
560 }
561 virtual void execute(DCmdSource source, TRAPS);
562 };
563
564 //---< BEGIN >--- CodeHeap State Analytics.
565 class CodeHeapAnalyticsDCmd : public DCmdWithParser {
566 protected:
567 DCmdArgument<char*> _function;
568 DCmdArgument<jlong> _granularity;
569 public:
570 static int num_arguments() { return 2; }
571 CodeHeapAnalyticsDCmd(outputStream* output, bool heap);
572 static const char* name() {
573 return "Compiler.CodeHeap_Analytics";
574 }
575 static const char* description() {
576 return "Print CodeHeap analytics";
577 }
578 static const char* impact() {
579 return "Low: Depends on code heap size and content. "
580 "Holds CodeCache_lock during analysis step, usually sub-second duration.";
581 }
582 virtual void execute(DCmdSource source, TRAPS);
583 };
584 //---< END >--- CodeHeap State Analytics.
585
586 class CompilerDirectivesPrintDCmd : public DCmd {
587 public:
588 CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
589 static const char* name() {
590 return "Compiler.directives_print";
591 }
592 static const char* description() {
593 return "Print all active compiler directives.";
594 }
595 static const char* impact() {
596 return "Low";
597 }
598 virtual void execute(DCmdSource source, TRAPS);
599 };
600
601 class CompilerDirectivesRemoveDCmd : public DCmd {
602 public:
603 CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
604 static const char* name() {
605 return "Compiler.directives_remove";
606 }
607 static const char* description() {
608 return "Remove latest added compiler directive.";
609 }
610 static const char* impact() {
611 return "Low";
612 }
613 virtual void execute(DCmdSource source, TRAPS);
614 };
615
616 class CompilerDirectivesAddDCmd : public DCmdWithParser {
617 protected:
618 DCmdArgument<char*> _filename;
619 public:
620 static int num_arguments() { return 1; }
621 CompilerDirectivesAddDCmd(outputStream* output, bool heap);
622 static const char* name() {
623 return "Compiler.directives_add";
624 }
625 static const char* description() {
626 return "Add compiler directives from file.";
627 }
628 static const char* impact() {
629 return "Low";
630 }
631 virtual void execute(DCmdSource source, TRAPS);
632 };
633
634 class CompilerDirectivesClearDCmd : public DCmd {
635 public:
636 CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
637 static const char* name() {
638 return "Compiler.directives_clear";
639 }
640 static const char* description() {
641 return "Remove all compiler directives.";
642 }
643 static const char* impact() {
644 return "Low";
645 }
646 virtual void execute(DCmdSource source, TRAPS);
647 };
648
649 ///////////////////////////////////////////////////////////////////////
650 //
651 // jcmd command support for symbol table, string table and system dictionary dumping:
652 // VM.symboltable -verbose: for dumping the symbol table
653 // VM.stringtable -verbose: for dumping the string table
654 // VM.systemdictionary -verbose: for dumping the system dictionary table
655 //
656 class VM_DumpHashtable : public VM_Operation {
657 private:
658 outputStream* _out;
659 int _which;
660 bool _verbose;
661 public:
662 enum {
663 DumpSymbols = 1 << 0,
664 DumpStrings = 1 << 1,
665 DumpSysDict = 1 << 2 // not implemented yet
666 };
667 VM_DumpHashtable(outputStream* out, int which, bool verbose) {
668 _out = out;
669 _which = which;
670 _verbose = verbose;
671 }
672
673 virtual VMOp_Type type() const { return VMOp_DumpHashtable; }
674
675 virtual void doit() {
676 switch (_which) {
677 case DumpSymbols:
678 SymbolTable::dump(_out, _verbose);
679 break;
680 case DumpStrings:
681 StringTable::dump(_out, _verbose);
682 break;
683 case DumpSysDict:
684 SystemDictionary::dump(_out, _verbose);
685 break;
686 default:
687 ShouldNotReachHere();
688 }
689 }
690 };
691
692 class SymboltableDCmd : public DCmdWithParser {
693 protected:
694 DCmdArgument<bool> _verbose;
695 public:
696 static int num_arguments() { return 1; }
697 SymboltableDCmd(outputStream* output, bool heap);
698 static const char* name() {
699 return "VM.symboltable";
700 }
701 static const char* description() {
702 return "Dump symbol table.";
703 }
704 static const char* impact() {
705 return "Medium: Depends on Java content.";
706 }
707 virtual void execute(DCmdSource source, TRAPS);
708 };
709
710 class StringtableDCmd : public DCmdWithParser {
711 protected:
712 DCmdArgument<bool> _verbose;
713 public:
714 static int num_arguments() { return 1; }
715 StringtableDCmd(outputStream* output, bool heap);
716 static const char* name() {
717 return "VM.stringtable";
718 }
719 static const char* description() {
720 return "Dump string table.";
721 }
722 static const char* impact() {
723 return "Medium: Depends on Java content.";
724 }
725 virtual void execute(DCmdSource source, TRAPS);
726 };
727
728 class SystemDictionaryDCmd : public DCmdWithParser {
729 protected:
730 DCmdArgument<bool> _verbose;
731 public:
732 static int num_arguments() { return 1; }
733 SystemDictionaryDCmd(outputStream* output, bool heap);
734 static const char* name() {
735 return "VM.systemdictionary";
736 }
737 static const char* description() {
738 return "Prints the statistics for dictionary hashtable sizes and bucket length";
739 }
740 static const char* impact() {
741 return "Medium: Depends on Java content.";
742 }
743 virtual void execute(DCmdSource source, TRAPS);
744 };
745
746 class ClassesDCmd : public DCmdWithParser {
747 protected:
748 DCmdArgument<bool> _verbose;
749 public:
750 static int num_arguments() { return 1; }
751 ClassesDCmd(outputStream* output, bool heap);
752 static const char* name() {
753 return "VM.classes";
754 }
755 static const char* description() {
756 return "Print all loaded classes";
757 }
758 static const char* impact() {
759 return "Medium: Depends on number of loaded classes.";
760 }
761 virtual void execute(DCmdSource source, TRAPS);
762 };
763
764 class EventLogDCmd : public DCmdWithParser {
765 protected:
766 DCmdArgument<char*> _log;
767 DCmdArgument<jlong> _max;
768 public:
769 static int num_arguments() { return 2; }
770 EventLogDCmd(outputStream* output, bool heap);
771 static const char* name() {
772 return "VM.events";
773 }
774 static const char* description() {
775 return "Print VM event logs";
776 }
777 static const char* impact() {
778 return "Low: Depends on event log size. ";
779 }
780 virtual void execute(DCmdSource source, TRAPS);
781 };
782
783 class ThreadDumpToFileDCmd : public DCmdWithParser {
784 private:
785 void dumpToFile(Symbol* name, Symbol* signature, const char* path, bool overwrite, bool no_prettyprint, TRAPS);
786 protected:
787 DCmdArgument<char*> _format;
788 DCmdArgument<bool> _no_prettyprint;
789 DCmdArgument<char*> _filepath;
790 DCmdArgument<bool> _overwrite;
791 public:
792 static int num_arguments() { return 4; }
793 ThreadDumpToFileDCmd(outputStream *output, bool heap);
794 static const char *name() {
795 return "Thread.dump_to_file";
796 }
797 static const char *description() {
798 return "Dump all threads, with stack traces, "
799 "to a file in plain text or JSON format.";
800 }
801 static const char* impact() {
802 return "Medium: Depends on the number of threads.";
803 }
804 virtual void execute(DCmdSource source, TRAPS);
805 };
806
807 class VThreadSchedulerDCmd : public DCmd {
808 public:
809 VThreadSchedulerDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
810 static const char* name() {
811 return "Thread.vthread_scheduler";
812 }
813 static const char* description() {
814 return "Print the virtual thread scheduler, and the delayed task schedulers that support "
815 "virtual threads doing timed operations.";
816 }
817 static const char* impact() { return "Low"; }
818 virtual void execute(DCmdSource source, TRAPS);
819 };
820
821 class VThreadPollersDCmd : public DCmd {
822 public:
823 VThreadPollersDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
824 static const char* name() {
825 return "Thread.vthread_pollers";
826 }
827 static const char* description() {
828 return "Print the I/O pollers that support virtual threads doing blocking network I/O operations.";
829 }
830 static const char* impact() { return "Low"; }
831 virtual void execute(DCmdSource source, TRAPS);
832 };
833
834 class CompilationMemoryStatisticDCmd: public DCmdWithParser {
835 protected:
836 DCmdArgument<bool> _verbose;
837 DCmdArgument<bool> _legend;
838 DCmdArgument<MemorySizeArgument> _minsize;
839 public:
840 static int num_arguments() { return 3; }
841 CompilationMemoryStatisticDCmd(outputStream* output, bool heap);
842 static const char* name() {
843 return "Compiler.memory";
844 }
845 static const char* description() {
846 return "Print compilation footprint";
847 }
848 static const char* impact() {
849 return "Medium: Pause time depends on number of compiled methods";
850 }
851 virtual void execute(DCmdSource source, TRAPS);
852 };
853
854 #if defined(LINUX) || defined(_WIN64) || defined(__APPLE__)
855
856 class SystemMapDCmd : public DCmd {
857 public:
858 SystemMapDCmd(outputStream* output, bool heap);
859 static const char* name() { return "System.map"; }
860 static const char* description() {
861 return "Prints an annotated process memory map of the VM process (linux, Windows and MacOS only).";
862 }
863 static const char* impact() { return "Medium; can be high for very large java heaps."; }
864 virtual void execute(DCmdSource source, TRAPS);
865 };
866
867 class SystemDumpMapDCmd : public DCmdWithParser {
868 DCmdArgument<char*> _filename;
869 public:
870 static int num_arguments() { return 1; }
871 SystemDumpMapDCmd(outputStream* output, bool heap);
872 static const char* name() { return "System.dump_map"; }
873 static const char* description() {
874 return "Dumps an annotated process memory map to an output file (linux, Windows and MacOS only).";
875 }
876 static const char* impact() { return "Medium; can be high for very large java heaps."; }
877 virtual void execute(DCmdSource source, TRAPS);
878 };
879
880 #endif // LINUX, WINDOWS or MACOS
881
882 #endif // SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP