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