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

Update ScopedMemoryAccess_closeScope0 for JDK22 #19167

Merged
merged 1 commit into from
Mar 18, 2024
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
6 changes: 6 additions & 0 deletions runtime/gc_structs/VMThreadSlotIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ GC_VMThreadSlotIterator::nextSlot()
case 11:
return &(_vmThread->scopedValueCache);
#endif /* JAVA_SPEC_VERSION >= 19 */
#if JAVA_SPEC_VERSION >= 22
case 12:
return &(_vmThread->scopedError);
case 13:
return &(_vmThread->closeScopeObj);
#endif /* JAVA_SPEC_VERSION >= 22 */
default:
break;
}
Expand Down
75 changes: 32 additions & 43 deletions runtime/jcl/common/jdk_internal_misc_ScopedMemoryAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,49 +37,28 @@ Java_jdk_internal_misc_ScopedMemoryAccess_registerNatives(JNIEnv *env, jclass cl
{
}

static UDATA
closeScope0FrameWalkFunction(J9VMThread *vmThread, J9StackWalkState *walkState)
{
if (JNI_FALSE == *(jboolean *)walkState->userData2) {
/* scope has been found */
return J9_STACKWALK_STOP_ITERATING;
}
return J9_STACKWALK_KEEP_ITERATING;
}

static void
closeScope0OSlotWalkFunction(J9VMThread *vmThread, J9StackWalkState *walkState, j9object_t *slot, const void *stackLocation)
{
J9Method *method = walkState->method;
if (NULL != method) {
J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
if (NULL != romMethod && J9ROMMETHOD_HAS_EXTENDED_MODIFIERS(romMethod)) {
U_32 extraModifiers = getExtendedModifiersDataFromROMMethod(romMethod);
if (J9ROMMETHOD_HAS_SCOPED_ANNOTATION(extraModifiers)) {
if (*slot == J9_JNI_UNWRAP_REFERENCE(walkState->userData1)) {
*(jboolean *)walkState->userData2 = JNI_FALSE;
}
}
}
}
}

/**
* For each thread, walk Java stack and look for the scope instance. Methods that can take and access a scope
* instance are marked with the "@Scoped" extended modifier. If the scope instance is found in a method, that
* method is accessing the memory segment associated with the scope and thus closing the scope will fail.
*/
#if JAVA_SPEC_VERSION >= 22
void JNICALL
Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject instance, jobject scope, jobject error)
#elif (JAVA_SPEC_VERSION >= 19) && (JAVA_SPEC_VERSION <= 21) /* JAVA_SPEC_VERSION >= 22 */
jboolean JNICALL
#if JAVA_SPEC_VERSION >= 19
Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject instance, jobject scope)
#else /* JAVA_SPEC_VERSION >= 19 */
#else /* JAVA_SPEC_VERSION >= 22 */
jboolean JNICALL
Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject instance, jobject scope, jobject exception)
#endif /* JAVA_SPEC_VERSION >= 19 */
#endif /* JAVA_SPEC_VERSION >= 22 */
{
J9VMThread *currentThread = (J9VMThread *)env;
J9JavaVM *vm = currentThread->javaVM;
const J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
jboolean scopeNotFound = JNI_TRUE;
#if JAVA_SPEC_VERSION <= 21
jboolean scopeFound = JNI_FALSE;
#endif /* JAVA_SPEC_VERSION <= 21 */

vmFuncs->internalEnterVMFromJNI(currentThread);

Expand All @@ -88,21 +67,29 @@ Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject insta
} else {
vmFuncs->acquireExclusiveVMAccess(currentThread);
J9VMThread *walkThread = J9_LINKED_LIST_START_DO(vm->mainThread);
j9object_t closeScopeObj = J9_JNI_UNWRAP_REFERENCE(scope);
#if JAVA_SPEC_VERSION >= 22
j9object_t errorObj = J9_JNI_UNWRAP_REFERENCE(error);
#endif /* JAVA_SPEC_VERSION >= 22 */
while (NULL != walkThread) {
if (VM_VMHelpers::threadCanRunJavaCode(walkThread)) {
J9StackWalkState walkState;
walkState.walkThread = walkThread;
walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_ITERATE_O_SLOTS;
walkState.skipCount = 0;
walkState.userData1 = (void *)scope;
walkState.userData2 = (void *)&scopeNotFound;
walkState.frameWalkFunction = closeScope0FrameWalkFunction;
walkState.objectSlotWalkFunction = closeScope0OSlotWalkFunction;
#if JAVA_SPEC_VERSION >= 22
/* Skip since an exception is already pending to be thrown.*/
if (NULL != walkThread->scopedError) {
continue;
}
#endif /* JAVA_SPEC_VERSION >= 22 */

vm->walkStackFrames(walkThread, &walkState);
if (JNI_FALSE == *(jboolean *)walkState.userData2) {
/* scope found */
if (vmFuncs->hasMemoryScope(walkThread, closeScopeObj)) {
/* Scope found. */
#if JAVA_SPEC_VERSION >= 22
setHaltFlag(walkThread, J9_PUBLIC_FLAGS_CLOSE_SCOPE);
walkThread->scopedError = errorObj;
walkThread->closeScopeObj = closeScopeObj;
#else /* JAVA_SPEC_VERSION >= 22 */
scopeFound = JNI_TRUE;
break;
#endif /* JAVA_SPEC_VERSION >= 22 */
}
}

Expand All @@ -112,7 +99,9 @@ Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject insta
}

vmFuncs->internalExitVMToJNI(currentThread);
return scopeNotFound;
#if JAVA_SPEC_VERSION <= 21
return !scopeFound;
#endif /* JAVA_SPEC_VERSION <= 21 */
}
#endif /* JAVA_SPEC_VERSION >= 16 */

Expand Down
2 changes: 1 addition & 1 deletion runtime/oti/j9consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ extern "C" {
#define J9_PUBLIC_FLAGS_THREAD_PARKED 0x20000
#define J9_PUBLIC_FLAGS_EXCLUSIVE_SET_NOT_SAFE 0x40000
#define J9_PUBLIC_FLAGS_THREAD_TIMED 0x80000
#define J9_PUBLIC_FLAGS_UNUSED_0x100000 0x100000
#define J9_PUBLIC_FLAGS_CLOSE_SCOPE 0x100000
#define J9_PUBLIC_FLAGS_HALT_THREAD_FOR_CHECKPOINT 0x200000
#define J9_PUBLIC_FLAGS_JNI_CRITICAL_REGION 0x400000
#define J9_PUBLIC_FLAGS_POP_FRAMES_INTERRUPT 0x800000
Expand Down
5 changes: 5 additions & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5074,6 +5074,7 @@ typedef struct J9InternalVMFunctions {
float (JNICALL *native2InterpJavaUpcallF)(struct J9UpcallMetaData *data, void *argsListPointer);
double (JNICALL *native2InterpJavaUpcallD)(struct J9UpcallMetaData *data, void *argsListPointer);
U_8 * (JNICALL *native2InterpJavaUpcallStruct)(struct J9UpcallMetaData *data, void *argsListPointer);
BOOLEAN (*hasMemoryScope)(struct J9VMThread *walkThread, j9object_t scope);
#endif /* JAVA_SPEC_VERSION >= 16 */
#if JAVA_SPEC_VERSION >= 19
void (*copyFieldsFromContinuation)(struct J9VMThread *currentThread, struct J9VMThread *vmThread, struct J9VMEntryLocalStorage *els, struct J9VMContinuation *continuation);
Expand Down Expand Up @@ -5440,6 +5441,10 @@ typedef struct J9VMThread {
#if JAVA_SPEC_VERSION >= 21
BOOLEAN isInCriticalDownCall;
#endif /* JAVA_SPEC_VERSION >= 21 */
#if JAVA_SPEC_VERSION >= 22
j9object_t scopedError;
j9object_t closeScopeObj;
#endif /* JAVA_SPEC_VERSION >= 22 */
} J9VMThread;

#define J9VMTHREAD_ALIGNMENT 0x100
Expand Down
10 changes: 7 additions & 3 deletions runtime/oti/jclprots.h
Original file line number Diff line number Diff line change
Expand Up @@ -1284,12 +1284,16 @@ Java_jdk_internal_foreign_abi_UpcallStubs_freeUpcallStub0(JNIEnv *env, jclass cl
void JNICALL
Java_jdk_internal_misc_ScopedMemoryAccess_registerNatives(JNIEnv *env, jclass clazz);

#if JAVA_SPEC_VERSION >= 22
void JNICALL
Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject instance, jobject scope, jobject error);
#elif (JAVA_SPEC_VERSION >= 19) && (JAVA_SPEC_VERSION < 22) /* JAVA_SPEC_VERSION >= 22 */
jboolean JNICALL
#if JAVA_SPEC_VERSION >= 19
Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject instance, jobject scope);
#else /* JAVA_SPEC_VERSION >= 19 */
#else /* JAVA_SPEC_VERSION >= 22 */
jboolean JNICALL
Java_jdk_internal_misc_ScopedMemoryAccess_closeScope0(JNIEnv *env, jobject instance, jobject scope, jobject exception);
#endif /* JAVA_SPEC_VERSION >= 19 */
#endif /* JAVA_SPEC_VERSION >= 22 */
#endif /* JAVA_SPEC_VERSION >= 16 */

#if defined(J9VM_OPT_CRIU_SUPPORT)
Expand Down
10 changes: 10 additions & 0 deletions runtime/oti/vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -5258,6 +5258,16 @@ native2InterpJavaUpcallD(J9UpcallMetaData *data, void *argsListPointer);
U_8 * JNICALL
native2InterpJavaUpcallStruct(J9UpcallMetaData *data, void *argsListPointer);

/**
* @brief Check if the memory's scope exists on the stack of the thread.
*
* @param[in] walkThread the J9VMThread to be walked
* @param[in] scope the object searched during the walk
*
* @return true if scope is found, false if not
*/
BOOLEAN
hasMemoryScope(J9VMThread *walkThread, j9object_t scope);
#endif /* JAVA_SPEC_VERSION >= 16 */

#ifdef __cplusplus
Expand Down
89 changes: 89 additions & 0 deletions runtime/vm/AsyncMessageHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,74 @@

extern "C" {

#if JAVA_SPEC_VERSION >= 16
/**
* Frame walk function, which is used with hasMemoryScope.
*
* @param[in] vmThread the J9VMThread
* @param[in] walkState the stack walk state
*
* @return J9_STACKWALK_STOP_ITERATING to stop iterating, and
* J9_STACKWALK_KEEP_ITERATING to continue iterating
*/
static UDATA
closeScope0FrameWalkFunction(J9VMThread *vmThread, J9StackWalkState *walkState)
{
if (*(bool *)walkState->userData2) {
/* Scope has been found. */
return J9_STACKWALK_STOP_ITERATING;
}
return J9_STACKWALK_KEEP_ITERATING;
}

/**
* O-slot walk function, which is used with hasMemoryScope.
*
* @param[in] vmThread the J9VMThread
* @param[in] walkState the stack walk state
* @param[in] slot the O-slot pointer
* @param[in] stackLocation the stack location
*/
static void
closeScope0OSlotWalkFunction(J9VMThread *vmThread, J9StackWalkState *walkState, j9object_t *slot, const void *stackLocation)
{
J9Method *method = walkState->method;
if (NULL != method) {
J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
if (NULL != romMethod && J9ROMMETHOD_HAS_EXTENDED_MODIFIERS(romMethod)) {
U_32 extraModifiers = getExtendedModifiersDataFromROMMethod(romMethod);
if (J9ROMMETHOD_HAS_SCOPED_ANNOTATION(extraModifiers)) {
if (*slot == walkState->userData1) {
*(bool *)walkState->userData2 = true;
}
}
}
}
}

BOOLEAN
hasMemoryScope(J9VMThread *walkThread, j9object_t scope)
{
bool scopeFound = false;

if (NULL != scope) {
J9StackWalkState walkState;

walkState.walkThread = walkThread;
walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_ITERATE_O_SLOTS;
walkState.skipCount = 0;
walkState.userData1 = (void *)scope;
walkState.userData2 = (void *)&scopeFound;
walkState.frameWalkFunction = closeScope0FrameWalkFunction;
walkState.objectSlotWalkFunction = closeScope0OSlotWalkFunction;

walkThread->javaVM->walkStackFrames(walkThread, &walkState);
}

return scopeFound;
}
#endif /* JAVA_SPEC_VERSION >= 16 */

void
clearAsyncEventFlags(J9VMThread *vmThread, UDATA flags)
{
Expand Down Expand Up @@ -72,6 +140,27 @@ javaCheckAsyncMessages(J9VMThread *currentThread, UDATA throwExceptions)
result = J9_CHECK_ASYNC_POP_FRAMES;
break;
}
#if JAVA_SPEC_VERSION >= 22
/* Check for a close scope request. */
if (J9_ARE_ANY_BITS_SET(publicFlags, J9_PUBLIC_FLAGS_CLOSE_SCOPE)) {
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;
} else {
VM_VMHelpers::indicateAsyncMessagePending(currentThread);
}
} else {
currentThread->scopedError = NULL;
currentThread->closeScopeObj = NULL;
clearEventFlag(currentThread, J9_PUBLIC_FLAGS_CLOSE_SCOPE);
}
break;
}
#endif /* JAVA_SPEC_VERSION >= 22 */
/* Check for a thread halt request */
if (J9_ARE_ANY_BITS_SET(publicFlags, J9_PUBLIC_FLAGS_RELEASE_ACCESS_REQUIRED_MASK)) {
Assert_VM_false(J9_ARE_ANY_BITS_SET(publicFlags, J9_PUBLIC_FLAGS_NOT_AT_SAFE_POINT));
Expand Down
1 change: 1 addition & 0 deletions runtime/vm/intfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ J9InternalVMFunctions J9InternalFunctions = {
native2InterpJavaUpcallF,
native2InterpJavaUpcallD,
native2InterpJavaUpcallStruct,
hasMemoryScope,
#endif /* JAVA_SPEC_VERSION >= 16 */
#if JAVA_SPEC_VERSION >= 19
copyFieldsFromContinuation,
Expand Down