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