Skip to content

Commit

Permalink
[JDK21] Add support for JVMTI StopThread
Browse files Browse the repository at this point in the history
Previously, StopThread returned JVMTI_ERROR_UNSUPPORTED_OPERATION for
a virtual thread.

In JDK21, StopThread includes support for virtual threads as per the
JVMTI specification:
- Error if a virtual thread is not suspended and not the current
  thread.
- Error if a virtual thread is unomunted since it won't be able to
  throw an asynchronous exception from the current frame.

Related:
- #17717
- #17718

Also, StopThread should not clear the
J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND flag. This behaviour is not
documented in the JVMTI specification. It causes incorrect behaviour
for ResumeThread when the following sequence of JVMTI functions are
invoked: SuspendThread -> StopThread -> ResumeThread.

Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
  • Loading branch information
babsingh committed Jul 17, 2023
1 parent e8bc291 commit a9f1c91
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions runtime/jvmti/jvmtiThread.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,21 +391,39 @@ jvmtiStopThread(jvmtiEnv *env,

rc = getVMThread(
currentThread, thread, &targetThread,
#if JAVA_SPEC_VERSION >= 19
JVMTI_ERROR_UNSUPPORTED_OPERATION,
#else /* JAVA_SPEC_VERSION >= 19 */
JVMTI_ERROR_NONE,
#endif /* JAVA_SPEC_VERSION >= 19 */
J9JVMTI_GETVMTHREAD_ERROR_ON_NULL_JTHREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_VIRTUALTHREAD);
J9JVMTI_GETVMTHREAD_ERROR_ON_NULL_JTHREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (JVMTI_ERROR_NONE == rc) {
#if JAVA_SPEC_VERSION >= 21
j9object_t threadObject = (NULL == thread) ? currentThread->threadObject : J9_JNI_UNWRAP_REFERENCE(thread);

/* Error if a virtual thread is not suspended and not the current thread. */
if ((currentThread != targetThread)
&& (0 == J9OBJECT_U32_LOAD(currentThread, threadObject, vm->isSuspendedInternalOffset))
&& IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject)
) {
rc = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
goto release;
}

/* Error if a virtual thread is unmounted since it won't be able to throw an
* asynchronous exception from the current frame.
*/
if (NULL == targetThread) {
rc = JVMTI_ERROR_OPAQUE_FRAME;
goto release;
}
#endif /* JAVA_SPEC_VERSION >= 21 */
omrthread_monitor_enter(targetThread->publicFlagsMutex);
if (OMR_ARE_NO_BITS_SET(targetThread->publicFlags, J9_PUBLIC_FLAGS_STOPPED)) {
omrthread_priority_interrupt(targetThread->osThread);
targetThread->stopThrowable = J9_JNI_UNWRAP_REFERENCE(exception);
clearHaltFlag(targetThread, J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND);
setHaltFlag(targetThread, J9_PUBLIC_FLAGS_STOP);
}
omrthread_monitor_exit(targetThread->publicFlagsMutex);
#if JAVA_SPEC_VERSION >= 21
release:
#endif /* JAVA_SPEC_VERSION >= 21 */
releaseVMThread(currentThread, targetThread, thread);
}
done:
Expand Down

0 comments on commit a9f1c91

Please sign in to comment.