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