7120511: Add diagnostic commands

Mon, 09 Jan 2012 10:27:24 +0100

author
fparain
date
Mon, 09 Jan 2012 10:27:24 +0100
changeset 3402
4f25538b54c9
parent 3383
66259eca2bf7
child 3403
865e0817f32b
child 3427
94ec88ca68e2

7120511: Add diagnostic commands
Reviewed-by: acorn, phh, dcubed, sspitsyn

src/share/vm/classfile/vmSymbols.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/arguments.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/init.cpp file | annotate | diff | comparison | revisions
src/share/vm/services/attachListener.cpp file | annotate | diff | comparison | revisions
src/share/vm/services/diagnosticCommand.cpp file | annotate | diff | comparison | revisions
src/share/vm/services/diagnosticCommand.hpp file | annotate | diff | comparison | revisions
src/share/vm/services/diagnosticFramework.cpp file | annotate | diff | comparison | revisions
src/share/vm/services/diagnosticFramework.hpp file | annotate | diff | comparison | revisions
src/share/vm/services/management.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Thu Jan 05 17:16:13 2012 -0500
     1.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Jan 09 10:27:24 2012 +0100
     1.3 @@ -296,6 +296,7 @@
     1.4    template(finalize_method_name,                      "finalize")                                 \
     1.5    template(reference_lock_name,                       "lock")                                     \
     1.6    template(reference_discovered_name,                 "discovered")                               \
     1.7 +  template(run_finalization_name,                     "runFinalization")                          \
     1.8    template(run_finalizers_on_exit_name,               "runFinalizersOnExit")                      \
     1.9    template(uncaughtException_name,                    "uncaughtException")                        \
    1.10    template(dispatchUncaughtException_name,            "dispatchUncaughtException")                \
     2.1 --- a/src/share/vm/runtime/arguments.cpp	Thu Jan 05 17:16:13 2012 -0500
     2.2 +++ b/src/share/vm/runtime/arguments.cpp	Mon Jan 09 10:27:24 2012 +0100
     2.3 @@ -2323,7 +2323,7 @@
     2.4  #ifndef PRODUCT
     2.5      // -Xprintflags
     2.6      } else if (match_option(option, "-Xprintflags", &tail)) {
     2.7 -      CommandLineFlags::printFlags();
     2.8 +      CommandLineFlags::printFlags(tty, false);
     2.9        vm_exit(0);
    2.10  #endif
    2.11      // -D
    2.12 @@ -2971,13 +2971,13 @@
    2.13        IgnoreUnrecognizedVMOptions = false;
    2.14      }
    2.15      if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) {
    2.16 -      CommandLineFlags::printFlags();
    2.17 +      CommandLineFlags::printFlags(tty, false);
    2.18        vm_exit(0);
    2.19      }
    2.20  
    2.21  #ifndef PRODUCT
    2.22      if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) {
    2.23 -      CommandLineFlags::printFlags(true);
    2.24 +      CommandLineFlags::printFlags(tty, true);
    2.25        vm_exit(0);
    2.26      }
    2.27  #endif
    2.28 @@ -3170,7 +3170,7 @@
    2.29  #endif
    2.30  
    2.31    if (PrintCommandLineFlags) {
    2.32 -    CommandLineFlags::printSetFlags();
    2.33 +    CommandLineFlags::printSetFlags(tty);
    2.34    }
    2.35  
    2.36    // Apply CPU specific policy for the BiasedLocking
     3.1 --- a/src/share/vm/runtime/globals.cpp	Thu Jan 05 17:16:13 2012 -0500
     3.2 +++ b/src/share/vm/runtime/globals.cpp	Mon Jan 09 10:27:24 2012 +0100
     3.3 @@ -488,7 +488,7 @@
     3.4    }
     3.5  }
     3.6  
     3.7 -void CommandLineFlags::printSetFlags() {
     3.8 +void CommandLineFlags::printSetFlags(outputStream* out) {
     3.9    // Print which flags were set on the command line
    3.10    // note: this method is called before the thread structure is in place
    3.11    //       which means resource allocation cannot be used.
    3.12 @@ -507,11 +507,11 @@
    3.13    // Print
    3.14    for (int i = 0; i < length; i++) {
    3.15      if (array[i]->origin /* naked field! */) {
    3.16 -      array[i]->print_as_flag(tty);
    3.17 -      tty->print(" ");
    3.18 +      array[i]->print_as_flag(out);
    3.19 +      out->print(" ");
    3.20      }
    3.21    }
    3.22 -  tty->cr();
    3.23 +  out->cr();
    3.24    FREE_C_HEAP_ARRAY(Flag*, array);
    3.25  }
    3.26  
    3.27 @@ -524,7 +524,7 @@
    3.28  
    3.29  #endif // PRODUCT
    3.30  
    3.31 -void CommandLineFlags::printFlags(bool withComments) {
    3.32 +void CommandLineFlags::printFlags(outputStream* out, bool withComments) {
    3.33    // Print the flags sorted by name
    3.34    // note: this method is called before the thread structure is in place
    3.35    //       which means resource allocation cannot be used.
    3.36 @@ -541,10 +541,10 @@
    3.37    qsort(array, length, sizeof(Flag*), compare_flags);
    3.38  
    3.39    // Print
    3.40 -  tty->print_cr("[Global flags]");
    3.41 +  out->print_cr("[Global flags]");
    3.42    for (int i = 0; i < length; i++) {
    3.43      if (array[i]->is_unlocked()) {
    3.44 -      array[i]->print_on(tty, withComments);
    3.45 +      array[i]->print_on(out, withComments);
    3.46      }
    3.47    }
    3.48    FREE_C_HEAP_ARRAY(Flag*, array);
     4.1 --- a/src/share/vm/runtime/globals.hpp	Thu Jan 05 17:16:13 2012 -0500
     4.2 +++ b/src/share/vm/runtime/globals.hpp	Mon Jan 09 10:27:24 2012 +0100
     4.3 @@ -326,9 +326,9 @@
     4.4  
     4.5    // Returns false if name is not a command line flag.
     4.6    static bool wasSetOnCmdline(const char* name, bool* value);
     4.7 -  static void printSetFlags();
     4.8 +  static void printSetFlags(outputStream* out);
     4.9  
    4.10 -  static void printFlags(bool withComments = false );
    4.11 +  static void printFlags(outputStream* out, bool withComments);
    4.12  
    4.13    static void verify() PRODUCT_RETURN;
    4.14  };
     5.1 --- a/src/share/vm/runtime/init.cpp	Thu Jan 05 17:16:13 2012 -0500
     5.2 +++ b/src/share/vm/runtime/init.cpp	Mon Jan 09 10:27:24 2012 +0100
     5.3 @@ -140,7 +140,7 @@
     5.4    // All the flags that get adjusted by VM_Version_init and os::init_2
     5.5    // have been set so dump the flags now.
     5.6    if (PrintFlagsFinal) {
     5.7 -    CommandLineFlags::printFlags();
     5.8 +    CommandLineFlags::printFlags(tty, false);
     5.9    }
    5.10  
    5.11    return JNI_OK;
     6.1 --- a/src/share/vm/services/attachListener.cpp	Thu Jan 05 17:16:13 2012 -0500
     6.2 +++ b/src/share/vm/services/attachListener.cpp	Mon Jan 09 10:27:24 2012 +0100
     6.3 @@ -99,6 +99,7 @@
     6.4  }
     6.5  
     6.6  // Implementation of "properties" command.
     6.7 +// See also: PrintSystemPropertiesDCmd class
     6.8  static jint get_system_properties(AttachOperation* op, outputStream* out) {
     6.9    return get_properties(op, out, vmSymbols::serializePropertiesToByteArray_name());
    6.10  }
    6.11 @@ -127,6 +128,7 @@
    6.12  }
    6.13  
    6.14  // Implementation of "threaddump" command - essentially a remote ctrl-break
    6.15 +// See also: ThreadDumpDCmd class
    6.16  //
    6.17  static jint thread_dump(AttachOperation* op, outputStream* out) {
    6.18    bool print_concurrent_locks = false;
    6.19 @@ -158,6 +160,7 @@
    6.20    DCmd::parse_and_execute(out, op->arg(0), ' ', THREAD);
    6.21    if (HAS_PENDING_EXCEPTION) {
    6.22      java_lang_Throwable::print(PENDING_EXCEPTION, out);
    6.23 +    out->cr();
    6.24      CLEAR_PENDING_EXCEPTION;
    6.25      // The exception has been printed on the output stream
    6.26      // If the JVM returns JNI_ERR, the attachAPI throws a generic I/O
    6.27 @@ -169,6 +172,7 @@
    6.28  
    6.29  #ifndef SERVICES_KERNEL   // Heap dumping not supported
    6.30  // Implementation of "dumpheap" command.
    6.31 +// See also: HeapDumpDCmd class
    6.32  //
    6.33  // Input arguments :-
    6.34  //   arg0: Name of the dump file
    6.35 @@ -211,6 +215,7 @@
    6.36  #endif // SERVICES_KERNEL
    6.37  
    6.38  // Implementation of "inspectheap" command
    6.39 +// See also: ClassHistogramDCmd class
    6.40  //
    6.41  // Input arguments :-
    6.42  //   arg0: "-live" or "-all"
    6.43 @@ -354,6 +359,7 @@
    6.44  }
    6.45  
    6.46  // Implementation of "printflag" command
    6.47 +// See also: PrintVMFlagsDCmd class
    6.48  static jint print_flag(AttachOperation* op, outputStream* out) {
    6.49    const char* name = NULL;
    6.50    if ((name = op->arg(0)) == NULL) {
     7.1 --- a/src/share/vm/services/diagnosticCommand.cpp	Thu Jan 05 17:16:13 2012 -0500
     7.2 +++ b/src/share/vm/services/diagnosticCommand.cpp	Mon Jan 09 10:27:24 2012 +0100
     7.3 @@ -23,11 +23,15 @@
     7.4   */
     7.5  
     7.6  #include "precompiled.hpp"
     7.7 +#include "gc_implementation/shared/vmGCOperations.hpp"
     7.8 +#include "runtime/javaCalls.hpp"
     7.9  #include "services/diagnosticArgument.hpp"
    7.10  #include "services/diagnosticCommand.hpp"
    7.11  #include "services/diagnosticFramework.hpp"
    7.12 +#include "services/heapDumper.hpp"
    7.13 +#include "services/management.hpp"
    7.14  
    7.15 -HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap),
    7.16 +HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
    7.17    _all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
    7.18    _cmd("command name", "The name of the command for which we want help",
    7.19          "STRING", false) {
    7.20 @@ -35,14 +39,6 @@
    7.21    _dcmdparser.add_dcmd_argument(&_cmd);
    7.22  };
    7.23  
    7.24 -void HelpDCmd::parse(CmdLine* line, char delim, TRAPS) {
    7.25 -  _dcmdparser.parse(line, delim, CHECK);
    7.26 -}
    7.27 -
    7.28 -void HelpDCmd::print_help(outputStream* out) {
    7.29 -  _dcmdparser.print_help(out, name());
    7.30 -}
    7.31 -
    7.32  void HelpDCmd::execute(TRAPS) {
    7.33    if (_all.value()) {
    7.34      GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list();
    7.35 @@ -66,10 +62,11 @@
    7.36                           factory->is_enabled() ? "" : " [disabled]");
    7.37        output()->print_cr(factory->description());
    7.38        output()->print_cr("\nImpact: %s", factory->impact());
    7.39 +      output()->cr();
    7.40        cmd = factory->create_resource_instance(output());
    7.41        if (cmd != NULL) {
    7.42          DCmdMark mark(cmd);
    7.43 -        cmd->print_help(output());
    7.44 +        cmd->print_help(factory->name());
    7.45        }
    7.46      } else {
    7.47        output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value());
    7.48 @@ -90,14 +87,6 @@
    7.49    }
    7.50  }
    7.51  
    7.52 -void HelpDCmd::reset(TRAPS) {
    7.53 -  _dcmdparser.reset(CHECK);
    7.54 -}
    7.55 -
    7.56 -void HelpDCmd::cleanup() {
    7.57 -  _dcmdparser.cleanup();
    7.58 -}
    7.59 -
    7.60  int HelpDCmd::num_arguments() {
    7.61    ResourceMark rm;
    7.62    HelpDCmd* dcmd = new HelpDCmd(NULL, false);
    7.63 @@ -109,14 +98,6 @@
    7.64    }
    7.65  }
    7.66  
    7.67 -GrowableArray<const char*>* HelpDCmd::argument_name_array() {
    7.68 -  return _dcmdparser.argument_name_array();
    7.69 -}
    7.70 -
    7.71 -GrowableArray<DCmdArgumentInfo*>* HelpDCmd::argument_info_array() {
    7.72 -  return _dcmdparser.argument_info_array();
    7.73 -}
    7.74 -
    7.75  void VersionDCmd::execute(TRAPS) {
    7.76    output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(),
    7.77            Abstract_VM_Version::vm_release());
    7.78 @@ -129,3 +110,210 @@
    7.79              jdk_version.minor_version());
    7.80    }
    7.81  }
    7.82 +
    7.83 +PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) :
    7.84 +                                   DCmdWithParser(output, heap),
    7.85 +  _all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") {
    7.86 +  _dcmdparser.add_dcmd_option(&_all);
    7.87 +}
    7.88 +
    7.89 +void PrintVMFlagsDCmd::execute(TRAPS) {
    7.90 +  if (_all.value()) {
    7.91 +    CommandLineFlags::printFlags(output(), true);
    7.92 +  } else {
    7.93 +    CommandLineFlags::printSetFlags(output());
    7.94 +  }
    7.95 +}
    7.96 +
    7.97 +int PrintVMFlagsDCmd::num_arguments() {
    7.98 +    ResourceMark rm;
    7.99 +    PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false);
   7.100 +    if (dcmd != NULL) {
   7.101 +      DCmdMark mark(dcmd);
   7.102 +      return dcmd->_dcmdparser.num_arguments();
   7.103 +    } else {
   7.104 +      return 0;
   7.105 +    }
   7.106 +}
   7.107 +
   7.108 +void PrintSystemPropertiesDCmd::execute(TRAPS) {
   7.109 +  // load sun.misc.VMSupport
   7.110 +  Symbol* klass = vmSymbols::sun_misc_VMSupport();
   7.111 +  klassOop k = SystemDictionary::resolve_or_fail(klass, true, CHECK);
   7.112 +  instanceKlassHandle ik (THREAD, k);
   7.113 +  if (ik->should_be_initialized()) {
   7.114 +    ik->initialize(THREAD);
   7.115 +  }
   7.116 +  if (HAS_PENDING_EXCEPTION) {
   7.117 +    java_lang_Throwable::print(PENDING_EXCEPTION, output());
   7.118 +    output()->cr();
   7.119 +    CLEAR_PENDING_EXCEPTION;
   7.120 +    return;
   7.121 +  }
   7.122 +
   7.123 +  // invoke the serializePropertiesToByteArray method
   7.124 +  JavaValue result(T_OBJECT);
   7.125 +  JavaCallArguments args;
   7.126 +
   7.127 +  Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature();
   7.128 +  JavaCalls::call_static(&result,
   7.129 +                         ik,
   7.130 +                         vmSymbols::serializePropertiesToByteArray_name(),
   7.131 +                         signature,
   7.132 +                         &args,
   7.133 +                         THREAD);
   7.134 +  if (HAS_PENDING_EXCEPTION) {
   7.135 +    java_lang_Throwable::print(PENDING_EXCEPTION, output());
   7.136 +    output()->cr();
   7.137 +    CLEAR_PENDING_EXCEPTION;
   7.138 +    return;
   7.139 +  }
   7.140 +
   7.141 +  // The result should be a [B
   7.142 +  oop res = (oop)result.get_jobject();
   7.143 +  assert(res->is_typeArray(), "just checking");
   7.144 +  assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking");
   7.145 +
   7.146 +  // copy the bytes to the output stream
   7.147 +  typeArrayOop ba = typeArrayOop(res);
   7.148 +  jbyte* addr = typeArrayOop(res)->byte_at_addr(0);
   7.149 +  output()->print_raw((const char*)addr, ba->length());
   7.150 +}
   7.151 +
   7.152 +VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) :
   7.153 +                           DCmdWithParser(output, heap),
   7.154 +  _date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") {
   7.155 +  _dcmdparser.add_dcmd_option(&_date);
   7.156 +}
   7.157 +
   7.158 +void VMUptimeDCmd::execute(TRAPS) {
   7.159 +  if (_date.value()) {
   7.160 +    output()->date_stamp(true, "", ": ");
   7.161 +  }
   7.162 +  output()->time_stamp().update_to(tty->time_stamp().ticks());
   7.163 +  output()->stamp();
   7.164 +  output()->print_cr(" s");
   7.165 +}
   7.166 +
   7.167 +int VMUptimeDCmd::num_arguments() {
   7.168 +  ResourceMark rm;
   7.169 +  VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false);
   7.170 +  if (dcmd != NULL) {
   7.171 +    DCmdMark mark(dcmd);
   7.172 +    return dcmd->_dcmdparser.num_arguments();
   7.173 +  } else {
   7.174 +    return 0;
   7.175 +  }
   7.176 +}
   7.177 +
   7.178 +void SystemGCDCmd::execute(TRAPS) {
   7.179 +  Universe::heap()->collect(GCCause::_java_lang_system_gc);
   7.180 +}
   7.181 +
   7.182 +void RunFinalizationDCmd::execute(TRAPS) {
   7.183 +  klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
   7.184 +                                                 true, CHECK);
   7.185 +  instanceKlassHandle klass(THREAD, k);
   7.186 +  JavaValue result(T_VOID);
   7.187 +  JavaCalls::call_static(&result, klass,
   7.188 +                         vmSymbols::run_finalization_name(),
   7.189 +                         vmSymbols::void_method_signature(), CHECK);
   7.190 +}
   7.191 +
   7.192 +#ifndef SERVICES_KERNEL   // Heap dumping not supported
   7.193 +HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
   7.194 +                           DCmdWithParser(output, heap),
   7.195 +  _filename("filename","Name of the dump file", "STRING",true),
   7.196 +  _all("-all", "Dump all objects, including unreachable objects",
   7.197 +       "BOOLEAN", false, "false") {
   7.198 +  _dcmdparser.add_dcmd_option(&_all);
   7.199 +  _dcmdparser.add_dcmd_argument(&_filename);
   7.200 +}
   7.201 +
   7.202 +void HeapDumpDCmd::execute(TRAPS) {
   7.203 +  // Request a full GC before heap dump if _all is false
   7.204 +  // This helps reduces the amount of unreachable objects in the dump
   7.205 +  // and makes it easier to browse.
   7.206 +  HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
   7.207 +  int res = dumper.dump(_filename.value());
   7.208 +  if (res == 0) {
   7.209 +    output()->print_cr("Heap dump file created");
   7.210 +  } else {
   7.211 +    // heap dump failed
   7.212 +    ResourceMark rm;
   7.213 +    char* error = dumper.error_as_C_string();
   7.214 +    if (error == NULL) {
   7.215 +      output()->print_cr("Dump failed - reason unknown");
   7.216 +    } else {
   7.217 +      output()->print_cr("%s", error);
   7.218 +    }
   7.219 +  }
   7.220 +}
   7.221 +
   7.222 +int HeapDumpDCmd::num_arguments() {
   7.223 +  ResourceMark rm;
   7.224 +  HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false);
   7.225 +  if (dcmd != NULL) {
   7.226 +    DCmdMark mark(dcmd);
   7.227 +    return dcmd->_dcmdparser.num_arguments();
   7.228 +  } else {
   7.229 +    return 0;
   7.230 +  }
   7.231 +}
   7.232 +#endif // SERVICES_KERNEL
   7.233 +
   7.234 +ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
   7.235 +                                       DCmdWithParser(output, heap),
   7.236 +  _all("-all", "Inspect all objects, including unreachable objects",
   7.237 +       "BOOLEAN", false, "false") {
   7.238 +  _dcmdparser.add_dcmd_option(&_all);
   7.239 +}
   7.240 +
   7.241 +void ClassHistogramDCmd::execute(TRAPS) {
   7.242 +  VM_GC_HeapInspection heapop(output(),
   7.243 +                              !_all.value() /* request full gc if false */,
   7.244 +                              true /* need_prologue */);
   7.245 +  VMThread::execute(&heapop);
   7.246 +}
   7.247 +
   7.248 +int ClassHistogramDCmd::num_arguments() {
   7.249 +  ResourceMark rm;
   7.250 +  ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false);
   7.251 +  if (dcmd != NULL) {
   7.252 +    DCmdMark mark(dcmd);
   7.253 +    return dcmd->_dcmdparser.num_arguments();
   7.254 +  } else {
   7.255 +    return 0;
   7.256 +  }
   7.257 +}
   7.258 +
   7.259 +ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
   7.260 +                               DCmdWithParser(output, heap),
   7.261 +  _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
   7.262 +  _dcmdparser.add_dcmd_option(&_locks);
   7.263 +}
   7.264 +
   7.265 +void ThreadDumpDCmd::execute(TRAPS) {
   7.266 +  // thread stacks
   7.267 +  VM_PrintThreads op1(output(), _locks.value());
   7.268 +  VMThread::execute(&op1);
   7.269 +
   7.270 +  // JNI global handles
   7.271 +  VM_PrintJNI op2(output());
   7.272 +  VMThread::execute(&op2);
   7.273 +
   7.274 +  // Deadlock detection
   7.275 +  VM_FindDeadlocks op3(output());
   7.276 +  VMThread::execute(&op3);
   7.277 +}
   7.278 +
   7.279 +int ThreadDumpDCmd::num_arguments() {
   7.280 +  ResourceMark rm;
   7.281 +  ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false);
   7.282 +  if (dcmd != NULL) {
   7.283 +    DCmdMark mark(dcmd);
   7.284 +    return dcmd->_dcmdparser.num_arguments();
   7.285 +  } else {
   7.286 +    return 0;
   7.287 +  }
   7.288 +}
     8.1 --- a/src/share/vm/services/diagnosticCommand.hpp	Thu Jan 05 17:16:13 2012 -0500
     8.2 +++ b/src/share/vm/services/diagnosticCommand.hpp	Mon Jan 09 10:27:24 2012 +0100
     8.3 @@ -35,9 +35,8 @@
     8.4  #include "services/diagnosticCommand.hpp"
     8.5  #include "services/diagnosticFramework.hpp"
     8.6  
     8.7 -class HelpDCmd : public DCmd {
     8.8 +class HelpDCmd : public DCmdWithParser {
     8.9  protected:
    8.10 -  DCmdParser _dcmdparser;
    8.11    DCmdArgument<bool> _all;
    8.12    DCmdArgument<char*> _cmd;
    8.13  public:
    8.14 @@ -50,13 +49,7 @@
    8.15    }
    8.16    static const char* impact() { return "Low: "; }
    8.17    static int num_arguments();
    8.18 -  virtual void parse(CmdLine* line, char delim, TRAPS);
    8.19    virtual void execute(TRAPS);
    8.20 -  virtual void reset(TRAPS);
    8.21 -  virtual void cleanup();
    8.22 -  virtual void print_help(outputStream* out);
    8.23 -  virtual GrowableArray<const char*>* argument_name_array();
    8.24 -  virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array();
    8.25  };
    8.26  
    8.27  class VersionDCmd : public DCmd {
    8.28 @@ -68,9 +61,156 @@
    8.29    }
    8.30    static const char* impact() { return "Low: "; }
    8.31    static int num_arguments() { return 0; }
    8.32 -  virtual void parse(CmdLine* line, char delim, TRAPS) { }
    8.33    virtual void execute(TRAPS);
    8.34 -  virtual void print_help(outputStream* out) { }
    8.35 +};
    8.36 +
    8.37 +class CommandLineDCmd : public DCmd {
    8.38 +public:
    8.39 +  CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
    8.40 +  static const char* name() { return "VM.command_line"; }
    8.41 +  static const char* description() {
    8.42 +    return "Print the command line used to start this VM instance.";
    8.43 +  }
    8.44 +  static const char* impact() { return "Low: "; }
    8.45 +  static int num_arguments() { return 0; }
    8.46 +  virtual void execute(TRAPS) {
    8.47 +    Arguments::print_on(_output);
    8.48 +  }
    8.49 +};
    8.50 +
    8.51 +// See also: get_system_properties in attachListener.cpp
    8.52 +class PrintSystemPropertiesDCmd : public DCmd {
    8.53 +public:
    8.54 +  PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
    8.55 +    static const char* name() { return "VM.system_properties"; }
    8.56 +    static const char* description() {
    8.57 +      return "Print system properties.";
    8.58 +    }
    8.59 +    static const char* impact() {
    8.60 +      return "Low: ";
    8.61 +    }
    8.62 +    static int num_arguments() { return 0; }
    8.63 +    virtual void execute(TRAPS);
    8.64 +};
    8.65 +
    8.66 +// See also: print_flag in attachListener.cpp
    8.67 +class PrintVMFlagsDCmd : public DCmdWithParser {
    8.68 +protected:
    8.69 +  DCmdArgument<bool> _all;
    8.70 +public:
    8.71 +  PrintVMFlagsDCmd(outputStream* output, bool heap);
    8.72 +  static const char* name() { return "VM.flags"; }
    8.73 +  static const char* description() {
    8.74 +    return "Print VM flag options and their current values.";
    8.75 +  }
    8.76 +  static const char* impact() {
    8.77 +    return "Low: ";
    8.78 +  }
    8.79 +  static int num_arguments();
    8.80 +  virtual void execute(TRAPS);
    8.81 +};
    8.82 +
    8.83 +class VMUptimeDCmd : public DCmdWithParser {
    8.84 +protected:
    8.85 +  DCmdArgument<bool> _date;
    8.86 +public:
    8.87 +  VMUptimeDCmd(outputStream* output, bool heap);
    8.88 +  static const char* name() { return "VM.uptime"; }
    8.89 +  static const char* description() {
    8.90 +    return "Print VM uptime.";
    8.91 +  }
    8.92 +  static const char* impact() {
    8.93 +    return "Low: ";
    8.94 +  }
    8.95 +  static int num_arguments();
    8.96 +  virtual void execute(TRAPS);
    8.97 +};
    8.98 +
    8.99 +class SystemGCDCmd : public DCmd {
   8.100 +public:
   8.101 +  SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
   8.102 +    static const char* name() { return "GC.run"; }
   8.103 +    static const char* description() {
   8.104 +      return "Call java.lang.System.gc().";
   8.105 +    }
   8.106 +    static const char* impact() {
   8.107 +      return "Medium: Depends on Java heap size and content.";
   8.108 +    }
   8.109 +    static int num_arguments() { return 0; }
   8.110 +    virtual void execute(TRAPS);
   8.111 +};
   8.112 +
   8.113 +class RunFinalizationDCmd : public DCmd {
   8.114 +public:
   8.115 +  RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
   8.116 +    static const char* name() { return "GC.run_finalization"; }
   8.117 +    static const char* description() {
   8.118 +      return "Call java.lang.System.runFinalization().";
   8.119 +    }
   8.120 +    static const char* impact() {
   8.121 +      return "Medium: Depends on Java content.";
   8.122 +    }
   8.123 +    static int num_arguments() { return 0; }
   8.124 +    virtual void execute(TRAPS);
   8.125 +};
   8.126 +
   8.127 +#ifndef SERVICES_KERNEL   // Heap dumping not supported
   8.128 +// See also: dump_heap in attachListener.cpp
   8.129 +class HeapDumpDCmd : public DCmdWithParser {
   8.130 +protected:
   8.131 +  DCmdArgument<char*> _filename;
   8.132 +  DCmdArgument<bool>  _all;
   8.133 +public:
   8.134 +  HeapDumpDCmd(outputStream* output, bool heap);
   8.135 +  static const char* name() {
   8.136 +    return "GC.heap_dump";
   8.137 +  }
   8.138 +  static const char* description() {
   8.139 +    return "Generate a HPROF format dump of the Java heap.";
   8.140 +  }
   8.141 +  static const char* impact() {
   8.142 +    return "High: Depends on Java heap size and content. "
   8.143 +           "Request a full GC unless the '-all' option is specified.";
   8.144 +  }
   8.145 +  static int num_arguments();
   8.146 +  virtual void execute(TRAPS);
   8.147 +};
   8.148 +#endif // SERVICES_KERNEL
   8.149 +
   8.150 +// See also: inspeactheap in attachListener.cpp
   8.151 +class ClassHistogramDCmd : public DCmdWithParser {
   8.152 +protected:
   8.153 +  DCmdArgument<bool> _all;
   8.154 +public:
   8.155 +  ClassHistogramDCmd(outputStream* output, bool heap);
   8.156 +  static const char* name() {
   8.157 +    return "GC.class_histogram";
   8.158 +  }
   8.159 +  static const char* description() {
   8.160 +    return "Provide statistics about the Java heap usage.";
   8.161 +  }
   8.162 +  static const char* impact() {
   8.163 +    return "High: Depends on Java heap size and content.";
   8.164 +  }
   8.165 +  static int num_arguments();
   8.166 +  virtual void execute(TRAPS);
   8.167 +};
   8.168 +
   8.169 +// See also: thread_dump in attachListener.cpp
   8.170 +class ThreadDumpDCmd : public DCmdWithParser {
   8.171 +protected:
   8.172 +  DCmdArgument<bool> _locks;
   8.173 +public:
   8.174 +  ThreadDumpDCmd(outputStream* output, bool heap);
   8.175 +  static const char* name() { return "Thread.print"; }
   8.176 +  static const char* description() {
   8.177 +    return "Print all threads with stacktraces.";
   8.178 +  }
   8.179 +  static const char* impact() {
   8.180 +    return "Medium: Depends on the number of threads.";
   8.181 +  }
   8.182 +  static int num_arguments();
   8.183 +  virtual void execute(TRAPS);
   8.184  };
   8.185  
   8.186  #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
     9.1 --- a/src/share/vm/services/diagnosticFramework.cpp	Thu Jan 05 17:16:13 2012 -0500
     9.2 +++ b/src/share/vm/services/diagnosticFramework.cpp	Mon Jan 09 10:27:24 2012 +0100
     9.3 @@ -226,7 +226,7 @@
     9.4  }
     9.5  
     9.6  void DCmdParser::print_help(outputStream* out, const char* cmd_name) {
     9.7 -  out->print("\nSyntax : %s %s", cmd_name, _options == NULL ? "" : "[options]");
     9.8 +  out->print("Syntax : %s %s", cmd_name, _options == NULL ? "" : "[options]");
     9.9    GenDCmdArgument* arg = _arguments_list;
    9.10    while (arg != NULL) {
    9.11      if (arg->is_mandatory()) {
    9.12 @@ -373,6 +373,30 @@
    9.13    }
    9.14  }
    9.15  
    9.16 +void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) {
    9.17 +  _dcmdparser.parse(line, delim, CHECK);
    9.18 +}
    9.19 +
    9.20 +void DCmdWithParser::print_help(const char* name) {
    9.21 +  _dcmdparser.print_help(output(), name);
    9.22 +}
    9.23 +
    9.24 +void DCmdWithParser::reset(TRAPS) {
    9.25 +  _dcmdparser.reset(CHECK);
    9.26 +}
    9.27 +
    9.28 +void DCmdWithParser::cleanup() {
    9.29 +  _dcmdparser.cleanup();
    9.30 +}
    9.31 +
    9.32 +GrowableArray<const char*>* DCmdWithParser::argument_name_array() {
    9.33 +  return _dcmdparser.argument_name_array();
    9.34 +}
    9.35 +
    9.36 +GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() {
    9.37 +  return _dcmdparser.argument_info_array();
    9.38 +}
    9.39 +
    9.40  Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
    9.41  
    9.42  DCmdFactory* DCmdFactory::factory(const char* name, size_t len) {
    10.1 --- a/src/share/vm/services/diagnosticFramework.hpp	Thu Jan 05 17:16:13 2012 -0500
    10.2 +++ b/src/share/vm/services/diagnosticFramework.hpp	Mon Jan 09 10:27:24 2012 +0100
    10.3 @@ -241,8 +241,17 @@
    10.4    static int num_arguments() { return 0; }
    10.5    outputStream* output() { return _output; }
    10.6    bool is_heap_allocated()  { return _is_heap_allocated; }
    10.7 -  virtual void print_help(outputStream* out) { };
    10.8 -  virtual void parse(CmdLine* line, char delim, TRAPS) { }
    10.9 +  virtual void print_help(const char* name) {
   10.10 +    output()->print_cr("Syntax: %s", name);
   10.11 +  }
   10.12 +  virtual void parse(CmdLine* line, char delim, TRAPS) {
   10.13 +    DCmdArgIter iter(line->args_addr(), line->args_len(), delim);
   10.14 +    bool has_arg = iter.next(CHECK);
   10.15 +    if (has_arg) {
   10.16 +      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   10.17 +                "Unknown argument in diagnostic command");
   10.18 +    }
   10.19 +  }
   10.20    virtual void execute(TRAPS) { }
   10.21    virtual void reset(TRAPS) { }
   10.22    virtual void cleanup() { }
   10.23 @@ -262,6 +271,25 @@
   10.24                                  char delim, TRAPS);
   10.25  };
   10.26  
   10.27 +class DCmdWithParser : public DCmd {
   10.28 +protected:
   10.29 +  DCmdParser _dcmdparser;
   10.30 +public:
   10.31 +  DCmdWithParser (outputStream *output, bool heap=false) : DCmd(output, heap) { }
   10.32 +  static const char* name() { return "No Name";}
   10.33 +  static const char* description() { return "No Help";}
   10.34 +  static const char* disabled_message() { return "Diagnostic command currently disabled"; }
   10.35 +  static const char* impact() { return "Low: No impact"; }
   10.36 +  static int num_arguments() { return 0; }
   10.37 +  virtual void parse(CmdLine *line, char delim, TRAPS);
   10.38 +  virtual void execute(TRAPS) { }
   10.39 +  virtual void reset(TRAPS);
   10.40 +  virtual void cleanup();
   10.41 +  virtual void print_help(const char* name);
   10.42 +  virtual GrowableArray<const char*>* argument_name_array();
   10.43 +  virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array();
   10.44 +};
   10.45 +
   10.46  class DCmdMark : public StackObj {
   10.47    DCmd* _ref;
   10.48  public:
    11.1 --- a/src/share/vm/services/management.cpp	Thu Jan 05 17:16:13 2012 -0500
    11.2 +++ b/src/share/vm/services/management.cpp	Mon Jan 09 10:27:24 2012 +0100
    11.3 @@ -118,8 +118,22 @@
    11.4  #endif // SERVICES_KERNEL
    11.5    _optional_support.isThreadAllocatedMemorySupported = 1;
    11.6  
    11.7 +  // Registration of the diagnostic commands
    11.8 +  // First boolean argument specifies if the command is enabled
    11.9 +  // Second boolean argument specifies if the command is hidden
   11.10    DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false));
   11.11    DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false));
   11.12 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false));
   11.13 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false));
   11.14 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false));
   11.15 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
   11.16 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
   11.17 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
   11.18 +#ifndef SERVICES_KERNEL   // Heap dumping not supported
   11.19 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
   11.20 +#endif // SERVICES_KERNEL
   11.21 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
   11.22 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
   11.23  }
   11.24  
   11.25  void Management::initialize(TRAPS) {

mercurial