1 /*
   2  * Copyright (c) 2011, 2014, 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 #include "precompiled.hpp"
  26 #include "classfile/classLoaderStats.hpp"
  27 #include "classfile/compactHashtable.hpp"
  28 #include "gc_implementation/shared/vmGCOperations.hpp"
  29 #include "runtime/javaCalls.hpp"
  30 #include "runtime/os.hpp"
  31 #include "services/diagnosticArgument.hpp"
  32 #include "services/diagnosticCommand.hpp"
  33 #include "services/diagnosticFramework.hpp"
  34 #include "services/heapDumper.hpp"
  35 #include "services/management.hpp"
  36 #include "utilities/macros.hpp"
  37 
  38 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  39 
  40 void DCmdRegistrant::register_dcmds(){
  41   // Registration of the diagnostic commands
  42   // First argument specifies which interfaces will export the command
  43   // Second argument specifies if the command is enabled
  44   // Third  argument specifies if the command is hidden
  45   uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI
  46                          | DCmd_Source_MBean;
  47   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(full_export, true, false));
  48   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(full_export, true, false));
  49   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(full_export, true, false));
  50   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(full_export, true, false));
  51   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(full_export, true, false));
  52   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));
  53   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
  54   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
  55   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
  56 #if INCLUDE_SERVICES // Heap dumping/inspection supported
  57   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));
  58   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));
  59   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false));
  60   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false));
  61   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false));
  62 #endif // INCLUDE_SERVICES
  63   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
  64   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
  65   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
  66   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompileQueueDCmd>(full_export, true, false));
  67   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeListDCmd>(full_export, true, false));
  68   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeCacheDCmd>(full_export, true, false));
  69 
  70   // Enhanced JMX Agent Support
  71   // These commands won't be exported via the DiagnosticCommandMBean until an
  72   // appropriate permission is created for them
  73   uint32_t jmx_agent_export_flags = DCmd_Source_Internal | DCmd_Source_AttachAPI;
  74   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(jmx_agent_export_flags, true,false));
  75   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(jmx_agent_export_flags, true,false));
  76   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(jmx_agent_export_flags, true,false));
  77 
  78 }
  79 
  80 #ifndef HAVE_EXTRA_DCMD
  81 void DCmdRegistrant::register_dcmds_ext(){
  82    // Do nothing here
  83 }
  84 #endif
  85 
  86 
  87 HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
  88   _all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
  89   _cmd("command name", "The name of the command for which we want help",
  90         "STRING", false) {
  91   _dcmdparser.add_dcmd_option(&_all);
  92   _dcmdparser.add_dcmd_argument(&_cmd);
  93 };
  94 
  95 void HelpDCmd::execute(DCmdSource source, TRAPS) {
  96   if (_all.value()) {
  97     GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list(source);
  98     for (int i = 0; i < cmd_list->length(); i++) {
  99       DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),
 100                                                   strlen(cmd_list->at(i)));
 101       output()->print_cr("%s%s", factory->name(),
 102                          factory->is_enabled() ? "" : " [disabled]");
 103       output()->print_cr("\t%s", factory->description());
 104       output()->cr();
 105       factory = factory->next();
 106     }
 107   } else if (_cmd.has_value()) {
 108     DCmd* cmd = NULL;
 109     DCmdFactory* factory = DCmdFactory::factory(source, _cmd.value(),
 110                                                 strlen(_cmd.value()));
 111     if (factory != NULL) {
 112       output()->print_cr("%s%s", factory->name(),
 113                          factory->is_enabled() ? "" : " [disabled]");
 114       output()->print_cr("%s", factory->description());
 115       output()->print_cr("\nImpact: %s", factory->impact());
 116       JavaPermission p = factory->permission();
 117       if(p._class != NULL) {
 118         if(p._action != NULL) {
 119           output()->print_cr("\nPermission: %s(%s, %s)",
 120                   p._class, p._name == NULL ? "null" : p._name, p._action);
 121         } else {
 122           output()->print_cr("\nPermission: %s(%s)",
 123                   p._class, p._name == NULL ? "null" : p._name);
 124         }
 125       }
 126       output()->cr();
 127       cmd = factory->create_resource_instance(output());
 128       if (cmd != NULL) {
 129         DCmdMark mark(cmd);
 130         cmd->print_help(factory->name());
 131       }
 132     } else {
 133       output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value());
 134     }
 135   } else {
 136     output()->print_cr("The following commands are available:");
 137     GrowableArray<const char *>* cmd_list = DCmdFactory::DCmd_list(source);
 138     for (int i = 0; i < cmd_list->length(); i++) {
 139       DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),
 140                                                   strlen(cmd_list->at(i)));
 141       output()->print_cr("%s%s", factory->name(),
 142                          factory->is_enabled() ? "" : " [disabled]");
 143       factory = factory->_next;
 144     }
 145     output()->print_cr("\nFor more information about a specific command use 'help <command>'.");
 146   }
 147 }
 148 
 149 int HelpDCmd::num_arguments() {
 150   ResourceMark rm;
 151   HelpDCmd* dcmd = new HelpDCmd(NULL, false);
 152   if (dcmd != NULL) {
 153     DCmdMark mark(dcmd);
 154     return dcmd->_dcmdparser.num_arguments();
 155   } else {
 156     return 0;
 157   }
 158 }
 159 
 160 void VersionDCmd::execute(DCmdSource source, TRAPS) {
 161   output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(),
 162           Abstract_VM_Version::vm_release());
 163   JDK_Version jdk_version = JDK_Version::current();
 164   if (jdk_version.update_version() > 0) {
 165     output()->print_cr("JDK %d.%d_%02d", jdk_version.major_version(),
 166             jdk_version.minor_version(), jdk_version.update_version());
 167   } else {
 168     output()->print_cr("JDK %d.%d", jdk_version.major_version(),
 169             jdk_version.minor_version());
 170   }
 171 }
 172 
 173 PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) :
 174                                    DCmdWithParser(output, heap),
 175   _all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") {
 176   _dcmdparser.add_dcmd_option(&_all);
 177 }
 178 
 179 void PrintVMFlagsDCmd::execute(DCmdSource source, TRAPS) {
 180   if (_all.value()) {
 181     CommandLineFlags::printFlags(output(), true);
 182   } else {
 183     CommandLineFlags::printSetFlags(output());
 184   }
 185 }
 186 
 187 int PrintVMFlagsDCmd::num_arguments() {
 188     ResourceMark rm;
 189     PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false);
 190     if (dcmd != NULL) {
 191       DCmdMark mark(dcmd);
 192       return dcmd->_dcmdparser.num_arguments();
 193     } else {
 194       return 0;
 195     }
 196 }
 197 
 198 void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) {
 199   // load sun.misc.VMSupport
 200   Symbol* klass = vmSymbols::sun_misc_VMSupport();
 201   Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK);
 202   instanceKlassHandle ik (THREAD, k);
 203   if (ik->should_be_initialized()) {
 204     ik->initialize(THREAD);
 205   }
 206   if (HAS_PENDING_EXCEPTION) {
 207     java_lang_Throwable::print(PENDING_EXCEPTION, output());
 208     output()->cr();
 209     CLEAR_PENDING_EXCEPTION;
 210     return;
 211   }
 212 
 213   // invoke the serializePropertiesToByteArray method
 214   JavaValue result(T_OBJECT);
 215   JavaCallArguments args;
 216 
 217   Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature();
 218   JavaCalls::call_static(&result,
 219                          ik,
 220                          vmSymbols::serializePropertiesToByteArray_name(),
 221                          signature,
 222                          &args,
 223                          THREAD);
 224   if (HAS_PENDING_EXCEPTION) {
 225     java_lang_Throwable::print(PENDING_EXCEPTION, output());
 226     output()->cr();
 227     CLEAR_PENDING_EXCEPTION;
 228     return;
 229   }
 230 
 231   // The result should be a [B
 232   oop res = (oop)result.get_jobject();
 233   assert(res->is_typeArray(), "just checking");
 234   assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking");
 235 
 236   // copy the bytes to the output stream
 237   typeArrayOop ba = typeArrayOop(res);
 238   jbyte* addr = typeArrayOop(res)->byte_at_addr(0);
 239   output()->print_raw((const char*)addr, ba->length());
 240 }
 241 
 242 VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) :
 243                            DCmdWithParser(output, heap),
 244   _date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") {
 245   _dcmdparser.add_dcmd_option(&_date);
 246 }
 247 
 248 void VMUptimeDCmd::execute(DCmdSource source, TRAPS) {
 249   if (_date.value()) {
 250     output()->date_stamp(true, "", ": ");
 251   }
 252   output()->time_stamp().update_to(tty->time_stamp().ticks());
 253   output()->stamp();
 254   output()->print_cr(" s");
 255 }
 256 
 257 int VMUptimeDCmd::num_arguments() {
 258   ResourceMark rm;
 259   VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false);
 260   if (dcmd != NULL) {
 261     DCmdMark mark(dcmd);
 262     return dcmd->_dcmdparser.num_arguments();
 263   } else {
 264     return 0;
 265   }
 266 }
 267 
 268 void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
 269   if (!DisableExplicitGC) {
 270     Universe::heap()->collect(GCCause::_java_lang_system_gc);
 271   } else {
 272     output()->print_cr("Explicit GC is disabled, no GC has been performed.");
 273   }
 274 }
 275 
 276 void RunFinalizationDCmd::execute(DCmdSource source, TRAPS) {
 277   Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
 278                                                  true, CHECK);
 279   instanceKlassHandle klass(THREAD, k);
 280   JavaValue result(T_VOID);
 281   JavaCalls::call_static(&result, klass,
 282                          vmSymbols::run_finalization_name(),
 283                          vmSymbols::void_method_signature(), CHECK);
 284 }
 285 
 286 #if INCLUDE_SERVICES // Heap dumping/inspection supported
 287 HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
 288                            DCmdWithParser(output, heap),
 289   _filename("filename","Name of the dump file", "STRING",true),
 290   _all("-all", "Dump all objects, including unreachable objects",
 291        "BOOLEAN", false, "false") {
 292   _dcmdparser.add_dcmd_option(&_all);
 293   _dcmdparser.add_dcmd_argument(&_filename);
 294 }
 295 
 296 void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
 297   // Request a full GC before heap dump if _all is false
 298   // This helps reduces the amount of unreachable objects in the dump
 299   // and makes it easier to browse.
 300   HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
 301   int res = dumper.dump(_filename.value());
 302   if (res == 0) {
 303     output()->print_cr("Heap dump file created");
 304   } else {
 305     // heap dump failed
 306     ResourceMark rm;
 307     char* error = dumper.error_as_C_string();
 308     if (error == NULL) {
 309       output()->print_cr("Dump failed - reason unknown");
 310     } else {
 311       output()->print_cr("%s", error);
 312     }
 313   }
 314 }
 315 
 316 int HeapDumpDCmd::num_arguments() {
 317   ResourceMark rm;
 318   HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false);
 319   if (dcmd != NULL) {
 320     DCmdMark mark(dcmd);
 321     return dcmd->_dcmdparser.num_arguments();
 322   } else {
 323     return 0;
 324   }
 325 }
 326 
 327 ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
 328                                        DCmdWithParser(output, heap),
 329   _all("-all", "Inspect all objects, including unreachable objects",
 330        "BOOLEAN", false, "false") {
 331   _dcmdparser.add_dcmd_option(&_all);
 332 }
 333 
 334 void ClassHistogramDCmd::execute(DCmdSource source, TRAPS) {
 335   VM_GC_HeapInspection heapop(output(),
 336                               !_all.value() /* request full gc if false */);
 337   VMThread::execute(&heapop);
 338 }
 339 
 340 int ClassHistogramDCmd::num_arguments() {
 341   ResourceMark rm;
 342   ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false);
 343   if (dcmd != NULL) {
 344     DCmdMark mark(dcmd);
 345     return dcmd->_dcmdparser.num_arguments();
 346   } else {
 347     return 0;
 348   }
 349 }
 350 
 351 #define DEFAULT_COLUMNS "InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total"
 352 ClassStatsDCmd::ClassStatsDCmd(outputStream* output, bool heap) :
 353                                        DCmdWithParser(output, heap),
 354   _csv("-csv", "Print in CSV (comma-separated values) format for spreadsheets",
 355        "BOOLEAN", false, "false"),
 356   _all("-all", "Show all columns",
 357        "BOOLEAN", false, "false"),
 358   _help("-help", "Show meaning of all the columns",
 359        "BOOLEAN", false, "false"),
 360   _columns("columns", "Comma-separated list of all the columns to show. "
 361            "If not specified, the following columns are shown: " DEFAULT_COLUMNS,
 362            "STRING", false) {
 363   _dcmdparser.add_dcmd_option(&_all);
 364   _dcmdparser.add_dcmd_option(&_csv);
 365   _dcmdparser.add_dcmd_option(&_help);
 366   _dcmdparser.add_dcmd_argument(&_columns);
 367 }
 368 
 369 void ClassStatsDCmd::execute(DCmdSource source, TRAPS) {
 370   if (!UnlockDiagnosticVMOptions) {
 371     output()->print_cr("GC.class_stats command requires -XX:+UnlockDiagnosticVMOptions");
 372     return;
 373   }
 374 
 375   VM_GC_HeapInspection heapop(output(),
 376                               true /* request_full_gc */);
 377   heapop.set_csv_format(_csv.value());
 378   heapop.set_print_help(_help.value());
 379   heapop.set_print_class_stats(true);
 380   if (_all.value()) {
 381     if (_columns.has_value()) {
 382       output()->print_cr("Cannot specify -all and individual columns at the same time");
 383       return;
 384     } else {
 385       heapop.set_columns(NULL);
 386     }
 387   } else {
 388     if (_columns.has_value()) {
 389       heapop.set_columns(_columns.value());
 390     } else {
 391       heapop.set_columns(DEFAULT_COLUMNS);
 392     }
 393   }
 394   VMThread::execute(&heapop);
 395 }
 396 
 397 int ClassStatsDCmd::num_arguments() {
 398   ResourceMark rm;
 399   ClassStatsDCmd* dcmd = new ClassStatsDCmd(NULL, false);
 400   if (dcmd != NULL) {
 401     DCmdMark mark(dcmd);
 402     return dcmd->_dcmdparser.num_arguments();
 403   } else {
 404     return 0;
 405   }
 406 }
 407 #endif // INCLUDE_SERVICES
 408 
 409 ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
 410                                DCmdWithParser(output, heap),
 411   _locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
 412   _dcmdparser.add_dcmd_option(&_locks);
 413 }
 414 
 415 void ThreadDumpDCmd::execute(DCmdSource source, TRAPS) {
 416   // thread stacks
 417   VM_PrintThreads op1(output(), _locks.value());
 418   VMThread::execute(&op1);
 419 
 420   // JNI global handles
 421   VM_PrintJNI op2(output());
 422   VMThread::execute(&op2);
 423 
 424   // Deadlock detection
 425   VM_FindDeadlocks op3(output());
 426   VMThread::execute(&op3);
 427 }
 428 
 429 int ThreadDumpDCmd::num_arguments() {
 430   ResourceMark rm;
 431   ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false);
 432   if (dcmd != NULL) {
 433     DCmdMark mark(dcmd);
 434     return dcmd->_dcmdparser.num_arguments();
 435   } else {
 436     return 0;
 437   }
 438 }
 439 
 440 // Enhanced JMX Agent support
 441 
 442 JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated) :
 443 
 444   DCmdWithParser(output, heap_allocated),
 445 
 446   _config_file
 447   ("config.file",
 448    "set com.sun.management.config.file", "STRING", false),
 449 
 450   _jmxremote_port
 451   ("jmxremote.port",
 452    "set com.sun.management.jmxremote.port", "STRING", false),
 453 
 454   _jmxremote_rmi_port
 455   ("jmxremote.rmi.port",
 456    "set com.sun.management.jmxremote.rmi.port", "STRING", false),
 457 
 458   _jmxremote_ssl
 459   ("jmxremote.ssl",
 460    "set com.sun.management.jmxremote.ssl", "STRING", false),
 461 
 462   _jmxremote_registry_ssl
 463   ("jmxremote.registry.ssl",
 464    "set com.sun.management.jmxremote.registry.ssl", "STRING", false),
 465 
 466   _jmxremote_authenticate
 467   ("jmxremote.authenticate",
 468    "set com.sun.management.jmxremote.authenticate", "STRING", false),
 469 
 470   _jmxremote_password_file
 471   ("jmxremote.password.file",
 472    "set com.sun.management.jmxremote.password.file", "STRING", false),
 473 
 474   _jmxremote_access_file
 475   ("jmxremote.access.file",
 476    "set com.sun.management.jmxremote.access.file", "STRING", false),
 477 
 478   _jmxremote_login_config
 479   ("jmxremote.login.config",
 480    "set com.sun.management.jmxremote.login.config", "STRING", false),
 481 
 482   _jmxremote_ssl_enabled_cipher_suites
 483   ("jmxremote.ssl.enabled.cipher.suites",
 484    "set com.sun.management.jmxremote.ssl.enabled.cipher.suite", "STRING", false),
 485 
 486   _jmxremote_ssl_enabled_protocols
 487   ("jmxremote.ssl.enabled.protocols",
 488    "set com.sun.management.jmxremote.ssl.enabled.protocols", "STRING", false),
 489 
 490   _jmxremote_ssl_need_client_auth
 491   ("jmxremote.ssl.need.client.auth",
 492    "set com.sun.management.jmxremote.need.client.auth", "STRING", false),
 493 
 494   _jmxremote_ssl_config_file
 495   ("jmxremote.ssl.config.file",
 496    "set com.sun.management.jmxremote.ssl_config_file", "STRING", false),
 497 
 498 // JDP Protocol support
 499   _jmxremote_autodiscovery
 500   ("jmxremote.autodiscovery",
 501    "set com.sun.management.jmxremote.autodiscovery", "STRING", false),
 502 
 503    _jdp_port
 504   ("jdp.port",
 505    "set com.sun.management.jdp.port", "INT", false),
 506 
 507    _jdp_address
 508   ("jdp.address",
 509    "set com.sun.management.jdp.address", "STRING", false),
 510 
 511    _jdp_source_addr
 512   ("jdp.source_addr",
 513    "set com.sun.management.jdp.source_addr", "STRING", false),
 514 
 515    _jdp_ttl
 516   ("jdp.ttl",
 517    "set com.sun.management.jdp.ttl", "INT", false),
 518 
 519    _jdp_pause
 520   ("jdp.pause",
 521    "set com.sun.management.jdp.pause", "INT", false),
 522 
 523    _jdp_name
 524   ("jdp.name",
 525    "set com.sun.management.jdp.name", "STRING", false)
 526 
 527   {
 528     _dcmdparser.add_dcmd_option(&_config_file);
 529     _dcmdparser.add_dcmd_option(&_jmxremote_port);
 530     _dcmdparser.add_dcmd_option(&_jmxremote_rmi_port);
 531     _dcmdparser.add_dcmd_option(&_jmxremote_ssl);
 532     _dcmdparser.add_dcmd_option(&_jmxremote_registry_ssl);
 533     _dcmdparser.add_dcmd_option(&_jmxremote_authenticate);
 534     _dcmdparser.add_dcmd_option(&_jmxremote_password_file);
 535     _dcmdparser.add_dcmd_option(&_jmxremote_access_file);
 536     _dcmdparser.add_dcmd_option(&_jmxremote_login_config);
 537     _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_cipher_suites);
 538     _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_protocols);
 539     _dcmdparser.add_dcmd_option(&_jmxremote_ssl_need_client_auth);
 540     _dcmdparser.add_dcmd_option(&_jmxremote_ssl_config_file);
 541     _dcmdparser.add_dcmd_option(&_jmxremote_autodiscovery);
 542     _dcmdparser.add_dcmd_option(&_jdp_port);
 543     _dcmdparser.add_dcmd_option(&_jdp_address);
 544     _dcmdparser.add_dcmd_option(&_jdp_source_addr);
 545     _dcmdparser.add_dcmd_option(&_jdp_ttl);
 546     _dcmdparser.add_dcmd_option(&_jdp_pause);
 547     _dcmdparser.add_dcmd_option(&_jdp_name);
 548 }
 549 
 550 
 551 int JMXStartRemoteDCmd::num_arguments() {
 552   ResourceMark rm;
 553   JMXStartRemoteDCmd* dcmd = new JMXStartRemoteDCmd(NULL, false);
 554   if (dcmd != NULL) {
 555     DCmdMark mark(dcmd);
 556     return dcmd->_dcmdparser.num_arguments();
 557   } else {
 558     return 0;
 559   }
 560 }
 561 
 562 
 563 void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPS) {
 564     ResourceMark rm(THREAD);
 565     HandleMark hm(THREAD);
 566 
 567     // Load and initialize the sun.management.Agent class
 568     // invoke startRemoteManagementAgent(string) method to start
 569     // the remote management server.
 570     // throw java.lang.NoSuchMethodError if the method doesn't exist
 571 
 572     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
 573     Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
 574     instanceKlassHandle ik (THREAD, k);
 575 
 576     JavaValue result(T_VOID);
 577 
 578     // Pass all command line arguments to java as key=value,...
 579     // All checks are done on java side
 580 
 581     int len = 0;
 582     stringStream options;
 583     char comma[2] = {0,0};
 584 
 585     // Leave default values on Agent.class side and pass only
 586     // agruments explicitly set by user. All arguments passed
 587     // to jcmd override properties with the same name set by
 588     // command line with -D or by managmenent.properties
 589     // file.
 590 #define PUT_OPTION(a) \
 591     if ( (a).is_set() ){ \
 592         options.print(\
 593                ( *((a).type()) == 'I' ) ? "%scom.sun.management.%s=%d" : "%scom.sun.management.%s=%s",\
 594                 comma, (a).name(), (a).value()); \
 595         comma[0] = ','; \
 596     }
 597 
 598     PUT_OPTION(_config_file);
 599     PUT_OPTION(_jmxremote_port);
 600     PUT_OPTION(_jmxremote_rmi_port);
 601     PUT_OPTION(_jmxremote_ssl);
 602     PUT_OPTION(_jmxremote_registry_ssl);
 603     PUT_OPTION(_jmxremote_authenticate);
 604     PUT_OPTION(_jmxremote_password_file);
 605     PUT_OPTION(_jmxremote_access_file);
 606     PUT_OPTION(_jmxremote_login_config);
 607     PUT_OPTION(_jmxremote_ssl_enabled_cipher_suites);
 608     PUT_OPTION(_jmxremote_ssl_enabled_protocols);
 609     PUT_OPTION(_jmxremote_ssl_need_client_auth);
 610     PUT_OPTION(_jmxremote_ssl_config_file);
 611     PUT_OPTION(_jmxremote_autodiscovery);
 612     PUT_OPTION(_jdp_port);
 613     PUT_OPTION(_jdp_address);
 614     PUT_OPTION(_jdp_source_addr);
 615     PUT_OPTION(_jdp_ttl);
 616     PUT_OPTION(_jdp_pause);
 617     PUT_OPTION(_jdp_name);
 618 
 619 #undef PUT_OPTION
 620 
 621     Handle str = java_lang_String::create_from_str(options.as_string(), CHECK);
 622     JavaCalls::call_static(&result, ik, vmSymbols::startRemoteAgent_name(), vmSymbols::string_void_signature(), str, CHECK);
 623 }
 624 
 625 JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) :
 626   DCmd(output, heap_allocated) {
 627   // do nothing
 628 }
 629 
 630 void JMXStartLocalDCmd::execute(DCmdSource source, TRAPS) {
 631     ResourceMark rm(THREAD);
 632     HandleMark hm(THREAD);
 633 
 634     // Load and initialize the sun.management.Agent class
 635     // invoke startLocalManagementAgent(void) method to start
 636     // the local management server
 637     // throw java.lang.NoSuchMethodError if method doesn't exist
 638 
 639     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
 640     Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
 641     instanceKlassHandle ik (THREAD, k);
 642 
 643     JavaValue result(T_VOID);
 644     JavaCalls::call_static(&result, ik, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK);
 645 }
 646 
 647 void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) {
 648     ResourceMark rm(THREAD);
 649     HandleMark hm(THREAD);
 650 
 651     // Load and initialize the sun.management.Agent class
 652     // invoke stopRemoteManagementAgent method to stop the
 653     // management server
 654     // throw java.lang.NoSuchMethodError if method doesn't exist
 655 
 656     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
 657     Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
 658     instanceKlassHandle ik (THREAD, k);
 659 
 660     JavaValue result(T_VOID);
 661     JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK);
 662 }
 663 
 664 VMDynamicLibrariesDCmd::VMDynamicLibrariesDCmd(outputStream *output, bool heap_allocated) :
 665   DCmd(output, heap_allocated) {
 666   // do nothing
 667 }
 668 
 669 void VMDynamicLibrariesDCmd::execute(DCmdSource source, TRAPS) {
 670   os::print_dll_info(output());
 671   output()->cr();
 672 }
 673 
 674 void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) {
 675   if (UseGCLogFileRotation) {
 676     VM_RotateGCLog rotateop(output());
 677     VMThread::execute(&rotateop);
 678   } else {
 679     output()->print_cr("Target VM does not support GC log file rotation.");
 680   }
 681 }
 682 
 683 void CompileQueueDCmd::execute(DCmdSource source, TRAPS) {
 684   VM_PrintCompileQueue printCompileQueueOp(output());
 685   VMThread::execute(&printCompileQueueOp);
 686 }
 687 
 688 void CodeListDCmd::execute(DCmdSource source, TRAPS) {
 689   VM_PrintCodeList printCodeListOp(output());
 690   VMThread::execute(&printCodeListOp);
 691 }
 692 
 693 void CodeCacheDCmd::execute(DCmdSource source, TRAPS) {
 694   VM_PrintCodeCache printCodeCacheOp(output());
 695   VMThread::execute(&printCodeCacheOp);
 696 }
 697