Mercurial > hg > graal-compiler
comparison src/share/vm/services/diagnosticFramework.cpp @ 10215:31a4e55f8c9d
8004095: Add support for JMX interface to Diagnostic Framework and Commands
Reviewed-by: acorn, sla
author | fparain |
---|---|
date | Fri, 03 May 2013 05:05:31 -0700 |
parents | 5a1f452f8f90 |
children | 78bbf4d43a14 |
comparison
equal
deleted
inserted
replaced
10167:8fe2542bdc8d | 10215:31a4e55f8c9d |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
357 int idx = 0; | 357 int idx = 0; |
358 GenDCmdArgument* arg = _arguments_list; | 358 GenDCmdArgument* arg = _arguments_list; |
359 while (arg != NULL) { | 359 while (arg != NULL) { |
360 array->append(new DCmdArgumentInfo(arg->name(), arg->description(), | 360 array->append(new DCmdArgumentInfo(arg->name(), arg->description(), |
361 arg->type(), arg->default_string(), arg->is_mandatory(), | 361 arg->type(), arg->default_string(), arg->is_mandatory(), |
362 false, idx)); | 362 false, arg->allow_multiple(), idx)); |
363 idx++; | 363 idx++; |
364 arg = arg->next(); | 364 arg = arg->next(); |
365 } | 365 } |
366 arg = _options; | 366 arg = _options; |
367 while (arg != NULL) { | 367 while (arg != NULL) { |
368 array->append(new DCmdArgumentInfo(arg->name(), arg->description(), | 368 array->append(new DCmdArgumentInfo(arg->name(), arg->description(), |
369 arg->type(), arg->default_string(), arg->is_mandatory(), | 369 arg->type(), arg->default_string(), arg->is_mandatory(), |
370 true)); | 370 true, arg->allow_multiple())); |
371 arg = arg->next(); | 371 arg = arg->next(); |
372 } | 372 } |
373 return array; | 373 return array; |
374 } | 374 } |
375 | 375 |
376 DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL; | 376 DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL; |
377 | 377 bool DCmdFactory::_has_pending_jmx_notification = false; |
378 void DCmd::parse_and_execute(outputStream* out, const char* cmdline, | 378 |
379 char delim, TRAPS) { | 379 void DCmd::parse_and_execute(DCmdSource source, outputStream* out, |
380 const char* cmdline, char delim, TRAPS) { | |
380 | 381 |
381 if (cmdline == NULL) return; // Nothing to do! | 382 if (cmdline == NULL) return; // Nothing to do! |
382 DCmdIter iter(cmdline, '\n'); | 383 DCmdIter iter(cmdline, '\n'); |
383 | 384 |
385 int count = 0; | |
384 while (iter.has_next()) { | 386 while (iter.has_next()) { |
387 if(source == DCmd_Source_MBean && count > 0) { | |
388 // When diagnostic commands are invoked via JMX, each command line | |
389 // must contains one and only one command because of the Permission | |
390 // checks performed by the DiagnosticCommandMBean | |
391 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
392 "Invalid syntax"); | |
393 } | |
385 CmdLine line = iter.next(); | 394 CmdLine line = iter.next(); |
386 if (line.is_stop()) { | 395 if (line.is_stop()) { |
387 break; | 396 break; |
388 } | 397 } |
389 if (line.is_executable()) { | 398 if (line.is_executable()) { |
390 DCmd* command = DCmdFactory::create_local_DCmd(line, out, CHECK); | 399 DCmd* command = DCmdFactory::create_local_DCmd(source, line, out, CHECK); |
391 assert(command != NULL, "command error must be handled before this line"); | 400 assert(command != NULL, "command error must be handled before this line"); |
392 DCmdMark mark(command); | 401 DCmdMark mark(command); |
393 command->parse(&line, delim, CHECK); | 402 command->parse(&line, delim, CHECK); |
394 command->execute(CHECK); | 403 command->execute(source, CHECK); |
395 } | 404 } |
405 count++; | |
396 } | 406 } |
397 } | 407 } |
398 | 408 |
399 void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) { | 409 void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) { |
400 _dcmdparser.parse(line, delim, CHECK); | 410 _dcmdparser.parse(line, delim, CHECK); |
418 | 428 |
419 GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() { | 429 GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() { |
420 return _dcmdparser.argument_info_array(); | 430 return _dcmdparser.argument_info_array(); |
421 } | 431 } |
422 | 432 |
433 void DCmdFactory::push_jmx_notification_request() { | |
434 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); | |
435 _has_pending_jmx_notification = true; | |
436 Service_lock->notify_all(); | |
437 } | |
438 | |
439 void DCmdFactory::send_notification(TRAPS) { | |
440 DCmdFactory::send_notification_internal(THREAD); | |
441 // Clearing pending exception to avoid premature termination of | |
442 // the service thread | |
443 if (HAS_PENDING_EXCEPTION) { | |
444 CLEAR_PENDING_EXCEPTION; | |
445 } | |
446 } | |
447 void DCmdFactory::send_notification_internal(TRAPS) { | |
448 ResourceMark rm(THREAD); | |
449 HandleMark hm(THREAD); | |
450 bool notif = false; | |
451 { | |
452 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); | |
453 notif = _has_pending_jmx_notification; | |
454 _has_pending_jmx_notification = false; | |
455 } | |
456 if (notif) { | |
457 | |
458 Klass* k = Management::sun_management_ManagementFactoryHelper_klass(CHECK); | |
459 instanceKlassHandle mgmt_factory_helper_klass(THREAD, k); | |
460 | |
461 JavaValue result(T_OBJECT); | |
462 JavaCalls::call_static(&result, | |
463 mgmt_factory_helper_klass, | |
464 vmSymbols::getDiagnosticCommandMBean_name(), | |
465 vmSymbols::getDiagnosticCommandMBean_signature(), | |
466 CHECK); | |
467 | |
468 instanceOop m = (instanceOop) result.get_jobject(); | |
469 instanceHandle dcmd_mbean_h(THREAD, m); | |
470 | |
471 Klass* k2 = Management::sun_management_DiagnosticCommandImpl_klass(CHECK); | |
472 instanceKlassHandle dcmd_mbean_klass(THREAD, k2); | |
473 | |
474 if (!dcmd_mbean_h->is_a(k2)) { | |
475 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
476 "ManagementFactory.getDiagnosticCommandMBean didn't return a DiagnosticCommandMBean instance"); | |
477 } | |
478 | |
479 JavaValue result2(T_VOID); | |
480 JavaCallArguments args2(dcmd_mbean_h); | |
481 | |
482 JavaCalls::call_virtual(&result2, | |
483 dcmd_mbean_klass, | |
484 vmSymbols::createDiagnosticFrameworkNotification_name(), | |
485 vmSymbols::void_method_signature(), | |
486 &args2, | |
487 CHECK); | |
488 } | |
489 } | |
490 | |
423 Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true); | 491 Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true); |
424 | 492 bool DCmdFactory::_send_jmx_notification = false; |
425 DCmdFactory* DCmdFactory::factory(const char* name, size_t len) { | 493 |
494 DCmdFactory* DCmdFactory::factory(DCmdSource source, const char* name, size_t len) { | |
426 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | 495 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
427 DCmdFactory* factory = _DCmdFactoryList; | 496 DCmdFactory* factory = _DCmdFactoryList; |
428 while (factory != NULL) { | 497 while (factory != NULL) { |
429 if (strlen(factory->name()) == len && | 498 if (strlen(factory->name()) == len && |
430 strncmp(name, factory->name(), len) == 0) { | 499 strncmp(name, factory->name(), len) == 0) { |
431 return factory; | 500 if(factory->export_flags() & source) { |
501 return factory; | |
502 } else { | |
503 return NULL; | |
504 } | |
432 } | 505 } |
433 factory = factory->_next; | 506 factory = factory->_next; |
434 } | 507 } |
435 return NULL; | 508 return NULL; |
436 } | 509 } |
437 | 510 |
438 int DCmdFactory::register_DCmdFactory(DCmdFactory* factory) { | 511 int DCmdFactory::register_DCmdFactory(DCmdFactory* factory) { |
439 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | 512 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
440 factory->_next = _DCmdFactoryList; | 513 factory->_next = _DCmdFactoryList; |
441 _DCmdFactoryList = factory; | 514 _DCmdFactoryList = factory; |
515 if (_send_jmx_notification && !factory->_hidden | |
516 && (factory->_export_flags & DCmd_Source_MBean)) { | |
517 DCmdFactory::push_jmx_notification_request(); | |
518 } | |
442 return 0; // Actually, there's no checks for duplicates | 519 return 0; // Actually, there's no checks for duplicates |
443 } | 520 } |
444 | 521 |
445 DCmd* DCmdFactory::create_global_DCmd(CmdLine &line, outputStream* out, TRAPS) { | 522 DCmd* DCmdFactory::create_global_DCmd(DCmdSource source, CmdLine &line, |
446 DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); | 523 outputStream* out, TRAPS) { |
524 DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len()); | |
447 if (f != NULL) { | 525 if (f != NULL) { |
448 if (f->is_enabled()) { | 526 if (f->is_enabled()) { |
449 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | 527 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
450 f->disabled_message()); | 528 f->disabled_message()); |
451 } | 529 } |
453 } | 531 } |
454 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | 532 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
455 "Unknown diagnostic command"); | 533 "Unknown diagnostic command"); |
456 } | 534 } |
457 | 535 |
458 DCmd* DCmdFactory::create_local_DCmd(CmdLine &line, outputStream* out, TRAPS) { | 536 DCmd* DCmdFactory::create_local_DCmd(DCmdSource source, CmdLine &line, |
459 DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); | 537 outputStream* out, TRAPS) { |
538 DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len()); | |
460 if (f != NULL) { | 539 if (f != NULL) { |
461 if (!f->is_enabled()) { | 540 if (!f->is_enabled()) { |
462 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | 541 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
463 f->disabled_message()); | 542 f->disabled_message()); |
464 } | 543 } |
466 } | 545 } |
467 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | 546 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
468 "Unknown diagnostic command"); | 547 "Unknown diagnostic command"); |
469 } | 548 } |
470 | 549 |
471 GrowableArray<const char*>* DCmdFactory::DCmd_list() { | 550 GrowableArray<const char*>* DCmdFactory::DCmd_list(DCmdSource source) { |
472 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | 551 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
473 GrowableArray<const char*>* array = new GrowableArray<const char*>(); | 552 GrowableArray<const char*>* array = new GrowableArray<const char*>(); |
474 DCmdFactory* factory = _DCmdFactoryList; | 553 DCmdFactory* factory = _DCmdFactoryList; |
475 while (factory != NULL) { | 554 while (factory != NULL) { |
476 if (!factory->is_hidden()) { | 555 if (!factory->is_hidden() && (factory->export_flags() & source)) { |
477 array->append(factory->name()); | 556 array->append(factory->name()); |
478 } | 557 } |
479 factory = factory->next(); | 558 factory = factory->next(); |
480 } | 559 } |
481 return array; | 560 return array; |
482 } | 561 } |
483 | 562 |
484 GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list() { | 563 GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list(DCmdSource source ) { |
485 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | 564 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
486 GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>(); | 565 GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>(); |
487 DCmdFactory* factory = _DCmdFactoryList; | 566 DCmdFactory* factory = _DCmdFactoryList; |
488 while (factory != NULL) { | 567 while (factory != NULL) { |
489 if (!factory->is_hidden()) { | 568 if (!factory->is_hidden() && (factory->export_flags() & source)) { |
490 array->append(new DCmdInfo(factory->name(), | 569 array->append(new DCmdInfo(factory->name(), |
491 factory->description(), factory->impact(), | 570 factory->description(), factory->impact(), |
492 factory->num_arguments(), factory->is_enabled())); | 571 factory->permission(), factory->num_arguments(), |
572 factory->is_enabled())); | |
493 } | 573 } |
494 factory = factory->next(); | 574 factory = factory->next(); |
495 } | 575 } |
496 return array; | 576 return array; |
497 } | 577 } |