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