From a1cdacfa1755f1e6c839d52e430d9f401b4c28cd Mon Sep 17 00:00:00 2001 From: Babneet Singh Date: Wed, 8 Nov 2023 13:25:26 -0500 Subject: [PATCH] Re-fetch objects after VM access is released and reacquired Stale objects can manifest many issues. In this case, stale objects cause complex and intermittent synchronization issues. Related: https://github.com/eclipse-openj9/openj9/issues/17865 Related: https://github.com/eclipse-openj9/openj9/issues/17869 Related: https://github.com/eclipse-openj9/openj9/issues/18370 Signed-off-by: Babneet Singh --- runtime/jvmti/jvmtiHelpers.c | 15 +++++++++++---- runtime/vm/ContinuationHelpers.cpp | 7 ++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/runtime/jvmti/jvmtiHelpers.c b/runtime/jvmti/jvmtiHelpers.c index 4a617a7dfdb..6f48b1af470 100644 --- a/runtime/jvmti/jvmtiHelpers.c +++ b/runtime/jvmti/jvmtiHelpers.c @@ -143,10 +143,13 @@ getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr, #if JAVA_SPEC_VERSION >= 19 isVirtualThread = IS_JAVA_LANG_VIRTUALTHREAD(currentThread, threadObject); if (isVirtualThread) { + jint vthreadState = 0; + j9object_t carrierThread = NULL; vm->internalVMFunctions->acquireVThreadInspector(currentThread, thread, TRUE); - - jint vthreadState = J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, threadObject); - j9object_t carrierThread = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObject); + /* Re-fetch threadObject since acquireVThreadInspector can release and reacquire VM access. */ + threadObject = J9_JNI_UNWRAP_REFERENCE(thread); + vthreadState = J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, threadObject); + carrierThread = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(currentThread, threadObject); if (NULL != carrierThread) { targetThread = J9VMJAVALANGTHREAD_THREADREF(currentThread, carrierThread); } @@ -1659,7 +1662,7 @@ setEventNotificationMode(J9JVMTIEnv * j9env, J9VMThread * currentThread, jint mo if (event_thread == NULL) { eventMap = &(j9env->globalEventEnable); } else { - j9object_t threadObject = J9_JNI_UNWRAP_REFERENCE(event_thread); + j9object_t threadObject = NULL; J9VMThread *vmThreadForTLS = NULL; rc = getVMThread( currentThread, event_thread, &targetThread, JVMTI_ERROR_NONE, @@ -1668,6 +1671,10 @@ setEventNotificationMode(J9JVMTIEnv * j9env, J9VMThread * currentThread, jint mo goto done; } vmThreadForTLS = targetThread; + /* Fetch threadObject after getVMThread because getVMThread can release and + * reacquire VM access. + */ + threadObject = J9_JNI_UNWRAP_REFERENCE(event_thread); #if JAVA_SPEC_VERSION >= 19 rc = allocateTLS(vm, threadObject); if (JVMTI_ERROR_NONE != rc) { diff --git a/runtime/vm/ContinuationHelpers.cpp b/runtime/vm/ContinuationHelpers.cpp index 2ff86decc30..e88f7e7652c 100644 --- a/runtime/vm/ContinuationHelpers.cpp +++ b/runtime/vm/ContinuationHelpers.cpp @@ -531,9 +531,11 @@ acquireVThreadInspector(J9VMThread *currentThread, jobject thread, BOOLEAN spin) J9JavaVM *vm = currentThread->javaVM; J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions; MM_ObjectAccessBarrierAPI objectAccessBarrier = MM_ObjectAccessBarrierAPI(currentThread); - j9object_t threadObj = J9_JNI_UNWRAP_REFERENCE(thread); - I_64 vthreadInspectorCount; + j9object_t threadObj = NULL; + I_64 vthreadInspectorCount = 0; retry: + /* Consistently re-fetch threadObj for all the cases below. */ + threadObj = J9_JNI_UNWRAP_REFERENCE(thread); vthreadInspectorCount = J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset); if (vthreadInspectorCount < 0) { /* Thread is in transition, wait. */ @@ -541,7 +543,6 @@ acquireVThreadInspector(J9VMThread *currentThread, jobject thread, BOOLEAN spin) VM_AtomicSupport::yieldCPU(); /* After wait, the thread may suspend here. */ vmFuncs->internalEnterVMFromJNI(currentThread); - threadObj = J9_JNI_UNWRAP_REFERENCE(thread); if (spin) { goto retry; } else {