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