Skip to content

Commit f11b808

Browse files
Aditi SrinivasAditi Srinivas
authored andcommitted
Refactor HeapArgInfo to Support Queue-Based Tracking
Fix for Issue #21944 Fix for failing java/foreign/TestBufferStack.java test. Replaced single HeapArgInfo with a thread-local Deque. To track multiple argument sets for recursions. Each downcall pushes a new HeapArgInfo. Clears the most recent entry after completion. FIFO based management for heap-based arguments in Java 22+.
1 parent 73d4eb1 commit f11b808

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

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

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
2828
import java.util.HashMap;
2929
import java.util.List;
30+
import java.util.Deque;
31+
import java.util.ArrayDeque;
3032
/*[IF JAVA_SPEC_VERSION >= 21]*/
3133
import java.util.Objects;
3234
/*[ENDIF] JAVA_SPEC_VERSION >= 21 */
@@ -123,7 +125,8 @@ void clear() {
123125
}
124126
}
125127

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);
127130
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
128131

129132
/* The hashtables of sessions/scopes is intended for multithreading in which case
@@ -311,7 +314,8 @@ private void validateMemScope(ResourceScope memScope) throws IllegalStateExcepti
311314
*/
312315
private final long memSegmtOfPtrToLongArg(MemorySegment argValue, LinkerOptions options) throws IllegalStateException {
313316
/*[IF JAVA_SPEC_VERSION >= 22]*/
314-
HeapArgInfo info = heapArgInfo.get();
317+
Deque<HeapArgInfo> infoStack = heapArgInfo.get();
318+
HeapArgInfo info = infoStack.peek();
315319
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
316320

317321
try {
@@ -323,18 +327,21 @@ private final long memSegmtOfPtrToLongArg(MemorySegment argValue, LinkerOptions
323327
* is captured so as to reset the internal index and avoid retaining the references
324328
* to the unreachable objects.
325329
*/
326-
if (info != null) {
327-
info.clear();
330+
if(!flagCreateHeapArgInfo.get() && !infoStack.isEmpty()) {
331+
infoStack.pop();
332+
flagCreateHeapArgInfo.set(Boolean.TRUE);
328333
}
329334
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
330335
throw e;
331336
}
332337

333338
long address = argValue.address();
334339
/*[IF JAVA_SPEC_VERSION >= 22]*/
335-
if (info == null) {
340+
341+
if ((info == null) || flagCreateHeapArgInfo.get()) {
336342
info = new HeapArgInfo(argLayoutArray.length);
337-
heapArgInfo.set(info);
343+
infoStack.push(info);
344+
flagCreateHeapArgInfo.set(Boolean.FALSE);
338345
}
339346

340347
if (!argValue.isNative() && options.allowsHeapAccess()) {
@@ -369,9 +376,10 @@ private final long memSegmtToLongArg(MemorySegment argValue) throws IllegalState
369376
* is captured so as to reset the internal index and avoid retaining the references
370377
* to the unreachable objects.
371378
*/
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);
375383
}
376384
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
377385
throw e;
@@ -506,10 +514,6 @@ public InternalDowncallHandler(MethodType functionMethodType, FunctionDescriptor
506514
scopeHandleMap = new ConcurrentHashMap<>();
507515
/*[ENDIF] JAVA_SPEC_VERSION == 17 */
508516

509-
/*[IF JAVA_SPEC_VERSION >= 22]*/
510-
heapArgInfo = new ThreadLocal<>();
511-
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
512-
513517
try {
514518
/*[IF JAVA_SPEC_VERSION >= 21]*/
515519
longObjToMemSegmtRetFilter = lookup.bind(this, "longObjToMemSegmtRet", methodType(MemorySegment.class, Object.class));
@@ -882,7 +886,17 @@ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator
882886

883887
long returnVal;
884888
/*[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+
}
886900
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
887901
/* The scope associated with memory specific arguments must be kept alive
888902
* during the downcall since JDK17, including the downcall adddress.
@@ -936,8 +950,8 @@ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator
936950
* so as to reset the internal index and avoid retaining the references to the
937951
* unreachable objects.
938952
*/
939-
if (info != null) {
940-
info.clear();
953+
if (!infoStack.isEmpty() && pushed) {
954+
infoStack.pop();
941955
}
942956
}
943957
/*[ENDIF] JAVA_SPEC_VERSION >= 22 */

0 commit comments

Comments
 (0)