@@ -278,14 +278,8 @@ private void validateMemScope(MemorySession memScope) throws IllegalStateExcepti
278
278
private void validateMemScope (ResourceScope memScope ) throws IllegalStateException
279
279
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
280
280
{
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" );
289
283
}
290
284
}
291
285
/*[ENDIF] JAVA_SPEC_VERSION >= 17 */
@@ -855,31 +849,29 @@ private void releaseScope() {
855
849
}
856
850
/*[ENDIF] JAVA_SPEC_VERSION >= 19 */
857
851
858
- /*[IF JAVA_SPEC_VERSION >= 20]*/
859
852
/* Return the valid downcall address by doing the validity check on the address's scope
860
853
* in OpenJ9 since the related code and APIs were adjusted in JDK20 in which case the
861
854
* scope check on the downcall in address() in OpenJDK was entirely removed.
862
855
*/
856
+ /*[IF JAVA_SPEC_VERSION >= 20]*/
863
857
private long getValidDowncallAddr (MemorySegment downcallAddr ) {
864
858
validateMemScope (downcallAddr .scope ());
865
859
return downcallAddr .address ();
866
860
}
861
+ /*[ELSE] JAVA_SPEC_VERSION >= 20 */
862
+ private long getValidDowncallAddr (Addressable downcallAddr ) {
863
+ validateMemScope (downcallAddr .address ().scope ());
864
+ return downcallAddr .address ().toRawLongValue ();
865
+ }
867
866
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
868
867
869
868
/* 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]*/
871
869
/*[IF JAVA_SPEC_VERSION >= 20]*/
872
870
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 */
876
872
Object runNativeMethod (Addressable downcallAddr , SegmentAllocator segmtAllocator , long [] args ) throws IllegalArgumentException , IllegalStateException
877
873
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
878
- /*[ELSE] JAVA_SPEC_VERSION >= 17 */
879
- Object runNativeMethod (long [] args )
880
- /*[ENDIF] JAVA_SPEC_VERSION >= 17 */
881
874
{
882
- /*[IF JAVA_SPEC_VERSION >= 17]*/
883
875
/*[IF JAVA_SPEC_VERSION >= 20]*/
884
876
if (downcallAddr == MemorySegment .NULL )
885
877
/*[ELSE] JAVA_SPEC_VERSION >= 20 */
@@ -888,7 +880,6 @@ Object runNativeMethod(long[] args)
888
880
{
889
881
throw new IllegalArgumentException ("A non-null memory address is expected for downcall" ); //$NON-NLS-1$
890
882
}
891
- /*[ENDIF] JAVA_SPEC_VERSION >= 17 */
892
883
893
884
long retMemAddr = 0 ;
894
885
MemorySegment retStruSegmt = null ;
@@ -897,16 +888,11 @@ Object runNativeMethod(long[] args)
897
888
* JDK20+.
898
889
*/
899
890
if ((realReturnLayout != null ) && (realReturnLayout instanceof GroupLayout )) {
900
- /*[IF JAVA_SPEC_VERSION >= 17]*/
901
891
/* The segment allocator (introduced since Java 17 to replace NativeScope in Java 16) is confined
902
892
* by the memory session(Java19)/resource scope(Java17/18) defined in user applications in which
903
893
* case the allocated memory will be released automatically once the session/scope is closed.
904
894
*/
905
895
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 */
910
896
if (retStruSegmt == null ) {
911
897
throw new OutOfMemoryError ("Failed to allocate native memory for the returned memory segment" ); //$NON-NLS-1$
912
898
}
@@ -917,49 +903,31 @@ Object runNativeMethod(long[] args)
917
903
/*[ENDIF] JAVA_SPEC_VERSION >= 20 */
918
904
}
919
905
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
+
920
915
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 ());
955
924
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 */
962
925
}
926
+ /*[ELSE] JAVA_SPEC_VERSION >= 20 */
927
+ acquireScope ();
928
+ returnVal = invokeNative (retMemAddr , getValidDowncallAddr (downcallAddr ), cifNativeThunkAddr , args );
929
+ releaseScope ();
930
+ /*[ENDIF] JAVA_SPEC_VERSION >= 20 */
963
931
964
932
/* This struct specific MemorySegment object returns to the current thread in the multithreading environment,
965
933
* in which case the native invocations from threads end up with distinct returned structs.
0 commit comments