Skip to content

Commit

Permalink
ScopedMemoryAccess closeScope0 synchronization
Browse files Browse the repository at this point in the history
There are gaps where async exceptions are not processed in time (e.g.
JIT compiled code in a loop). Threads will wait in closeScope0 until
J9VMThread->scopedError (async exception) is transferred to
J9VMThread->currentException. The wait prevents a MemorySession to be
closed until no more operations are being performed on it.

Related: eclipse-openj9#13211

Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
  • Loading branch information
babsingh authored and AswathySK committed Jun 4, 2024
1 parent a35987d commit 5626399
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 0 deletions.
17 changes: 17 additions & 0 deletions runtime/jcl/common/jdk_internal_misc_ScopedMemoryAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject insta
setHaltFlag(walkThread, J9_PUBLIC_FLAGS_CLOSE_SCOPE);
walkThread->scopedError = errorObj;
walkThread->closeScopeObj = closeScopeObj;
/* Atomic add is not needed since exclusive VM access has been acquired. */
vm->closeScopeNotifyCount += 1;
#else /* JAVA_SPEC_VERSION >= 22 */
scopeFound = JNI_TRUE;
break;
Expand All @@ -99,6 +101,21 @@ Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject insta
}

vmFuncs->internalExitVMToJNI(currentThread);

#if JAVA_SPEC_VERSION >= 22
/* There are gaps where async exceptions are not processed in time
* (e.g. JIT compiled code in a loop). Wait until J9VMThread->scopedError
* (async exception) is transferred to J9VMThread->currentException. The
* wait prevents a MemorySession to be closed until no more operations are
* being performed on it.
*/
omrthread_monitor_enter(vm->closeScopeMutex);
while (0 != vm->closeScopeNotifyCount) {
omrthread_monitor_wait(vm->closeScopeMutex);
}
omrthread_monitor_exit(vm->closeScopeMutex);
#endif /* JAVA_SPEC_VERSION >= 22 */

#if JAVA_SPEC_VERSION <= 21
return !scopeFound;
#endif /* JAVA_SPEC_VERSION <= 21 */
Expand Down
4 changes: 4 additions & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -6053,6 +6053,10 @@ typedef struct J9JavaVM {
/* Pool for allocating J9MemberNameListNode. */
struct J9Pool *memberNameListNodePool;
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
#if JAVA_SPEC_VERSION >= 22
omrthread_monitor_t closeScopeMutex;
UDATA closeScopeNotifyCount;
#endif /* JAVA_SPEC_VERSION >= 22 */
} J9JavaVM;

#define J9VM_PHASE_STARTUP 1
Expand Down
17 changes: 17 additions & 0 deletions runtime/vm/AsyncMessageHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,37 @@ javaCheckAsyncMessages(J9VMThread *currentThread, UDATA throwExceptions)
#if JAVA_SPEC_VERSION >= 22
/* Check for a close scope request. */
if (J9_ARE_ANY_BITS_SET(publicFlags, J9_PUBLIC_FLAGS_CLOSE_SCOPE)) {
bool notifyThreads = false;
if (hasMemoryScope(currentThread, currentThread->closeScopeObj)) {
if (throwExceptions) {
currentThread->currentException = currentThread->scopedError;
currentThread->scopedError = NULL;
currentThread->closeScopeObj = NULL;
clearEventFlag(currentThread, J9_PUBLIC_FLAGS_CLOSE_SCOPE);
result = J9_CHECK_ASYNC_THROW_EXCEPTION;
notifyThreads = true;
} else {
VM_VMHelpers::indicateAsyncMessagePending(currentThread);
}
} else {
currentThread->scopedError = NULL;
currentThread->closeScopeObj = NULL;
clearEventFlag(currentThread, J9_PUBLIC_FLAGS_CLOSE_SCOPE);
notifyThreads = true;
}
if (notifyThreads) {
J9JavaVM *vm = currentThread->javaVM;
/* Notify all threads that are waiting in ScopedMemoryAccess closeScope0
* to continue since the MemorySession(s) will no longer be used and it
* is safe to close them.
*/
omrthread_monitor_enter(vm->closeScopeMutex);
Assert_VM_true(vm->closeScopeNotifyCount > 0);
vm->closeScopeNotifyCount -= 1;
if (0 == vm->closeScopeNotifyCount) {
omrthread_monitor_notify_all(vm->closeScopeMutex);
}
omrthread_monitor_exit(vm->closeScopeMutex);
}
break;
}
Expand Down
7 changes: 7 additions & 0 deletions runtime/vm/jvminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,13 @@ freeJavaVM(J9JavaVM * vm)
}
#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */

#if JAVA_SPEC_VERSION >= 22
if (NULL != vm->closeScopeMutex) {
omrthread_monitor_destroy(vm->closeScopeMutex);
vm->closeScopeMutex = NULL;
}
#endif /* JAVA_SPEC_VERSION >= 22 */

j9mem_free_memory(vm);

if (NULL != tmpLib->self_handle) {
Expand Down
4 changes: 4 additions & 0 deletions runtime/vm/vmthinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ UDATA initializeVMThreading(J9JavaVM *vm)
omrthread_monitor_init_with_name(&vm->delayedLockingOperationsMutex, 0, "Delayed locking operations mutex") ||
#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */

#if JAVA_SPEC_VERSION >= 22
omrthread_monitor_init_with_name(&vm->closeScopeMutex, 0, "ScopedMemoryAccess closeScope0 mutex") ||
#endif /* JAVA_SPEC_VERSION >= 22 */

initializeMonitorTable(vm)
)
{
Expand Down

0 comments on commit 5626399

Please sign in to comment.