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);
 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 class TouchedMethodsDCmd : public DCmd {
415 public:
416   TouchedMethodsDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
417   static const char* name() {
418     return "VM.print_touched_methods";
419   }
420   static const char* description() {
421     return "Print all methods that have ever been touched during the lifetime of this JVM.";
422   }
423   static const char* impact() {
424     return "Medium: Depends on Java content.";
425   }
426   virtual void execute(DCmdSource source, TRAPS);
427 };
428 
429 #if INCLUDE_CDS
430 class DumpSharedArchiveDCmd: public DCmdWithParser {
431 protected:
432   DCmdArgument<char*> _suboption;   // option of VM.cds
433   DCmdArgument<char*> _filename;    // file name, optional
434 public:
435   DumpSharedArchiveDCmd(outputStream* output, bool heap);
436   static const char* name() {
437     return "VM.cds";
438   }
439   static const char* description() {
440     return "Dump a static or dynamic shared archive including all shareable classes";
441   }
442   static const char* impact() {
443     return "Medium: Pause time depends on number of loaded classes";
444   }
445   static const JavaPermission permission() {
446     JavaPermission p = {"java.lang.management.ManagementPermission",
447                         "monitor", NULL};
448     return p;
449   }
450   static int num_arguments();
451   virtual void execute(DCmdSource source, TRAPS);
452 };
453 #endif // INCLUDE_CDS
454 
455 // See also: thread_dump in attachListener.cpp
456 class ThreadDumpDCmd : public DCmdWithParser {
457 protected:
458   DCmdArgument<bool> _locks;
459   DCmdArgument<bool> _extended;
460 public:
461   ThreadDumpDCmd(outputStream* output, bool heap);
462   static const char* name() { return "Thread.print"; }
463   static const char* description() {
464     return "Print all threads with stacktraces.";
465   }
466   static const char* impact() {
467     return "Medium: Depends on the number of threads.";
468   }
469   static const JavaPermission permission() {
470     JavaPermission p = {"java.lang.management.ManagementPermission",
471                         "monitor", NULL};
472     return p;
473   }
474   virtual void execute(DCmdSource source, TRAPS);
475 };
476 
477 // Enhanced JMX Agent support
478 
479 class JMXStartRemoteDCmd : public DCmdWithParser {
480 
481   // Explicitly list all properties that could be
482   // passed to Agent.startRemoteManagementAgent()
483   // com.sun.management is omitted
484 
485   DCmdArgument<char *> _config_file;
486   DCmdArgument<char *> _jmxremote_host;
487   DCmdArgument<char *> _jmxremote_port;
488   DCmdArgument<char *> _jmxremote_rmi_port;
489   DCmdArgument<char *> _jmxremote_ssl;
490   DCmdArgument<char *> _jmxremote_registry_ssl;
491   DCmdArgument<char *> _jmxremote_authenticate;
492   DCmdArgument<char *> _jmxremote_password_file;
493   DCmdArgument<char *> _jmxremote_access_file;
494   DCmdArgument<char *> _jmxremote_login_config;
495   DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites;
496   DCmdArgument<char *> _jmxremote_ssl_enabled_protocols;
497   DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
498   DCmdArgument<char *> _jmxremote_ssl_config_file;
499 
500   // JDP support
501   // Keep autodiscovery char* not bool to pass true/false
502   // as property value to java level.
503   DCmdArgument<char *> _jmxremote_autodiscovery;
504   DCmdArgument<jlong>  _jdp_port;
505   DCmdArgument<char *> _jdp_address;
506   DCmdArgument<char *> _jdp_source_addr;
507   DCmdArgument<jlong>  _jdp_ttl;
508   DCmdArgument<jlong>  _jdp_pause;
509   DCmdArgument<char *> _jdp_name;
510 
511 public:
512   JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
513 
514   static const char *name() {
515     return "ManagementAgent.start";
516   }
517 
518   static const char *description() {
519     return "Start remote management agent.";
520   }
521 
522   virtual void execute(DCmdSource source, TRAPS);
523 };
524 
525 class JMXStartLocalDCmd : public DCmd {
526 
527   // Explicitly request start of local agent,
528   // it will not be started by start dcmd
529 
530 
531 public:
532   JMXStartLocalDCmd(outputStream *output, bool heap_allocated);
533 
534   static const char *name() {
535     return "ManagementAgent.start_local";
536   }
537 
538   static const char *description() {
539     return "Start local management agent.";
540   }
541 
542   virtual void execute(DCmdSource source, TRAPS);
543 
544 };
545 
546 class JMXStopRemoteDCmd : public DCmd {
547 public:
548   JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) :
549   DCmd(output, heap_allocated) {
550     // Do Nothing
551   }
552 
553   static const char *name() {
554     return "ManagementAgent.stop";
555   }
556 
557   static const char *description() {
558     return "Stop remote management agent.";
559   }
560 
561   virtual void execute(DCmdSource source, TRAPS);
562 };
563 
564 // Print the JMX system status
565 class JMXStatusDCmd : public DCmd {
566 public:
567   JMXStatusDCmd(outputStream *output, bool heap_allocated);
568 
569   static const char *name() {
570     return "ManagementAgent.status";
571   }
572 
573   static const char *description() {
574     return "Print the management agent status.";
575   }
576 
577   static const JavaPermission permission() {
578     JavaPermission p = {"java.lang.management.ManagementPermission",
579                         "monitor", NULL};
580     return p;
581   }
582 
583   virtual void execute(DCmdSource source, TRAPS);
584 
585 };
586 
587 class CompileQueueDCmd : public DCmd {
588 public:
589   CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
590   static const char* name() {
591     return "Compiler.queue";
592   }
593   static const char* description() {
594     return "Print methods queued for compilation.";
595   }
596   static const char* impact() {
597     return "Low";
598   }
599   static const JavaPermission permission() {
600     JavaPermission p = {"java.lang.management.ManagementPermission",
601                         "monitor", NULL};
602     return p;
603   }
604   virtual void execute(DCmdSource source, TRAPS);
605 };
606 
607 #ifdef LINUX
608 class PerfMapDCmd : public DCmd {
609 public:
610   PerfMapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
611   static const char* name() {
612     return "Compiler.perfmap";
613   }
614   static const char* description() {
615     return "Write map file for Linux perf tool.";
616   }
617   static const char* impact() {
618     return "Low";
619   }
620   static const JavaPermission permission() {
621     JavaPermission p = {"java.lang.management.ManagementPermission",
622                         "monitor", NULL};
623     return p;
624   }
625   virtual void execute(DCmdSource source, TRAPS);
626 };
627 #endif // LINUX
628 
629 class CodeListDCmd : public DCmd {
630 public:
631   CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
632   static const char* name() {
633     return "Compiler.codelist";
634   }
635   static const char* description() {
636     return "Print all compiled methods in code cache that are alive";
637   }
638   static const char* impact() {
639     return "Medium";
640   }
641   static const JavaPermission permission() {
642     JavaPermission p = {"java.lang.management.ManagementPermission",
643                         "monitor", NULL};
644     return p;
645   }
646   virtual void execute(DCmdSource source, TRAPS);
647 };
648 
649 class CodeCacheDCmd : public DCmd {
650 public:
651   CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
652   static const char* name() {
653     return "Compiler.codecache";
654   }
655   static const char* description() {
656     return "Print code cache layout and bounds.";
657   }
658   static const char* impact() {
659     return "Low";
660   }
661   static const JavaPermission permission() {
662     JavaPermission p = {"java.lang.management.ManagementPermission",
663                         "monitor", NULL};
664     return p;
665   }
666   virtual void execute(DCmdSource source, TRAPS);
667 };
668 
669 //---<  BEGIN  >--- CodeHeap State Analytics.
670 class CodeHeapAnalyticsDCmd : public DCmdWithParser {
671 protected:
672   DCmdArgument<char*> _function;
673   DCmdArgument<jlong> _granularity;
674 public:
675   CodeHeapAnalyticsDCmd(outputStream* output, bool heap);
676   static const char* name() {
677     return "Compiler.CodeHeap_Analytics";
678   }
679   static const char* description() {
680     return "Print CodeHeap analytics";
681   }
682   static const char* impact() {
683     return "Low: Depends on code heap size and content. "
684            "Holds CodeCache_lock during analysis step, usually sub-second duration.";
685   }
686   static const JavaPermission permission() {
687     JavaPermission p = {"java.lang.management.ManagementPermission",
688                         "monitor", NULL};
689     return p;
690   }
691   virtual void execute(DCmdSource source, TRAPS);
692 };
693 //---<  END  >--- CodeHeap State Analytics.
694 
695 class CompilerDirectivesPrintDCmd : public DCmd {
696 public:
697   CompilerDirectivesPrintDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
698   static const char* name() {
699     return "Compiler.directives_print";
700   }
701   static const char* description() {
702     return "Print all active compiler directives.";
703   }
704   static const char* impact() {
705     return "Low";
706   }
707   static const JavaPermission permission() {
708     JavaPermission p = {"java.lang.management.ManagementPermission",
709                         "monitor", NULL};
710     return p;
711   }
712   virtual void execute(DCmdSource source, TRAPS);
713 };
714 
715 class CompilerDirectivesRemoveDCmd : public DCmd {
716 public:
717   CompilerDirectivesRemoveDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
718   static const char* name() {
719     return "Compiler.directives_remove";
720   }
721   static const char* description() {
722     return "Remove latest added compiler directive.";
723   }
724   static const char* impact() {
725     return "Low";
726   }
727   static const JavaPermission permission() {
728     JavaPermission p = {"java.lang.management.ManagementPermission",
729                         "monitor", NULL};
730     return p;
731   }
732   virtual void execute(DCmdSource source, TRAPS);
733 };
734 
735 class CompilerDirectivesAddDCmd : public DCmdWithParser {
736 protected:
737   DCmdArgument<char*> _filename;
738 public:
739   CompilerDirectivesAddDCmd(outputStream* output, bool heap);
740   static const char* name() {
741     return "Compiler.directives_add";
742   }
743   static const char* description() {
744     return "Add compiler directives from file.";
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   virtual void execute(DCmdSource source, TRAPS);
755 };
756 
757 class CompilerDirectivesClearDCmd : public DCmd {
758 public:
759   CompilerDirectivesClearDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
760   static const char* name() {
761     return "Compiler.directives_clear";
762   }
763   static const char* description() {
764     return "Remove all compiler directives.";
765   }
766   static const char* impact() {
767     return "Low";
768   }
769   static const JavaPermission permission() {
770     JavaPermission p = {"java.lang.management.ManagementPermission",
771                         "monitor", NULL};
772     return p;
773   }
774   virtual void execute(DCmdSource source, TRAPS);
775 };
776 
777 ///////////////////////////////////////////////////////////////////////
778 //
779 // jcmd command support for symbol table, string table and system dictionary dumping:
780 //   VM.symboltable -verbose: for dumping the symbol table
781 //   VM.stringtable -verbose: for dumping the string table
782 //   VM.systemdictionary -verbose: for dumping the system dictionary table
783 //
784 class VM_DumpHashtable : public VM_Operation {
785 private:
786   outputStream* _out;
787   int _which;
788   bool _verbose;
789 public:
790   enum {
791     DumpSymbols = 1 << 0,
792     DumpStrings = 1 << 1,
793     DumpSysDict = 1 << 2  // not implemented yet
794   };
795   VM_DumpHashtable(outputStream* out, int which, bool verbose) {
796     _out = out;
797     _which = which;
798     _verbose = verbose;
799   }
800 
801   virtual VMOp_Type type() const { return VMOp_DumpHashtable; }
802 
803   virtual void doit() {
804     switch (_which) {
805     case DumpSymbols:
806       SymbolTable::dump(_out, _verbose);
807       break;
808     case DumpStrings:
809       StringTable::dump(_out, _verbose);
810       break;
811     case DumpSysDict:
812       SystemDictionary::dump(_out, _verbose);
813       break;
814     default:
815       ShouldNotReachHere();
816     }
817   }
818 };
819 
820 class SymboltableDCmd : public DCmdWithParser {
821 protected:
822   DCmdArgument<bool> _verbose;
823 public:
824   SymboltableDCmd(outputStream* output, bool heap);
825   static const char* name() {
826     return "VM.symboltable";
827   }
828   static const char* description() {
829     return "Dump symbol table.";
830   }
831   static const char* impact() {
832     return "Medium: Depends on Java content.";
833   }
834   static const JavaPermission permission() {
835     JavaPermission p = {"java.lang.management.ManagementPermission",
836                         "monitor", NULL};
837     return p;
838   }
839   virtual void execute(DCmdSource source, TRAPS);
840 };
841 
842 class StringtableDCmd : public DCmdWithParser {
843 protected:
844   DCmdArgument<bool> _verbose;
845 public:
846   StringtableDCmd(outputStream* output, bool heap);
847   static const char* name() {
848     return "VM.stringtable";
849   }
850   static const char* description() {
851     return "Dump string table.";
852   }
853   static const char* impact() {
854     return "Medium: Depends on Java content.";
855   }
856   static const JavaPermission permission() {
857     JavaPermission p = {"java.lang.management.ManagementPermission",
858                         "monitor", NULL};
859     return p;
860   }
861   virtual void execute(DCmdSource source, TRAPS);
862 };
863 
864 class SystemDictionaryDCmd : public DCmdWithParser {
865 protected:
866   DCmdArgument<bool> _verbose;
867 public:
868   SystemDictionaryDCmd(outputStream* output, bool heap);
869   static const char* name() {
870     return "VM.systemdictionary";
871   }
872   static const char* description() {
873     return "Prints the statistics for dictionary hashtable sizes and bucket length";
874   }
875   static const char* impact() {
876       return "Medium: Depends on Java content.";
877   }
878   static const JavaPermission permission() {
879     JavaPermission p = {"java.lang.management.ManagementPermission",
880                         "monitor", NULL};
881     return p;
882   }
883   virtual void execute(DCmdSource source, TRAPS);
884 };
885 
886 #if INCLUDE_JVMTI
887 class DebugOnCmdStartDCmd : public DCmd {
888 public:
889   DebugOnCmdStartDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
890   static const char* name() {
891     return "VM.start_java_debugging";
892   }
893   static const char* description() {
894     return "Starts up the Java debugging if the jdwp agentlib was enabled with the option onjcmd=y.";
895   }
896   static const char* impact() {
897     return "High: Switches the VM into Java debug mode.";
898   }
899   static const JavaPermission permission() {
900     JavaPermission p = { "java.lang.management.ManagementPermission", "control", NULL };
901     return p;
902   }
903   virtual void execute(DCmdSource source, TRAPS);
904 };
905 #endif // INCLUDE_JVMTI
906 
907 class EventLogDCmd : public DCmdWithParser {
908 protected:
909   DCmdArgument<char*> _log;
910   DCmdArgument<char*> _max;
911 public:
912   EventLogDCmd(outputStream* output, bool heap);
913   static const char* name() {
914     return "VM.events";
915   }
916   static const char* description() {
917     return "Print VM event logs";
918   }
919   static const char* impact() {
920     return "Low: Depends on event log size. ";
921   }
922   static const JavaPermission permission() {
923     JavaPermission p = {"java.lang.management.ManagementPermission",
924                         "monitor", NULL};
925     return p;
926   }
927   virtual void execute(DCmdSource source, TRAPS);
928 };
929 
930 #endif // SHARE_SERVICES_DIAGNOSTICCOMMAND_HPP
--- EOF ---