diff --git a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedThreadMXBeanImpl.java b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedThreadMXBeanImpl.java index 27a465c2af1..da10ca7f9dd 100644 --- a/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedThreadMXBeanImpl.java +++ b/jcl/src/jdk.management/share/classes/com/ibm/lang/management/internal/ExtendedThreadMXBeanImpl.java @@ -37,7 +37,7 @@ public final class ExtendedThreadMXBeanImpl extends ThreadMXBeanImpl implements /** * Singleton accessor method. - * + * * @return the ExtendedThreadMXBeanImpl singleton. */ public static ThreadMXBean getInstance() { @@ -67,12 +67,22 @@ public ExtendedThreadInfo[] dumpAllExtendedThreads(boolean lockedMonitors, boole return resultArray; } + private native static long getThreadAllocatedBytesImpl(long threadID); + /** * {@inheritDoc} */ @Override public long getThreadAllocatedBytes(long threadId) { - throw new UnsupportedOperationException(); + if (isThreadAllocatedMemorySupported()) { + if (isThreadAllocatedMemoryEnabled()) { + return getThreadAllocatedBytesImpl(threadId); + } else { + return -1; + } + } else { + throw new UnsupportedOperationException(); + } } /** @@ -80,7 +90,14 @@ public long getThreadAllocatedBytes(long threadId) { */ @Override public long[] getThreadAllocatedBytes(long[] threadIds) { - throw new UnsupportedOperationException(); + int length = threadIds.length; + long[] allocatedBytes = new long[length]; + + for (int i = 0; i < length; i++) { + allocatedBytes[i] = getThreadAllocatedBytes(threadIds[i]); + } + + return allocatedBytes; } /** @@ -135,12 +152,15 @@ public long[] getThreadUserTime(long[] threadIds) { return result; } + private boolean isThreadAllocatedMemoryEnabled = true; + /** * {@inheritDoc} */ @Override public boolean isThreadAllocatedMemorySupported() { - return false; + /* Currently, this capability is always supported. */ + return true; } /** @@ -148,7 +168,7 @@ public boolean isThreadAllocatedMemorySupported() { */ @Override public boolean isThreadAllocatedMemoryEnabled() { - throw new UnsupportedOperationException(); + return isThreadAllocatedMemoryEnabled && isThreadAllocatedMemorySupported(); } /** @@ -156,6 +176,6 @@ public boolean isThreadAllocatedMemoryEnabled() { */ @Override public void setThreadAllocatedMemoryEnabled(boolean value) { - throw new UnsupportedOperationException(); + isThreadAllocatedMemoryEnabled = value; } } diff --git a/runtime/gc/gctable.c b/runtime/gc/gctable.c index 1f86a78d6c7..1ee5f62a067 100644 --- a/runtime/gc/gctable.c +++ b/runtime/gc/gctable.c @@ -249,6 +249,7 @@ J9MemoryManagerFunctions MemoryManagerFunctions = { #endif /* !J9VM_ENV_DATA64 */ #endif /* J9VM_GC_OBJECT_ACCESS_BARRIER */ j9gc_get_bytes_allocated_by_thread, + j9gc_get_cumulative_bytes_allocated_by_thread, j9mm_iterate_all_ownable_synchronizer_objects, j9mm_iterate_all_continuation_objects, ownableSynchronizerObjectCreated, diff --git a/runtime/gc_base/gc_internal.h b/runtime/gc_base/gc_internal.h index 55fe884cccc..0f0ef4bfc98 100644 --- a/runtime/gc_base/gc_internal.h +++ b/runtime/gc_base/gc_internal.h @@ -291,6 +291,7 @@ extern BOOLEAN j9gc_stringHashEqualFn (void *leftKey, void *rightKey, void *user /* modronapi.cpp */ extern J9_CFUNC UDATA j9gc_get_bytes_allocated_by_thread(J9VMThread* vmThread); +extern J9_CFUNC BOOLEAN j9gc_get_cumulative_bytes_allocated_by_thread(J9VMThread *vmThread, UDATA *cumulativeValue); #ifdef __cplusplus } diff --git a/runtime/gc_base/modronapi.cpp b/runtime/gc_base/modronapi.cpp index 286e7f37279..f4cfa77c723 100644 --- a/runtime/gc_base/modronapi.cpp +++ b/runtime/gc_base/modronapi.cpp @@ -967,6 +967,17 @@ j9gc_get_bytes_allocated_by_thread(J9VMThread *vmThread) return MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread)->_objectAllocationInterface->getAllocationStats()->bytesAllocated(); } +/** + * @param[in] vmThread the vmThread we are querying about + * @param[out] cumulativeValue pointer to a variable where to store cumulative number of bytes allocated by a thread since the start of VM + * @return false if the value just rolled over or if cumulativeValue pointer is null, otherwise true + */ +BOOLEAN +j9gc_get_cumulative_bytes_allocated_by_thread(J9VMThread *vmThread, UDATA *cumulativeValue) +{ + return MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread)->_objectAllocationInterface->getAllocationStats()->bytesAllocatedCumulative(cumulativeValue); +} + /** * Return information about the total CPU time consumed by GC threads, as well * as the number of GC threads. The time for the main and worker threads is diff --git a/runtime/gc_base/modronapi.hpp b/runtime/gc_base/modronapi.hpp index 86bba800ee0..a0874491805 100644 --- a/runtime/gc_base/modronapi.hpp +++ b/runtime/gc_base/modronapi.hpp @@ -93,6 +93,7 @@ void j9gc_set_memoryController(J9VMThread *vmThread, j9object_t objectPtr, j9obj void j9gc_set_allocation_sampling_interval(J9JavaVM *vm, UDATA samplingInterval); void j9gc_set_allocation_threshold(J9VMThread *vmThread, UDATA low, UDATA high); UDATA j9gc_get_bytes_allocated_by_thread(J9VMThread *vmThread); +BOOLEAN j9gc_get_cumulative_bytes_allocated_by_thread(J9VMThread *vmThread, UDATA *cumulativeValue); void j9gc_get_CPU_times(J9JavaVM *javaVM, U_64 *mainCpuMillis, U_64 *workerCpuMillis, U_32 *maxThreads, U_32 *currentThreads); J9HookInterface** j9gc_get_private_hook_interface(J9JavaVM *javaVM); /** diff --git a/runtime/jcl/common/mgmtthread.c b/runtime/jcl/common/mgmtthread.c index 2b0e95f07a3..52dcac2a160 100644 --- a/runtime/jcl/common/mgmtthread.c +++ b/runtime/jcl/common/mgmtthread.c @@ -84,12 +84,12 @@ typedef struct ThreadInfo { jobject blocker; jobject blockerOwner; jobjectArray stackTrace; - + struct { UDATA len; UDATA *pcs; } stack; - + struct { UDATA len; J9ObjectMonitorInfo *arr_unsafe; @@ -182,7 +182,7 @@ jobject JNICALL Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_findMonitorDeadlockedThreadsImpl(JNIEnv *env, jobject beanInstance) { jlongArray result; - + result = findDeadlockedThreads(env, 0); return result; } @@ -191,8 +191,8 @@ jlongArray JNICALL Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_findDeadlockedThreadsImpl(JNIEnv *env, jobject beanInstance) { jlongArray result; - - result = findDeadlockedThreads(env, + + result = findDeadlockedThreads(env, J9VMTHREAD_FINDDEADLOCKFLAG_INCLUDESYNCHRONIZERS | J9VMTHREAD_FINDDEADLOCKFLAG_INCLUDEWAITING); return result; @@ -207,8 +207,8 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getAllThreadIdsImpl( J9VMThread *vmThread = (J9VMThread *) env; J9JavaVM *javaVM = vmThread->javaVM; jlong threadCount = 0; - J9VMThread * currentThread; - + J9VMThread * currentThread; + enterVMFromJNI((J9VMThread *) env); omrthread_monitor_enter(javaVM->vmThreadListMutex); @@ -265,7 +265,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getThreadCpuTimeImpl J9InternalVMFunctions *vmfns = javaVM->internalVMFunctions; vmfns->internalEnterVMFromJNI(currentThread); - + /* shortcut for the current thread */ if (getThreadID(currentThread, (j9object_t)currentThread->threadObject) == threadID) { vmfns->internalExitVMToJNI(currentThread); @@ -297,7 +297,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getThreadCpuTimeImpl return cpuTime; } -/* +/* * TODO This API should be split for current vs arbitrary thread. */ jlong JNICALL @@ -310,13 +310,13 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getThreadUserTimeImp J9InternalVMFunctions *vmfns = javaVM->internalVMFunctions; vmfns->internalEnterVMFromJNI(currentThread); - + /* shortcut for the current thread */ if (getThreadID(currentThread, (j9object_t)currentThread->threadObject) == threadID) { vmfns->internalExitVMToJNI(currentThread); return getCurrentThreadUserTime(currentThread->osThread); } - + /* walk the vmthreads until we find the matching one */ omrthread_monitor_enter(javaVM->vmThreadListMutex); for (targetThread = currentThread->linkNext; @@ -338,7 +338,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getThreadUserTimeImp } omrthread_monitor_exit(javaVM->vmThreadListMutex); vmfns->internalExitVMToJNI(currentThread); - + return userTime; } @@ -388,7 +388,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getThreadCountImpl(J jint result = 0; { omrthread_rwmutex_enter_read( mgmt->managementDataLock ); - + result = (jint)mgmt->liveJavaThreads; omrthread_rwmutex_exit_read( mgmt->managementDataLock ); @@ -450,6 +450,54 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_isThreadCpuTimeEnabl return (jboolean)mgmt->threadCpuTimeEnabledFlag; } +jlong JNICALL +Java_com_ibm_lang_management_internal_ExtendedThreadMXBeanImpl_getThreadAllocatedBytesImpl(JNIEnv *env, jobject unused, jlong threadID) +{ + jlong result = -1; + UDATA allocatedBytes = 0; + J9VMThread *currentThread = (J9VMThread *)env; + J9VMThread *targetThread = NULL; + J9JavaVM *javaVM = currentThread->javaVM; + J9InternalVMFunctions *vmfns = javaVM->internalVMFunctions; + J9MemoryManagerFunctions *mmfns = javaVM->memoryManagerFunctions; + + vmfns->internalEnterVMFromJNI(currentThread); + + /* Shortcut for the current thread. */ + if (getThreadID(currentThread, (j9object_t)currentThread->threadObject) == threadID) { + if (mmfns->j9gc_get_cumulative_bytes_allocated_by_thread(currentThread, &allocatedBytes)) { + result = (jlong) allocatedBytes; + } + goto done; + } + + /* Walk the vmthreads until we find the matching one. */ + omrthread_monitor_enter(javaVM->vmThreadListMutex); + for (targetThread = currentThread->linkNext; + targetThread != currentThread; + targetThread = targetThread->linkNext + ) { + if (targetThread->threadObject != NULL) { + /* Check that thread's ID matches. */ + if (getThreadID(currentThread, (j9object_t)targetThread->threadObject) == threadID) { + /* Check if the thread is alive. */ + if (J9VMJAVALANGTHREAD_THREADREF(currentThread, targetThread->threadObject) != NULL) { + if (mmfns->j9gc_get_cumulative_bytes_allocated_by_thread(targetThread, &allocatedBytes)) { + result = (jlong) allocatedBytes; + } + } + break; + } + } + } + omrthread_monitor_exit(javaVM->vmThreadListMutex); + +done: + vmfns->internalExitVMToJNI(currentThread); + + return result; +} + void JNICALL Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_resetPeakThreadCountImpl(JNIEnv *env, jobject beanInstance) { @@ -473,7 +521,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_setThreadContentionM J9JavaLangManagementData *mgmt = javaVM->managementData; J9VMThread * currentThread; J9HookInterface** vmHooks = javaVM->internalVMFunctions->getVMHookInterface(javaVM); - + U_64 timeNowNS = (U_64)j9time_nano_time(); if (mgmt->threadContentionMonitoringFlag == flag ) { @@ -523,7 +571,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_setThreadContentionM if ((currentThread = currentThread->linkNext) == javaVM->mainThread) { /* Back at starting thread: we're done */ break; - } + } } if (flag == JNI_TRUE) { @@ -536,7 +584,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_setThreadContentionM (*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_UNPARKED, handlerMonitorWaited, OMR_GET_CALLSITE(), NULL); (*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_SLEEP, handlerMonitorWait, OMR_GET_CALLSITE(), NULL); (*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_SLEPT, handlerMonitorWaited, OMR_GET_CALLSITE(), NULL); - + } omrthread_rwmutex_exit_write( mgmt->managementDataLock ); @@ -565,7 +613,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_isCurrentThreadCpuTi return isSupported; } -jboolean JNICALL +jboolean JNICALL Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_isObjectMonitorUsageSupportedImpl(JNIEnv *env, jobject beanInstance) { return JNI_TRUE; @@ -587,7 +635,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getThreadInfoImpl(JN ThreadInfo *allinfo = NULL; PORT_ACCESS_FROM_ENV(env); - Trc_JCL_threadmxbean_getThreadInfoImpl6_Entry(env, id, + Trc_JCL_threadmxbean_getThreadInfoImpl6_Entry(env, id, maxStackDepth, getLockedMonitors, getLockedSynchronizers); allinfo = getArrayOfThreadInfo(env, &id, 1, getLockedMonitors, getLockedSynchronizers); @@ -606,7 +654,7 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getThreadInfoImpl(JN jobjectArray JNICALL Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getMultiThreadInfoImpl( JNIEnv *env, jobject beanInstance, - jlongArray ids, jint maxStackDepth, + jlongArray ids, jint maxStackDepth, jboolean getLockedMonitors, jboolean getLockedSynchronizers) { ThreadInfo *allinfo = NULL; @@ -615,12 +663,12 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getMultiThreadInfoIm jlong *threadIDs = NULL; jboolean isCopy = JNI_FALSE; PORT_ACCESS_FROM_ENV(env); - + Trc_JCL_threadmxbean_getArrayOfThreadInfo_Entry( env, ids, getLockedMonitors, getLockedSynchronizers); numThreads = (*env)->GetArrayLength(env, ids); - + /* There's a special case when we get a 0 length thread list that * we are still expected to return an array of size zero, not null, * so skip doing anything extra and just return the new array @@ -644,9 +692,9 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_getMultiThreadInfoIm j9mem_free_memory(allinfo); } } - + Trc_JCL_threadmxbean_getArrayOfThreadInfo_Exit(env, result); - + return result; } @@ -697,7 +745,7 @@ Java_openj9_internal_tools_attach_target_DiagnosticUtils_dumpAllThreadsImpl(JNIE break; } - /* Verify that thread is alive */ + /* Verify that thread is alive */ if (vmThread->threadObject && (J9VMJAVALANGTHREAD_THREADREF(currentThread, vmThread->threadObject) == vmThread)) { { ++numThreads; @@ -748,7 +796,7 @@ Java_openj9_internal_tools_attach_target_DiagnosticUtils_dumpAllThreadsImpl(JNIE result = createThreadInfoArray(env, allinfo, numThreads, maxDepth); j9mem_free_memory(allinfo); - + Trc_JCL_threadmxbean_dumpAllThreads_Exit(env, result); return result; @@ -774,13 +822,13 @@ Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_dumpAllThreadsImpl /** * Allocate and populate an array of ThreadInfo for a given array of threadIDs - * + * * @param[in] env * @param[in] threadIDs Array of thread IDs. May include dead threads. * @param[in] numThreads Length of threadIDs[]. * @param[in] getLockedMonitors Whether locked monitors should be discovered. * @param[in] getLockedSynchronizers Whether locked synchronizers should be discovered. - * + * * @return array of ThreadInfo * @retval non-NULL success * @retval NULL error, an exception is set @@ -806,7 +854,7 @@ getArrayOfThreadInfo(JNIEnv *env, jlong *threadIDs, jint numThreads, vm->memoryManagerFunctions->j9gc_ensureLockedSynchronizersIntegrity(currentThread); } - /** + /** * @todo Slightly evil. * Overwrites entries in the threadID array with the J9VMThread*s. */ @@ -814,9 +862,9 @@ getArrayOfThreadInfo(JNIEnv *env, jlong *threadIDs, jint numThreads, for (i = 0; (jint)i < numThreads; ++i) { J9VMThread *vmThread; - + vmThread = getThread(env, threadIDs[i]); - /* + /* * Dead threads should not be removed from the array. * They should get a null entry in the corresponding ThreadInfo array. */ @@ -894,7 +942,7 @@ getArrayOfThreadInfo(JNIEnv *env, jlong *threadIDs, jint numThreads, /** * Get the tid of a thread object (equivalent of Thread.getId()) - * + * * @pre VM access * @param[in] currentThread * @param[in] threadObj @@ -919,10 +967,10 @@ getThreadID(J9VMThread *currentThread, j9object_t threadObj) * @retval non-NULL the J9VMThread corresponding to the tid */ static J9VMThread * -getThread(JNIEnv *env, jlong threadID) +getThread(JNIEnv *env, jlong threadID) { J9JavaVM *javaVM = ((J9VMThread *) env)->javaVM; - J9VMThread *currentThread; + J9VMThread *currentThread; /* Grab any thread (mainThread will do) */ currentThread = javaVM->mainThread; @@ -964,9 +1012,9 @@ static jlong getThreadUserTime(omrthread_t thread) { jlong userTime = -1; - + userTime = omrthread_get_user_time(thread); - + #if defined(J9ZOS390) || defined(LINUX) || defined(OSX) if (-1 == userTime) { /* For z/OS, Linux and OSX, user time is not available from the OS. @@ -975,7 +1023,7 @@ getThreadUserTime(omrthread_t thread) userTime = omrthread_get_cpu_time(thread); } #endif /* ZOS, LINUX or OSX */ - + return userTime; } @@ -988,9 +1036,9 @@ static jlong getCurrentThreadUserTime(omrthread_t self) { jlong userTime = -1; - + userTime = omrthread_get_self_user_time(self); - + #if defined(J9ZOS390) || defined(LINUX) || defined(OSX) if (-1 == userTime) { /* For z/OS, Linux and OSX, user time is not available from the OS. @@ -999,11 +1047,11 @@ getCurrentThreadUserTime(omrthread_t self) userTime = omrthread_get_self_cpu_time(self); } #endif /* defined(J9ZOS390) || defined(LINUX) || defined(OSX) */ - + return userTime; } -static void +static void handlerContendedEnter(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData) { J9VMMonitorContendedEnterEvent* event = (J9VMMonitorContendedEnterEvent*)eventData; @@ -1016,7 +1064,7 @@ handlerContendedEnter(J9HookInterface** hook, UDATA eventNum, void* eventData, v } } -static void +static void handlerContendedEntered(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData) { J9VMMonitorContendedEnteredEvent* event = (J9VMMonitorContendedEnteredEvent*)eventData; @@ -1032,7 +1080,7 @@ handlerContendedEntered(J9HookInterface** hook, UDATA eventNum, void* eventData, } } -static void +static void handlerMonitorWait(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData) { J9VMThread* currentThread = NULL; @@ -1063,7 +1111,7 @@ handlerMonitorWait(J9HookInterface** hook, UDATA eventNum, void* eventData, void } } -static void +static void handlerMonitorWaited(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData) { J9VMThread* currentThread = NULL; @@ -1087,9 +1135,9 @@ handlerMonitorWaited(J9HookInterface** hook, UDATA eventNum, void* eventData, vo break; } - if (currentThread){ + if (currentThread){ PORT_ACCESS_FROM_JAVAVM( currentThread->javaVM ); - + if (currentThread->mgmtWaitedStart) { currentThread->mgmtWaitedTimeTotal += checkedTimeInterval((U_64)j9time_nano_time(), currentThread->mgmtWaitedTimeStart); @@ -1113,13 +1161,13 @@ Java_openj9_management_internal_IDCacheInitializer_initIDCache(JNIEnv *env, jcla jclass cls = NULL; jclass gcls = NULL; jmethodID mid = NULL; - + /* cache OutOfMemoryError */ oom = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); if (!oom) { goto initIDCache_fail; } - + cls = (*env)->FindClass(env, "openj9/management/internal/ThreadInfoBase"); if (!cls) { goto initIDCache_fail; @@ -1129,7 +1177,7 @@ Java_openj9_management_internal_IDCacheInitializer_initIDCache(JNIEnv *env, jcla } JCL_CACHE_SET(env, CLS_openj9_management_internal_ThreadInfoBase, gcls); - mid = (*env)->GetMethodID(env, gcls, "", + mid = (*env)->GetMethodID(env, gcls, "", "(Ljava/lang/Thread;JIZZJJJJ[Ljava/lang/StackTraceElement;Ljava/lang/Object;Ljava/lang/Thread;[Lopenj9/management/internal/MonitorInfoBase;[Lopenj9/management/internal/LockInfoBase;)V"); if (mid) { JCL_CACHE_SET(env, MID_openj9_management_internal_ThreadInfoBase_init, mid); @@ -1159,7 +1207,7 @@ Java_openj9_management_internal_IDCacheInitializer_initIDCache(JNIEnv *env, jcla if (!cls) { goto initIDCache_fail; } - mid = (*env)->GetMethodID(env, cls, "getName", "()Ljava/lang/String;"); + mid = (*env)->GetMethodID(env, cls, "getName", "()Ljava/lang/String;"); if (!mid) { goto initIDCache_fail; } @@ -1225,7 +1273,7 @@ Java_openj9_management_internal_IDCacheInitializer_initIDCache(JNIEnv *env, jcla * * @pre allinfo should be initialized to 0 so that it doesn't contain garbage pointers. * @note This function may free() null pointers. - * + * * @param[in] currentThread * @param[in] allinfo array of ThreadInfo * @param[in] allinfolen length of allinfo[] @@ -1242,7 +1290,7 @@ freeThreadInfos(J9VMThread *currentThread, ThreadInfo *allinfo, UDATA allinfolen j9mem_free_memory(allinfo[i].stack.pcs); j9mem_free_memory(allinfo[i].lockedMonitors.arr_unsafe); j9mem_free_memory(allinfo[i].lockedMonitors.arr_safe); - + sinfo = allinfo[i].lockedSynchronizers.list; while (sinfo) { next = sinfo->next; @@ -1255,17 +1303,17 @@ freeThreadInfos(J9VMThread *currentThread, ThreadInfo *allinfo, UDATA allinfolen /** * Populate the ThreadInfo for a given VMThread. - * + * * @pre VM access. * @pre The target thread must be halted. - * @pre The owner of the target thread's blocking object must not be able to exit. + * @pre The owner of the target thread's blocking object must not be able to exit. * This usually implies that exclusive VM access is required. - * + * * @param[in] currentThread * @param[in] targetThread The thread to be examined. * @param[out] info The ThreadInfo element to be populated. Must be non-NULL. * @param[in] getLockedMonitors Whether locked monitors should be discovered. - * + * * @return error status * @retval 0 success * @retval >0 error, the index of a known exception @@ -1361,7 +1409,7 @@ static void getContentionStats(J9VMThread *currentThread, J9VMThread *vmThread, ThreadInfo *tinfo) { PORT_ACCESS_FROM_JAVAVM(currentThread->javaVM); - J9JavaLangManagementData *mgmt = currentThread->javaVM->managementData; + J9JavaLangManagementData *mgmt = currentThread->javaVM->managementData; tinfo->blockedCount = vmThread->mgmtBlockedCount; tinfo->waitedCount = vmThread->mgmtWaitedCount; @@ -1421,8 +1469,8 @@ getStackFramePCs(J9VMThread *currentThread, J9VMThread *targetThread, ThreadInfo /* walk stack and cache PCs */ walkState.walkThread = targetThread; walkState.flags = J9_STACKWALK_CACHE_PCS | J9_STACKWALK_WALK_TRANSLATE_PC - | J9_STACKWALK_SKIP_INLINES - | J9_STACKWALK_INCLUDE_NATIVES + | J9_STACKWALK_SKIP_INLINES + | J9_STACKWALK_INCLUDE_NATIVES | J9_STACKWALK_VISIBLE_ONLY; walkState.skipCount = 0; @@ -1434,7 +1482,7 @@ getStackFramePCs(J9VMThread *currentThread, J9VMThread *targetThread, ThreadInfo exc = J9VMCONSTANTPOOL_JAVALANGOUTOFMEMORYERROR; return exc; } - + /* copy cache */ tinfo->stack.len = walkState.framesWalked; tinfo->stack.pcs = j9mem_allocate_memory(sizeof(UDATA) * tinfo->stack.len, J9MEM_CATEGORY_VM_JCL); @@ -1442,7 +1490,7 @@ getStackFramePCs(J9VMThread *currentThread, J9VMThread *targetThread, ThreadInfo memcpy(tinfo->stack.pcs, walkState.cache, sizeof(UDATA) * tinfo->stack.len); } vmfns->freeStackWalkCaches(currentThread, &walkState); - + if (!tinfo->stack.pcs) { exc = J9VMCONSTANTPOOL_JAVALANGOUTOFMEMORYERROR; } @@ -1467,19 +1515,19 @@ getSynchronizers(J9VMThread *currentThread, ThreadInfo *allinfo, UDATA allinfole SynchronizerIterData data; UDATA exc = 0; jvmtiIterationControl rc; - + Trc_JCL_threadmxbean_getSynchronizers_Entry(currentThread, allinfo, allinfolen); data.allinfo = allinfo; data.allinfolen = allinfolen; /* ensure that all thread-local buffers are flushed */ - mmfns->j9gc_flush_nonAllocationCaches_for_walk(currentThread->javaVM); + mmfns->j9gc_flush_nonAllocationCaches_for_walk(currentThread->javaVM); rc = mmfns->j9mm_iterate_all_ownable_synchronizer_objects(currentThread, vm->portLibrary, 0, getSynchronizersHeapIterator, &data); if (rc == JVMTI_ITERATION_ABORT) { exc = J9VMCONSTANTPOOL_JAVALANGOUTOFMEMORYERROR; } - + Trc_JCL_threadmxbean_getSynchronizers_Exit(currentThread, exc); return exc; } @@ -1518,7 +1566,7 @@ getSynchronizersHeapIterator(J9VMThread *vmThread, J9MM_IterateObjectDescriptor /* OwnableSynchronizer collection should only contain instances of java.util.concurrent.locks.AbstractOwnableSynchronizer */ Assert_JCL_true(instanceOfOrCheckCast(clazz, aosClazz)); - + owner = J9VMJAVAUTILCONCURRENTLOCKSABSTRACTOWNABLESYNCHRONIZER_EXCLUSIVEOWNERTHREAD(vmThread, object); if (owner) { /** @@ -1583,7 +1631,7 @@ getMonitors(J9VMThread *currentThread, J9VMThread *targetThread, ThreadInfo *tin exc = J9VMCONSTANTPOOL_JAVALANGOUTOFMEMORYERROR; } } - + Trc_JCL_threadmxbean_getMonitors_Exit(currentThread, exc); return exc; } @@ -1667,7 +1715,7 @@ createThreadInfo(JNIEnv *env, ThreadInfo *tinfo, jsize maxStackDepth) getOwnedLocks = JNI_FALSE; } Assert_JCL_notNull(ctor); - + if (tinfo->vmstate == J9VMTHREAD_STATE_SUSPENDED) { isSuspended = JNI_TRUE; } else { @@ -1685,7 +1733,7 @@ createThreadInfo(JNIEnv *env, ThreadInfo *tinfo, jsize maxStackDepth) if (lockedMonitors == NULL) { return NULL; } - + lockedSynchronizers = createLockedSynchronizers(env, tinfo); if (!lockedSynchronizers) { return NULL; @@ -1698,11 +1746,11 @@ createThreadInfo(JNIEnv *env, ThreadInfo *tinfo, jsize maxStackDepth) } if (JNI_TRUE == getOwnedLocks) { - result = (*env)->NewObject(env, cls, ctor, tinfo->thread, tinfo->nativeTID, state, isSuspended, isNative, + result = (*env)->NewObject(env, cls, ctor, tinfo->thread, tinfo->nativeTID, state, isSuspended, isNative, tinfo->blockedCount, tinfo->blockedTime, tinfo->waitedCount, tinfo->waitedTime, prunedTrace, tinfo->blocker, tinfo->blockerOwner, lockedMonitors, lockedSynchronizers); } else { - result = (*env)->NewObject(env, cls, ctor, tinfo->thread, tinfo->nativeTID, state, isSuspended, isNative, + result = (*env)->NewObject(env, cls, ctor, tinfo->thread, tinfo->nativeTID, state, isSuspended, isNative, tinfo->blockedCount, tinfo->blockedTime, tinfo->waitedCount, tinfo->waitedTime, prunedTrace, tinfo->blocker, tinfo->blockerOwner); } @@ -1732,10 +1780,10 @@ createThreadInfo(JNIEnv *env, ThreadInfo *tinfo, jsize maxStackDepth) /** * Allocate and populate the MonitorInfo array to be returned by * ThreadInfo.getLockedMonitors(). - * + * * According to spec, lockedMonitors should be a 0-sized array * if there are no locked monitors. - * + * * @pre must not have VM access * @post frees tinfo->lockedMonitors.arr_safe. * @param[in] env @@ -1743,7 +1791,7 @@ createThreadInfo(JNIEnv *env, ThreadInfo *tinfo, jsize maxStackDepth) * @return openj9/management/internal/MonitorInfoBase[] * @retval non-null success * @retval null error, an exception is set - */ + */ static jobjectArray createLockedMonitors(JNIEnv *env, ThreadInfo *tinfo) { @@ -1829,21 +1877,21 @@ createLockedMonitors(JNIEnv *env, ThreadInfo *tinfo) } /** - * Allocate and populate the LockInfo array to be returned by + * Allocate and populate the LockInfo array to be returned by * ThreadInfo.getLockedSynchronizers(). * * According to spec, lockedSynchronizers should be a 0-sized array * if there are no locked monitors. - * + * * @pre must not have VM access * @post frees tinfo->lockedSynchronizers.list - * + * * @param[in] env * @param[in] tinfo * @return openj9/management/internal/LockInfoBase[] * @retval non-null success * @retval null error, an exception is set - */ + */ static jobjectArray createLockedSynchronizers(JNIEnv *env, ThreadInfo *tinfo) { @@ -1897,8 +1945,8 @@ createLockedSynchronizers(JNIEnv *env, ThreadInfo *tinfo) /** * Allocate and populate a stack trace object. - * - * @pre VM access. + * + * @pre VM access. * @post frees tinfo->stack.pcs. * @note May release VM access. * @param[in] currentThread @@ -1925,7 +1973,7 @@ createStackTrace(J9VMThread *currentThread, ThreadInfo *tinfo) j9mem_free_memory(tinfo->stack.pcs); tinfo->stack.pcs = NULL; - + if (throwable) { throwableRef = vmfns->j9jni_createLocalRef((JNIEnv *)currentThread, throwable); stackTrace = (j9object_t)getStackTrace(currentThread, (j9object_t*)throwableRef, FALSE); @@ -1943,8 +1991,8 @@ createStackTrace(J9VMThread *currentThread, ThreadInfo *tinfo) /** * Prune a stack trace object to a given length. * The original object might be returned if no pruning is required. - * - * @pre most not have VM access. + * + * @pre most not have VM access. * @param[in] env * @param[in] stackTrace * @param[in] maxStackDepth The maximum stack trace length desired. @@ -1968,7 +2016,7 @@ pruneStackTrace(JNIEnv *env, jobjectArray stackTrace, jsize maxStackDepth) if (maxStackDepth < 0) { return stackTrace; } - + arrayLength = (*env)->GetArrayLength(env, stackTrace); if ((arrayLength <= 0) || (arrayLength <= maxStackDepth)) { return stackTrace; @@ -1995,7 +2043,7 @@ pruneStackTrace(JNIEnv *env, jobjectArray stackTrace, jsize maxStackDepth) return prunedTrace; } -/** +/** * Convert unsafe object references into local refs before releasing VM access * @pre VM access * @param[in] env @@ -2042,7 +2090,7 @@ saveObjectRefs(JNIEnv *env, ThreadInfo *info) } } } - + return exc; } @@ -2052,7 +2100,7 @@ saveObjectRefs(JNIEnv *env, ThreadInfo *info) * @param[in] env * @param[in] stackTrace * @returns Whether the top frame of the stack trace is a native method. - * On error, this function may set an exception. The caller must check for pending exceptions. + * On error, this function may set an exception. The caller must check for pending exceptions. */ static jboolean isInNative(JNIEnv *env, jobjectArray stackTrace) @@ -2074,15 +2122,15 @@ isInNative(JNIEnv *env, jobjectArray stackTrace) (*env)->ExceptionClear(env); } } - + return result; } /** * Discover deadlocked threads. * @param[in] env - * @param[in] findFlags J9VMTHREAD_FINDDEADLOCKFLAG_xxx. Flags passed to the VM helper - * that determine whether deadlocks among synchronizers or waiting threads should be + * @param[in] findFlags J9VMTHREAD_FINDDEADLOCKFLAG_xxx. Flags passed to the VM helper + * that determine whether deadlocks among synchronizers or waiting threads should be * considered. * @return array of thread IDs for deadlocked threads. * null array is returned if there are no deadlocked threads. @@ -2102,10 +2150,10 @@ findDeadlockedThreads(JNIEnv *env, UDATA findFlags) UDATA i; vmfns->internalEnterVMFromJNI(currentThread); - + deadCount = vmfns->findObjectDeadlockedThreads(currentThread, &threads, NULL, findFlags); - /* spec says to return NULL array for no threads */ + /* spec says to return NULL array for no threads */ if (deadCount <= 0) { if (deadCount < 0) { oom: @@ -2115,7 +2163,7 @@ findDeadlockedThreads(JNIEnv *env, UDATA findFlags) j9mem_free_memory(threads); return NULL; } - + /* Finally, ready to output the list of deadlocked threads */ deadIDs = (jlong *)j9mem_allocate_memory(deadCount * sizeof(jlong), J9MEM_CATEGORY_VM_JCL); if (!deadIDs) { @@ -2209,7 +2257,7 @@ Java_com_ibm_lang_management_internal_JvmCpuMonitor_getThreadsCpuUsageImpl(JNIEn } JCL_CACHE_SET(env, CLS_java_com_ibm_lang_management_JvmCpuMonitorInfo, CLS_JvmCpuMonitorInfo); } - MID_updateValues = JCL_CACHE_GET(env, MID_java_com_ibm_lang_management_JvmCpuMonitorInfo_updateValues); + MID_updateValues = JCL_CACHE_GET(env, MID_java_com_ibm_lang_management_JvmCpuMonitorInfo_updateValues); if (NULL == MID_updateValues) { /* Get the method ID for updateValues() method */ MID_updateValues = (*env)->GetMethodID(env, CLS_JvmCpuMonitorInfo, "updateValues", "(JJJJJJ[J)V"); @@ -2261,7 +2309,7 @@ Java_com_ibm_lang_management_internal_JvmCpuMonitor_getThreadsCpuUsageImpl(JNIEn /** * Return the internal omrthread structure for a given threadID. - * + * * @param currentThread * @param threadID * @return the omrthread_t on success or NULL om failure. @@ -2377,7 +2425,7 @@ Java_com_ibm_lang_management_internal_JvmCpuMonitor_setThreadCategoryImpl(JNIEnv goto err_exit; } } - + /* Get the current thread category */ origCat = omrthread_get_category(t_osThread); @@ -2438,7 +2486,7 @@ Java_com_ibm_lang_management_internal_JvmCpuMonitor_getThreadCategoryImpl(JNIEnv return THREAD_CATEGORY_INVALID; } } - + category = omrthread_get_category(t_osThread); if (t_osThread != currentThread->osThread) { @@ -2490,7 +2538,7 @@ Java_com_ibm_lang_management_internal_JvmCpuMonitor_getThreadCategoryImpl(JNIEnv * @param[in] currentThread * @param[in] threadID The unique thread identifier * @return Native thread identifier. If no such thread is found, returns -1. - * @pre Caller must acquire the vmThreadListMutex when invoking findNativeThreadId + * @pre Caller must acquire the vmThreadListMutex when invoking findNativeThreadId * to avoid thread list from being altered as it iterates through it. */ static jlong @@ -2525,7 +2573,7 @@ findNativeThreadId(J9VMThread *currentThread, jlong threadID) } /** - * Returns the native (operating system assigned) thread ID for a thread whose unique (java/lang/Thread.getId()) + * Returns the native (operating system assigned) thread ID for a thread whose unique (java/lang/Thread.getId()) * ID is passed. If the thread ID passed cannot be found (thread no longer exists in the VM), return a -1 to * indicate this. * diff --git a/runtime/jcl/exports.cmake b/runtime/jcl/exports.cmake index 24c28e8c491..bcaa87aca58 100644 --- a/runtime/jcl/exports.cmake +++ b/runtime/jcl/exports.cmake @@ -111,6 +111,7 @@ omr_add_exports(jclse Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_resetPeakThreadCountImpl Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_setThreadContentionMonitoringEnabledImpl Java_com_ibm_java_lang_management_internal_ThreadMXBeanImpl_setThreadCpuTimeEnabledImpl + Java_com_ibm_lang_management_internal_ExtendedThreadMXBeanImpl_getThreadAllocatedBytesImpl Java_com_ibm_jit_JITHelpers_arrayShapeElementCountMask Java_com_ibm_jit_JITHelpers_getNumBitsInDescriptionWord Java_com_ibm_jit_JITHelpers_getNumBitsInReferenceField diff --git a/runtime/jcl/uma/se6_vm-side_natives_exports.xml b/runtime/jcl/uma/se6_vm-side_natives_exports.xml index d460ad7d2f7..3792059bb71 100644 --- a/runtime/jcl/uma/se6_vm-side_natives_exports.xml +++ b/runtime/jcl/uma/se6_vm-side_natives_exports.xml @@ -1,19 +1,19 @@ -