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

[JDK21] Add support for JVMTI ForceEarlyReturn #17874

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
48 changes: 36 additions & 12 deletions runtime/jvmti/jvmtiForceEarlyReturn.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,43 @@ jvmtiForceEarlyReturn(jvmtiEnv* env,
ENSURE_CAPABILITY(env, can_force_early_return);

rc = getVMThread(
currentThread, thread, &targetThread, JVMTI_ERROR_OPAQUE_FRAME,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_VIRTUALTHREAD);
currentThread, thread, &targetThread, JVMTI_ERROR_NONE,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (rc == JVMTI_ERROR_NONE) {
/* Does this thread need to be suspended at an event? */
vm->internalVMFunctions->haltThreadForInspection(currentThread, targetThread);
if ((currentThread != targetThread) && !(targetThread->publicFlags & J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND)) {
/* A thread other then current must be suspended in order to force early return */
#if JAVA_SPEC_VERSION >= 21
j9object_t threadObject = NULL;
/* Error if a virtual thread is unmounted since it won't be able to
* force an early return.
*/
if (NULL == targetThread) {
rc = JVMTI_ERROR_OPAQUE_FRAME;
goto release;
}
threadObject = (NULL == thread) ? currentThread->threadObject : J9_JNI_UNWRAP_REFERENCE(thread);
#endif /* JAVA_SPEC_VERSION >= 21 */

if ((currentThread != targetThread)
#if JAVA_SPEC_VERSION >= 21
&& (0 == J9OBJECT_U32_LOAD(currentThread, threadObject, vm->isSuspendedInternalOffset))
#else /* JAVA_SPEC_VERSION >= 21 */
&& OMR_ARE_NO_BITS_SET(targetThread->publicFlags, J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND)
#endif /* JAVA_SPEC_VERSION >= 21 */
) {
/* All threads except the current thread must be suspended in order to force an early return. */
rc = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
} else {
J9StackWalkState walkState;

rc = findDecompileInfo(currentThread, targetThread, 0, &walkState);
J9StackWalkState walkState = {0};
J9VMThread *threadToWalk = targetThread;
#if JAVA_SPEC_VERSION >= 21
J9VMThread stackThread = {0};
J9VMEntryLocalStorage els = {0};
J9VMContinuation *continuation = getJ9VMContinuationToWalk(currentThread, targetThread, threadObject);
if (NULL != continuation) {
vm->internalVMFunctions->copyFieldsFromContinuation(currentThread, &stackThread, &els, continuation);
threadToWalk = &stackThread;
}
#endif /* JAVA_SPEC_VERSION >= 21 */
rc = findDecompileInfo(currentThread, threadToWalk, 0, &walkState);
if (JVMTI_ERROR_NONE == rc) {
J9Method *method = walkState.userData3;
J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
Expand Down Expand Up @@ -201,7 +226,7 @@ jvmtiForceEarlyReturn(jvmtiEnv* env,
if (NULL != walkState.jitInfo) {
if (NULL == vm->jitConfig->jitAddDecompilationForFramePop(currentThread, &walkState)) {
rc = JVMTI_ERROR_OUT_OF_MEMORY;
goto resume;
goto release;
}
}
vm->internalVMFunctions->setHaltFlag(targetThread, J9_PUBLIC_FLAGS_POP_FRAMES_INTERRUPT);
Expand Down Expand Up @@ -231,8 +256,7 @@ jvmtiForceEarlyReturn(jvmtiEnv* env,
}
}
}
resume:
vm->internalVMFunctions->resumeThreadForInspection(currentThread, targetThread);
release:
releaseVMThread(currentThread, targetThread, thread);
}
done:
Expand Down
4 changes: 2 additions & 2 deletions runtime/jvmti/jvmtiStackFrame.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,8 @@ jvmtiPopFrame(jvmtiEnv* env,
J9VMEntryLocalStorage els = {0};
J9VMContinuation *continuation = getJ9VMContinuationToWalk(currentThread, targetThread, threadObject);
if (NULL != continuation) {
vm->internalVMFunctions->copyFieldsFromContinuation(currentThread, &stackThread, &els, continuation);
threadToWalk = &stackThread;
vm->internalVMFunctions->copyFieldsFromContinuation(currentThread, &stackThread, &els, continuation);
threadToWalk = &stackThread;
}
#endif /* JAVA_SPEC_VERSION >= 21 */
walkState.walkThread = threadToWalk;
Expand Down