1 /*
2  * Copyright (c) 2011, 2021, 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);
name()48   static const char* name() { return "help"; }
description()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   }
impact()54   static const char* impact() { return "Low"; }
55   virtual void execute(DCmdSource source, TRAPS);
56 };
57 
58 class VersionDCmd : public DCmd {
59 public:
VersionDCmd(outputStream * output,bool heap)60   VersionDCmd(outputStream* output, bool heap) : DCmd(output,heap) { }
name()61   static const char* name() { return "VM.version"; }
description()62   static const char* description() {
63     return "Print JVM version information.";
64   }
impact()65   static const char* impact() { return "Low"; }
permission()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:
CommandLineDCmd(outputStream * output,bool heap)76   CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()77   static const char* name() { return "VM.command_line"; }
description()78   static const char* description() {
79     return "Print the command line used to start this VM instance.";
80   }
impact()81   static const char* impact() { return "Low"; }
permission()82   static const JavaPermission permission() {
83     JavaPermission p = {"java.lang.management.ManagementPermission",
84                         "monitor", NULL};
85     return p;
86   }
execute(DCmdSource source,TRAPS)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:
PrintSystemPropertiesDCmd(outputStream * output,bool heap)95   PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()96     static const char* name() { return "VM.system_properties"; }
description()97     static const char* description() {
98       return "Print system properties.";
99     }
impact()100     static const char* impact() {
101       return "Low";
102     }
permission()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);
name()117   static const char* name() { return "VM.flags"; }
description()118   static const char* description() {
119     return "Print VM flag options and their current values.";
120   }
impact()121   static const char* impact() {
122     return "Low";
123   }
permission()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);
name()139   static const char* name() { return "VM.set_flag"; }
description()140   static const char* description() {
141     return "Sets VM flag option using the provided value.";
142   }
impact()143   static const char* impact() {
144     return "Low";
145   }
permission()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:
JVMTIDataDumpDCmd(outputStream * output,bool heap)156   JVMTIDataDumpDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()157   static const char* name() { return "JVMTI.data_dump"; }
description()158   static const char* description() {
159     return "Signal the JVM to do a data-dump request for JVMTI.";
160   }
impact()161   static const char* impact() {
162     return "High";
163   }
permission()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);
name()180   static const char* name() { return "JVMTI.agent_load"; }
description()181   static const char* description() {
182     return "Load JVMTI native agent.";
183   }
impact()184   static const char* impact() { return "Low"; }
permission()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);
name()198   static const char* name() {
199     return "VM.dynlibs";
200   }
description()201   static const char* description() {
202     return "Print loaded dynamic libraries.";
203   }
impact()204   static const char* impact() {
205     return "Low";
206   }
permission()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);
name()220   static const char* name() { return "VM.uptime"; }
description()221   static const char* description() {
222     return "Print VM uptime.";
223   }
impact()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:
VMInfoDCmd(outputStream * output,bool heap)232   VMInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()233   static const char* name() { return "VM.info"; }
description()234   static const char* description() {
235     return "Print information about JVM environment and status.";
236   }
impact()237   static const char* impact() { return "Low"; }
permission()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:
SystemGCDCmd(outputStream * output,bool heap)248   SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()249     static const char* name() { return "GC.run"; }
description()250     static const char* description() {
251       return "Call java.lang.System.gc().";
252     }
impact()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:
RunFinalizationDCmd(outputStream * output,bool heap)261   RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()262     static const char* name() { return "GC.run_finalization"; }
description()263     static const char* description() {
264       return "Call java.lang.System.runFinalization().";
265     }
impact()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:
HeapInfoDCmd(outputStream * output,bool heap)274   HeapInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()275   static const char* name() { return "GC.heap_info"; }
description()276   static const char* description() {
277     return "Provide generic Java heap information.";
278   }
impact()279   static const char* impact() {
280     return "Medium";
281   }
permission()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:
FinalizerInfoDCmd(outputStream * output,bool heap)293   FinalizerInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
name()294   static const char* name() { return "GC.finalizer_info"; }
description()295   static const char* description() {
296     return "Provide information about Java finalization queue.";
297   }
impact()298   static const char* impact() {
299     return "Medium";
300   }
permission()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);
name()320   static const char* name() {
321     return "GC.heap_dump";
322   }
description()323   static const char* description() {
324     return "Generate a HPROF format dump of the Java heap.";
325   }
impact()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   }
permission()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);
name()346   static const char* name() {
347     return "GC.class_histogram";
348   }
description()349   static const char* description() {
350     return "Provide statistics about the Java heap usage.";
351   }
impact()352   static const char* impact() {
353     return "High: Depends on Java heap size and content.";
354   }
permission()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);
name()370   static const char* name() {
371     return "VM.class_hierarchy";
372   }
description()373   static const char* description() {
374     return "Print a list of all loaded classes, indented to show the class hiearchy. "
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   }
impact()378   static const char* impact() {
379       return "Medium: Depends on number of loaded classes.";
380   }
permission()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 TouchedMethodsDCmd : public DCmd {
390 public:
TouchedMethodsDCmd(outputStream * output,bool heap)391   TouchedMethodsDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()392   static const char* name() {
393     return "VM.print_touched_methods";
394   }
description()395   static const char* description() {
396     return "Print all methods that have ever been touched during the lifetime of this JVM.";
397   }
impact()398   static const char* impact() {
399     return "Medium: Depends on Java content.";
400   }
401   virtual void execute(DCmdSource source, TRAPS);
402 };
403 
404 #if INCLUDE_CDS
405 class DumpSharedArchiveDCmd: public DCmdWithParser {
406 protected:
407   DCmdArgument<char*> _suboption;   // option of VM.cds
408   DCmdArgument<char*> _filename;    // file name, optional
409 public:
410   DumpSharedArchiveDCmd(outputStream* output, bool heap);
name()411   static const char* name() {
412     return "VM.cds";
413   }
description()414   static const char* description() {
415     return "Dump a static or dynamic shared archive including all shareable classes";
416   }
impact()417   static const char* impact() {
418     return "Medium: Pause time depends on number of loaded classes";
419   }
permission()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 #endif // INCLUDE_CDS
429 
430 // See also: thread_dump in attachListener.cpp
431 class ThreadDumpDCmd : public DCmdWithParser {
432 protected:
433   DCmdArgument<bool> _locks;
434   DCmdArgument<bool> _extended;
435 public:
436   ThreadDumpDCmd(outputStream* output, bool heap);
name()437   static const char* name() { return "Thread.print"; }
description()438   static const char* description() {
439     return "Print all threads with stacktraces.";
440   }
impact()441   static const char* impact() {
442     return "Medium: Depends on the number of threads.";
443   }
permission()444   static const JavaPermission permission() {
445     JavaPermission p = {"java.lang.management.ManagementPermission",
446                         "monitor", NULL};
447     return p;
448   }
449   virtual void execute(DCmdSource source, TRAPS);
450 };
451 
452 // Enhanced JMX Agent support
453 
454 class JMXStartRemoteDCmd : public DCmdWithParser {
455 
456   // Explicitly list all properties that could be
457   // passed to Agent.startRemoteManagementAgent()
458   // com.sun.management is omitted
459 
460   DCmdArgument<char *> _config_file;
461   DCmdArgument<char *> _jmxremote_host;
462   DCmdArgument<char *> _jmxremote_port;
463   DCmdArgument<char *> _jmxremote_rmi_port;
464   DCmdArgument<char *> _jmxremote_ssl;
465   DCmdArgument<char *> _jmxremote_registry_ssl;
466   DCmdArgument<char *> _jmxremote_authenticate;
467   DCmdArgument<char *> _jmxremote_password_file;
468   DCmdArgument<char *> _jmxremote_access_file;
469   DCmdArgument<char *> _jmxremote_login_config;
470   DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites;
471   DCmdArgument<char *> _jmxremote_ssl_enabled_protocols;
472   DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
473   DCmdArgument<char *> _jmxremote_ssl_config_file;
474 
475   // JDP support
476   // Keep autodiscovery char* not bool to pass true/false
477   // as property value to java level.
478   DCmdArgument<char *> _jmxremote_autodiscovery;
479   DCmdArgument<jlong>  _jdp_port;
480   DCmdArgument<char *> _jdp_address;
481   DCmdArgument<char *> _jdp_source_addr;
482   DCmdArgument<jlong>  _jdp_ttl;
483   DCmdArgument<jlong>  _jdp_pause;
484   DCmdArgument<char *> _jdp_name;
485 
486 public:
487   JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
488 
name()489   static const char *name() {
490     return "ManagementAgent.start";
491   }
492 
description()493   static const char *description() {
494     return "Start remote management agent.";
495   }
496 
497   virtual void execute(DCmdSource source, TRAPS);
498 };
499 
500 class JMXStartLocalDCmd : public DCmd {
501 
502   // Explicitly request start of local agent,
503   // it will not be started by start dcmd
504 
505 
506 public:
507   JMXStartLocalDCmd(outputStream *output, bool heap_allocated);
508 
name()509   static const char *name() {
510     return "ManagementAgent.start_local";
511   }
512 
description()513   static const char *description() {
514     return "Start local management agent.";
515   }
516 
517   virtual void execute(DCmdSource source, TRAPS);
518 
519 };
520 
521 class JMXStopRemoteDCmd : public DCmd {
522 public:
JMXStopRemoteDCmd(outputStream * output,bool heap_allocated)523   JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) :
524   DCmd(output, heap_allocated) {
525     // Do Nothing
526   }
527 
name()528   static const char *name() {
529     return "ManagementAgent.stop";
530   }
531 
description()532   static const char *description() {
533     return "Stop remote management agent.";
534   }
535 
536   virtual void execute(DCmdSource source, TRAPS);
537 };
538 
539 // Print the JMX system status
540 class JMXStatusDCmd : public DCmd {
541 public:
542   JMXStatusDCmd(outputStream *output, bool heap_allocated);
543 
name()544   static const char *name() {
545     return "ManagementAgent.status";
546   }
547 
description()548   static const char *description() {
549     return "Print the management agent status.";
550   }
551 
permission()552   static const JavaPermission permission() {
553     JavaPermission p = {"java.lang.management.ManagementPermission",
554                         "monitor", NULL};
555     return p;
556   }
557 
558   virtual void execute(DCmdSource source, TRAPS);
559 
560 };
561 
562 class CompileQueueDCmd : public DCmd {
563 public:
CompileQueueDCmd(outputStream * output,bool heap)564   CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()565   static const char* name() {
566     return "Compiler.queue";
567   }
description()568   static const char* description() {
569     return "Print methods queued for compilation.";
570   }
impact()571   static const char* impact() {
572     return "Low";
573   }
permission()574   static const JavaPermission permission() {
575     JavaPermission p = {"java.lang.management.ManagementPermission",
576                         "monitor", NULL};
577     return p;
578   }
579   virtual void execute(DCmdSource source, TRAPS);
580 };
581 
582 #ifdef LINUX
583 class PerfMapDCmd : public DCmd {
584 public:
PerfMapDCmd(outputStream * output,bool heap)585   PerfMapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()586   static const char* name() {
587     return "Compiler.perfmap";
588   }
description()589   static const char* description() {
590     return "Write map file for Linux perf tool.";
591   }
impact()592   static const char* impact() {
593     return "Low";
594   }
permission()595   static const JavaPermission permission() {
596     JavaPermission p = {"java.lang.management.ManagementPermission",
597                         "monitor", NULL};
598     return p;
599   }
600   virtual void execute(DCmdSource source, TRAPS);
601 };
602 #endif // LINUX
603 
604 class CodeListDCmd : public DCmd {
605 public:
CodeListDCmd(outputStream * output,bool heap)606   CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()607   static const char* name() {
608     return "Compiler.codelist";
609   }
description()610   static const char* description() {
611     return "Print all compiled methods in code cache that are alive";
612   }
impact()613   static const char* impact() {
614     return "Medium";
615   }
permission()616   static const JavaPermission permission() {
617     JavaPermission p = {"java.lang.management.ManagementPermission",
618                         "monitor", NULL};
619     return p;
620   }
621   virtual void execute(DCmdSource source, TRAPS);
622 };
623 
624 class CodeCacheDCmd : public DCmd {
625 public:
CodeCacheDCmd(outputStream * output,bool heap)626   CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()627   static const char* name() {
628     return "Compiler.codecache";
629   }
description()630   static const char* description() {
631     return "Print code cache layout and bounds.";
632   }
impact()633   static const char* impact() {
634     return "Low";
635   }
permission()636   static const JavaPermission permission() {
637     JavaPermission p = {"java.lang.management.ManagementPermission",
638                         "monitor", NULL};
639     return p;
640   }
641   virtual void execute(DCmdSource source, TRAPS);
642 };
643 
644 //---<  BEGIN  >--- CodeHeap State Analytics.
645 class CodeHeapAnalyticsDCmd : public DCmdWithParser {
646 protected:
647   DCmdArgument<char*> _function;
648   DCmdArgument<jlong> _granularity;
649 public:
650   CodeHeapAnalyticsDCmd(outputStream* output, bool heap);
name()651   static const char* name() {
652     return "Compiler.CodeHeap_Analytics";
653   }
description()654   static const char* description() {
655     return "Print CodeHeap analytics";
656   }
impact()657   static const char* impact() {
658     return "Low: Depends on code heap size and content. "
659            "Holds CodeCache_lock during analysis step, usually sub-second duration.";
660   }
permission()661   static const JavaPermission permission() {
662     JavaPermission p = {"java.lang.management.ManagementPermission",
663                         "monitor", NULL};
664     return p;
665   }
666   virtual void execute(DCmdSource source, TRAPS);
667 };
668 //---<  END  >--- CodeHeap State Analytics.
669 
670 class CompilerDirectivesPrintDCmd : public DCmd {
671 public:
CompilerDirectivesPrintDCmd(outputStream * output,bool heap)672   CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()673   static const char* name() {
674     return "Compiler.directives_print";
675   }
description()676   static const char* description() {
677     return "Print all active compiler directives.";
678   }
impact()679   static const char* impact() {
680     return "Low";
681   }
permission()682   static const JavaPermission permission() {
683     JavaPermission p = {"java.lang.management.ManagementPermission",
684                         "monitor", NULL};
685     return p;
686   }
687   virtual void execute(DCmdSource source, TRAPS);
688 };
689 
690 class CompilerDirectivesRemoveDCmd : public DCmd {
691 public:
CompilerDirectivesRemoveDCmd(outputStream * output,bool heap)692   CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()693   static const char* name() {
694     return "Compiler.directives_remove";
695   }
description()696   static const char* description() {
697     return "Remove latest added compiler directive.";
698   }
impact()699   static const char* impact() {
700     return "Low";
701   }
permission()702   static const JavaPermission permission() {
703     JavaPermission p = {"java.lang.management.ManagementPermission",
704                         "monitor", NULL};
705     return p;
706   }
707   virtual void execute(DCmdSource source, TRAPS);
708 };
709 
710 class CompilerDirectivesAddDCmd : public DCmdWithParser {
711 protected:
712   DCmdArgument<char*> _filename;
713 public:
714   CompilerDirectivesAddDCmd(outputStream* output, bool heap);
name()715   static const char* name() {
716     return "Compiler.directives_add";
717   }
description()718   static const char* description() {
719     return "Add compiler directives from file.";
720   }
impact()721   static const char* impact() {
722     return "Low";
723   }
permission()724   static const JavaPermission permission() {
725     JavaPermission p = {"java.lang.management.ManagementPermission",
726                         "monitor", NULL};
727     return p;
728   }
729   virtual void execute(DCmdSource source, TRAPS);
730 };
731 
732 class CompilerDirectivesClearDCmd : public DCmd {
733 public:
CompilerDirectivesClearDCmd(outputStream * output,bool heap)734   CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()735   static const char* name() {
736     return "Compiler.directives_clear";
737   }
description()738   static const char* description() {
739     return "Remove all compiler directives.";
740   }
impact()741   static const char* impact() {
742     return "Low";
743   }
permission()744   static const JavaPermission permission() {
745     JavaPermission p = {"java.lang.management.ManagementPermission",
746                         "monitor", NULL};
747     return p;
748   }
749   virtual void execute(DCmdSource source, TRAPS);
750 };
751 
752 ///////////////////////////////////////////////////////////////////////
753 //
754 // jcmd command support for symbol table, string table and system dictionary dumping:
755 //   VM.symboltable -verbose: for dumping the symbol table
756 //   VM.stringtable -verbose: for dumping the string table
757 //   VM.systemdictionary -verbose: for dumping the system dictionary table
758 //
759 class VM_DumpHashtable : public VM_Operation {
760 private:
761   outputStream* _out;
762   int _which;
763   bool _verbose;
764 public:
765   enum {
766     DumpSymbols = 1 << 0,
767     DumpStrings = 1 << 1,
768     DumpSysDict = 1 << 2  // not implemented yet
769   };
VM_DumpHashtable(outputStream * out,int which,bool verbose)770   VM_DumpHashtable(outputStream* out, int which, bool verbose) {
771     _out = out;
772     _which = which;
773     _verbose = verbose;
774   }
775 
type() const776   virtual VMOp_Type type() const { return VMOp_DumpHashtable; }
777 
doit()778   virtual void doit() {
779     switch (_which) {
780     case DumpSymbols:
781       SymbolTable::dump(_out, _verbose);
782       break;
783     case DumpStrings:
784       StringTable::dump(_out, _verbose);
785       break;
786     case DumpSysDict:
787       SystemDictionary::dump(_out, _verbose);
788       break;
789     default:
790       ShouldNotReachHere();
791     }
792   }
793 };
794 
795 class SymboltableDCmd : public DCmdWithParser {
796 protected:
797   DCmdArgument<bool> _verbose;
798 public:
799   SymboltableDCmd(outputStream* output, bool heap);
name()800   static const char* name() {
801     return "VM.symboltable";
802   }
description()803   static const char* description() {
804     return "Dump symbol table.";
805   }
impact()806   static const char* impact() {
807     return "Medium: Depends on Java content.";
808   }
permission()809   static const JavaPermission permission() {
810     JavaPermission p = {"java.lang.management.ManagementPermission",
811                         "monitor", NULL};
812     return p;
813   }
814   virtual void execute(DCmdSource source, TRAPS);
815 };
816 
817 class StringtableDCmd : public DCmdWithParser {
818 protected:
819   DCmdArgument<bool> _verbose;
820 public:
821   StringtableDCmd(outputStream* output, bool heap);
name()822   static const char* name() {
823     return "VM.stringtable";
824   }
description()825   static const char* description() {
826     return "Dump string table.";
827   }
impact()828   static const char* impact() {
829     return "Medium: Depends on Java content.";
830   }
permission()831   static const JavaPermission permission() {
832     JavaPermission p = {"java.lang.management.ManagementPermission",
833                         "monitor", NULL};
834     return p;
835   }
836   virtual void execute(DCmdSource source, TRAPS);
837 };
838 
839 class SystemDictionaryDCmd : public DCmdWithParser {
840 protected:
841   DCmdArgument<bool> _verbose;
842 public:
843   SystemDictionaryDCmd(outputStream* output, bool heap);
name()844   static const char* name() {
845     return "VM.systemdictionary";
846   }
description()847   static const char* description() {
848     return "Prints the statistics for dictionary hashtable sizes and bucket length";
849   }
impact()850   static const char* impact() {
851       return "Medium: Depends on Java content.";
852   }
permission()853   static const JavaPermission permission() {
854     JavaPermission p = {"java.lang.management.ManagementPermission",
855                         "monitor", NULL};
856     return p;
857   }
858   virtual void execute(DCmdSource source, TRAPS);
859 };
860 
861 #if INCLUDE_JVMTI
862 class DebugOnCmdStartDCmd : public DCmd {
863 public:
DebugOnCmdStartDCmd(outputStream * output,bool heap)864   DebugOnCmdStartDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
name()865   static const char* name() {
866     return "VM.start_java_debugging";
867   }
description()868   static const char* description() {
869     return "Starts up the Java debugging if the jdwp agentlib was enabled with the option onjcmd=y.";
870   }
impact()871   static const char* impact() {
872     return "High: Switches the VM into Java debug mode.";
873   }
permission()874   static const JavaPermission permission() {
875     JavaPermission p = { "java.lang.management.ManagementPermission", "control", NULL };
876     return p;
877   }
878   virtual void execute(DCmdSource source, TRAPS);
879 };
880 #endif // INCLUDE_JVMTI
881 
882 class EventLogDCmd : public DCmdWithParser {
883 protected:
884   DCmdArgument<char*> _log;
885   DCmdArgument<char*> _max;
886 public:
887   EventLogDCmd(outputStream* output, bool heap);
name()888   static const char* name() {
889     return "VM.events";
890   }
description()891   static const char* description() {
892     return "Print VM event logs";
893   }
impact()894   static const char* impact() {
895     return "Low: Depends on event log size. ";
896   }
permission()897   static const JavaPermission permission() {
898     JavaPermission p = {"java.lang.management.ManagementPermission",
899                         "monitor", NULL};
900     return p;
901   }
902   virtual void execute(DCmdSource source, TRAPS);
903 };
904 
905 #endif // SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP
906