Path: blob/master/src/hotspot/share/services/management.cpp
41144 views
/*1* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "jmm.h"26#include "classfile/classLoader.hpp"27#include "classfile/systemDictionary.hpp"28#include "classfile/vmClasses.hpp"29#include "compiler/compileBroker.hpp"30#include "gc/shared/collectedHeap.hpp"31#include "memory/allocation.inline.hpp"32#include "memory/iterator.hpp"33#include "memory/oopFactory.hpp"34#include "memory/resourceArea.hpp"35#include "memory/universe.hpp"36#include "oops/klass.hpp"37#include "oops/klass.inline.hpp"38#include "oops/objArrayKlass.hpp"39#include "oops/objArrayOop.inline.hpp"40#include "oops/oop.inline.hpp"41#include "oops/oopHandle.inline.hpp"42#include "oops/typeArrayOop.inline.hpp"43#include "runtime/flags/jvmFlag.hpp"44#include "runtime/globals.hpp"45#include "runtime/handles.inline.hpp"46#include "runtime/interfaceSupport.inline.hpp"47#include "runtime/javaCalls.hpp"48#include "runtime/jniHandles.inline.hpp"49#include "runtime/notificationThread.hpp"50#include "runtime/os.hpp"51#include "runtime/thread.inline.hpp"52#include "runtime/threadSMR.hpp"53#include "runtime/vmOperations.hpp"54#include "services/classLoadingService.hpp"55#include "services/diagnosticCommand.hpp"56#include "services/diagnosticFramework.hpp"57#include "services/writeableFlags.hpp"58#include "services/heapDumper.hpp"59#include "services/lowMemoryDetector.hpp"60#include "services/gcNotifier.hpp"61#include "services/nmtDCmd.hpp"62#include "services/management.hpp"63#include "services/memoryManager.hpp"64#include "services/memoryPool.hpp"65#include "services/memoryService.hpp"66#include "services/runtimeService.hpp"67#include "services/threadService.hpp"68#include "utilities/debug.hpp"69#include "utilities/formatBuffer.hpp"70#include "utilities/macros.hpp"7172PerfVariable* Management::_begin_vm_creation_time = NULL;73PerfVariable* Management::_end_vm_creation_time = NULL;74PerfVariable* Management::_vm_init_done_time = NULL;7576InstanceKlass* Management::_diagnosticCommandImpl_klass = NULL;77InstanceKlass* Management::_garbageCollectorExtImpl_klass = NULL;78InstanceKlass* Management::_garbageCollectorMXBean_klass = NULL;79InstanceKlass* Management::_gcInfo_klass = NULL;80InstanceKlass* Management::_managementFactoryHelper_klass = NULL;81InstanceKlass* Management::_memoryManagerMXBean_klass = NULL;82InstanceKlass* Management::_memoryPoolMXBean_klass = NULL;83InstanceKlass* Management::_memoryUsage_klass = NULL;84InstanceKlass* Management::_sensor_klass = NULL;85InstanceKlass* Management::_threadInfo_klass = NULL;8687jmmOptionalSupport Management::_optional_support = {0};88TimeStamp Management::_stamp;8990void management_init() {91#if INCLUDE_MANAGEMENT92Management::init();93ThreadService::init();94RuntimeService::init();95ClassLoadingService::init();96#else97ThreadService::init();98#endif // INCLUDE_MANAGEMENT99}100101#if INCLUDE_MANAGEMENT102103void Management::init() {104EXCEPTION_MARK;105106// These counters are for java.lang.management API support.107// They are created even if -XX:-UsePerfData is set and in108// that case, they will be allocated on C heap.109110_begin_vm_creation_time =111PerfDataManager::create_variable(SUN_RT, "createVmBeginTime",112PerfData::U_None, CHECK);113114_end_vm_creation_time =115PerfDataManager::create_variable(SUN_RT, "createVmEndTime",116PerfData::U_None, CHECK);117118_vm_init_done_time =119PerfDataManager::create_variable(SUN_RT, "vmInitDoneTime",120PerfData::U_None, CHECK);121122// Initialize optional support123_optional_support.isLowMemoryDetectionSupported = 1;124_optional_support.isCompilationTimeMonitoringSupported = 1;125_optional_support.isThreadContentionMonitoringSupported = 1;126127if (os::is_thread_cpu_time_supported()) {128_optional_support.isCurrentThreadCpuTimeSupported = 1;129_optional_support.isOtherThreadCpuTimeSupported = 1;130} else {131_optional_support.isCurrentThreadCpuTimeSupported = 0;132_optional_support.isOtherThreadCpuTimeSupported = 0;133}134135_optional_support.isObjectMonitorUsageSupported = 1;136#if INCLUDE_SERVICES137// This depends on the heap inspector138_optional_support.isSynchronizerUsageSupported = 1;139#endif // INCLUDE_SERVICES140_optional_support.isThreadAllocatedMemorySupported = 1;141_optional_support.isRemoteDiagnosticCommandsSupported = 1;142143// Registration of the diagnostic commands144DCmdRegistrant::register_dcmds();145DCmdRegistrant::register_dcmds_ext();146uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI147| DCmd_Source_MBean;148DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<NMTDCmd>(full_export, true, false));149}150151void Management::initialize(TRAPS) {152if (UseNotificationThread) {153NotificationThread::initialize();154}155if (ManagementServer) {156ResourceMark rm(THREAD);157HandleMark hm(THREAD);158159// Load and initialize the jdk.internal.agent.Agent class160// invoke startAgent method to start the management server161Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());162Klass* k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_agent_Agent(),163loader,164Handle(),165THREAD);166if (k == NULL) {167vm_exit_during_initialization("Management agent initialization failure: "168"class jdk.internal.agent.Agent not found.");169}170171JavaValue result(T_VOID);172JavaCalls::call_static(&result,173k,174vmSymbols::startAgent_name(),175vmSymbols::void_method_signature(),176CHECK);177}178}179180void Management::get_optional_support(jmmOptionalSupport* support) {181memcpy(support, &_optional_support, sizeof(jmmOptionalSupport));182}183184InstanceKlass* Management::load_and_initialize_klass(Symbol* sh, TRAPS) {185Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);186return initialize_klass(k, THREAD);187}188189InstanceKlass* Management::load_and_initialize_klass_or_null(Symbol* sh, TRAPS) {190Klass* k = SystemDictionary::resolve_or_null(sh, CHECK_NULL);191if (k == NULL) {192return NULL;193}194return initialize_klass(k, THREAD);195}196197InstanceKlass* Management::initialize_klass(Klass* k, TRAPS) {198InstanceKlass* ik = InstanceKlass::cast(k);199if (ik->should_be_initialized()) {200ik->initialize(CHECK_NULL);201}202// If these classes change to not be owned by the boot loader, they need203// to be walked to keep their class loader alive in oops_do.204assert(ik->class_loader() == NULL, "need to follow in oops_do");205return ik;206}207208void Management::record_vm_startup_time(jlong begin, jlong duration) {209// if the performance counter is not initialized,210// then vm initialization failed; simply return.211if (_begin_vm_creation_time == NULL) return;212213_begin_vm_creation_time->set_value(begin);214_end_vm_creation_time->set_value(begin + duration);215PerfMemory::set_accessible(true);216}217218jlong Management::timestamp() {219TimeStamp t;220t.update();221return t.ticks() - _stamp.ticks();222}223224InstanceKlass* Management::java_lang_management_ThreadInfo_klass(TRAPS) {225if (_threadInfo_klass == NULL) {226_threadInfo_klass = load_and_initialize_klass(vmSymbols::java_lang_management_ThreadInfo(), CHECK_NULL);227}228return _threadInfo_klass;229}230231InstanceKlass* Management::java_lang_management_MemoryUsage_klass(TRAPS) {232if (_memoryUsage_klass == NULL) {233_memoryUsage_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryUsage(), CHECK_NULL);234}235return _memoryUsage_klass;236}237238InstanceKlass* Management::java_lang_management_MemoryPoolMXBean_klass(TRAPS) {239if (_memoryPoolMXBean_klass == NULL) {240_memoryPoolMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryPoolMXBean(), CHECK_NULL);241}242return _memoryPoolMXBean_klass;243}244245InstanceKlass* Management::java_lang_management_MemoryManagerMXBean_klass(TRAPS) {246if (_memoryManagerMXBean_klass == NULL) {247_memoryManagerMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryManagerMXBean(), CHECK_NULL);248}249return _memoryManagerMXBean_klass;250}251252InstanceKlass* Management::java_lang_management_GarbageCollectorMXBean_klass(TRAPS) {253if (_garbageCollectorMXBean_klass == NULL) {254_garbageCollectorMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_GarbageCollectorMXBean(), CHECK_NULL);255}256return _garbageCollectorMXBean_klass;257}258259InstanceKlass* Management::sun_management_Sensor_klass(TRAPS) {260if (_sensor_klass == NULL) {261_sensor_klass = load_and_initialize_klass(vmSymbols::sun_management_Sensor(), CHECK_NULL);262}263return _sensor_klass;264}265266InstanceKlass* Management::sun_management_ManagementFactoryHelper_klass(TRAPS) {267if (_managementFactoryHelper_klass == NULL) {268_managementFactoryHelper_klass = load_and_initialize_klass(vmSymbols::sun_management_ManagementFactoryHelper(), CHECK_NULL);269}270return _managementFactoryHelper_klass;271}272273InstanceKlass* Management::com_sun_management_internal_GarbageCollectorExtImpl_klass(TRAPS) {274if (_garbageCollectorExtImpl_klass == NULL) {275_garbageCollectorExtImpl_klass =276load_and_initialize_klass_or_null(vmSymbols::com_sun_management_internal_GarbageCollectorExtImpl(), CHECK_NULL);277}278return _garbageCollectorExtImpl_klass;279}280281InstanceKlass* Management::com_sun_management_GcInfo_klass(TRAPS) {282if (_gcInfo_klass == NULL) {283_gcInfo_klass = load_and_initialize_klass(vmSymbols::com_sun_management_GcInfo(), CHECK_NULL);284}285return _gcInfo_klass;286}287288InstanceKlass* Management::com_sun_management_internal_DiagnosticCommandImpl_klass(TRAPS) {289if (_diagnosticCommandImpl_klass == NULL) {290_diagnosticCommandImpl_klass = load_and_initialize_klass(vmSymbols::com_sun_management_internal_DiagnosticCommandImpl(), CHECK_NULL);291}292return _diagnosticCommandImpl_klass;293}294295static void initialize_ThreadInfo_constructor_arguments(JavaCallArguments* args, ThreadSnapshot* snapshot, TRAPS) {296Handle snapshot_thread(THREAD, snapshot->threadObj());297298jlong contended_time;299jlong waited_time;300if (ThreadService::is_thread_monitoring_contention()) {301contended_time = Management::ticks_to_ms(snapshot->contended_enter_ticks());302waited_time = Management::ticks_to_ms(snapshot->monitor_wait_ticks() + snapshot->sleep_ticks());303} else {304// set them to -1 if thread contention monitoring is disabled.305contended_time = max_julong;306waited_time = max_julong;307}308309int thread_status = static_cast<int>(snapshot->thread_status());310assert((thread_status & JMM_THREAD_STATE_FLAG_MASK) == 0, "Flags already set in thread_status in Thread object");311if (snapshot->is_suspended()) {312thread_status |= JMM_THREAD_STATE_FLAG_SUSPENDED;313}314if (snapshot->is_in_native()) {315thread_status |= JMM_THREAD_STATE_FLAG_NATIVE;316}317318ThreadStackTrace* st = snapshot->get_stack_trace();319Handle stacktrace_h;320if (st != NULL) {321stacktrace_h = st->allocate_fill_stack_trace_element_array(CHECK);322} else {323stacktrace_h = Handle();324}325326args->push_oop(snapshot_thread);327args->push_int(thread_status);328args->push_oop(Handle(THREAD, snapshot->blocker_object()));329args->push_oop(Handle(THREAD, snapshot->blocker_object_owner()));330args->push_long(snapshot->contended_enter_count());331args->push_long(contended_time);332args->push_long(snapshot->monitor_wait_count() + snapshot->sleep_count());333args->push_long(waited_time);334args->push_oop(stacktrace_h);335}336337// Helper function to construct a ThreadInfo object338instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot, TRAPS) {339InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);340JavaCallArguments args(14);341342// initialize the arguments for the ThreadInfo constructor343initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);344345// Call ThreadInfo constructor with no locked monitors and synchronizers346Handle element = JavaCalls::construct_new_instance(347ik,348vmSymbols::java_lang_management_ThreadInfo_constructor_signature(),349&args,350CHECK_NULL);351return (instanceOop) element();352}353354instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot,355objArrayHandle monitors_array,356typeArrayHandle depths_array,357objArrayHandle synchronizers_array,358TRAPS) {359InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);360JavaCallArguments args(17);361362// initialize the arguments for the ThreadInfo constructor363initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);364365// push the locked monitors and synchronizers in the arguments366args.push_oop(monitors_array);367args.push_oop(depths_array);368args.push_oop(synchronizers_array);369370// Call ThreadInfo constructor with locked monitors and synchronizers371Handle element = JavaCalls::construct_new_instance(372ik,373vmSymbols::java_lang_management_ThreadInfo_with_locks_constructor_signature(),374&args,375CHECK_NULL);376return (instanceOop) element();377}378379380static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {381if (mgr == NULL) {382THROW_(vmSymbols::java_lang_NullPointerException(), NULL);383}384oop mgr_obj = JNIHandles::resolve(mgr);385instanceHandle h(THREAD, (instanceOop) mgr_obj);386387InstanceKlass* k = Management::java_lang_management_GarbageCollectorMXBean_klass(CHECK_NULL);388if (!h->is_a(k)) {389THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),390"the object is not an instance of java.lang.management.GarbageCollectorMXBean class",391NULL);392}393394MemoryManager* gc = MemoryService::get_memory_manager(h);395if (gc == NULL || !gc->is_gc_memory_manager()) {396THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),397"Invalid GC memory manager",398NULL);399}400return (GCMemoryManager*) gc;401}402403static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) {404if (obj == NULL) {405THROW_(vmSymbols::java_lang_NullPointerException(), NULL);406}407408oop pool_obj = JNIHandles::resolve(obj);409assert(pool_obj->is_instance(), "Should be an instanceOop");410instanceHandle ph(THREAD, (instanceOop) pool_obj);411412return MemoryService::get_memory_pool(ph);413}414415#endif // INCLUDE_MANAGEMENT416417static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {418int num_threads = ids_ah->length();419420// Validate input thread IDs421int i = 0;422for (i = 0; i < num_threads; i++) {423jlong tid = ids_ah->long_at(i);424if (tid <= 0) {425// throw exception if invalid thread id.426THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),427"Invalid thread ID entry");428}429}430}431432#if INCLUDE_MANAGEMENT433434static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {435// check if the element of infoArray is of type ThreadInfo class436Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);437Klass* element_klass = ObjArrayKlass::cast(infoArray_h->klass())->element_klass();438if (element_klass != threadinfo_klass) {439THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),440"infoArray element type is not ThreadInfo class");441}442}443444445static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) {446if (obj == NULL) {447THROW_(vmSymbols::java_lang_NullPointerException(), NULL);448}449450oop mgr_obj = JNIHandles::resolve(obj);451assert(mgr_obj->is_instance(), "Should be an instanceOop");452instanceHandle mh(THREAD, (instanceOop) mgr_obj);453454return MemoryService::get_memory_manager(mh);455}456457// Returns a version string and sets major and minor version if458// the input parameters are non-null.459JVM_LEAF(jint, jmm_GetVersion(JNIEnv *env))460return JMM_VERSION;461JVM_END462463// Gets the list of VM monitoring and management optional supports464// Returns 0 if succeeded; otherwise returns non-zero.465JVM_LEAF(jint, jmm_GetOptionalSupport(JNIEnv *env, jmmOptionalSupport* support))466if (support == NULL) {467return -1;468}469Management::get_optional_support(support);470return 0;471JVM_END472473// Returns an array of java/lang/management/MemoryPoolMXBean object474// one for each memory pool if obj == null; otherwise returns475// an array of memory pools for a given memory manager if476// it is a valid memory manager.477JVM_ENTRY(jobjectArray, jmm_GetMemoryPools(JNIEnv* env, jobject obj))478ResourceMark rm(THREAD);479480int num_memory_pools;481MemoryManager* mgr = NULL;482if (obj == NULL) {483num_memory_pools = MemoryService::num_memory_pools();484} else {485mgr = get_memory_manager_from_jobject(obj, CHECK_NULL);486if (mgr == NULL) {487return NULL;488}489num_memory_pools = mgr->num_memory_pools();490}491492// Allocate the resulting MemoryPoolMXBean[] object493InstanceKlass* ik = Management::java_lang_management_MemoryPoolMXBean_klass(CHECK_NULL);494objArrayOop r = oopFactory::new_objArray(ik, num_memory_pools, CHECK_NULL);495objArrayHandle poolArray(THREAD, r);496497if (mgr == NULL) {498// Get all memory pools499for (int i = 0; i < num_memory_pools; i++) {500MemoryPool* pool = MemoryService::get_memory_pool(i);501instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);502instanceHandle ph(THREAD, p);503poolArray->obj_at_put(i, ph());504}505} else {506// Get memory pools managed by a given memory manager507for (int i = 0; i < num_memory_pools; i++) {508MemoryPool* pool = mgr->get_memory_pool(i);509instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);510instanceHandle ph(THREAD, p);511poolArray->obj_at_put(i, ph());512}513}514return (jobjectArray) JNIHandles::make_local(THREAD, poolArray());515JVM_END516517// Returns an array of java/lang/management/MemoryManagerMXBean object518// one for each memory manager if obj == null; otherwise returns519// an array of memory managers for a given memory pool if520// it is a valid memory pool.521JVM_ENTRY(jobjectArray, jmm_GetMemoryManagers(JNIEnv* env, jobject obj))522ResourceMark rm(THREAD);523524int num_mgrs;525MemoryPool* pool = NULL;526if (obj == NULL) {527num_mgrs = MemoryService::num_memory_managers();528} else {529pool = get_memory_pool_from_jobject(obj, CHECK_NULL);530if (pool == NULL) {531return NULL;532}533num_mgrs = pool->num_memory_managers();534}535536// Allocate the resulting MemoryManagerMXBean[] object537InstanceKlass* ik = Management::java_lang_management_MemoryManagerMXBean_klass(CHECK_NULL);538objArrayOop r = oopFactory::new_objArray(ik, num_mgrs, CHECK_NULL);539objArrayHandle mgrArray(THREAD, r);540541if (pool == NULL) {542// Get all memory managers543for (int i = 0; i < num_mgrs; i++) {544MemoryManager* mgr = MemoryService::get_memory_manager(i);545instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);546instanceHandle ph(THREAD, p);547mgrArray->obj_at_put(i, ph());548}549} else {550// Get memory managers for a given memory pool551for (int i = 0; i < num_mgrs; i++) {552MemoryManager* mgr = pool->get_memory_manager(i);553instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);554instanceHandle ph(THREAD, p);555mgrArray->obj_at_put(i, ph());556}557}558return (jobjectArray) JNIHandles::make_local(THREAD, mgrArray());559JVM_END560561562// Returns a java/lang/management/MemoryUsage object containing the memory usage563// of a given memory pool.564JVM_ENTRY(jobject, jmm_GetMemoryPoolUsage(JNIEnv* env, jobject obj))565ResourceMark rm(THREAD);566567MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);568if (pool != NULL) {569MemoryUsage usage = pool->get_memory_usage();570Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);571return JNIHandles::make_local(THREAD, h());572} else {573return NULL;574}575JVM_END576577// Returns a java/lang/management/MemoryUsage object containing the memory usage578// of a given memory pool.579JVM_ENTRY(jobject, jmm_GetPeakMemoryPoolUsage(JNIEnv* env, jobject obj))580ResourceMark rm(THREAD);581582MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);583if (pool != NULL) {584MemoryUsage usage = pool->get_peak_memory_usage();585Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);586return JNIHandles::make_local(THREAD, h());587} else {588return NULL;589}590JVM_END591592// Returns a java/lang/management/MemoryUsage object containing the memory usage593// of a given memory pool after most recent GC.594JVM_ENTRY(jobject, jmm_GetPoolCollectionUsage(JNIEnv* env, jobject obj))595ResourceMark rm(THREAD);596597MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);598if (pool != NULL && pool->is_collected_pool()) {599MemoryUsage usage = pool->get_last_collection_usage();600Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);601return JNIHandles::make_local(THREAD, h());602} else {603return NULL;604}605JVM_END606607// Sets the memory pool sensor for a threshold type608JVM_ENTRY(void, jmm_SetPoolSensor(JNIEnv* env, jobject obj, jmmThresholdType type, jobject sensorObj))609if (obj == NULL || sensorObj == NULL) {610THROW(vmSymbols::java_lang_NullPointerException());611}612613InstanceKlass* sensor_klass = Management::sun_management_Sensor_klass(CHECK);614oop s = JNIHandles::resolve(sensorObj);615assert(s->is_instance(), "Sensor should be an instanceOop");616instanceHandle sensor_h(THREAD, (instanceOop) s);617if (!sensor_h->is_a(sensor_klass)) {618THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),619"Sensor is not an instance of sun.management.Sensor class");620}621622MemoryPool* mpool = get_memory_pool_from_jobject(obj, CHECK);623assert(mpool != NULL, "MemoryPool should exist");624625switch (type) {626case JMM_USAGE_THRESHOLD_HIGH:627case JMM_USAGE_THRESHOLD_LOW:628// have only one sensor for threshold high and low629mpool->set_usage_sensor_obj(sensor_h);630break;631case JMM_COLLECTION_USAGE_THRESHOLD_HIGH:632case JMM_COLLECTION_USAGE_THRESHOLD_LOW:633// have only one sensor for threshold high and low634mpool->set_gc_usage_sensor_obj(sensor_h);635break;636default:637assert(false, "Unrecognized type");638}639640JVM_END641642643// Sets the threshold of a given memory pool.644// Returns the previous threshold.645//646// Input parameters:647// pool - the MemoryPoolMXBean object648// type - threshold type649// threshold - the new threshold (must not be negative)650//651JVM_ENTRY(jlong, jmm_SetPoolThreshold(JNIEnv* env, jobject obj, jmmThresholdType type, jlong threshold))652if (threshold < 0) {653THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),654"Invalid threshold value",655-1);656}657658if ((size_t)threshold > max_uintx) {659stringStream st;660st.print("Invalid valid threshold value. Threshold value (" JLONG_FORMAT ") > max value of size_t (" UINTX_FORMAT ")", threshold, max_uintx);661THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), st.as_string(), -1);662}663664MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_(0L));665assert(pool != NULL, "MemoryPool should exist");666667jlong prev = 0;668switch (type) {669case JMM_USAGE_THRESHOLD_HIGH:670if (!pool->usage_threshold()->is_high_threshold_supported()) {671return -1;672}673prev = pool->usage_threshold()->set_high_threshold((size_t) threshold);674break;675676case JMM_USAGE_THRESHOLD_LOW:677if (!pool->usage_threshold()->is_low_threshold_supported()) {678return -1;679}680prev = pool->usage_threshold()->set_low_threshold((size_t) threshold);681break;682683case JMM_COLLECTION_USAGE_THRESHOLD_HIGH:684if (!pool->gc_usage_threshold()->is_high_threshold_supported()) {685return -1;686}687// return and the new threshold is effective for the next GC688return pool->gc_usage_threshold()->set_high_threshold((size_t) threshold);689690case JMM_COLLECTION_USAGE_THRESHOLD_LOW:691if (!pool->gc_usage_threshold()->is_low_threshold_supported()) {692return -1;693}694// return and the new threshold is effective for the next GC695return pool->gc_usage_threshold()->set_low_threshold((size_t) threshold);696697default:698assert(false, "Unrecognized type");699return -1;700}701702// When the threshold is changed, reevaluate if the low memory703// detection is enabled.704if (prev != threshold) {705LowMemoryDetector::recompute_enabled_for_collected_pools();706LowMemoryDetector::detect_low_memory(pool);707}708return prev;709JVM_END710711// Returns a java/lang/management/MemoryUsage object representing712// the memory usage for the heap or non-heap memory.713JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))714ResourceMark rm(THREAD);715716MemoryUsage usage;717718if (heap) {719usage = Universe::heap()->memory_usage();720} else {721// Calculate the memory usage by summing up the pools.722size_t total_init = 0;723size_t total_used = 0;724size_t total_committed = 0;725size_t total_max = 0;726bool has_undefined_init_size = false;727bool has_undefined_max_size = false;728729for (int i = 0; i < MemoryService::num_memory_pools(); i++) {730MemoryPool* pool = MemoryService::get_memory_pool(i);731if (pool->is_non_heap()) {732MemoryUsage u = pool->get_memory_usage();733total_used += u.used();734total_committed += u.committed();735736if (u.init_size() == MemoryUsage::undefined_size()) {737has_undefined_init_size = true;738}739if (!has_undefined_init_size) {740total_init += u.init_size();741}742743if (u.max_size() == MemoryUsage::undefined_size()) {744has_undefined_max_size = true;745}746if (!has_undefined_max_size) {747total_max += u.max_size();748}749}750}751752// if any one of the memory pool has undefined init_size or max_size,753// set it to MemoryUsage::undefined_size()754if (has_undefined_init_size) {755total_init = MemoryUsage::undefined_size();756}757if (has_undefined_max_size) {758total_max = MemoryUsage::undefined_size();759}760761usage = MemoryUsage(total_init, total_used, total_committed, total_max);762}763764Handle obj = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);765return JNIHandles::make_local(THREAD, obj());766JVM_END767768// Returns the boolean value of a given attribute.769JVM_LEAF(jboolean, jmm_GetBoolAttribute(JNIEnv *env, jmmBoolAttribute att))770switch (att) {771case JMM_VERBOSE_GC:772return MemoryService::get_verbose();773case JMM_VERBOSE_CLASS:774return ClassLoadingService::get_verbose();775case JMM_THREAD_CONTENTION_MONITORING:776return ThreadService::is_thread_monitoring_contention();777case JMM_THREAD_CPU_TIME:778return ThreadService::is_thread_cpu_time_enabled();779case JMM_THREAD_ALLOCATED_MEMORY:780return ThreadService::is_thread_allocated_memory_enabled();781default:782assert(0, "Unrecognized attribute");783return false;784}785JVM_END786787// Sets the given boolean attribute and returns the previous value.788JVM_ENTRY(jboolean, jmm_SetBoolAttribute(JNIEnv *env, jmmBoolAttribute att, jboolean flag))789switch (att) {790case JMM_VERBOSE_GC:791return MemoryService::set_verbose(flag != 0);792case JMM_VERBOSE_CLASS:793return ClassLoadingService::set_verbose(flag != 0);794case JMM_THREAD_CONTENTION_MONITORING:795return ThreadService::set_thread_monitoring_contention(flag != 0);796case JMM_THREAD_CPU_TIME:797return ThreadService::set_thread_cpu_time_enabled(flag != 0);798case JMM_THREAD_ALLOCATED_MEMORY:799return ThreadService::set_thread_allocated_memory_enabled(flag != 0);800default:801assert(0, "Unrecognized attribute");802return false;803}804JVM_END805806807static jlong get_gc_attribute(GCMemoryManager* mgr, jmmLongAttribute att) {808switch (att) {809case JMM_GC_TIME_MS:810return mgr->gc_time_ms();811812case JMM_GC_COUNT:813return mgr->gc_count();814815case JMM_GC_EXT_ATTRIBUTE_INFO_SIZE:816// current implementation only has 1 ext attribute817return 1;818819default:820assert(0, "Unrecognized GC attribute");821return -1;822}823}824825class VmThreadCountClosure: public ThreadClosure {826private:827int _count;828public:829VmThreadCountClosure() : _count(0) {};830void do_thread(Thread* thread);831int count() { return _count; }832};833834void VmThreadCountClosure::do_thread(Thread* thread) {835// exclude externally visible JavaThreads836if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) {837return;838}839840_count++;841}842843static jint get_vm_thread_count() {844VmThreadCountClosure vmtcc;845{846MutexLocker ml(Threads_lock);847Threads::threads_do(&vmtcc);848}849850return vmtcc.count();851}852853static jint get_num_flags() {854// last flag entry is always NULL, so subtract 1855int nFlags = (int) JVMFlag::numFlags - 1;856int count = 0;857for (int i = 0; i < nFlags; i++) {858JVMFlag* flag = &JVMFlag::flags[i];859// Exclude the locked (diagnostic, experimental) flags860if (flag->is_unlocked() || flag->is_unlocker()) {861count++;862}863}864return count;865}866867static jlong get_long_attribute(jmmLongAttribute att) {868switch (att) {869case JMM_CLASS_LOADED_COUNT:870return ClassLoadingService::loaded_class_count();871872case JMM_CLASS_UNLOADED_COUNT:873return ClassLoadingService::unloaded_class_count();874875case JMM_THREAD_TOTAL_COUNT:876return ThreadService::get_total_thread_count();877878case JMM_THREAD_LIVE_COUNT:879return ThreadService::get_live_thread_count();880881case JMM_THREAD_PEAK_COUNT:882return ThreadService::get_peak_thread_count();883884case JMM_THREAD_DAEMON_COUNT:885return ThreadService::get_daemon_thread_count();886887case JMM_JVM_INIT_DONE_TIME_MS:888return Management::vm_init_done_time();889890case JMM_JVM_UPTIME_MS:891return Management::ticks_to_ms(os::elapsed_counter());892893case JMM_COMPILE_TOTAL_TIME_MS:894return Management::ticks_to_ms(CompileBroker::total_compilation_ticks());895896case JMM_OS_PROCESS_ID:897return os::current_process_id();898899// Hotspot-specific counters900case JMM_CLASS_LOADED_BYTES:901return ClassLoadingService::loaded_class_bytes();902903case JMM_CLASS_UNLOADED_BYTES:904return ClassLoadingService::unloaded_class_bytes();905906case JMM_SHARED_CLASS_LOADED_COUNT:907return ClassLoadingService::loaded_shared_class_count();908909case JMM_SHARED_CLASS_UNLOADED_COUNT:910return ClassLoadingService::unloaded_shared_class_count();911912913case JMM_SHARED_CLASS_LOADED_BYTES:914return ClassLoadingService::loaded_shared_class_bytes();915916case JMM_SHARED_CLASS_UNLOADED_BYTES:917return ClassLoadingService::unloaded_shared_class_bytes();918919case JMM_TOTAL_CLASSLOAD_TIME_MS:920return ClassLoader::classloader_time_ms();921922case JMM_VM_GLOBAL_COUNT:923return get_num_flags();924925case JMM_SAFEPOINT_COUNT:926return RuntimeService::safepoint_count();927928case JMM_TOTAL_SAFEPOINTSYNC_TIME_MS:929return RuntimeService::safepoint_sync_time_ms();930931case JMM_TOTAL_STOPPED_TIME_MS:932return RuntimeService::safepoint_time_ms();933934case JMM_TOTAL_APP_TIME_MS:935return RuntimeService::application_time_ms();936937case JMM_VM_THREAD_COUNT:938return get_vm_thread_count();939940case JMM_CLASS_INIT_TOTAL_COUNT:941return ClassLoader::class_init_count();942943case JMM_CLASS_INIT_TOTAL_TIME_MS:944return ClassLoader::class_init_time_ms();945946case JMM_CLASS_VERIFY_TOTAL_TIME_MS:947return ClassLoader::class_verify_time_ms();948949case JMM_METHOD_DATA_SIZE_BYTES:950return ClassLoadingService::class_method_data_size();951952case JMM_OS_MEM_TOTAL_PHYSICAL_BYTES:953return os::physical_memory();954955default:956return -1;957}958}959960961// Returns the long value of a given attribute.962JVM_ENTRY(jlong, jmm_GetLongAttribute(JNIEnv *env, jobject obj, jmmLongAttribute att))963if (obj == NULL) {964return get_long_attribute(att);965} else {966GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK_(0L));967if (mgr != NULL) {968return get_gc_attribute(mgr, att);969}970}971return -1;972JVM_END973974// Gets the value of all attributes specified in the given array975// and sets the value in the result array.976// Returns the number of attributes found.977JVM_ENTRY(jint, jmm_GetLongAttributes(JNIEnv *env,978jobject obj,979jmmLongAttribute* atts,980jint count,981jlong* result))982983int num_atts = 0;984if (obj == NULL) {985for (int i = 0; i < count; i++) {986result[i] = get_long_attribute(atts[i]);987if (result[i] != -1) {988num_atts++;989}990}991} else {992GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK_0);993for (int i = 0; i < count; i++) {994result[i] = get_gc_attribute(mgr, atts[i]);995if (result[i] != -1) {996num_atts++;997}998}999}1000return num_atts;1001JVM_END10021003// Helper function to do thread dump for a specific list of threads1004static void do_thread_dump(ThreadDumpResult* dump_result,1005typeArrayHandle ids_ah, // array of thread ID (long[])1006int num_threads,1007int max_depth,1008bool with_locked_monitors,1009bool with_locked_synchronizers,1010TRAPS) {1011// no need to actually perform thread dump if no TIDs are specified1012if (num_threads == 0) return;10131014// First get an array of threadObj handles.1015// A JavaThread may terminate before we get the stack trace.1016GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);10171018{1019// Need this ThreadsListHandle for converting Java thread IDs into1020// threadObj handles; dump_result->set_t_list() is called in the1021// VM op below so we can't use it yet.1022ThreadsListHandle tlh;1023for (int i = 0; i < num_threads; i++) {1024jlong tid = ids_ah->long_at(i);1025JavaThread* jt = tlh.list()->find_JavaThread_from_java_tid(tid);1026oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);1027instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);1028thread_handle_array->append(threadObj_h);1029}1030}10311032// Obtain thread dumps and thread snapshot information1033VM_ThreadDump op(dump_result,1034thread_handle_array,1035num_threads,1036max_depth, /* stack depth */1037with_locked_monitors,1038with_locked_synchronizers);1039VMThread::execute(&op);1040}10411042// Gets an array of ThreadInfo objects. Each element is the ThreadInfo1043// for the thread ID specified in the corresponding entry in1044// the given array of thread IDs; or NULL if the thread does not exist1045// or has terminated.1046//1047// Input parameters:1048// ids - array of thread IDs1049// maxDepth - the maximum depth of stack traces to be dumped:1050// maxDepth == -1 requests to dump entire stack trace.1051// maxDepth == 0 requests no stack trace.1052// infoArray - array of ThreadInfo objects1053//1054// QQQ - Why does this method return a value instead of void?1055JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray))1056// Check if threads is null1057if (ids == NULL || infoArray == NULL) {1058THROW_(vmSymbols::java_lang_NullPointerException(), -1);1059}10601061if (maxDepth < -1) {1062THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),1063"Invalid maxDepth", -1);1064}10651066ResourceMark rm(THREAD);1067typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));1068typeArrayHandle ids_ah(THREAD, ta);10691070oop infoArray_obj = JNIHandles::resolve_non_null(infoArray);1071objArrayOop oa = objArrayOop(infoArray_obj);1072objArrayHandle infoArray_h(THREAD, oa);10731074// validate the thread id array1075validate_thread_id_array(ids_ah, CHECK_0);10761077// validate the ThreadInfo[] parameters1078validate_thread_info_array(infoArray_h, CHECK_0);10791080// infoArray must be of the same length as the given array of thread IDs1081int num_threads = ids_ah->length();1082if (num_threads != infoArray_h->length()) {1083THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),1084"The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);1085}10861087// Must use ThreadDumpResult to store the ThreadSnapshot.1088// GC may occur after the thread snapshots are taken but before1089// this function returns. The threadObj and other oops kept1090// in the ThreadSnapshot are marked and adjusted during GC.1091ThreadDumpResult dump_result(num_threads);10921093if (maxDepth == 0) {1094// No stack trace to dump so we do not need to stop the world.1095// Since we never do the VM op here we must set the threads list.1096dump_result.set_t_list();1097for (int i = 0; i < num_threads; i++) {1098jlong tid = ids_ah->long_at(i);1099JavaThread* jt = dump_result.t_list()->find_JavaThread_from_java_tid(tid);1100if (jt == NULL) {1101// if the thread does not exist or now it is terminated,1102// create dummy snapshot1103dump_result.add_thread_snapshot();1104} else {1105dump_result.add_thread_snapshot(jt);1106}1107}1108} else {1109// obtain thread dump with the specific list of threads with stack trace1110do_thread_dump(&dump_result,1111ids_ah,1112num_threads,1113maxDepth,1114false, /* no locked monitor */1115false, /* no locked synchronizers */1116CHECK_0);1117}11181119int num_snapshots = dump_result.num_snapshots();1120assert(num_snapshots == num_threads, "Must match the number of thread snapshots");1121assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");1122int index = 0;1123for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; index++, ts = ts->next()) {1124// For each thread, create an java/lang/management/ThreadInfo object1125// and fill with the thread information11261127if (ts->threadObj() == NULL) {1128// if the thread does not exist or now it is terminated, set threadinfo to NULL1129infoArray_h->obj_at_put(index, NULL);1130continue;1131}11321133// Create java.lang.management.ThreadInfo object1134instanceOop info_obj = Management::create_thread_info_instance(ts, CHECK_0);1135infoArray_h->obj_at_put(index, info_obj);1136}1137return 0;1138JVM_END11391140// Dump thread info for the specified threads.1141// It returns an array of ThreadInfo objects. Each element is the ThreadInfo1142// for the thread ID specified in the corresponding entry in1143// the given array of thread IDs; or NULL if the thread does not exist1144// or has terminated.1145//1146// Input parameter:1147// ids - array of thread IDs; NULL indicates all live threads1148// locked_monitors - if true, dump locked object monitors1149// locked_synchronizers - if true, dump locked JSR-166 synchronizers1150//1151JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors,1152jboolean locked_synchronizers, jint maxDepth))1153ResourceMark rm(THREAD);11541155typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));1156int num_threads = (ta != NULL ? ta->length() : 0);1157typeArrayHandle ids_ah(THREAD, ta);11581159ThreadDumpResult dump_result(num_threads); // can safepoint11601161if (ids_ah() != NULL) {11621163// validate the thread id array1164validate_thread_id_array(ids_ah, CHECK_NULL);11651166// obtain thread dump of a specific list of threads1167do_thread_dump(&dump_result,1168ids_ah,1169num_threads,1170maxDepth, /* stack depth */1171(locked_monitors ? true : false), /* with locked monitors */1172(locked_synchronizers ? true : false), /* with locked synchronizers */1173CHECK_NULL);1174} else {1175// obtain thread dump of all threads1176VM_ThreadDump op(&dump_result,1177maxDepth, /* stack depth */1178(locked_monitors ? true : false), /* with locked monitors */1179(locked_synchronizers ? true : false) /* with locked synchronizers */);1180VMThread::execute(&op);1181}11821183int num_snapshots = dump_result.num_snapshots();1184assert(num_snapshots == 0 || dump_result.t_list_has_been_set(), "ThreadsList must have been set if we have a snapshot");11851186// create the result ThreadInfo[] object1187InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);1188objArrayOop r = oopFactory::new_objArray(ik, num_snapshots, CHECK_NULL);1189objArrayHandle result_h(THREAD, r);11901191int index = 0;1192for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {1193if (ts->threadObj() == NULL) {1194// if the thread does not exist or now it is terminated, set threadinfo to NULL1195result_h->obj_at_put(index, NULL);1196continue;1197}11981199ThreadStackTrace* stacktrace = ts->get_stack_trace();1200assert(stacktrace != NULL, "Must have a stack trace dumped");12011202// Create Object[] filled with locked monitors1203// Create int[] filled with the stack depth where a monitor was locked1204int num_frames = stacktrace->get_stack_depth();1205int num_locked_monitors = stacktrace->num_jni_locked_monitors();12061207// Count the total number of locked monitors1208for (int i = 0; i < num_frames; i++) {1209StackFrameInfo* frame = stacktrace->stack_frame_at(i);1210num_locked_monitors += frame->num_locked_monitors();1211}12121213objArrayHandle monitors_array;1214typeArrayHandle depths_array;1215objArrayHandle synchronizers_array;12161217if (locked_monitors) {1218// Constructs Object[] and int[] to contain the object monitor and the stack depth1219// where the thread locked it1220objArrayOop array = oopFactory::new_objArray(vmClasses::Object_klass(), num_locked_monitors, CHECK_NULL);1221objArrayHandle mh(THREAD, array);1222monitors_array = mh;12231224typeArrayOop tarray = oopFactory::new_typeArray(T_INT, num_locked_monitors, CHECK_NULL);1225typeArrayHandle dh(THREAD, tarray);1226depths_array = dh;12271228int count = 0;1229int j = 0;1230for (int depth = 0; depth < num_frames; depth++) {1231StackFrameInfo* frame = stacktrace->stack_frame_at(depth);1232int len = frame->num_locked_monitors();1233GrowableArray<OopHandle>* locked_monitors = frame->locked_monitors();1234for (j = 0; j < len; j++) {1235oop monitor = locked_monitors->at(j).resolve();1236assert(monitor != NULL, "must be a Java object");1237monitors_array->obj_at_put(count, monitor);1238depths_array->int_at_put(count, depth);1239count++;1240}1241}12421243GrowableArray<OopHandle>* jni_locked_monitors = stacktrace->jni_locked_monitors();1244for (j = 0; j < jni_locked_monitors->length(); j++) {1245oop object = jni_locked_monitors->at(j).resolve();1246assert(object != NULL, "must be a Java object");1247monitors_array->obj_at_put(count, object);1248// Monitor locked via JNI MonitorEnter call doesn't have stack depth info1249depths_array->int_at_put(count, -1);1250count++;1251}1252assert(count == num_locked_monitors, "number of locked monitors doesn't match");1253}12541255if (locked_synchronizers) {1256// Create Object[] filled with locked JSR-166 synchronizers1257assert(ts->threadObj() != NULL, "Must be a valid JavaThread");1258ThreadConcurrentLocks* tcl = ts->get_concurrent_locks();1259GrowableArray<OopHandle>* locks = (tcl != NULL ? tcl->owned_locks() : NULL);1260int num_locked_synchronizers = (locks != NULL ? locks->length() : 0);12611262objArrayOop array = oopFactory::new_objArray(vmClasses::Object_klass(), num_locked_synchronizers, CHECK_NULL);1263objArrayHandle sh(THREAD, array);1264synchronizers_array = sh;12651266for (int k = 0; k < num_locked_synchronizers; k++) {1267synchronizers_array->obj_at_put(k, locks->at(k).resolve());1268}1269}12701271// Create java.lang.management.ThreadInfo object1272instanceOop info_obj = Management::create_thread_info_instance(ts,1273monitors_array,1274depths_array,1275synchronizers_array,1276CHECK_NULL);1277result_h->obj_at_put(index, info_obj);1278}12791280return (jobjectArray) JNIHandles::make_local(THREAD, result_h());1281JVM_END12821283// Reset statistic. Return true if the requested statistic is reset.1284// Otherwise, return false.1285//1286// Input parameters:1287// obj - specify which instance the statistic associated with to be reset1288// For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.1289// For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.1290// type - the type of statistic to be reset1291//1292JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))1293ResourceMark rm(THREAD);12941295switch (type) {1296case JMM_STAT_PEAK_THREAD_COUNT:1297ThreadService::reset_peak_thread_count();1298return true;12991300case JMM_STAT_THREAD_CONTENTION_COUNT:1301case JMM_STAT_THREAD_CONTENTION_TIME: {1302jlong tid = obj.j;1303if (tid < 0) {1304THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);1305}13061307// Look for the JavaThread of this given tid1308JavaThreadIteratorWithHandle jtiwh;1309if (tid == 0) {1310// reset contention statistics for all threads if tid == 01311for (; JavaThread *java_thread = jtiwh.next(); ) {1312if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {1313ThreadService::reset_contention_count_stat(java_thread);1314} else {1315ThreadService::reset_contention_time_stat(java_thread);1316}1317}1318} else {1319// reset contention statistics for a given thread1320JavaThread* java_thread = jtiwh.list()->find_JavaThread_from_java_tid(tid);1321if (java_thread == NULL) {1322return false;1323}13241325if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {1326ThreadService::reset_contention_count_stat(java_thread);1327} else {1328ThreadService::reset_contention_time_stat(java_thread);1329}1330}1331return true;1332break;1333}1334case JMM_STAT_PEAK_POOL_USAGE: {1335jobject o = obj.l;1336if (o == NULL) {1337THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);1338}13391340oop pool_obj = JNIHandles::resolve(o);1341assert(pool_obj->is_instance(), "Should be an instanceOop");1342instanceHandle ph(THREAD, (instanceOop) pool_obj);13431344MemoryPool* pool = MemoryService::get_memory_pool(ph);1345if (pool != NULL) {1346pool->reset_peak_memory_usage();1347return true;1348}1349break;1350}1351case JMM_STAT_GC_STAT: {1352jobject o = obj.l;1353if (o == NULL) {1354THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);1355}13561357GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(o, CHECK_false);1358if (mgr != NULL) {1359mgr->reset_gc_stat();1360return true;1361}1362break;1363}1364default:1365assert(0, "Unknown Statistic Type");1366}1367return false;1368JVM_END13691370// Returns the fast estimate of CPU time consumed by1371// a given thread (in nanoseconds).1372// If thread_id == 0, return CPU time for the current thread.1373JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))1374if (!os::is_thread_cpu_time_supported()) {1375return -1;1376}13771378if (thread_id < 0) {1379THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),1380"Invalid thread ID", -1);1381}13821383JavaThread* java_thread = NULL;1384if (thread_id == 0) {1385// current thread1386return os::current_thread_cpu_time();1387} else {1388ThreadsListHandle tlh;1389java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);1390if (java_thread != NULL) {1391return os::thread_cpu_time((Thread*) java_thread);1392}1393}1394return -1;1395JVM_END13961397// Returns a String array of all VM global flag names1398JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))1399// last flag entry is always NULL, so subtract 11400int nFlags = (int) JVMFlag::numFlags - 1;1401// allocate a temp array1402objArrayOop r = oopFactory::new_objArray(vmClasses::String_klass(),1403nFlags, CHECK_NULL);1404objArrayHandle flags_ah(THREAD, r);1405int num_entries = 0;1406for (int i = 0; i < nFlags; i++) {1407JVMFlag* flag = &JVMFlag::flags[i];1408// Exclude notproduct and develop flags in product builds.1409if (flag->is_constant_in_binary()) {1410continue;1411}1412// Exclude the locked (experimental, diagnostic) flags1413if (flag->is_unlocked() || flag->is_unlocker()) {1414Handle s = java_lang_String::create_from_str(flag->name(), CHECK_NULL);1415flags_ah->obj_at_put(num_entries, s());1416num_entries++;1417}1418}14191420if (num_entries < nFlags) {1421// Return array of right length1422objArrayOop res = oopFactory::new_objArray(vmClasses::String_klass(), num_entries, CHECK_NULL);1423for(int i = 0; i < num_entries; i++) {1424res->obj_at_put(i, flags_ah->obj_at(i));1425}1426return (jobjectArray)JNIHandles::make_local(THREAD, res);1427}14281429return (jobjectArray)JNIHandles::make_local(THREAD, flags_ah());1430JVM_END14311432// Utility function used by jmm_GetVMGlobals. Returns false if flag type1433// can't be determined, true otherwise. If false is returned, then *global1434// will be incomplete and invalid.1435bool add_global_entry(Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) {1436Handle flag_name;1437if (name() == NULL) {1438flag_name = java_lang_String::create_from_str(flag->name(), CHECK_false);1439} else {1440flag_name = name;1441}1442global->name = (jstring)JNIHandles::make_local(THREAD, flag_name());14431444if (flag->is_bool()) {1445global->value.z = flag->get_bool() ? JNI_TRUE : JNI_FALSE;1446global->type = JMM_VMGLOBAL_TYPE_JBOOLEAN;1447} else if (flag->is_int()) {1448global->value.j = (jlong)flag->get_int();1449global->type = JMM_VMGLOBAL_TYPE_JLONG;1450} else if (flag->is_uint()) {1451global->value.j = (jlong)flag->get_uint();1452global->type = JMM_VMGLOBAL_TYPE_JLONG;1453} else if (flag->is_intx()) {1454global->value.j = (jlong)flag->get_intx();1455global->type = JMM_VMGLOBAL_TYPE_JLONG;1456} else if (flag->is_uintx()) {1457global->value.j = (jlong)flag->get_uintx();1458global->type = JMM_VMGLOBAL_TYPE_JLONG;1459} else if (flag->is_uint64_t()) {1460global->value.j = (jlong)flag->get_uint64_t();1461global->type = JMM_VMGLOBAL_TYPE_JLONG;1462} else if (flag->is_double()) {1463global->value.d = (jdouble)flag->get_double();1464global->type = JMM_VMGLOBAL_TYPE_JDOUBLE;1465} else if (flag->is_size_t()) {1466global->value.j = (jlong)flag->get_size_t();1467global->type = JMM_VMGLOBAL_TYPE_JLONG;1468} else if (flag->is_ccstr()) {1469Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false);1470global->value.l = (jobject)JNIHandles::make_local(THREAD, str());1471global->type = JMM_VMGLOBAL_TYPE_JSTRING;1472} else {1473global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;1474return false;1475}14761477global->writeable = flag->is_writeable();1478global->external = flag->is_external();1479switch (flag->get_origin()) {1480case JVMFlagOrigin::DEFAULT:1481global->origin = JMM_VMGLOBAL_ORIGIN_DEFAULT;1482break;1483case JVMFlagOrigin::COMMAND_LINE:1484global->origin = JMM_VMGLOBAL_ORIGIN_COMMAND_LINE;1485break;1486case JVMFlagOrigin::ENVIRON_VAR:1487global->origin = JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR;1488break;1489case JVMFlagOrigin::CONFIG_FILE:1490global->origin = JMM_VMGLOBAL_ORIGIN_CONFIG_FILE;1491break;1492case JVMFlagOrigin::MANAGEMENT:1493global->origin = JMM_VMGLOBAL_ORIGIN_MANAGEMENT;1494break;1495case JVMFlagOrigin::ERGONOMIC:1496global->origin = JMM_VMGLOBAL_ORIGIN_ERGONOMIC;1497break;1498case JVMFlagOrigin::ATTACH_ON_DEMAND:1499global->origin = JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND;1500break;1501default:1502global->origin = JMM_VMGLOBAL_ORIGIN_OTHER;1503}15041505return true;1506}15071508// Fill globals array of count length with jmmVMGlobal entries1509// specified by names. If names == NULL, fill globals array1510// with all Flags. Return value is number of entries1511// created in globals.1512// If a JVMFlag with a given name in an array element does not1513// exist, globals[i].name will be set to NULL.1514JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env,1515jobjectArray names,1516jmmVMGlobal *globals,1517jint count))151815191520if (globals == NULL) {1521THROW_(vmSymbols::java_lang_NullPointerException(), 0);1522}15231524ResourceMark rm(THREAD);15251526if (names != NULL) {1527// return the requested globals1528objArrayOop ta = objArrayOop(JNIHandles::resolve_non_null(names));1529objArrayHandle names_ah(THREAD, ta);1530// Make sure we have a String array1531Klass* element_klass = ObjArrayKlass::cast(names_ah->klass())->element_klass();1532if (element_klass != vmClasses::String_klass()) {1533THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),1534"Array element type is not String class", 0);1535}15361537int names_length = names_ah->length();1538int num_entries = 0;1539for (int i = 0; i < names_length && i < count; i++) {1540oop s = names_ah->obj_at(i);1541if (s == NULL) {1542THROW_(vmSymbols::java_lang_NullPointerException(), 0);1543}15441545Handle sh(THREAD, s);1546char* str = java_lang_String::as_utf8_string(s);1547JVMFlag* flag = JVMFlag::find_flag(str);1548if (flag != NULL &&1549add_global_entry(sh, &globals[i], flag, THREAD)) {1550num_entries++;1551} else {1552globals[i].name = NULL;1553}1554}1555return num_entries;1556} else {1557// return all globals if names == NULL15581559// last flag entry is always NULL, so subtract 11560int nFlags = (int) JVMFlag::numFlags - 1;1561Handle null_h;1562int num_entries = 0;1563for (int i = 0; i < nFlags && num_entries < count; i++) {1564JVMFlag* flag = &JVMFlag::flags[i];1565// Exclude notproduct and develop flags in product builds.1566if (flag->is_constant_in_binary()) {1567continue;1568}1569// Exclude the locked (diagnostic, experimental) flags1570if ((flag->is_unlocked() || flag->is_unlocker()) &&1571add_global_entry(null_h, &globals[num_entries], flag, THREAD)) {1572num_entries++;1573}1574}1575return num_entries;1576}1577JVM_END15781579JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value))1580ResourceMark rm(THREAD);15811582oop fn = JNIHandles::resolve_external_guard(flag_name);1583if (fn == NULL) {1584THROW_MSG(vmSymbols::java_lang_NullPointerException(),1585"The flag name cannot be null.");1586}1587char* name = java_lang_String::as_utf8_string(fn);15881589FormatBuffer<80> error_msg("%s", "");1590int succeed = WriteableFlags::set_flag(name, new_value, JVMFlagOrigin::MANAGEMENT, error_msg);15911592if (succeed != JVMFlag::SUCCESS) {1593if (succeed == JVMFlag::MISSING_VALUE) {1594// missing value causes NPE to be thrown1595THROW(vmSymbols::java_lang_NullPointerException());1596} else {1597// all the other errors are reported as IAE with the appropriate error message1598THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),1599error_msg.buffer());1600}1601}1602assert(succeed == JVMFlag::SUCCESS, "Setting flag should succeed");1603JVM_END16041605class ThreadTimesClosure: public ThreadClosure {1606private:1607objArrayHandle _names_strings;1608char **_names_chars;1609typeArrayHandle _times;1610int _names_len;1611int _times_len;1612int _count;16131614public:1615ThreadTimesClosure(objArrayHandle names, typeArrayHandle times);1616~ThreadTimesClosure();1617virtual void do_thread(Thread* thread);1618void do_unlocked(TRAPS);1619int count() { return _count; }1620};16211622ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,1623typeArrayHandle times) {1624assert(names() != NULL, "names was NULL");1625assert(times() != NULL, "times was NULL");1626_names_strings = names;1627_names_len = names->length();1628_names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);1629_times = times;1630_times_len = times->length();1631_count = 0;1632}16331634//1635// Called with Threads_lock held1636//1637void ThreadTimesClosure::do_thread(Thread* thread) {1638assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");1639assert(thread != NULL, "thread was NULL");16401641// exclude externally visible JavaThreads1642if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) {1643return;1644}16451646if (_count >= _names_len || _count >= _times_len) {1647// skip if the result array is not big enough1648return;1649}16501651ResourceMark rm; // thread->name() uses ResourceArea16521653assert(thread->name() != NULL, "All threads should have a name");1654_names_chars[_count] = os::strdup_check_oom(thread->name());1655_times->long_at_put(_count, os::is_thread_cpu_time_supported() ?1656os::thread_cpu_time(thread) : -1);1657_count++;1658}16591660// Called without Threads_lock, we can allocate String objects.1661void ThreadTimesClosure::do_unlocked(TRAPS) {16621663for (int i = 0; i < _count; i++) {1664Handle s = java_lang_String::create_from_str(_names_chars[i], CHECK);1665_names_strings->obj_at_put(i, s());1666}1667}16681669ThreadTimesClosure::~ThreadTimesClosure() {1670for (int i = 0; i < _count; i++) {1671os::free(_names_chars[i]);1672}1673FREE_C_HEAP_ARRAY(char *, _names_chars);1674}16751676// Fills names with VM internal thread names and times with the corresponding1677// CPU times. If names or times is NULL, a NullPointerException is thrown.1678// If the element type of names is not String, an IllegalArgumentException is1679// thrown.1680// If an array is not large enough to hold all the entries, only the entries1681// that fit will be returned. Return value is the number of VM internal1682// threads entries.1683JVM_ENTRY(jint, jmm_GetInternalThreadTimes(JNIEnv *env,1684jobjectArray names,1685jlongArray times))1686if (names == NULL || times == NULL) {1687THROW_(vmSymbols::java_lang_NullPointerException(), 0);1688}1689objArrayOop na = objArrayOop(JNIHandles::resolve_non_null(names));1690objArrayHandle names_ah(THREAD, na);16911692// Make sure we have a String array1693Klass* element_klass = ObjArrayKlass::cast(names_ah->klass())->element_klass();1694if (element_klass != vmClasses::String_klass()) {1695THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),1696"Array element type is not String class", 0);1697}16981699typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times));1700typeArrayHandle times_ah(THREAD, ta);17011702ThreadTimesClosure ttc(names_ah, times_ah);1703{1704MutexLocker ml(THREAD, Threads_lock);1705Threads::threads_do(&ttc);1706}1707ttc.do_unlocked(THREAD);1708return ttc.count();1709JVM_END17101711static Handle find_deadlocks(bool object_monitors_only, TRAPS) {1712ResourceMark rm(THREAD);17131714VM_FindDeadlocks op(!object_monitors_only /* also check concurrent locks? */);1715VMThread::execute(&op);17161717DeadlockCycle* deadlocks = op.result();1718if (deadlocks == NULL) {1719// no deadlock found and return1720return Handle();1721}17221723int num_threads = 0;1724DeadlockCycle* cycle;1725for (cycle = deadlocks; cycle != NULL; cycle = cycle->next()) {1726num_threads += cycle->num_threads();1727}17281729objArrayOop r = oopFactory::new_objArray(vmClasses::Thread_klass(), num_threads, CHECK_NH);1730objArrayHandle threads_ah(THREAD, r);17311732int index = 0;1733for (cycle = deadlocks; cycle != NULL; cycle = cycle->next()) {1734GrowableArray<JavaThread*>* deadlock_threads = cycle->threads();1735int len = deadlock_threads->length();1736for (int i = 0; i < len; i++) {1737threads_ah->obj_at_put(index, deadlock_threads->at(i)->threadObj());1738index++;1739}1740}1741return threads_ah;1742}17431744// Finds cycles of threads that are deadlocked involved in object monitors1745// and JSR-166 synchronizers.1746// Returns an array of Thread objects which are in deadlock, if any.1747// Otherwise, returns NULL.1748//1749// Input parameter:1750// object_monitors_only - if true, only check object monitors1751//1752JVM_ENTRY(jobjectArray, jmm_FindDeadlockedThreads(JNIEnv *env, jboolean object_monitors_only))1753Handle result = find_deadlocks(object_monitors_only != 0, CHECK_NULL);1754return (jobjectArray) JNIHandles::make_local(THREAD, result());1755JVM_END17561757// Finds cycles of threads that are deadlocked on monitor locks1758// Returns an array of Thread objects which are in deadlock, if any.1759// Otherwise, returns NULL.1760JVM_ENTRY(jobjectArray, jmm_FindMonitorDeadlockedThreads(JNIEnv *env))1761Handle result = find_deadlocks(true, CHECK_NULL);1762return (jobjectArray) JNIHandles::make_local(THREAD, result());1763JVM_END17641765// Gets the information about GC extension attributes including1766// the name of the attribute, its type, and a short description.1767//1768// Input parameters:1769// mgr - GC memory manager1770// info - caller allocated array of jmmExtAttributeInfo1771// count - number of elements of the info array1772//1773// Returns the number of GC extension attributes filled in the info array; or1774// -1 if info is not big enough1775//1776JVM_ENTRY(jint, jmm_GetGCExtAttributeInfo(JNIEnv *env, jobject mgr, jmmExtAttributeInfo* info, jint count))1777// All GC memory managers have 1 attribute (number of GC threads)1778if (count == 0) {1779return 0;1780}17811782if (info == NULL) {1783THROW_(vmSymbols::java_lang_NullPointerException(), 0);1784}17851786info[0].name = "GcThreadCount";1787info[0].type = 'I';1788info[0].description = "Number of GC threads";1789return 1;1790JVM_END17911792// verify the given array is an array of java/lang/management/MemoryUsage objects1793// of a given length and return the objArrayOop1794static objArrayOop get_memory_usage_objArray(jobjectArray array, int length, TRAPS) {1795if (array == NULL) {1796THROW_(vmSymbols::java_lang_NullPointerException(), 0);1797}17981799objArrayOop oa = objArrayOop(JNIHandles::resolve_non_null(array));1800objArrayHandle array_h(THREAD, oa);18011802// array must be of the given length1803if (length != array_h->length()) {1804THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),1805"The length of the given MemoryUsage array does not match the number of memory pools.", 0);1806}18071808// check if the element of array is of type MemoryUsage class1809Klass* usage_klass = Management::java_lang_management_MemoryUsage_klass(CHECK_NULL);1810Klass* element_klass = ObjArrayKlass::cast(array_h->klass())->element_klass();1811if (element_klass != usage_klass) {1812THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),1813"The element type is not MemoryUsage class", 0);1814}18151816return array_h();1817}18181819// Gets the statistics of the last GC of a given GC memory manager.1820// Input parameters:1821// obj - GarbageCollectorMXBean object1822// gc_stat - caller allocated jmmGCStat where:1823// a. before_gc_usage - array of MemoryUsage objects1824// b. after_gc_usage - array of MemoryUsage objects1825// c. gc_ext_attributes_values_size is set to the1826// gc_ext_attribute_values array allocated1827// d. gc_ext_attribute_values is a caller allocated array of jvalue.1828//1829// On return,1830// gc_index == 0 indicates no GC statistics available1831//1832// before_gc_usage and after_gc_usage - filled with per memory pool1833// before and after GC usage in the same order as the memory pools1834// returned by GetMemoryPools for a given GC memory manager.1835// num_gc_ext_attributes indicates the number of elements in1836// the gc_ext_attribute_values array is filled; or1837// -1 if the gc_ext_attributes_values array is not big enough1838//1839JVM_ENTRY(void, jmm_GetLastGCStat(JNIEnv *env, jobject obj, jmmGCStat *gc_stat))1840ResourceMark rm(THREAD);18411842if (gc_stat->gc_ext_attribute_values_size > 0 && gc_stat->gc_ext_attribute_values == NULL) {1843THROW(vmSymbols::java_lang_NullPointerException());1844}18451846// Get the GCMemoryManager1847GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK);18481849// Make a copy of the last GC statistics1850// GC may occur while constructing the last GC information1851int num_pools = MemoryService::num_memory_pools();1852GCStatInfo stat(num_pools);1853if (mgr->get_last_gc_stat(&stat) == 0) {1854gc_stat->gc_index = 0;1855return;1856}18571858gc_stat->gc_index = stat.gc_index();1859gc_stat->start_time = Management::ticks_to_ms(stat.start_time());1860gc_stat->end_time = Management::ticks_to_ms(stat.end_time());18611862// Current implementation does not have GC extension attributes1863gc_stat->num_gc_ext_attributes = 0;18641865// Fill the arrays of MemoryUsage objects with before and after GC1866// per pool memory usage1867objArrayOop bu = get_memory_usage_objArray(gc_stat->usage_before_gc,1868num_pools,1869CHECK);1870objArrayHandle usage_before_gc_ah(THREAD, bu);18711872objArrayOop au = get_memory_usage_objArray(gc_stat->usage_after_gc,1873num_pools,1874CHECK);1875objArrayHandle usage_after_gc_ah(THREAD, au);18761877for (int i = 0; i < num_pools; i++) {1878Handle before_usage = MemoryService::create_MemoryUsage_obj(stat.before_gc_usage_for_pool(i), CHECK);1879Handle after_usage;18801881MemoryUsage u = stat.after_gc_usage_for_pool(i);1882if (u.max_size() == 0 && u.used() > 0) {1883// If max size == 0, this pool is a survivor space.1884// Set max size = -1 since the pools will be swapped after GC.1885MemoryUsage usage(u.init_size(), u.used(), u.committed(), (size_t)-1);1886after_usage = MemoryService::create_MemoryUsage_obj(usage, CHECK);1887} else {1888after_usage = MemoryService::create_MemoryUsage_obj(stat.after_gc_usage_for_pool(i), CHECK);1889}1890usage_before_gc_ah->obj_at_put(i, before_usage());1891usage_after_gc_ah->obj_at_put(i, after_usage());1892}18931894if (gc_stat->gc_ext_attribute_values_size > 0) {1895// Current implementation only has 1 attribute (number of GC threads)1896// The type is 'I'1897gc_stat->gc_ext_attribute_values[0].i = mgr->num_gc_threads();1898}1899JVM_END19001901JVM_ENTRY(void, jmm_SetGCNotificationEnabled(JNIEnv *env, jobject obj, jboolean enabled))1902ResourceMark rm(THREAD);1903// Get the GCMemoryManager1904GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK);1905mgr->set_notification_enabled(enabled?true:false);1906JVM_END19071908// Dump heap - Returns 0 if succeeds.1909JVM_ENTRY(jint, jmm_DumpHeap0(JNIEnv *env, jstring outputfile, jboolean live))1910#if INCLUDE_SERVICES1911ResourceMark rm(THREAD);1912oop on = JNIHandles::resolve_external_guard(outputfile);1913if (on == NULL) {1914THROW_MSG_(vmSymbols::java_lang_NullPointerException(),1915"Output file name cannot be null.", -1);1916}1917Handle onhandle(THREAD, on);1918char* name = java_lang_String::as_platform_dependent_str(onhandle, CHECK_(-1));1919if (name == NULL) {1920THROW_MSG_(vmSymbols::java_lang_NullPointerException(),1921"Output file name cannot be null.", -1);1922}1923HeapDumper dumper(live ? true : false);1924if (dumper.dump(name) != 0) {1925const char* errmsg = dumper.error_as_C_string();1926THROW_MSG_(vmSymbols::java_io_IOException(), errmsg, -1);1927}1928return 0;1929#else // INCLUDE_SERVICES1930return -1;1931#endif // INCLUDE_SERVICES1932JVM_END19331934JVM_ENTRY(jobjectArray, jmm_GetDiagnosticCommands(JNIEnv *env))1935ResourceMark rm(THREAD);1936GrowableArray<const char *>* dcmd_list = DCmdFactory::DCmd_list(DCmd_Source_MBean);1937objArrayOop cmd_array_oop = oopFactory::new_objArray(vmClasses::String_klass(),1938dcmd_list->length(), CHECK_NULL);1939objArrayHandle cmd_array(THREAD, cmd_array_oop);1940for (int i = 0; i < dcmd_list->length(); i++) {1941oop cmd_name = java_lang_String::create_oop_from_str(dcmd_list->at(i), CHECK_NULL);1942cmd_array->obj_at_put(i, cmd_name);1943}1944return (jobjectArray) JNIHandles::make_local(THREAD, cmd_array());1945JVM_END19461947JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds,1948dcmdInfo* infoArray))1949if (cmds == NULL || infoArray == NULL) {1950THROW(vmSymbols::java_lang_NullPointerException());1951}19521953ResourceMark rm(THREAD);19541955objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(cmds));1956objArrayHandle cmds_ah(THREAD, ca);19571958// Make sure we have a String array1959Klass* element_klass = ObjArrayKlass::cast(cmds_ah->klass())->element_klass();1960if (element_klass != vmClasses::String_klass()) {1961THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),1962"Array element type is not String class");1963}19641965GrowableArray<DCmdInfo *>* info_list = DCmdFactory::DCmdInfo_list(DCmd_Source_MBean);19661967int num_cmds = cmds_ah->length();1968for (int i = 0; i < num_cmds; i++) {1969oop cmd = cmds_ah->obj_at(i);1970if (cmd == NULL) {1971THROW_MSG(vmSymbols::java_lang_NullPointerException(),1972"Command name cannot be null.");1973}1974char* cmd_name = java_lang_String::as_utf8_string(cmd);1975if (cmd_name == NULL) {1976THROW_MSG(vmSymbols::java_lang_NullPointerException(),1977"Command name cannot be null.");1978}1979int pos = info_list->find((void*)cmd_name,DCmdInfo::by_name);1980if (pos == -1) {1981THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),1982"Unknown diagnostic command");1983}1984DCmdInfo* info = info_list->at(pos);1985infoArray[i].name = info->name();1986infoArray[i].description = info->description();1987infoArray[i].impact = info->impact();1988JavaPermission p = info->permission();1989infoArray[i].permission_class = p._class;1990infoArray[i].permission_name = p._name;1991infoArray[i].permission_action = p._action;1992infoArray[i].num_arguments = info->num_arguments();1993infoArray[i].enabled = info->is_enabled();1994}1995JVM_END19961997JVM_ENTRY(void, jmm_GetDiagnosticCommandArgumentsInfo(JNIEnv *env,1998jstring command, dcmdArgInfo* infoArray))1999ResourceMark rm(THREAD);2000oop cmd = JNIHandles::resolve_external_guard(command);2001if (cmd == NULL) {2002THROW_MSG(vmSymbols::java_lang_NullPointerException(),2003"Command line cannot be null.");2004}2005char* cmd_name = java_lang_String::as_utf8_string(cmd);2006if (cmd_name == NULL) {2007THROW_MSG(vmSymbols::java_lang_NullPointerException(),2008"Command line content cannot be null.");2009}2010DCmd* dcmd = NULL;2011DCmdFactory*factory = DCmdFactory::factory(DCmd_Source_MBean, cmd_name,2012strlen(cmd_name));2013if (factory != NULL) {2014dcmd = factory->create_resource_instance(NULL);2015}2016if (dcmd == NULL) {2017THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),2018"Unknown diagnostic command");2019}2020DCmdMark mark(dcmd);2021GrowableArray<DCmdArgumentInfo*>* array = dcmd->argument_info_array();2022if (array->length() == 0) {2023return;2024}2025for (int i = 0; i < array->length(); i++) {2026infoArray[i].name = array->at(i)->name();2027infoArray[i].description = array->at(i)->description();2028infoArray[i].type = array->at(i)->type();2029infoArray[i].default_string = array->at(i)->default_string();2030infoArray[i].mandatory = array->at(i)->is_mandatory();2031infoArray[i].option = array->at(i)->is_option();2032infoArray[i].multiple = array->at(i)->is_multiple();2033infoArray[i].position = array->at(i)->position();2034}2035return;2036JVM_END20372038JVM_ENTRY(jstring, jmm_ExecuteDiagnosticCommand(JNIEnv *env, jstring commandline))2039ResourceMark rm(THREAD);2040oop cmd = JNIHandles::resolve_external_guard(commandline);2041if (cmd == NULL) {2042THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),2043"Command line cannot be null.");2044}2045char* cmdline = java_lang_String::as_utf8_string(cmd);2046if (cmdline == NULL) {2047THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),2048"Command line content cannot be null.");2049}2050bufferedStream output;2051DCmd::parse_and_execute(DCmd_Source_MBean, &output, cmdline, ' ', CHECK_NULL);2052oop result = java_lang_String::create_oop_from_str(output.as_string(), CHECK_NULL);2053return (jstring) JNIHandles::make_local(THREAD, result);2054JVM_END20552056JVM_ENTRY(void, jmm_SetDiagnosticFrameworkNotificationEnabled(JNIEnv *env, jboolean enabled))2057DCmdFactory::set_jmx_notification_enabled(enabled?true:false);2058JVM_END20592060jlong Management::ticks_to_ms(jlong ticks) {2061assert(os::elapsed_frequency() > 0, "Must be non-zero");2062return (jlong)(((double)ticks / (double)os::elapsed_frequency())2063* (double)1000.0);2064}2065#endif // INCLUDE_MANAGEMENT20662067// Gets the amount of memory allocated on the Java heap for a single thread.2068// Returns -1 if the thread does not exist or has terminated.2069JVM_ENTRY(jlong, jmm_GetOneThreadAllocatedMemory(JNIEnv *env, jlong thread_id))2070if (thread_id < 0) {2071THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),2072"Invalid thread ID", -1);2073}20742075if (thread_id == 0) { // current thread2076return thread->cooked_allocated_bytes();2077}20782079ThreadsListHandle tlh;2080JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);20812082if (java_thread != NULL) {2083return java_thread->cooked_allocated_bytes();2084}2085return -1;2086JVM_END20872088// Gets an array containing the amount of memory allocated on the Java2089// heap for a set of threads (in bytes). Each element of the array is2090// the amount of memory allocated for the thread ID specified in the2091// corresponding entry in the given array of thread IDs; or -1 if the2092// thread does not exist or has terminated.2093JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,2094jlongArray sizeArray))2095// Check if threads is null2096if (ids == NULL || sizeArray == NULL) {2097THROW(vmSymbols::java_lang_NullPointerException());2098}20992100ResourceMark rm(THREAD);2101typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));2102typeArrayHandle ids_ah(THREAD, ta);21032104typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));2105typeArrayHandle sizeArray_h(THREAD, sa);21062107// validate the thread id array2108validate_thread_id_array(ids_ah, CHECK);21092110// sizeArray must be of the same length as the given array of thread IDs2111int num_threads = ids_ah->length();2112if (num_threads != sizeArray_h->length()) {2113THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),2114"The length of the given long array does not match the length of "2115"the given array of thread IDs");2116}21172118ThreadsListHandle tlh;2119for (int i = 0; i < num_threads; i++) {2120JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(ids_ah->long_at(i));2121if (java_thread != NULL) {2122sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());2123}2124}2125JVM_END21262127// Returns the CPU time consumed by a given thread (in nanoseconds).2128// If thread_id == 0, CPU time for the current thread is returned.2129// If user_sys_cpu_time = true, user level and system CPU time of2130// a given thread is returned; otherwise, only user level CPU time2131// is returned.2132JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))2133if (!os::is_thread_cpu_time_supported()) {2134return -1;2135}21362137if (thread_id < 0) {2138THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),2139"Invalid thread ID", -1);2140}21412142JavaThread* java_thread = NULL;2143if (thread_id == 0) {2144// current thread2145return os::current_thread_cpu_time(user_sys_cpu_time != 0);2146} else {2147ThreadsListHandle tlh;2148java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);2149if (java_thread != NULL) {2150return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);2151}2152}2153return -1;2154JVM_END21552156// Gets an array containing the CPU times consumed by a set of threads2157// (in nanoseconds). Each element of the array is the CPU time for the2158// thread ID specified in the corresponding entry in the given array2159// of thread IDs; or -1 if the thread does not exist or has terminated.2160// If user_sys_cpu_time = true, the sum of user level and system CPU time2161// for the given thread is returned; otherwise, only user level CPU time2162// is returned.2163JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,2164jlongArray timeArray,2165jboolean user_sys_cpu_time))2166// Check if threads is null2167if (ids == NULL || timeArray == NULL) {2168THROW(vmSymbols::java_lang_NullPointerException());2169}21702171ResourceMark rm(THREAD);2172typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));2173typeArrayHandle ids_ah(THREAD, ta);21742175typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));2176typeArrayHandle timeArray_h(THREAD, tia);21772178// validate the thread id array2179validate_thread_id_array(ids_ah, CHECK);21802181// timeArray must be of the same length as the given array of thread IDs2182int num_threads = ids_ah->length();2183if (num_threads != timeArray_h->length()) {2184THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),2185"The length of the given long array does not match the length of "2186"the given array of thread IDs");2187}21882189ThreadsListHandle tlh;2190for (int i = 0; i < num_threads; i++) {2191JavaThread* java_thread = tlh.list()->find_JavaThread_from_java_tid(ids_ah->long_at(i));2192if (java_thread != NULL) {2193timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,2194user_sys_cpu_time != 0));2195}2196}2197JVM_END2198219922002201#if INCLUDE_MANAGEMENT2202const struct jmmInterface_1_ jmm_interface = {2203NULL,2204NULL,2205jmm_GetVersion,2206jmm_GetOptionalSupport,2207jmm_GetThreadInfo,2208jmm_GetMemoryPools,2209jmm_GetMemoryManagers,2210jmm_GetMemoryPoolUsage,2211jmm_GetPeakMemoryPoolUsage,2212jmm_GetOneThreadAllocatedMemory,2213jmm_GetThreadAllocatedMemory,2214jmm_GetMemoryUsage,2215jmm_GetLongAttribute,2216jmm_GetBoolAttribute,2217jmm_SetBoolAttribute,2218jmm_GetLongAttributes,2219jmm_FindMonitorDeadlockedThreads,2220jmm_GetThreadCpuTime,2221jmm_GetVMGlobalNames,2222jmm_GetVMGlobals,2223jmm_GetInternalThreadTimes,2224jmm_ResetStatistic,2225jmm_SetPoolSensor,2226jmm_SetPoolThreshold,2227jmm_GetPoolCollectionUsage,2228jmm_GetGCExtAttributeInfo,2229jmm_GetLastGCStat,2230jmm_GetThreadCpuTimeWithKind,2231jmm_GetThreadCpuTimesWithKind,2232jmm_DumpHeap0,2233jmm_FindDeadlockedThreads,2234jmm_SetVMGlobal,2235NULL,2236jmm_DumpThreads,2237jmm_SetGCNotificationEnabled,2238jmm_GetDiagnosticCommands,2239jmm_GetDiagnosticCommandInfo,2240jmm_GetDiagnosticCommandArgumentsInfo,2241jmm_ExecuteDiagnosticCommand,2242jmm_SetDiagnosticFrameworkNotificationEnabled2243};2244#endif // INCLUDE_MANAGEMENT22452246void* Management::get_jmm_interface(int version) {2247#if INCLUDE_MANAGEMENT2248if (version == JMM_VERSION) {2249return (void*) &jmm_interface;2250}2251#endif // INCLUDE_MANAGEMENT2252return NULL;2253}225422552256