1 /*
   2  * Copyright (c) 2011, 2015, 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/vmSymbols.hpp"
  29 #include "runtime/arguments.hpp"
  30 #include "runtime/os.hpp"
  31 #include "runtime/vmThread.hpp"
  32 #include "services/diagnosticArgument.hpp"
  33 #include "services/diagnosticCommand.hpp"
  34 #include "services/diagnosticCommand_ext.hpp"
  35 #include "services/diagnosticFramework.hpp"
  36 #include "utilities/macros.hpp"
  37 #include "utilities/ostream.hpp"
  38 #include "oops/method.hpp"
  39 
  40 class HelpDCmd : public DCmdWithParser {
  41 protected:
  42   DCmdArgument<bool> _all;
  43   DCmdArgument<char*> _cmd;
  44 public:
  45   HelpDCmd(outputStream* output, bool heap);
  46   static const char* name() { return "help"; }
  47   static const char* description() {
  48     return "For more information about a specific command use 'help <command>'. "
  49            "With no argument this will show a list of available commands. "
  50            "'help all' will show help for all commands.";
  51   }
  52   static const char* impact() { return "Low"; }
  53   static int num_arguments();
  54   virtual void execute(DCmdSource source, TRAPS);
  55 };
  56 
  57 class VersionDCmd : public DCmd {
  58 public:
  59   VersionDCmd(outputStream* output, bool heap) : DCmd(output,heap) { }
  60   static const char* name() { return "VM.version"; }
  61   static const char* description() {
  62     return "Print JVM version information.";
  63   }
  64   static const char* impact() { return "Low"; }
  65   static const JavaPermission permission() {
  66     JavaPermission p = {"java.util.PropertyPermission",
  67                         "java.vm.version", "read"};
  68     return p;
  69   }
  70   static int num_arguments() { return 0; }
  71   virtual void execute(DCmdSource source, TRAPS);
  72 };
  73 
  74 class CommandLineDCmd : public DCmd {
  75 public:
  76   CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
  77   static const char* name() { return "VM.command_line"; }
  78   static const char* description() {
  79     return "Print the command line used to start this VM instance.";
  80   }
  81   static const char* impact() { return "Low"; }
  82   static const JavaPermission permission() {
  83     JavaPermission p = {"java.lang.management.ManagementPermission",
  84                         "monitor", NULL};
  85     return p;
  86   }
  87   static int num_arguments() { return 0; }
  88   virtual void execute(DCmdSource source, TRAPS) {
  89     Arguments::print_on(_output);
  90   }
  91 };
  92 
  93 // See also: get_system_properties in attachListener.cpp
  94 class PrintSystemPropertiesDCmd : public DCmd {
  95 public:
  96   PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
  97     static const char* name() { return "VM.system_properties"; }
  98     static const char* description() {
  99       return "Print system properties.";
 100     }
 101     static const char* impact() {
 102       return "Low";
 103     }
 104     static const JavaPermission permission() {
 105       JavaPermission p = {"java.util.PropertyPermission",
 106                           "*", "read"};
 107       return p;
 108     }
 109     static int num_arguments() { return 0; }
 110     virtual void execute(DCmdSource source, TRAPS);
 111 };
 112 
 113 // See also: print_flag in attachListener.cpp
 114 class PrintVMFlagsDCmd : public DCmdWithParser {
 115 protected:
 116   DCmdArgument<bool> _all;
 117 public:
 118   PrintVMFlagsDCmd(outputStream* output, bool heap);
 119   static const char* name() { return "VM.flags"; }
 120   static const char* description() {
 121     return "Print VM flag options and their current values.";
 122   }
 123   static const char* impact() {
 124     return "Low";
 125   }
 126   static const JavaPermission permission() {
 127     JavaPermission p = {"java.lang.management.ManagementPermission",
 128                         "monitor", NULL};
 129     return p;
 130   }
 131   static int num_arguments();
 132   virtual void execute(DCmdSource source, TRAPS);
 133 };
 134 
 135 class SetVMFlagDCmd : public DCmdWithParser {
 136 protected:
 137   DCmdArgument<char*> _flag;
 138   DCmdArgument<char*> _value;
 139 
 140 public:
 141   SetVMFlagDCmd(outputStream* output, bool heap);
 142   static const char* name() { return "VM.set_flag"; }
 143   static const char* description() {
 144     return "Sets VM flag option using the provided value.";
 145   }
 146   static const char* impact() {
 147     return "Low";
 148   }
 149   static const JavaPermission permission() {
 150     JavaPermission p = {"java.lang.management.ManagementPermission",
 151                         "control", NULL};
 152     return p;
 153   }
 154   static int num_arguments();
 155   virtual void execute(DCmdSource source, TRAPS);
 156 };
 157 
 158 class JVMTIDataDumpDCmd : public DCmd {
 159 public:
 160   JVMTIDataDumpDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 161   static const char* name() { return "JVMTI.data_dump"; }
 162   static const char* description() {
 163     return "Signal the JVM to do a data-dump request for JVMTI.";
 164   }
 165   static const char* impact() {
 166     return "High";
 167   }
 168   static const JavaPermission permission() {
 169     JavaPermission p = {"java.lang.management.ManagementPermission",
 170                         "monitor", NULL};
 171     return p;
 172   }
 173   static int num_arguments() { return 0; }
 174   virtual void execute(DCmdSource source, TRAPS);
 175 };
 176 
 177 class VMDynamicLibrariesDCmd : public DCmd {
 178 public:
 179   VMDynamicLibrariesDCmd(outputStream* output, bool heap);
 180   static const char* name() {
 181     return "VM.dynlibs";
 182   }
 183   static const char* description() {
 184     return "Print loaded dynamic libraries.";
 185   }
 186   static const char* impact() {
 187     return "Low";
 188   }
 189   static const JavaPermission permission() {
 190     JavaPermission p = {"java.lang.management.ManagementPermission",
 191                         "monitor", NULL};
 192     return p;
 193   }
 194   static int num_arguments() {
 195     return 0;
 196   };
 197   virtual void execute(DCmdSource source, TRAPS);
 198 };
 199 
 200 class VMUptimeDCmd : public DCmdWithParser {
 201 protected:
 202   DCmdArgument<bool> _date;
 203 public:
 204   VMUptimeDCmd(outputStream* output, bool heap);
 205   static const char* name() { return "VM.uptime"; }
 206   static const char* description() {
 207     return "Print VM uptime.";
 208   }
 209   static const char* impact() {
 210     return "Low";
 211   }
 212   static int num_arguments();
 213   virtual void execute(DCmdSource source, TRAPS);
 214 };
 215 
 216 class VMInfoDCmd : public DCmd {
 217 public:
 218   VMInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 219   static const char* name() { return "VM.info"; }
 220   static const char* description() {
 221     return "Print information about JVM environment and status.";
 222   }
 223   static const char* impact() { return "Low"; }
 224   static const JavaPermission permission() {
 225     JavaPermission p = {"java.lang.management.ManagementPermission",
 226                         "monitor", NULL};
 227     return p;
 228   }
 229   static int num_arguments() { return 0; }
 230   virtual void execute(DCmdSource source, TRAPS);
 231 };
 232 
 233 class SystemGCDCmd : public DCmd {
 234 public:
 235   SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 236     static const char* name() { return "GC.run"; }
 237     static const char* description() {
 238       return "Call java.lang.System.gc().";
 239     }
 240     static const char* impact() {
 241       return "Medium: Depends on Java heap size and content.";
 242     }
 243     static int num_arguments() { return 0; }
 244     virtual void execute(DCmdSource source, TRAPS);
 245 };
 246 
 247 class RunFinalizationDCmd : public DCmd {
 248 public:
 249   RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 250     static const char* name() { return "GC.run_finalization"; }
 251     static const char* description() {
 252       return "Call java.lang.System.runFinalization().";
 253     }
 254     static const char* impact() {
 255       return "Medium: Depends on Java content.";
 256     }
 257     static int num_arguments() { return 0; }
 258     virtual void execute(DCmdSource source, TRAPS);
 259 };
 260 
 261 class HeapInfoDCmd : public DCmd {
 262 public:
 263   HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 264   static const char* name() { return "GC.heap_info"; }
 265   static const char* description() {
 266     return "Provide generic Java heap information.";
 267   }
 268   static const char* impact() {
 269     return "Medium";
 270   }
 271   static int num_arguments() { return 0; }
 272   static const JavaPermission permission() {
 273     JavaPermission p = {"java.lang.management.ManagementPermission",
 274       "monitor", NULL};
 275       return p;
 276   }
 277 
 278   virtual void execute(DCmdSource source, TRAPS);
 279 };
 280 
 281 class FinalizerInfoDCmd : public DCmd {
 282 public:
 283   FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
 284   static const char* name() { return "GC.finalizer_info"; }
 285   static const char* description() {
 286     return "Provide information about Java finalization queue.";
 287   }
 288   static const char* impact() {
 289     return "Medium";
 290   }
 291   static int num_arguments() { return 0; }
 292   static const JavaPermission permission() {
 293     JavaPermission p = {"java.lang.management.ManagementPermission",
 294       "monitor", NULL};
 295       return p;
 296   }
 297 
 298   virtual void execute(DCmdSource source, TRAPS);
 299 };
 300 
 301 #if INCLUDE_SERVICES   // Heap dumping supported
 302 // See also: dump_heap in attachListener.cpp
 303 class HeapDumpDCmd : public DCmdWithParser {
 304 protected:
 305   DCmdArgument<char*> _filename;
 306   DCmdArgument<bool>  _all;
 307 public:
 308   HeapDumpDCmd(outputStream* output, bool heap);
 309   static const char* name() {
 310     return "GC.heap_dump";
 311   }
 312   static const char* description() {
 313     return "Generate a HPROF format dump of the Java heap.";
 314   }
 315   static const char* impact() {
 316     return "High: Depends on Java heap size and content. "
 317            "Request a full GC unless the '-all' option is specified.";
 318   }
 319   static const JavaPermission permission() {
 320     JavaPermission p = {"java.lang.management.ManagementPermission",
 321                         "monitor", NULL};
 322     return p;
 323   }
 324   static int num_arguments();
 325   virtual void execute(DCmdSource source, TRAPS);
 326 };
 327 #endif // INCLUDE_SERVICES
 328 
 329 // See also: inspectheap in attachListener.cpp
 330 class ClassHistogramDCmd : public DCmdWithParser {
 331 protected:
 332   DCmdArgument<bool> _all;
 333 public:
 334   ClassHistogramDCmd(outputStream* output, bool heap);
 335   static const char* name() {
 336     return "GC.class_histogram";
 337   }
 338   static const char* description() {
 339     return "Provide statistics about the Java heap usage.";
 340   }
 341   static const char* impact() {
 342     return "High: Depends on Java heap size and content.";
 343   }
 344   static const JavaPermission permission() {
 345     JavaPermission p = {"java.lang.management.ManagementPermission",
 346                         "monitor", NULL};
 347     return p;
 348   }
 349   static int num_arguments();
 350   virtual void execute(DCmdSource source, TRAPS);
 351 };
 352 
 353 class ClassStatsDCmd : public DCmdWithParser {
 354 protected:
 355   DCmdArgument<bool> _all;
 356   DCmdArgument<bool> _csv;
 357   DCmdArgument<bool> _help;
 358   DCmdArgument<char*> _columns;
 359 public:
 360   ClassStatsDCmd(outputStream* output, bool heap);
 361   static const char* name() {
 362     return "GC.class_stats";
 363   }
 364   static const char* description() {
 365     return "Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions.";
 366   }
 367   static const char* impact() {
 368     return "High: Depends on Java heap size and content.";
 369   }
 370   static int num_arguments();
 371   virtual void execute(DCmdSource source, TRAPS);
 372 };
 373 
 374 
 375 class ClassHierarchyDCmd : public DCmdWithParser {
 376 protected:
 377   DCmdArgument<bool> _print_interfaces; // true if inherited interfaces should be printed.
 378   DCmdArgument<bool> _print_subclasses; // true if subclasses of the specified classname should be printed.
 379   DCmdArgument<char*> _classname; // Optional single class name whose hierarchy should be printed.
 380 public:
 381   ClassHierarchyDCmd(outputStream* output, bool heap);
 382   static const char* name() {
 383     return "VM.class_hierarchy";
 384   }
 385   static const char* description() {
 386     return "Print a list of all loaded classes, indented to show the class hiearchy. "
 387            "The name of each class is followed by the ClassLoaderData* of its ClassLoader, "
 388            "or \"null\" if loaded by the bootstrap class loader.";
 389   }
 390   static const char* impact() {
 391       return "Medium: Depends on number of loaded classes.";
 392   }
 393   static const JavaPermission permission() {
 394     JavaPermission p = {"java.lang.management.ManagementPermission",
 395                         "monitor", NULL};
 396     return p;
 397   }
 398   static int num_arguments();
 399   virtual void execute(DCmdSource source, TRAPS);
 400 };
 401 
 402 class TouchedMethodsDCmd : public DCmdWithParser {
 403 public:
 404   TouchedMethodsDCmd(outputStream* output, bool heap);
 405   static const char* name() {
 406     return "VM.print_touched_methods";
 407   }
 408   static const char* description() {
 409     return "Print all methods that have ever been touched during the lifetime of this JVM.";
 410   }
 411   static const char* impact() {
 412     return "Medium: Depends on Java content.";
 413   }
 414   static int num_arguments();
 415   virtual void execute(DCmdSource source, TRAPS);
 416 };
 417 
 418 // See also: thread_dump in attachListener.cpp
 419 class ThreadDumpDCmd : public DCmdWithParser {
 420 protected:
 421   DCmdArgument<bool> _locks;
 422 public:
 423   ThreadDumpDCmd(outputStream* output, bool heap);
 424   static const char* name() { return "Thread.print"; }
 425   static const char* description() {
 426     return "Print all threads with stacktraces.";
 427   }
 428   static const char* impact() {
 429     return "Medium: Depends on the number of threads.";
 430   }
 431   static const JavaPermission permission() {
 432     JavaPermission p = {"java.lang.management.ManagementPermission",
 433                         "monitor", NULL};
 434     return p;
 435   }
 436   static int num_arguments();
 437   virtual void execute(DCmdSource source, TRAPS);
 438 };
 439 
 440 // Enhanced JMX Agent support
 441 
 442 class JMXStartRemoteDCmd : public DCmdWithParser {
 443 
 444   // Explicitly list all properties that could be
 445   // passed to Agent.startRemoteManagementAgent()
 446   // com.sun.management is omitted
 447 
 448   DCmdArgument<char *> _config_file;
 449   DCmdArgument<char *> _jmxremote_port;
 450   DCmdArgument<char *> _jmxremote_rmi_port;
 451   DCmdArgument<char *> _jmxremote_ssl;
 452   DCmdArgument<char *> _jmxremote_registry_ssl;
 453   DCmdArgument<char *> _jmxremote_authenticate;
 454   DCmdArgument<char *> _jmxremote_password_file;
 455   DCmdArgument<char *> _jmxremote_access_file;
 456   DCmdArgument<char *> _jmxremote_login_config;
 457   DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites;
 458   DCmdArgument<char *> _jmxremote_ssl_enabled_protocols;
 459   DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
 460   DCmdArgument<char *> _jmxremote_ssl_config_file;
 461 
 462   // JDP support
 463   // Keep autodiscovery char* not bool to pass true/false
 464   // as property value to java level.
 465   DCmdArgument<char *> _jmxremote_autodiscovery;
 466   DCmdArgument<jlong>  _jdp_port;
 467   DCmdArgument<char *> _jdp_address;
 468   DCmdArgument<char *> _jdp_source_addr;
 469   DCmdArgument<jlong>  _jdp_ttl;
 470   DCmdArgument<jlong>  _jdp_pause;
 471   DCmdArgument<char *> _jdp_name;
 472 
 473 public:
 474   JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
 475 
 476   static const char *name() {
 477     return "ManagementAgent.start";
 478   }
 479 
 480   static const char *description() {
 481     return "Start remote management agent.";
 482   }
 483 
 484   static int num_arguments();
 485 
 486   virtual void execute(DCmdSource source, TRAPS);
 487 
 488 };
 489 
 490 class JMXStartLocalDCmd : public DCmd {
 491 
 492   // Explicitly request start of local agent,
 493   // it will not be started by start dcmd
 494 
 495 
 496 public:
 497   JMXStartLocalDCmd(outputStream *output, bool heap_allocated);
 498 
 499   static const char *name() {
 500     return "ManagementAgent.start_local";
 501   }
 502 
 503   static const char *description() {
 504     return "Start local management agent.";
 505   }
 506 
 507   virtual void execute(DCmdSource source, TRAPS);
 508 
 509 };
 510 
 511 class JMXStopRemoteDCmd : public DCmd {
 512 public:
 513   JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) :
 514   DCmd(output, heap_allocated) {
 515     // Do Nothing
 516   }
 517 
 518   static const char *name() {
 519     return "ManagementAgent.stop";
 520   }
 521 
 522   static const char *description() {
 523     return "Stop remote management agent.";
 524   }
 525 
 526   virtual void execute(DCmdSource source, TRAPS);
 527 };
 528 
 529 // Print the JMX system status
 530 class JMXStatusDCmd : public DCmd {
 531 public:
 532   JMXStatusDCmd(outputStream *output, bool heap_allocated);
 533 
 534   static const char *name() {
 535     return "ManagementAgent.status";
 536   }
 537 
 538   static const char *description() {
 539     return "Print the management agent status.";
 540   }
 541 
 542   static const JavaPermission permission() {
 543     JavaPermission p = {"java.lang.management.ManagementPermission",
 544                         "monitor", NULL};
 545     return p;
 546   }
 547 
 548   virtual void execute(DCmdSource source, TRAPS);
 549 
 550 };
 551 
 552 class RotateGCLogDCmd : public DCmd {
 553 public:
 554   RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 555   static const char* name() { return "GC.rotate_log"; }
 556   static const char* description() {
 557     return "Force the GC log file to be rotated.";
 558   }
 559   static const char* impact() { return "Low"; }
 560   virtual void execute(DCmdSource source, TRAPS);
 561   static int num_arguments() { return 0; }
 562   static const JavaPermission permission() {
 563     JavaPermission p = {"java.lang.management.ManagementPermission",
 564                         "control", NULL};
 565     return p;
 566   }
 567 };
 568 
 569 class CompileQueueDCmd : public DCmd {
 570 public:
 571   CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 572   static const char* name() {
 573     return "Compiler.queue";
 574   }
 575   static const char* description() {
 576     return "Print methods queued for compilation.";
 577   }
 578   static const char* impact() {
 579     return "Low";
 580   }
 581   static const JavaPermission permission() {
 582     JavaPermission p = {"java.lang.management.ManagementPermission",
 583                         "monitor", NULL};
 584     return p;
 585   }
 586   static int num_arguments() { return 0; }
 587   virtual void execute(DCmdSource source, TRAPS);
 588 };
 589 
 590 class CodeListDCmd : public DCmd {
 591 public:
 592   CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 593   static const char* name() {
 594     return "Compiler.codelist";
 595   }
 596   static const char* description() {
 597     return "Print all compiled methods in code cache that are alive";
 598   }
 599   static const char* impact() {
 600     return "Medium";
 601   }
 602   static const JavaPermission permission() {
 603     JavaPermission p = {"java.lang.management.ManagementPermission",
 604                         "monitor", NULL};
 605     return p;
 606   }
 607   static int num_arguments() { return 0; }
 608   virtual void execute(DCmdSource source, TRAPS);
 609 };
 610 
 611 
 612 class CodeCacheDCmd : public DCmd {
 613 public:
 614   CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 615   static const char* name() {
 616     return "Compiler.codecache";
 617   }
 618   static const char* description() {
 619     return "Print code cache layout and bounds.";
 620   }
 621   static const char* impact() {
 622     return "Low";
 623   }
 624   static const JavaPermission permission() {
 625     JavaPermission p = {"java.lang.management.ManagementPermission",
 626                         "monitor", NULL};
 627     return p;
 628   }
 629   static int num_arguments() { return 0; }
 630   virtual void execute(DCmdSource source, TRAPS);
 631 };
 632 
 633 class CompilerDirectivesPrintDCmd : public DCmd {
 634 public:
 635   CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 636   static const char* name() {
 637     return "Compiler.directives_print";
 638   }
 639   static const char* description() {
 640     return "Print all active compiler directives.";
 641   }
 642   static const char* impact() {
 643     return "Low";
 644   }
 645   static const JavaPermission permission() {
 646     JavaPermission p = {"java.lang.management.ManagementPermission",
 647                         "monitor", NULL};
 648     return p;
 649   }
 650   static int num_arguments() { return 0; }
 651   virtual void execute(DCmdSource source, TRAPS);
 652 };
 653 
 654 class CompilerDirectivesRemoveDCmd : public DCmd {
 655 public:
 656   CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 657   static const char* name() {
 658     return "Compiler.directives_remove";
 659   }
 660   static const char* description() {
 661     return "Remove latest added compiler directive.";
 662   }
 663   static const char* impact() {
 664     return "Low";
 665   }
 666   static const JavaPermission permission() {
 667     JavaPermission p = {"java.lang.management.ManagementPermission",
 668                         "monitor", NULL};
 669     return p;
 670   }
 671   static int num_arguments() { return 0; }
 672   virtual void execute(DCmdSource source, TRAPS);
 673 };
 674 
 675 class CompilerDirectivesAddDCmd : public DCmdWithParser {
 676 protected:
 677   DCmdArgument<char*> _filename;
 678 public:
 679   CompilerDirectivesAddDCmd(outputStream* output, bool heap);
 680   static const char* name() {
 681     return "Compiler.directives_add";
 682   }
 683   static const char* description() {
 684     return "Add compiler directives from file.";
 685   }
 686   static const char* impact() {
 687     return "Low";
 688   }
 689   static const JavaPermission permission() {
 690     JavaPermission p = {"java.lang.management.ManagementPermission",
 691                         "monitor", NULL};
 692     return p;
 693   }
 694   static int num_arguments();
 695   virtual void execute(DCmdSource source, TRAPS);
 696 };
 697 
 698 class CompilerDirectivesClearDCmd : public DCmd {
 699 public:
 700   CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
 701   static const char* name() {
 702     return "Compiler.directives_clear";
 703   }
 704   static const char* description() {
 705     return "Remove all compiler directives.";
 706   }
 707   static const char* impact() {
 708     return "Low";
 709   }
 710   static const JavaPermission permission() {
 711     JavaPermission p = {"java.lang.management.ManagementPermission",
 712                         "monitor", NULL};
 713     return p;
 714   }
 715   static int num_arguments() { return 0; }
 716   virtual void execute(DCmdSource source, TRAPS);
 717 };
 718 
 719 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP