Skip to content

Commit 088b836

Browse files
authored
Merge pull request #17563 from ChengJin01/ffi_jtreg_liblookuptest_keep_downcall_addr_alive_jdk20_v0.39.0
[FFI/Jtreg_JDK20] Keep the downcall address alive for downcall (0.39)
2 parents 9076eed + b4ef68c commit 088b836

File tree

1 file changed

+31
-63
lines changed

1 file changed

+31
-63
lines changed

jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java

Lines changed: 31 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -278,14 +278,8 @@ private void validateMemScope(MemorySession memScope) throws IllegalStateExcepti
278278
private void validateMemScope(ResourceScope memScope) throws IllegalStateException
279279
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
280280
{
281-
if (!memScope.isAlive())
282-
{
283-
/*[IF JAVA_SPEC_VERSION == 19]*/
284-
String scopeName = "session";
285-
/*[ELSE] JAVA_SPEC_VERSION == 19 */
286-
String scopeName = "scope";
287-
/*[ENDIF] JAVA_SPEC_VERSION == 19 */
288-
throw new IllegalStateException("Already closed: attempted to access the memory value in a closed " + scopeName); //$NON-NLS-1$
281+
if (!memScope.isAlive()) {
282+
throw new IllegalStateException("Already closed: attempted to access the memory value in a closed scope");
289283
}
290284
}
291285
/*[ENDIF] JAVA_SPEC_VERSION >= 17 */
@@ -855,31 +849,29 @@ private void releaseScope() {
855849
}
856850
/*[ENDIF] JAVA_SPEC_VERSION >= 19 */
857851

858-
/*[IF JAVA_SPEC_VERSION >= 20]*/
859852
/* Return the valid downcall address by doing the validity check on the address's scope
860853
* in OpenJ9 since the related code and APIs were adjusted in JDK20 in which case the
861854
* scope check on the downcall in address() in OpenJDK was entirely removed.
862855
*/
856+
/*[IF JAVA_SPEC_VERSION >= 20]*/
863857
private long getValidDowncallAddr(MemorySegment downcallAddr) {
864858
validateMemScope(downcallAddr.scope());
865859
return downcallAddr.address();
866860
}
861+
/*[ELSE] JAVA_SPEC_VERSION >= 20 */
862+
private long getValidDowncallAddr(Addressable downcallAddr) {
863+
validateMemScope(downcallAddr.address().scope());
864+
return downcallAddr.address().toRawLongValue();
865+
}
867866
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
868867

869868
/* The method (bound by the method handle to the native code) intends to invoke the C function via the inlined code. */
870-
/*[IF JAVA_SPEC_VERSION >= 17]*/
871869
/*[IF JAVA_SPEC_VERSION >= 20]*/
872870
Object runNativeMethod(MemorySegment downcallAddr, SegmentAllocator segmtAllocator, MemorySegment stateSegmt, long[] args) throws IllegalArgumentException, IllegalStateException
873-
/*[ELSEIF JAVA_SPEC_VERSION == 18]*/
874-
Object runNativeMethod(NativeSymbol downcallAddr, SegmentAllocator segmtAllocator, long[] args) throws IllegalArgumentException, IllegalStateException
875-
/*[ELSE] JAVA_SPEC_VERSION == 18 */
871+
/*[ELSE] JAVA_SPEC_VERSION >= 20 */
876872
Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator, long[] args) throws IllegalArgumentException, IllegalStateException
877873
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
878-
/*[ELSE] JAVA_SPEC_VERSION >= 17 */
879-
Object runNativeMethod(long[] args)
880-
/*[ENDIF] JAVA_SPEC_VERSION >= 17 */
881874
{
882-
/*[IF JAVA_SPEC_VERSION >= 17]*/
883875
/*[IF JAVA_SPEC_VERSION >= 20]*/
884876
if (downcallAddr == MemorySegment.NULL)
885877
/*[ELSE] JAVA_SPEC_VERSION >= 20 */
@@ -888,7 +880,6 @@ Object runNativeMethod(long[] args)
888880
{
889881
throw new IllegalArgumentException("A non-null memory address is expected for downcall"); //$NON-NLS-1$
890882
}
891-
/*[ENDIF] JAVA_SPEC_VERSION >= 17 */
892883

893884
long retMemAddr = 0;
894885
MemorySegment retStruSegmt = null;
@@ -897,16 +888,11 @@ Object runNativeMethod(long[] args)
897888
* JDK20+.
898889
*/
899890
if ((realReturnLayout != null) && (realReturnLayout instanceof GroupLayout)) {
900-
/*[IF JAVA_SPEC_VERSION >= 17]*/
901891
/* The segment allocator (introduced since Java 17 to replace NativeScope in Java 16) is confined
902892
* by the memory session(Java19)/resource scope(Java17/18) defined in user applications in which
903893
* case the allocated memory will be released automatically once the session/scope is closed.
904894
*/
905895
retStruSegmt = segmtAllocator.allocate(realReturnLayout);
906-
/*[ELSE] JAVA_SPEC_VERSION >= 17 */
907-
/* The memory segment will be released explicitly by users via close() in java code in Java 16. */
908-
retStruSegmt = MemorySegment.allocateNative(realReturnLayout);
909-
/*[ENDIF] JAVA_SPEC_VERSION >= 17 */
910896
if (retStruSegmt == null) {
911897
throw new OutOfMemoryError("Failed to allocate native memory for the returned memory segment"); //$NON-NLS-1$
912898
}
@@ -917,49 +903,31 @@ Object runNativeMethod(long[] args)
917903
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
918904
}
919905

906+
/* Add the scope of the downcall address to the set to ensure it is kept alive
907+
* till the downcall is finished.
908+
*/
909+
/*[IF JAVA_SPEC_VERSION >= 20]*/
910+
addMemArgScope(downcallAddr.scope());
911+
/*[ELSE] JAVA_SPEC_VERSION >= 20 */
912+
addMemArgScope(downcallAddr.address().scope());
913+
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
914+
920915
long returnVal = 0;
921-
/* The session/scope associated with memory specific arguments must be kept alive in downcall since JDK17. */
922-
if (!memArgScopeSet.isEmpty()) {
923-
/*[IF JAVA_SPEC_VERSION > 17]*/
924-
/*[IF JAVA_SPEC_VERSION >= 20]*/
925-
try (Arena arena = Arena.openConfined())
926-
/*[ELSEIF JAVA_SPEC_VERSION == 19]*/
927-
try (MemorySession nativeSession = MemorySession.openConfined())
928-
/*[ELSEIF JAVA_SPEC_VERSION == 18]*/
929-
try (ResourceScope nativeScope = ResourceScope.newConfinedScope())
930-
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
931-
{
932-
/*[IF JAVA_SPEC_VERSION >= 20]*/
933-
SetDependency(arena.scope());
934-
/*[ELSEIF JAVA_SPEC_VERSION == 19]*/
935-
SetDependency(nativeSession);
936-
/*[ELSEIF JAVA_SPEC_VERSION == 18]*/
937-
SetDependency(nativeScope);
938-
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
939-
940-
/*[IF JAVA_SPEC_VERSION >= 20]*/
941-
returnVal = invokeNative(stateSegmt.address(), retMemAddr, getValidDowncallAddr(downcallAddr), cifNativeThunkAddr, args);
942-
/*[ELSE] JAVA_SPEC_VERSION >= 20 */
943-
returnVal = invokeNative(retMemAddr, downcallAddr.address().toRawLongValue(), cifNativeThunkAddr, args);
944-
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
945-
}
946-
/*[ELSE] JAVA_SPEC_VERSION > 17 */
947-
acquireScope();
948-
returnVal = invokeNative(retMemAddr, downcallAddr.address().toRawLongValue(), cifNativeThunkAddr, args);
949-
releaseScope();
950-
/*[ENDIF] JAVA_SPEC_VERSION > 17 */
951-
}
952-
else
953-
{
954-
/*[IF JAVA_SPEC_VERSION >= 20]*/
916+
/* The scope associated with memory specific arguments must be kept alive
917+
* during the downcall since JDK17, including the downcall adddress.
918+
*
919+
*Note: memArgScopeSet is not empty with the downcall address added to the set.
920+
*/
921+
/*[IF JAVA_SPEC_VERSION >= 20]*/
922+
try (Arena arena = Arena.openConfined()) {
923+
SetDependency(arena.scope());
955924
returnVal = invokeNative(stateSegmt.address(), retMemAddr, getValidDowncallAddr(downcallAddr), cifNativeThunkAddr, args);
956-
/*[ELSEIF JAVA_SPEC_VERSION >= 17]*/
957-
returnVal = invokeNative(retMemAddr, downcallAddr.address().toRawLongValue(), cifNativeThunkAddr, args);
958-
/*[ELSE] JAVA_SPEC_VERSION >= 17 */
959-
/* The given function address never changes since the initialization of the downcall handler in JDK16. */
960-
returnVal = invokeNative(retMemAddr, functionAddr.address().toRawLongValue(), cifNativeThunkAddr, args);
961-
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
962925
}
926+
/*[ELSE] JAVA_SPEC_VERSION >= 20 */
927+
acquireScope();
928+
returnVal = invokeNative(retMemAddr, getValidDowncallAddr(downcallAddr), cifNativeThunkAddr, args);
929+
releaseScope();
930+
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
963931

964932
/* This struct specific MemorySegment object returns to the current thread in the multithreading environment,
965933
* in which case the native invocations from threads end up with distinct returned structs.

0 commit comments

Comments
 (0)