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 PrintClassLayoutDCmd : public DCmdWithParser {
338 protected:
339 DCmdArgument<char*> _classname; // lass name whose layout should be printed.
340 public:
341 PrintClassLayoutDCmd(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 private:
678 outputStream* _out;
679 int _which;
680 bool _verbose;
681 public:
682 enum {
683 DumpSymbols = 1 << 0,
684 DumpStrings = 1 << 1,
685 DumpSysDict = 1 << 2 // not implemented yet
686 };
687 VM_DumpHashtable(outputStream* out, int which, bool verbose) {
688 _out = out;
689 _which = which;
690 _verbose = verbose;
691 }
692
693 virtual VMOp_Type type() const { return VMOp_DumpHashtable; }
694
695 virtual void doit() {
696 switch (_which) {
697 case DumpSymbols:
698 SymbolTable::dump(_out, _verbose);
699 break;
700 case DumpStrings:
701 StringTable::dump(_out, _verbose);
702 break;
703 case DumpSysDict:
704 SystemDictionary::dump(_out, _verbose);
705 break;
706 default:
707 ShouldNotReachHere();
708 }
709 }
710 };
711
712 class SymboltableDCmd : public DCmdWithParser {
713 protected:
714 DCmdArgument<bool> _verbose;
715 public:
716 static int num_arguments() { return 1; }
717 SymboltableDCmd(outputStream* output, bool heap);
718 static const char* name() {
719 return "VM.symboltable";
720 }
721 static const char* description() {
722 return "Dump symbol table.";
723 }
724 static const char* impact() {
725 return "Medium: Depends on Java content.";
726 }
727 virtual void execute(DCmdSource source, TRAPS);
728 };
729
730 class StringtableDCmd : public DCmdWithParser {
731 protected:
732 DCmdArgument<bool> _verbose;
733 public:
734 static int num_arguments() { return 1; }
735 StringtableDCmd(outputStream* output, bool heap);
736 static const char* name() {
737 return "VM.stringtable";
738 }
739 static const char* description() {
740 return "Dump string table.";
741 }
742 static const char* impact() {
743 return "Medium: Depends on Java content.";
744 }
745 virtual void execute(DCmdSource source, TRAPS);
746 };
747
748 class SystemDictionaryDCmd : public DCmdWithParser {
749 protected:
750 DCmdArgument<bool> _verbose;
751 public:
752 static int num_arguments() { return 1; }
753 SystemDictionaryDCmd(outputStream* output, bool heap);
754 static const char* name() {
755 return "VM.systemdictionary";
756 }
757 static const char* description() {
758 return "Prints the statistics for dictionary hashtable sizes and bucket length";
759 }
760 static const char* impact() {
761 return "Medium: Depends on Java content.";
762 }
763 virtual void execute(DCmdSource source, TRAPS);
764 };
765
766 class ClassesDCmd : public DCmdWithParser {
767 protected:
768 DCmdArgument<bool> _verbose;
769 public:
770 static int num_arguments() { return 1; }
771 ClassesDCmd(outputStream* output, bool heap);
772 static const char* name() {
773 return "VM.classes";
774 }
775 static const char* description() {
776 return "Print all loaded classes";
777 }
778 static const char* impact() {
779 return "Medium: Depends on number of loaded classes.";
780 }
781 virtual void execute(DCmdSource source, TRAPS);
782 };
783
784 class EventLogDCmd : public DCmdWithParser {
785 protected:
786 DCmdArgument<char*> _log;
787 DCmdArgument<jlong> _max;
788 public:
789 static int num_arguments() { return 2; }
790 EventLogDCmd(outputStream* output, bool heap);
791 static const char* name() {
792 return "VM.events";
793 }
794 static const char* description() {
795 return "Print VM event logs";
796 }
797 static const char* impact() {
798 return "Low: Depends on event log size. ";
799 }
800 virtual void execute(DCmdSource source, TRAPS);
801 };
802
803 class ThreadDumpToFileDCmd : public DCmdWithParser {
804 private:
805 void dumpToFile(Symbol* name, Symbol* signature, const char* path, bool overwrite, TRAPS);
806 protected:
807 DCmdArgument<bool> _overwrite;
808 DCmdArgument<char*> _format;
809 DCmdArgument<char*> _filepath;
810 public:
811 static int num_arguments() { return 3; }
812 ThreadDumpToFileDCmd(outputStream *output, bool heap);
813 static const char *name() {
814 return "Thread.dump_to_file";
815 }
816 static const char *description() {
817 return "Dump all threads, with stack traces, "
818 "to a file in plain text or JSON format.";
819 }
820 static const char* impact() {
821 return "Medium: Depends on the number of threads.";
822 }
823 virtual void execute(DCmdSource source, TRAPS);
824 };
825
826 class VThreadSchedulerDCmd : public DCmd {
827 public:
828 VThreadSchedulerDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
829 static const char* name() {
830 return "Thread.vthread_scheduler";
831 }
832 static const char* description() {
833 return "Print the virtual thread scheduler, and the delayed task schedulers that support "
834 "virtual threads doing timed operations.";
835 }
836 static const char* impact() { return "Low"; }
837 virtual void execute(DCmdSource source, TRAPS);
838 };
839
840 class VThreadPollersDCmd : public DCmd {
841 public:
842 VThreadPollersDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
843 static const char* name() {
844 return "Thread.vthread_pollers";
845 }
846 static const char* description() {
847 return "Print the I/O pollers that support virtual threads doing blocking network I/O operations.";
848 }
849 static const char* impact() { return "Low"; }
850 virtual void execute(DCmdSource source, TRAPS);
851 };
852
853 class CompilationMemoryStatisticDCmd: public DCmdWithParser {
854 protected:
855 DCmdArgument<bool> _verbose;
856 DCmdArgument<bool> _legend;
857 DCmdArgument<MemorySizeArgument> _minsize;
858 public:
859 static int num_arguments() { return 3; }
860 CompilationMemoryStatisticDCmd(outputStream* output, bool heap);
861 static const char* name() {
862 return "Compiler.memory";
863 }
864 static const char* description() {
865 return "Print compilation footprint";
866 }
867 static const char* impact() {
868 return "Medium: Pause time depends on number of compiled methods";
869 }
870 virtual void execute(DCmdSource source, TRAPS);
871 };
872
873 #if defined(LINUX) || defined(_WIN64) || defined(__APPLE__)
874
875 class SystemMapDCmd : public DCmd {
876 public:
877 SystemMapDCmd(outputStream* output, bool heap);
878 static const char* name() { return "System.map"; }
879 static const char* description() {
880 return "Prints an annotated process memory map of the VM process (linux, Windows and MacOS only).";
881 }
882 static const char* impact() { return "Medium; can be high for very large java heaps."; }
883 virtual void execute(DCmdSource source, TRAPS);
884 };
885
886 class SystemDumpMapDCmd : public DCmdWithParser {
887 DCmdArgument<char*> _filename;
888 public:
889 static int num_arguments() { return 1; }
890 SystemDumpMapDCmd(outputStream* output, bool heap);
891 static const char* name() { return "System.dump_map"; }
892 static const char* description() {
893 return "Dumps an annotated process memory map to an output file (linux, Windows and MacOS only).";
894 }
895 static const char* impact() { return "Medium; can be high for very large java heaps."; }
896 virtual void execute(DCmdSource source, TRAPS);
897 };
898
899 #endif // LINUX, WINDOWS or MACOS
900
901 #endif // SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP