src/share/vm/services/diagnosticFramework.cpp

Print this page




 342   while (arg != NULL) {
 343     array->append(arg->name());
 344     arg = arg->next();
 345   }
 346   arg = _options;
 347   while (arg != NULL) {
 348     array->append(arg->name());
 349     arg = arg->next();
 350   }
 351   return array;
 352 }
 353 
 354 GrowableArray<DCmdArgumentInfo*>* DCmdParser::argument_info_array() {
 355   int count = num_arguments();
 356   GrowableArray<DCmdArgumentInfo*>* array = new GrowableArray<DCmdArgumentInfo *>(count);
 357   int idx = 0;
 358   GenDCmdArgument* arg = _arguments_list;
 359   while (arg != NULL) {
 360     array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
 361                   arg->type(), arg->default_string(), arg->is_mandatory(),
 362                   false, idx));
 363     idx++;
 364     arg = arg->next();
 365   }
 366   arg = _options;
 367   while (arg != NULL) {
 368     array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
 369                   arg->type(), arg->default_string(), arg->is_mandatory(),
 370                   true));
 371     arg = arg->next();
 372   }
 373   return array;
 374 }
 375 
 376 DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL;

 377 
 378 void DCmd::parse_and_execute(outputStream* out, const char* cmdline,
 379                              char delim, TRAPS) {
 380 
 381   if (cmdline == NULL) return; // Nothing to do!
 382   DCmdIter iter(cmdline, '\n');
 383 
 384   while (iter.has_next()) {
 385     CmdLine line = iter.next();
 386     if (line.is_stop()) {
 387       break;
 388     }
 389     if (line.is_executable()) {
 390       DCmd* command = DCmdFactory::create_local_DCmd(line, out, CHECK);
 391       assert(command != NULL, "command error must be handled before this line");
 392       DCmdMark mark(command);
 393       command->parse(&line, delim, CHECK);
 394       command->execute(CHECK);
 395     }
 396   }
 397 }
 398 
 399 void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) {
 400   _dcmdparser.parse(line, delim, CHECK);
 401 }
 402 
 403 void DCmdWithParser::print_help(const char* name) {
 404   _dcmdparser.print_help(output(), name);
 405 }
 406 
 407 void DCmdWithParser::reset(TRAPS) {
 408   _dcmdparser.reset(CHECK);
 409 }
 410 
 411 void DCmdWithParser::cleanup() {
 412   _dcmdparser.cleanup();
 413 }
 414 
 415 GrowableArray<const char*>* DCmdWithParser::argument_name_array() {
 416   return _dcmdparser.argument_name_array();
 417 }
 418 
 419 GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() {
 420   return _dcmdparser.argument_info_array();
 421 }
 422 




























































 423 Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);

 424 
 425 DCmdFactory* DCmdFactory::factory(const char* name, size_t len) {
 426   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 427   DCmdFactory* factory = _DCmdFactoryList;
 428   while (factory != NULL) {
 429     if (strlen(factory->name()) == len &&
 430         strncmp(name, factory->name(), len) == 0) {

 431       return factory;


 432     }

 433     factory = factory->_next;
 434   }
 435   return NULL;
 436 }
 437 
 438 int DCmdFactory::register_DCmdFactory(DCmdFactory* factory) {
 439   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 440   factory->_next = _DCmdFactoryList;
 441   _DCmdFactoryList = factory;




 442   return 0; // Actually, there's no checks for duplicates
 443 }
 444 
 445 DCmd* DCmdFactory::create_global_DCmd(CmdLine &line, outputStream* out, TRAPS) {
 446   DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len());

 447   if (f != NULL) {
 448     if (f->is_enabled()) {
 449       THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 450                      f->disabled_message());
 451     }
 452     return f->create_Cheap_instance(out);
 453   }
 454   THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 455              "Unknown diagnostic command");
 456 }
 457 
 458 DCmd* DCmdFactory::create_local_DCmd(CmdLine &line, outputStream* out, TRAPS) {
 459   DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len());

 460   if (f != NULL) {
 461     if (!f->is_enabled()) {
 462       THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 463                      f->disabled_message());
 464     }
 465     return f->create_resource_instance(out);
 466   }
 467   THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 468              "Unknown diagnostic command");
 469 }
 470 
 471 GrowableArray<const char*>* DCmdFactory::DCmd_list() {
 472   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 473   GrowableArray<const char*>* array = new GrowableArray<const char*>();
 474   DCmdFactory* factory = _DCmdFactoryList;
 475   while (factory != NULL) {
 476     if (!factory->is_hidden()) {
 477       array->append(factory->name());
 478     }
 479     factory = factory->next();
 480   }
 481   return array;
 482 }
 483 
 484 GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list() {
 485   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 486   GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>();
 487   DCmdFactory* factory = _DCmdFactoryList;
 488   while (factory != NULL) {
 489     if (!factory->is_hidden()) {
 490       array->append(new DCmdInfo(factory->name(),
 491                     factory->description(), factory->impact(),
 492                     factory->num_arguments(), factory->is_enabled()));

 493     }
 494     factory = factory->next();
 495   }
 496   return array;
 497 }


 342   while (arg != NULL) {
 343     array->append(arg->name());
 344     arg = arg->next();
 345   }
 346   arg = _options;
 347   while (arg != NULL) {
 348     array->append(arg->name());
 349     arg = arg->next();
 350   }
 351   return array;
 352 }
 353 
 354 GrowableArray<DCmdArgumentInfo*>* DCmdParser::argument_info_array() {
 355   int count = num_arguments();
 356   GrowableArray<DCmdArgumentInfo*>* array = new GrowableArray<DCmdArgumentInfo *>(count);
 357   int idx = 0;
 358   GenDCmdArgument* arg = _arguments_list;
 359   while (arg != NULL) {
 360     array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
 361                   arg->type(), arg->default_string(), arg->is_mandatory(),
 362                   false, arg->allow_multiple(), idx));
 363     idx++;
 364     arg = arg->next();
 365   }
 366   arg = _options;
 367   while (arg != NULL) {
 368     array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
 369                   arg->type(), arg->default_string(), arg->is_mandatory(),
 370                   true, arg->allow_multiple()));
 371     arg = arg->next();
 372   }
 373   return array;
 374 }
 375 
 376 DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL;
 377 bool DCmdFactory::_has_pending_jmx_notification = false;
 378 
 379 void DCmd::parse_and_execute(DCmdSource source, outputStream* out,
 380                              const char* cmdline, char delim, TRAPS) {
 381 
 382   if (cmdline == NULL) return; // Nothing to do!
 383   DCmdIter iter(cmdline, '\n');
 384 
 385   while (iter.has_next()) {
 386     CmdLine line = iter.next();
 387     if (line.is_stop()) {
 388       break;
 389     }
 390     if (line.is_executable()) {
 391       DCmd* command = DCmdFactory::create_local_DCmd(source, line, out, CHECK);
 392       assert(command != NULL, "command error must be handled before this line");
 393       DCmdMark mark(command);
 394       command->parse(&line, delim, CHECK);
 395       command->execute(source, CHECK);
 396     }
 397   }
 398 }
 399 
 400 void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) {
 401   _dcmdparser.parse(line, delim, CHECK);
 402 }
 403 
 404 void DCmdWithParser::print_help(const char* name) {
 405   _dcmdparser.print_help(output(), name);
 406 }
 407 
 408 void DCmdWithParser::reset(TRAPS) {
 409   _dcmdparser.reset(CHECK);
 410 }
 411 
 412 void DCmdWithParser::cleanup() {
 413   _dcmdparser.cleanup();
 414 }
 415 
 416 GrowableArray<const char*>* DCmdWithParser::argument_name_array() {
 417   return _dcmdparser.argument_name_array();
 418 }
 419 
 420 GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() {
 421   return _dcmdparser.argument_info_array();
 422 }
 423 
 424 void DCmdFactory::push_jmx_notification_request() {
 425   MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
 426   _has_pending_jmx_notification = true;
 427   Service_lock->notify_all();
 428 }
 429 
 430 void DCmdFactory::send_notification(TRAPS) {
 431   DCmdFactory::send_notification_internal(THREAD);
 432   // Clearing pending exception to avoid premature termination of
 433   // the service thread
 434   if (HAS_PENDING_EXCEPTION) {
 435     // Just for testing
 436     java_lang_Throwable::print(PENDING_EXCEPTION, tty);
 437     CLEAR_PENDING_EXCEPTION;
 438   }
 439 }
 440 void DCmdFactory::send_notification_internal(TRAPS) {
 441   ResourceMark rm(THREAD);
 442   HandleMark hm(THREAD);
 443   bool notif = false;
 444   {
 445     MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
 446     notif = _has_pending_jmx_notification;
 447     _has_pending_jmx_notification = false;
 448   }
 449   if (notif) {
 450 
 451     Klass* k = Management::sun_management_ManagementFactoryHelper_klass(CHECK);
 452     instanceKlassHandle mgmt_factory_helper_klass(THREAD, k);
 453 
 454     JavaValue result(T_OBJECT);
 455     JavaCalls::call_static(&result,
 456             mgmt_factory_helper_klass,
 457             vmSymbols::getDiagnosticCommandMBean_name(),
 458             vmSymbols::getDiagnosticCommandMBean_signature(),
 459             CHECK);
 460 
 461     instanceOop m = (instanceOop) result.get_jobject();
 462     instanceHandle dcmd_mbean_h(THREAD, m);
 463 
 464     Klass* k2 = Management::sun_management_DiagnosticCommandImpl_klass(CHECK);
 465     instanceKlassHandle dcmd_mbean_klass(THREAD, k2);
 466 
 467     if (!dcmd_mbean_h->is_a(k2)) {
 468       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
 469               "ManagementFactory.getDiagnosticCommandMBean didn't return a DiagnosticCommandMBean instance");
 470     }
 471 
 472     JavaValue result2(T_VOID);
 473     JavaCallArguments args2(dcmd_mbean_h);
 474 
 475     JavaCalls::call_virtual(&result2,
 476             dcmd_mbean_klass,
 477             vmSymbols::createDiagnosticFrameworkNotification_name(),
 478             vmSymbols::void_method_signature(),
 479             &args2,
 480             CHECK);
 481   }
 482 }
 483 
 484 Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
 485 bool DCmdFactory::_send_jmx_notification = false;
 486 
 487 DCmdFactory* DCmdFactory::factory(DCmdSource source, const char* name, size_t len) {
 488   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 489   DCmdFactory* factory = _DCmdFactoryList;
 490   while (factory != NULL) {
 491     if (strlen(factory->name()) == len &&
 492         strncmp(name, factory->name(), len) == 0) {
 493       if(factory->export_flags() & source) {
 494         return factory;
 495       } else {
 496         return NULL;
 497       }
 498     }
 499     factory = factory->_next;
 500   }
 501   return NULL;
 502 }
 503 
 504 int DCmdFactory::register_DCmdFactory(DCmdFactory* factory) {
 505   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 506   factory->_next = _DCmdFactoryList;
 507   _DCmdFactoryList = factory;
 508   if (_send_jmx_notification && !factory->_hidden
 509       && factory->_export_flags&DCmd_Source_MBean) {
 510     DCmdFactory::push_jmx_notification_request();
 511   }
 512   return 0; // Actually, there's no checks for duplicates
 513 }
 514 
 515 DCmd* DCmdFactory::create_global_DCmd(DCmdSource source, CmdLine &line,
 516                                       outputStream* out, TRAPS) {
 517   DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len());
 518   if (f != NULL) {
 519     if (f->is_enabled()) {
 520       THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 521                      f->disabled_message());
 522     }
 523     return f->create_Cheap_instance(out);
 524   }
 525   THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 526              "Unknown diagnostic command");
 527 }
 528 
 529 DCmd* DCmdFactory::create_local_DCmd(DCmdSource source, CmdLine &line,
 530                                      outputStream* out, TRAPS) {
 531   DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len());
 532   if (f != NULL) {
 533     if (!f->is_enabled()) {
 534       THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 535                      f->disabled_message());
 536     }
 537     return f->create_resource_instance(out);
 538   }
 539   THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
 540              "Unknown diagnostic command");
 541 }
 542 
 543 GrowableArray<const char*>* DCmdFactory::DCmd_list(DCmdSource source) {
 544   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 545   GrowableArray<const char*>* array = new GrowableArray<const char*>();
 546   DCmdFactory* factory = _DCmdFactoryList;
 547   while (factory != NULL) {
 548     if (!factory->is_hidden() && (factory->export_flags() & source)) {
 549       array->append(factory->name());
 550     }
 551     factory = factory->next();
 552   }
 553   return array;
 554 }
 555 
 556 GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list(DCmdSource source ) {
 557   MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
 558   GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>();
 559   DCmdFactory* factory = _DCmdFactoryList;
 560   while (factory != NULL) {
 561     if (!factory->is_hidden() && (factory->export_flags() & source)) {
 562       array->append(new DCmdInfo(factory->name(),
 563                     factory->description(), factory->impact(),
 564                     factory->permission(), factory->num_arguments(),
 565                     factory->is_enabled()));
 566     }
 567     factory = factory->next();
 568   }
 569   return array;
 570 }