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