Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix JVMTI methods #16008

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion runtime/j9vm/javanextvmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ JVM_VirtualThreadMountBegin(JNIEnv *env, jobject thread, jboolean firstMount)
f_monitorEnter(vm->liveVirtualThreadListMutex);
j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread);

assert(IS_VIRTUAL_THREAD(currentThread, threadObj));
assert(IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObj));

while (0 != J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset)) {
/* Thread is being inspected or unmounted, wait. */
Expand Down
2 changes: 1 addition & 1 deletion runtime/jcl/common/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ Java_java_lang_Thread_getStackTraceImpl(JNIEnv *env, jobject rcv)

#if JAVA_SPEC_VERSION >= 19
BOOLEAN releaseInspector = FALSE;
if (IS_VIRTUAL_THREAD(currentThread, receiverObject)) {
if (IS_JAVA_LANG_VIRTUALTHREAD(currentThread, receiverObject)) {
omrthread_monitor_enter(vm->liveVirtualThreadListMutex);
j9object_t carrierThread = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, receiverObject);
I_64 vthreadInspectorCount = J9OBJECT_I64_LOAD(currentThread, receiverObject, vm->virtualThreadInspectorCountOffset);
Expand Down
20 changes: 12 additions & 8 deletions runtime/jvmti/jvmtiExtensionMechanism.c
Original file line number Diff line number Diff line change
Expand Up @@ -1465,13 +1465,14 @@ jvmtiGetOSThreadID(jvmtiEnv* jvmti_env, ...)
ENSURE_PHASE_START_OR_LIVE(jvmti_env);
ENSURE_NON_NULL(threadid_ptr);

rc = getVMThread(
currentThread, thread, &targetThread,
#if JAVA_SPEC_VERSION >= 19
gacholio marked this conversation as resolved.
Show resolved Hide resolved
if (NULL != thread) {
ENSURE_JTHREAD_NOT_VIRTUAL(currentThread, thread, JVMTI_ERROR_UNSUPPORTED_OPERATION);
}
JVMTI_ERROR_UNSUPPORTED_OPERATION,
#else /* JAVA_SPEC_VERSION >= 19 */
JVMTI_ERROR_NONE,
#endif /* JAVA_SPEC_VERSION >= 19 */

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_VIRTUALTHREAD);
if (rc == JVMTI_ERROR_NONE) {
rv_threadid = (jlong) omrthread_get_osId(targetThread->osThread);
releaseVMThread(currentThread, targetThread, thread);
Expand Down Expand Up @@ -1524,7 +1525,9 @@ jvmtiGetStackTraceExtended(jvmtiEnv* env, ...)
ENSURE_NON_NULL(frame_buffer);
ENSURE_NON_NULL(count_ptr);

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc == JVMTI_ERROR_NONE) {
vm->internalVMFunctions->haltThreadForInspection(currentThread, targetThread);

Expand Down Expand Up @@ -3455,10 +3458,11 @@ jvmtiGetJ9vmThread(jvmtiEnv *env, ...)
vm->internalVMFunctions->internalEnterVMFromJNI(currentThread);

ENSURE_PHASE_START_OR_LIVE(env);
ENSURE_JTHREAD_NON_NULL(thread);
ENSURE_NON_NULL(vmThreadPtr);

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc == JVMTI_ERROR_NONE) {
rv_vmThread = targetThread;
releaseVMThread(currentThread, targetThread, thread);
Expand Down
14 changes: 3 additions & 11 deletions runtime/jvmti/jvmtiForceEarlyReturn.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,10 @@ jvmtiForceEarlyReturn(jvmtiEnv* env,

ENSURE_PHASE_LIVE(env);
ENSURE_CAPABILITY(env, can_force_early_return);

/* Check if the jthread is really a j.l.Thread. a NULL jthread indicates that
* the user wants to use the current thread hence defer the assignment to getVMThread */

if (NULL != thread) {
ENSURE_JTHREAD(currentThread, thread);
#if JAVA_SPEC_VERSION >= 19
ENSURE_JTHREAD_NOT_VIRTUAL(currentThread, thread, JVMTI_ERROR_OPAQUE_FRAME);
#endif /* JAVA_SPEC_VERSION >= 19 */
}

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_OPAQUE_FRAME,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_VIRTUALTHREAD);
if (rc == JVMTI_ERROR_NONE) {
/* Does this thread need to be suspended at an event? */
vm->internalVMFunctions->haltThreadForInspection(currentThread, targetThread);
Expand Down
59 changes: 41 additions & 18 deletions runtime/jvmti/jvmtiHelpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static UDATA watchedClassEqual (void *lhsEntry, void *rhsEntry, void *userData);


jvmtiError
getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr, UDATA allowNull, UDATA mustBeAlive)
getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr, jvmtiError vThreadError, UDATA flags)
{
J9JavaVM *vm = currentThread->javaVM;
j9object_t threadObject = NULL;
Expand All @@ -106,13 +106,30 @@ getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr,
#endif /* JAVA_SPEC_VERSION >= 19 */

if (NULL == thread) {
if (allowNull) {
*vmThreadPtr = currentThread;
return JVMTI_ERROR_NONE;
if (OMR_ARE_ANY_BITS_SET(flags, J9JVMTI_GETVMTHREAD_ERROR_ON_NULL_JTHREAD)) {
return JVMTI_ERROR_INVALID_THREAD;
}
#if JAVA_SPEC_VERSION >= 19
if (OMR_ARE_ANY_BITS_SET(flags, J9JVMTI_GETVMTHREAD_ERROR_ON_VIRTUALTHREAD)
&& IS_JAVA_LANG_VIRTUALTHREAD(currentThread, currentThread->threadObject)
) {
return vThreadError;
}
return JVMTI_ERROR_INVALID_THREAD;
#endif /* JAVA_SPEC_VERSION >= 19 */
*vmThreadPtr = currentThread;
return JVMTI_ERROR_NONE;
} else {
threadObject = J9_JNI_UNWRAP_REFERENCE(thread);
if (!IS_JAVA_LANG_THREAD(currentThread, threadObject)) {
return JVMTI_ERROR_INVALID_THREAD;
}
#if JAVA_SPEC_VERSION >= 19
if (OMR_ARE_ANY_BITS_SET(flags, J9JVMTI_GETVMTHREAD_ERROR_ON_VIRTUALTHREAD)
&& IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject)
) {
return vThreadError;
}
#endif /* JAVA_SPEC_VERSION >= 19 */
if (currentThread->threadObject == threadObject) {
*vmThreadPtr = currentThread;
return JVMTI_ERROR_NONE;
Expand All @@ -122,7 +139,7 @@ getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr,
/* Make sure the vmThread stays alive while it is being used. */
omrthread_monitor_enter(vm->vmThreadListMutex);
#if JAVA_SPEC_VERSION >= 19
isVirtualThread = IS_VIRTUAL_THREAD(currentThread, threadObject);
isVirtualThread = IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject);
if (isVirtualThread) {
omrthread_monitor_enter(vm->liveVirtualThreadListMutex);

Expand All @@ -148,7 +165,7 @@ getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr,
}

if (!isThreadAlive) {
if (mustBeAlive) {
if (OMR_ARE_ANY_BITS_SET(flags, J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD)) {
#if JAVA_SPEC_VERSION >= 19
if (isVirtualThread) {
omrthread_monitor_exit(vm->liveVirtualThreadListMutex);
Expand All @@ -174,8 +191,9 @@ getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr,
omrthread_monitor_exit(vm->vmThreadListMutex);

#if JAVA_SPEC_VERSION >= 19
if (mustBeAlive) {
Assert_JVMTI_true((NULL != targetThread) || isVirtualThread);
if (isThreadAlive && !isVirtualThread) {
/* targetThread should not be NULL for alive non-virtual threads. */
Assert_JVMTI_true(NULL != targetThread);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

Expand All @@ -190,7 +208,7 @@ releaseVMThread(J9VMThread *currentThread, J9VMThread *targetThread, jthread thr
#if JAVA_SPEC_VERSION >= 19
if (NULL != thread) {
j9object_t threadObject = J9_JNI_UNWRAP_REFERENCE(thread);
if ((currentThread->threadObject != threadObject) && IS_VIRTUAL_THREAD(currentThread, threadObject)) {
if ((currentThread->threadObject != threadObject) && IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject)) {
J9JavaVM *vm = currentThread->javaVM;
I_64 vthreadInspectorCount = 0;
/* Release the virtual thread (allow it to die) now that we are no longer inspecting it. */
Expand Down Expand Up @@ -788,7 +806,10 @@ getVirtualThreadState(J9VMThread *currentThread, jthread thread)
J9VMThread *targetThread = NULL;
Assert_JVMTI_notNull(thread);
Assert_JVMTI_mustHaveVMAccess(currentThread);
if (JVMTI_ERROR_NONE == getVMThread(currentThread, thread, &targetThread, FALSE, FALSE)) {
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_NULL_JTHREAD);
if (JVMTI_ERROR_NONE == rc) {
if (NULL != targetThread) {
vm->internalVMFunctions->haltThreadForInspection(currentThread, targetThread);
rc = getThreadState(currentThread, targetThread->carrierThreadObject);
Expand Down Expand Up @@ -1604,7 +1625,9 @@ setEventNotificationMode(J9JVMTIEnv * j9env, J9VMThread * currentThread, jint mo
} else {
j9object_t threadObject = J9_JNI_UNWRAP_REFERENCE(event_thread);
J9VMThread *vmThreadForTLS = NULL;
rc = getVMThread(currentThread, event_thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, event_thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc != JVMTI_ERROR_NONE) {
goto done;
}
Expand All @@ -1616,10 +1639,10 @@ setEventNotificationMode(J9JVMTIEnv * j9env, J9VMThread * currentThread, jint mo
goto done;
}
if (NULL == targetThread) {
/* targetThread is NULL only for virtual threads, as per the assertion in getVMThread,
* when mustBeAlive is TRUE. vmThreadForTLS is only used to acquire J9JavaVM in
* createThreadData and jvmtiTLSGet. If targetThread is NULL, currentThread is passed
* to createThreadData and jvmtiTLSGet for retrieving J9JavaVM in JDK19+.
/* targetThread is NULL only for virtual threads, as per the assertion in getVMThread.
* vmThreadForTLS is only used to acquire J9JavaVM in createThreadData and jvmtiTLSGet.
* If targetThread is NULL, currentThread is passed to createThreadData and jvmtiTLSGet
* for retrieving J9JavaVM in JDK19+.
*/
vmThreadForTLS = currentThread;
}
Expand Down Expand Up @@ -1915,7 +1938,7 @@ genericWalkStackFramesHelper(J9VMThread *currentThread, J9VMThread *targetThread
UDATA rc = J9_STACKWALK_RC_NONE;

#if JAVA_SPEC_VERSION >= 19
if (IS_VIRTUAL_THREAD(currentThread, threadObject)) {
if (IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject)) {
if (NULL != targetThread) {
walkState->walkThread = targetThread;
rc = vm->walkStackFrames(currentThread, walkState);
Expand Down Expand Up @@ -1947,7 +1970,7 @@ J9VMContinuation *
getJ9VMContinuationToWalk(J9VMThread *currentThread, J9VMThread *targetThread, j9object_t threadObject)
{
J9VMContinuation *continuation = NULL;
if (IS_VIRTUAL_THREAD(currentThread, threadObject)) {
if (IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject)) {
if (NULL == targetThread) {
/* An unmounted virtual thread will have a valid J9VMContinuation. */
j9object_t contObject = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CONT(currentThread, threadObject);
Expand Down
4 changes: 3 additions & 1 deletion runtime/jvmti/jvmtiLocalVariable.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,9 @@ jvmtiGetOrSetLocal(jvmtiEnv *env,
J9VMThread *targetThread = NULL;

vm->internalVMFunctions->internalEnterVMFromJNI(currentThread);
rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc == JVMTI_ERROR_NONE) {
J9StackWalkState walkState = {0};
BOOLEAN objectFetched = FALSE;
Expand Down
36 changes: 20 additions & 16 deletions runtime/jvmti/jvmtiStackFrame.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ jvmtiGetStackTrace(jvmtiEnv* env,
ENSURE_NON_NULL(frame_buffer);
ENSURE_NON_NULL(count_ptr);

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc == JVMTI_ERROR_NONE) {
j9object_t threadObject = (NULL == thread) ? currentThread->threadObject : J9_JNI_UNWRAP_REFERENCE(thread);
#if JAVA_SPEC_VERSION >= 19
Expand Down Expand Up @@ -216,9 +218,9 @@ jvmtiGetThreadListStackTraces(jvmtiEnv* env,
while (0 != thread_count) {
jthread thread = *thread_list;

if ((NULL != thread) && IS_VIRTUAL_THREAD(currentThread, J9_JNI_UNWRAP_REFERENCE(thread))) {
if ((NULL != thread) && IS_JAVA_LANG_VIRTUALTHREAD(currentThread, J9_JNI_UNWRAP_REFERENCE(thread))) {
J9VMThread *targetThread = NULL;
getVMThread(currentThread, thread, &targetThread, TRUE, FALSE);
getVMThread(currentThread, thread, &targetThread, JVMTI_ERROR_NONE, 0);
}
++thread_list;
--thread_count;
Expand Down Expand Up @@ -254,13 +256,13 @@ jvmtiGetThreadListStackTraces(jvmtiEnv* env,
}

threadObject = J9_JNI_UNWRAP_REFERENCE(thread);
if (!isSameOrSuperClassOf(J9VMJAVALANGTHREAD_OR_NULL(vm), J9OBJECT_CLAZZ(currentThread, threadObject))) {
if (!IS_JAVA_LANG_THREAD(currentThread, threadObject)) {
rc = JVMTI_ERROR_INVALID_THREAD;
goto deallocate;
}

#if JAVA_SPEC_VERSION >= 19
if (IS_VIRTUAL_THREAD(currentThread, threadObject)) {
if (IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject)) {
isVirtual = TRUE;
j9object_t carrierThread = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObject);
jint vthreadState = J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, threadObject);
Expand Down Expand Up @@ -323,7 +325,7 @@ jvmtiGetThreadListStackTraces(jvmtiEnv* env,

if (NULL != thread) {
j9object_t threadObject = J9_JNI_UNWRAP_REFERENCE(thread);
if (IS_VIRTUAL_THREAD(currentThread, threadObject)) {
if (IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject)) {
J9VMThread *targetThread = NULL;
j9object_t carrierThread = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObject);
if (NULL != carrierThread) {
Expand Down Expand Up @@ -371,7 +373,9 @@ jvmtiGetFrameCount(jvmtiEnv* env,

ENSURE_NON_NULL(count_ptr);

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc == JVMTI_ERROR_NONE) {
j9object_t threadObject = (NULL == thread) ? currentThread->threadObject : J9_JNI_UNWRAP_REFERENCE(thread);
J9StackWalkState walkState;
Expand Down Expand Up @@ -434,13 +438,9 @@ jvmtiPopFrame(jvmtiEnv* env,
ENSURE_PHASE_LIVE(env);
ENSURE_CAPABILITY(env, can_pop_frame);

#if JAVA_SPEC_VERSION >= 19
if (NULL != thread) {
ENSURE_JTHREAD_NOT_VIRTUAL(currentThread, thread, JVMTI_ERROR_OPAQUE_FRAME);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

rc = getVMThread(currentThread, thread, &targetThread, FALSE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_OPAQUE_FRAME,
J9JVMTI_GETVMTHREAD_ERROR_ON_NULL_JTHREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_VIRTUALTHREAD);
if (rc == JVMTI_ERROR_NONE) {
/* Does this thread need to be suspended at an event? */
vm->internalVMFunctions->haltThreadForInspection(currentThread, targetThread);
Expand Down Expand Up @@ -500,7 +500,9 @@ jvmtiGetFrameLocation(jvmtiEnv *env,
ENSURE_NON_NULL(method_ptr);
ENSURE_NON_NULL(location_ptr);

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc == JVMTI_ERROR_NONE) {
j9object_t threadObject = (NULL == thread) ? currentThread->threadObject : J9_JNI_UNWRAP_REFERENCE(thread);
J9StackWalkState walkState = {0};
Expand Down Expand Up @@ -574,7 +576,9 @@ jvmtiNotifyFramePop(jvmtiEnv *env,

ENSURE_NON_NEGATIVE(depth);

rc = getVMThread(currentThread, thread, &targetThread, TRUE, TRUE);
rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (JVMTI_ERROR_NONE == rc) {
#if JAVA_SPEC_VERSION >= 19
BOOLEAN isVThreadSuspended = FALSE;
Expand Down
Loading