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 class ClassPrintLayoutDCmd : public DCmdWithParser {
338 protected:
339 DCmdArgument<char*> _classname; // Class name whose layout should be printed.
340 public:
341 ClassPrintLayoutDCmd(outputStream* output, bool heap);
342 static const char* name() {
343 return "VM.class_print_layout";
344 }
345 static const char* description() {
346 return "Print the layout of an instance of a class, including flat fields. "
347 "The name of each class is followed by the ClassLoaderData* of its ClassLoader, "
348 "or \"null\" if loaded by the bootstrap class loader.";
349 }
350 static const char* impact() {
351 return "Medium: Depends on number of loaded classes.";
352 }
353 static int num_arguments();
354 virtual void execute(DCmdSource source, TRAPS);
355 };
356
357 #if INCLUDE_CDS
358 class AOTEndRecordingDCmd : public DCmd {
359 public:
360 AOTEndRecordingDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
361 static const char* name() { return "AOT.end_recording"; }
362 static const char* description() {
363 return "End AOT recording.";
364 }
365 static const char* impact() {
366 return "Medium: Pause time depends on number of loaded classes";
367 }
368 virtual void execute(DCmdSource source, TRAPS);
369 };
370 #endif // INCLUDE_CDS
371
372 #if INCLUDE_CDS
373 class DumpSharedArchiveDCmd: public DCmdWithParser {
374 protected:
375 DCmdArgument<char*> _suboption; // option of VM.cds
376 DCmdArgument<char*> _filename; // file name, optional
377 public:
378 static int num_arguments() { return 2; }
379 DumpSharedArchiveDCmd(outputStream* output, bool heap);
380 static const char* name() {
381 return "VM.cds";
382 }
383 static const char* description() {
384 return "Dump a static or dynamic shared archive including all shareable classes";
385 }
386 static const char* impact() {
387 return "Medium: Pause time depends on number of loaded classes";
388 }
389 virtual void execute(DCmdSource source, TRAPS);
390 };
391 #endif // INCLUDE_CDS
392
393 // See also: thread_dump in attachListener.cpp
394 class ThreadDumpDCmd : public DCmdWithParser {
395 protected:
396 DCmdArgument<bool> _locks;
397 DCmdArgument<bool> _extended;
398 public:
399 static int num_arguments() { return 2; }
400 ThreadDumpDCmd(outputStream* output, bool heap);
401 static const char* name() { return "Thread.print"; }
402 static const char* description() {
403 return "Print all platform threads, and mounted virtual threads, "
404 "with stack traces. The Thread.dump_to_file command will "
405 "print all threads to a file.";
406 }
407 static const char* impact() {
408 return "Medium: Depends on the number of threads.";
409 }
410 virtual void execute(DCmdSource source, TRAPS);
411 };
412
413 // Enhanced JMX Agent support
414
415 class JMXStartRemoteDCmd : public DCmdWithParser {
416
417 // Explicitly list all properties that could be
418 // passed to Agent.startRemoteManagementAgent()
419 // com.sun.management is omitted
420
421 DCmdArgument<char *> _config_file;
422 DCmdArgument<char *> _jmxremote_host;
423 DCmdArgument<char *> _jmxremote_port;
424 DCmdArgument<char *> _jmxremote_rmi_port;
425 DCmdArgument<char *> _jmxremote_ssl;
426 DCmdArgument<char *> _jmxremote_registry_ssl;
427 DCmdArgument<char *> _jmxremote_authenticate;
428 DCmdArgument<char *> _jmxremote_password_file;
429 DCmdArgument<char *> _jmxremote_access_file;
430 DCmdArgument<char *> _jmxremote_login_config;
431 DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites;
432 DCmdArgument<char *> _jmxremote_ssl_enabled_protocols;
433 DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
434 DCmdArgument<char *> _jmxremote_ssl_config_file;
435
436 // JDP support
437 // Keep autodiscovery char* not bool to pass true/false
438 // as property value to java level.
439 DCmdArgument<char *> _jmxremote_autodiscovery;
440 DCmdArgument<jlong> _jdp_port;
441 DCmdArgument<char *> _jdp_address;
442 DCmdArgument<char *> _jdp_source_addr;
443 DCmdArgument<jlong> _jdp_ttl;
444 DCmdArgument<jlong> _jdp_pause;
445 DCmdArgument<char *> _jdp_name;
446
447 public:
448 static int num_arguments() { return 21; }
449
450 JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
451
452 static const char *name() {
453 return "ManagementAgent.start";
454 }
455
456 static const char *description() {
457 return "Start remote management agent.";
458 }
459
460 virtual void execute(DCmdSource source, TRAPS);
461 };
462
463 class JMXStartLocalDCmd : public DCmd {
464
465 // Explicitly request start of local agent,
466 // it will not be started by start dcmd
467
468
469 public:
470 JMXStartLocalDCmd(outputStream *output, bool heap_allocated);
471
472 static const char *name() {
473 return "ManagementAgent.start_local";
474 }
475
476 static const char *description() {
477 return "Start local management agent.";
478 }
479
480 virtual void execute(DCmdSource source, TRAPS);
481
482 };
483
484 class JMXStopRemoteDCmd : public DCmd {
485 public:
486 JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) :
487 DCmd(output, heap_allocated) {
488 // Do Nothing
489 }
490
491 static const char *name() {
492 return "ManagementAgent.stop";
493 }
494
495 static const char *description() {
496 return "Stop remote management agent.";
497 }
498
499 virtual void execute(DCmdSource source, TRAPS);
500 };
501
502 // Print the JMX system status
503 class JMXStatusDCmd : public DCmd {
504 public:
505 JMXStatusDCmd(outputStream *output, bool heap_allocated);
506
507 static const char *name() {
508 return "ManagementAgent.status";
509 }
510
511 static const char *description() {
512 return "Print the management agent status.";
513 }
514
515 virtual void execute(DCmdSource source, TRAPS);
516
517 };
518
519 class CompileQueueDCmd : public DCmd {
520 public:
521 CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
522 static const char* name() {
523 return "Compiler.queue";
524 }
525 static const char* description() {
526 return "Print methods queued for compilation.";
527 }
528 static const char* impact() {
529 return "Low";
530 }
531 virtual void execute(DCmdSource source, TRAPS);
532 };
533
534 #ifdef LINUX
535 class PerfMapDCmd : public DCmdWithParser {
536 protected:
537 DCmdArgument<char*> _filename;
538 public:
539 static int num_arguments() { return 1; }
540 PerfMapDCmd(outputStream* output, bool heap);
541 static const char* name() {
542 return "Compiler.perfmap";
543 }
544 static const char* description() {
545 return "Write map file for Linux perf tool.";
546 }
547 static const char* impact() {
548 return "Low";
549 }
550 virtual void execute(DCmdSource source, TRAPS);
551 };
552 #endif // LINUX
553
554 class CodeListDCmd : public DCmd {
555 public:
556 CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
557 static const char* name() {
558 return "Compiler.codelist";
559 }
560 static const char* description() {
561 return "Print all compiled methods in code cache that are alive";
562 }
563 static const char* impact() {
564 return "Medium";
565 }
566 virtual void execute(DCmdSource source, TRAPS);
567 };
568
569 class CodeCacheDCmd : public DCmd {
570 public:
571 CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
572 static const char* name() {
573 return "Compiler.codecache";
574 }
575 static const char* description() {
576 return "Print code cache layout and bounds.";
577 }
578 static const char* impact() {
579 return "Low";
580 }
581 virtual void execute(DCmdSource source, TRAPS);
582 };
583
584 //---< BEGIN >--- CodeHeap State Analytics.
585 class CodeHeapAnalyticsDCmd : public DCmdWithParser {
586 protected:
587 DCmdArgument<char*> _function;
588 DCmdArgument<jlong> _granularity;
589 public:
590 static int num_arguments() { return 2; }
591 CodeHeapAnalyticsDCmd(outputStream* output, bool heap);
592 static const char* name() {
593 return "Compiler.CodeHeap_Analytics";
594 }
595 static const char* description() {
596 return "Print CodeHeap analytics";
597 }
598 static const char* impact() {
599 return "Low: Depends on code heap size and content. "
600 "Holds CodeCache_lock during analysis step, usually sub-second duration.";
601 }
602 virtual void execute(DCmdSource source, TRAPS);
603 };
604 //---< END >--- CodeHeap State Analytics.
605
606 class CompilerDirectivesPrintDCmd : public DCmd {
607 public:
608 CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
609 static const char* name() {
610 return "Compiler.directives_print";
611 }
612 static const char* description() {
613 return "Print all active compiler directives.";
614 }
615 static const char* impact() {
616 return "Low";
617 }
618 virtual void execute(DCmdSource source, TRAPS);
619 };
620
621 class CompilerDirectivesRemoveDCmd : public DCmd {
622 public:
623 CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
624 static const char* name() {
625 return "Compiler.directives_remove";
626 }
627 static const char* description() {
628 return "Remove latest added compiler directive.";
629 }
630 static const char* impact() {
631 return "Low";
632 }
633 virtual void execute(DCmdSource source, TRAPS);
634 };
635
636 class CompilerDirectivesAddDCmd : public DCmdWithParser {
637 protected:
638 DCmdArgument<char*> _filename;
639 public:
640 static int num_arguments() { return 1; }
641 CompilerDirectivesAddDCmd(outputStream* output, bool heap);
642 static const char* name() {
643 return "Compiler.directives_add";
644 }
645 static const char* description() {
646 return "Add compiler directives from file.";
647 }
648 static const char* impact() {
649 return "Low";
650 }
651 virtual void execute(DCmdSource source, TRAPS);
652 };
653
654 class CompilerDirectivesClearDCmd : public DCmd {
655 public:
656 CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
657 static const char* name() {
658 return "Compiler.directives_clear";
659 }
660 static const char* description() {
661 return "Remove all compiler directives.";
662 }
663 static const char* impact() {
664 return "Low";
665 }
666 virtual void execute(DCmdSource source, TRAPS);
667 };
668
669 ///////////////////////////////////////////////////////////////////////
670 //
671 // jcmd command support for symbol table, string table and system dictionary dumping:
672 // VM.symboltable -verbose: for dumping the symbol table
673 // VM.stringtable -verbose: for dumping the string table
674 // VM.systemdictionary -verbose: for dumping the system dictionary table
675 //
676 class VM_DumpHashtable : public VM_Operation {
677 public:
678 enum DumpKind {
679 DumpSymbols,
680 DumpStrings,
681 DumpSysDict
682 };
683
684 private:
685 outputStream* _out;
686 DumpKind _which;
687 bool _verbose;
688
689 public:
690 VM_DumpHashtable(outputStream* out, DumpKind which, bool verbose) {
691 _out = out;
692 _which = which;
693 _verbose = verbose;
694 }
695
696 virtual VMOp_Type type() const { return VMOp_DumpHashtable; }
697
698 virtual void doit() {
699 switch (_which) {
700 case DumpSymbols:
701 SymbolTable::dump(_out, _verbose);
702 break;
703 case DumpStrings:
704 StringTable::dump(_out, _verbose);
705 break;
706 case DumpSysDict:
707 SystemDictionary::dump(_out, _verbose);
708 break;
709 default:
710 ShouldNotReachHere();
711 }
712 }
713 };
714
715 class SymboltableDCmd : public DCmdWithParser {
716 protected:
717 DCmdArgument<bool> _verbose;
718 public:
719 static int num_arguments() { return 1; }
720 SymboltableDCmd(outputStream* output, bool heap);
721 static const char* name() {
722 return "VM.symboltable";
723 }
724 static const char* description() {
725 return "Dump symbol table.";
726 }
727 static const char* impact() {
728 return "Medium: Depends on Java content.";
729 }
730 virtual void execute(DCmdSource source, TRAPS);
731 };
732
733 class StringtableDCmd : public DCmdWithParser {
734 protected:
735 DCmdArgument<bool> _verbose;
736 public:
737 static int num_arguments() { return 1; }
738 StringtableDCmd(outputStream* output, bool heap);
739 static const char* name() {
740 return "VM.stringtable";
741 }
742 static const char* description() {
743 return "Dump string table.";
744 }
745 static const char* impact() {
746 return "Medium: Depends on Java content.";
747 }
748 virtual void execute(DCmdSource source, TRAPS);
749 };
750
751 class SystemDictionaryDCmd : public DCmdWithParser {
752 protected:
753 DCmdArgument<bool> _verbose;
754 public:
755 static int num_arguments() { return 1; }
756 SystemDictionaryDCmd(outputStream* output, bool heap);
757 static const char* name() {
758 return "VM.systemdictionary";
759 }
760 static const char* description() {
761 return "Prints the statistics for dictionary hashtable sizes and bucket length";
762 }
763 static const char* impact() {
764 return "Medium: Depends on Java content.";
765 }
766 virtual void execute(DCmdSource source, TRAPS);
767 };
768
769 class ClassesDCmd : public DCmdWithParser {
770 protected:
771 DCmdArgument<bool> _verbose;
772 public:
773 static int num_arguments() { return 1; }
774 ClassesDCmd(outputStream* output, bool heap);
775 static const char* name() {
776 return "VM.classes";
777 }
778 static const char* description() {
779 return "Print all loaded classes";
780 }
781 static const char* impact() {
782 return "Medium: Depends on number of loaded classes.";
783 }
784 virtual void execute(DCmdSource source, TRAPS);
785 };
786
787 class EventLogDCmd : public DCmdWithParser {
788 protected:
789 DCmdArgument<char*> _log;
790 DCmdArgument<jlong> _max;
791 public:
792 static int num_arguments() { return 2; }
793 EventLogDCmd(outputStream* output, bool heap);
794 static const char* name() {
795 return "VM.events";
796 }
797 static const char* description() {
798 return "Print VM event logs";
799 }
800 static const char* impact() {
801 return "Low: Depends on event log size. ";
802 }
803 virtual void execute(DCmdSource source, TRAPS);
804 };
805
806 class ThreadDumpToFileDCmd : public DCmdWithParser {
807 private:
808 void dumpToFile(Symbol* name, Symbol* signature, const char* path, bool overwrite, bool no_prettyprint, TRAPS);
809 protected:
810 DCmdArgument<char*> _format;
811 DCmdArgument<bool> _no_prettyprint;
812 DCmdArgument<char*> _filepath;
813 DCmdArgument<bool> _overwrite;
814 public:
815 static int num_arguments() { return 4; }
816 ThreadDumpToFileDCmd(outputStream *output, bool heap);
817 static const char *name() {
818 return "Thread.dump_to_file";
819 }
820 static const char *description() {
821 return "Dump all threads, with stack traces, "
822 "to a file in plain text or JSON format.";
823 }
824 static const char* impact() {
825 return "Medium: Depends on the number of threads.";
826 }
827 virtual void execute(DCmdSource source, TRAPS);
828 };
829
830 class VThreadSchedulerDCmd : public DCmd {
831 public:
832 VThreadSchedulerDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
833 static const char* name() {
834 return "Thread.vthread_scheduler";
835 }
836 static const char* description() {
837 return "Print the virtual thread scheduler, and the delayed task schedulers that support "
838 "virtual threads doing timed operations.";
839 }
840 static const char* impact() { return "Low"; }
841 virtual void execute(DCmdSource source, TRAPS);
842 };
843
844 class VThreadPollersDCmd : public DCmd {
845 public:
846 VThreadPollersDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
847 static const char* name() {
848 return "Thread.vthread_pollers";
849 }
850 static const char* description() {
851 return "Print the I/O pollers that support virtual threads doing blocking network I/O operations.";
852 }
853 static const char* impact() { return "Low"; }
854 virtual void execute(DCmdSource source, TRAPS);
855 };
856
857 class CompilationMemoryStatisticDCmd: public DCmdWithParser {
858 protected:
859 DCmdArgument<bool> _verbose;
860 DCmdArgument<bool> _legend;
861 DCmdArgument<MemorySizeArgument> _minsize;
862 public:
863 static int num_arguments() { return 3; }
864 CompilationMemoryStatisticDCmd(outputStream* output, bool heap);
865 static const char* name() {
866 return "Compiler.memory";
867 }
868 static const char* description() {
869 return "Print compilation footprint";
870 }
871 static const char* impact() {
872 return "Medium: Pause time depends on number of compiled methods";
873 }
874 virtual void execute(DCmdSource source, TRAPS);
875 };
876
877 #if defined(LINUX) || defined(_WIN64) || defined(__APPLE__)
878
879 class SystemMapDCmd : public DCmd {
880 public:
881 SystemMapDCmd(outputStream* output, bool heap);
882 static const char* name() { return "System.map"; }
883 static const char* description() {
884 return "Prints an annotated process memory map of the VM process (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 class SystemDumpMapDCmd : public DCmdWithParser {
891 DCmdArgument<char*> _filename;
892 public:
893 static int num_arguments() { return 1; }
894 SystemDumpMapDCmd(outputStream* output, bool heap);
895 static const char* name() { return "System.dump_map"; }
896 static const char* description() {
897 return "Dumps an annotated process memory map to an output file (linux, Windows and MacOS only).";
898 }
899 static const char* impact() { return "Medium; can be high for very large java heaps."; }
900 virtual void execute(DCmdSource source, TRAPS);
901 };
902
903 #endif // LINUX, WINDOWS or MACOS
904
905 #endif // SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP