27
27
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
28
28
import java .util .HashMap ;
29
29
import java .util .List ;
30
+ import java .util .Deque ;
31
+ import java .util .ArrayDeque ;
30
32
/*[IF JAVA_SPEC_VERSION >= 21]*/
31
33
import java .util .Objects ;
32
34
/*[ENDIF] JAVA_SPEC_VERSION >= 21 */
@@ -123,7 +125,8 @@ void clear() {
123
125
}
124
126
}
125
127
126
- private final ThreadLocal <HeapArgInfo > heapArgInfo ;
128
+ private static final ThreadLocal <Deque <HeapArgInfo >> heapArgInfo = ThreadLocal .withInitial (ArrayDeque ::new );
129
+ private static final ThreadLocal <Boolean > flagCreateHeapArgInfo = ThreadLocal .withInitial (()->Boolean .TRUE );
127
130
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
128
131
129
132
/* The hashtables of sessions/scopes is intended for multithreading in which case
@@ -311,7 +314,8 @@ private void validateMemScope(ResourceScope memScope) throws IllegalStateExcepti
311
314
*/
312
315
private final long memSegmtOfPtrToLongArg (MemorySegment argValue , LinkerOptions options ) throws IllegalStateException {
313
316
/*[IF JAVA_SPEC_VERSION >= 22]*/
314
- HeapArgInfo info = heapArgInfo .get ();
317
+ Deque <HeapArgInfo > infoStack = heapArgInfo .get ();
318
+ HeapArgInfo info = infoStack .peek ();
315
319
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
316
320
317
321
try {
@@ -323,18 +327,21 @@ private final long memSegmtOfPtrToLongArg(MemorySegment argValue, LinkerOptions
323
327
* is captured so as to reset the internal index and avoid retaining the references
324
328
* to the unreachable objects.
325
329
*/
326
- if (info != null ) {
327
- info .clear ();
330
+ if (!flagCreateHeapArgInfo .get () && !infoStack .isEmpty ()) {
331
+ infoStack .pop ();
332
+ flagCreateHeapArgInfo .set (Boolean .TRUE );
328
333
}
329
334
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
330
335
throw e ;
331
336
}
332
337
333
338
long address = argValue .address ();
334
339
/*[IF JAVA_SPEC_VERSION >= 22]*/
335
- if (info == null ) {
340
+
341
+ if ((info == null ) || flagCreateHeapArgInfo .get ()) {
336
342
info = new HeapArgInfo (argLayoutArray .length );
337
- heapArgInfo .set (info );
343
+ infoStack .push (info );
344
+ flagCreateHeapArgInfo .set (Boolean .FALSE );
338
345
}
339
346
340
347
if (!argValue .isNative () && options .allowsHeapAccess ()) {
@@ -369,9 +376,10 @@ private final long memSegmtToLongArg(MemorySegment argValue) throws IllegalState
369
376
* is captured so as to reset the internal index and avoid retaining the references
370
377
* to the unreachable objects.
371
378
*/
372
- HeapArgInfo info = heapArgInfo .get ();
373
- if (info != null ) {
374
- info .clear ();
379
+ Deque <HeapArgInfo > infoStack = heapArgInfo .get ();
380
+ if (!flagCreateHeapArgInfo .get () && !infoStack .isEmpty ()) {
381
+ infoStack .pop ();
382
+ flagCreateHeapArgInfo .set (Boolean .TRUE );
375
383
}
376
384
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
377
385
throw e ;
@@ -506,10 +514,6 @@ public InternalDowncallHandler(MethodType functionMethodType, FunctionDescriptor
506
514
scopeHandleMap = new ConcurrentHashMap <>();
507
515
/*[ENDIF] JAVA_SPEC_VERSION == 17 */
508
516
509
- /*[IF JAVA_SPEC_VERSION >= 22]*/
510
- heapArgInfo = new ThreadLocal <>();
511
- /*[ENDIF] JAVA_SPEC_VERSION >= 22 */
512
-
513
517
try {
514
518
/*[IF JAVA_SPEC_VERSION >= 21]*/
515
519
longObjToMemSegmtRetFilter = lookup .bind (this , "longObjToMemSegmtRet" , methodType (MemorySegment .class , Object .class ));
@@ -882,7 +886,17 @@ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator
882
886
883
887
long returnVal ;
884
888
/*[IF JAVA_SPEC_VERSION >= 22]*/
885
- HeapArgInfo info = heapArgInfo .get ();
889
+ Deque <HeapArgInfo > infoStack = heapArgInfo .get ();
890
+ HeapArgInfo info ;
891
+ boolean pushed = true ;
892
+ if (flagCreateHeapArgInfo .get ()) {
893
+ info = null ;
894
+ pushed = false ;
895
+ }
896
+ else {
897
+ info = infoStack .peek ();
898
+ flagCreateHeapArgInfo .set (Boolean .TRUE );
899
+ }
886
900
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
887
901
/* The scope associated with memory specific arguments must be kept alive
888
902
* during the downcall since JDK17, including the downcall adddress.
@@ -936,8 +950,8 @@ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator
936
950
* so as to reset the internal index and avoid retaining the references to the
937
951
* unreachable objects.
938
952
*/
939
- if (info != null ) {
940
- info . clear ();
953
+ if (! infoStack . isEmpty () && pushed ) {
954
+ infoStack . pop ();
941
955
}
942
956
}
943
957
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
0 commit comments