diff --git a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java index ed2c12c0f1d..3b21ff42ad4 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java +++ b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java @@ -189,6 +189,9 @@ void clear() { private static synchronized native void resolveRequiredFields(); private native void initCifNativeThunkData(String[] argLayouts, String retLayout, boolean newArgTypes, int varArgIndex); private native long invokeNative( + /*[IF JAVA_SPEC_VERSION >= 24]*/ + Object returnStateMemBase, + /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ /*[IF JAVA_SPEC_VERSION >= 22]*/ Object[] bases, long[] offsets, @@ -887,9 +890,29 @@ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator * Note: memArgScopeSet is not empty with the downcall address added to the set. */ /*[IF JAVA_SPEC_VERSION >= 21]*/ + /*[IF JAVA_SPEC_VERSION >= 24]*/ + long returnStateMemAddr; + Object returnStateMemBase; + if (linkerOpts.hasCapturedCallState() && !stateSegmt.isNative()) { + /* The CaptureCallState option can only use heap memory if allowed by the Critical option. */ + if (!linkerOpts.isCritical()) { + throw new IllegalArgumentException("Heap segment not allowed"); + } + AbstractMemorySegmentImpl segment = (AbstractMemorySegmentImpl)stateSegmt; + returnStateMemAddr = segment.unsafeGetOffset(); + returnStateMemBase = segment.unsafeGetBase(); + } else { + returnStateMemAddr = getValidDowncallMemAddr(stateSegmt); + returnStateMemBase = null; + } + /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ + try (Arena arena = Arena.ofConfined()) { SetDependency(arena.scope()); returnVal = invokeNative( + /*[IF JAVA_SPEC_VERSION >= 24]*/ + returnStateMemBase, + /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ /*[IF JAVA_SPEC_VERSION >= 22]*/ (info != null) ? info.bases : null, (info != null) ? info.offsets : null, @@ -897,7 +920,11 @@ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator /*[ELSE] JAVA_SPEC_VERSION >= 22 */ linkerOpts.isTrivial(), /*[ENDIF] JAVA_SPEC_VERSION >= 22 */ + /*[IF JAVA_SPEC_VERSION >= 24]*/ + returnStateMemAddr, + /*[ELSE] JAVA_SPEC_VERSION >= 24 */ getValidDowncallMemAddr(stateSegmt), + /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ retMemAddr, getValidDowncallMemAddr(downcallAddr), cifNativeThunkAddr, diff --git a/runtime/vm/BytecodeInterpreter.hpp b/runtime/vm/BytecodeInterpreter.hpp index e6a7aeaa91e..43d51041b44 100644 --- a/runtime/vm/BytecodeInterpreter.hpp +++ b/runtime/vm/BytecodeInterpreter.hpp @@ -5185,7 +5185,11 @@ class INTERPRETER_CLASS } #if JAVA_SPEC_VERSION >= 16 -#if JAVA_SPEC_VERSION >= 22 +#if JAVA_SPEC_VERSION >= 24 + /* openj9.internal.foreign.abi.InternalDowncallHandler: + * private native long invokeNative(Object returnStateMemBase, Object[] bases, long[] offsets, boolean isInCriticalDownCall, long returnStateMemAddr, long returnStructMemAddr, long functionAddr, long calloutThunk, long[] argValues); + */ +#elif JAVA_SPEC_VERSION >= 22 /* openj9.internal.foreign.abi.InternalDowncallHandler: * private native long invokeNative(Object[] bases, long[] offsets, boolean isInCriticalDownCall, long returnStateMemAddr, long returnStructMemAddr, long functionAddr, long calloutThunk, long[] argValues); */ @@ -5227,7 +5231,13 @@ class INTERPRETER_CLASS U_64 *ffiArgs = _currentThread->ffiArgs; U_64 sFfiArgs[16]; #if JAVA_SPEC_VERSION >= 22 +#if JAVA_SPEC_VERSION >= 24 + UDATA argSlots = 14; + UDATA returnStateMemAddr; + j9object_t returnStateMemBase = NULL; +#else /* JAVA_SPEC_VERSION >= 24 */ UDATA argSlots = 13; +#endif /* JAVA_SPEC_VERSION >= 24 */ I_32 *returnState = NULL; UDATA curPtrArgIdx = 0; j9object_t heapBase = NULL; @@ -5258,9 +5268,19 @@ class INTERPRETER_CLASS #if JAVA_SPEC_VERSION >= 21 /* The native memory is allocated at java level to save the execution state after performing the downcall. */ +#if JAVA_SPEC_VERSION >= 24 + returnStateMemAddr = (UDATA)*(I_64 *)(_sp + 7); /* returnStateMemAddr */ + returnStateMemBase = *(j9object_t *)(_sp + 12); /* returnStateMemBase */ + if (NULL != returnStateMemBase) { + returnState = (I_32 *)((UDATA)returnStateMemBase + returnStateMemAddr); + } else { + returnState = (I_32 *)returnStateMemAddr; + } +#else /* JAVA_SPEC_VERSION >= 24 */ returnState = (I_32 *)(UDATA)*(I_64 *)(_sp + 7); /* returnStateMemAddr */ +#endif /* JAVA_SPEC_VERSION >= 24 */ - /* Set the linker option to the current thread for the trivial downcall. */ + /* Set the linker option to the current thread for the critical downcall. */ _currentThread->isInCriticalDownCall = (0 == *(U_32*)(_sp + 9)) ? FALSE : TRUE; #endif /* JAVA_SPEC_VERSION >= 21 */ @@ -5465,7 +5485,7 @@ class INTERPRETER_CLASS done: #if JAVA_SPEC_VERSION >= 21 - /* Clear the trivial downcall flag. */ + /* Clear the critical downcall flag. */ _currentThread->isInCriticalDownCall = FALSE; #endif /* JAVA_SPEC_VERSION >= 21 */ diff --git a/runtime/vm/bindnatv.cpp b/runtime/vm/bindnatv.cpp index b71c3760f18..40e4c966d69 100644 --- a/runtime/vm/bindnatv.cpp +++ b/runtime/vm/bindnatv.cpp @@ -301,7 +301,9 @@ static inlMapping mappings[] = { { "Java_sun_reflect_Reflection_getClassAccessFlags__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_REFLECTION_GETCLASSACCESSFLAGS }, #endif /* JAVA_SPEC_VERSION >= 11 */ -#if JAVA_SPEC_VERSION >= 22 +#if JAVA_SPEC_VERSION >= 24 + { "Java_openj9_internal_foreign_abi_InternalDowncallHandler_invokeNative__Ljava_lang_Object_2_3Ljava_lang_Object_2_3JZJJJJ_3J", J9_BCLOOP_SEND_TARGET_INL_INTERNALDOWNCALLHANDLER_INVOKENATIVE }, +#elif JAVA_SPEC_VERSION >= 22 { "Java_openj9_internal_foreign_abi_InternalDowncallHandler_invokeNative___3Ljava_lang_Object_2_3JZJJJJ_3J", J9_BCLOOP_SEND_TARGET_INL_INTERNALDOWNCALLHANDLER_INVOKENATIVE }, #elif JAVA_SPEC_VERSION == 21 { "Java_openj9_internal_foreign_abi_InternalDowncallHandler_invokeNative__ZJJJJ_3J", J9_BCLOOP_SEND_TARGET_INL_INTERNALDOWNCALLHANDLER_INVOKENATIVE },