Skip to content

Commit 27b7bd3

Browse files
committed
Free all native object stubs in lookup table at context finalization
1 parent e395345 commit 27b7bd3

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
8181
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandleContext;
8282
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonNode;
83+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonObjectReference;
8384
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.ToPythonWrapperNode;
8485
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.CheckFunctionResultNode;
8586
import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
@@ -875,16 +876,28 @@ public void finalizeCapi() {
875876
CApiTransitions.disableReferenceQueuePolling(getContext().nativeContext);
876877
// TODO(fa): remove GIL acquisition (GR-51314)
877878
try (GilNode.UncachedAcquire gil = GilNode.uncachedAcquire()) {
879+
HandleContext nativeContext = getContext().nativeContext;
878880
freeSmallInts();
879881
for (int i = 0; i < singletonNativePtrs.length; i++) {
880882
PythonNativeWrapper singletonNativeWrapper = singletonNativePtrs[i];
881883
singletonNativePtrs[i] = null;
882884
assert singletonNativeWrapper != null;
883885
if (singletonNativeWrapper.ref != null) {
884-
CApiTransitions.nativeStubLookupRemove(getContext().nativeContext, singletonNativeWrapper.ref);
886+
CApiTransitions.nativeStubLookupRemove(nativeContext, singletonNativeWrapper.ref);
885887
}
886888
PyTruffleObjectFree.releaseNativeWrapperUncached(singletonNativeWrapper);
887889
}
890+
/*
891+
* Clear all remaining native object stubs. This must be done after the small int and
892+
* the singleton wrappers were cleared because they might also end up in the lookup
893+
* table and may otherwise be double-free'd.
894+
*/
895+
for (PythonObjectReference ref : nativeContext.nativeStubLookup) {
896+
if (ref != null) {
897+
CApiTransitions.nativeStubLookupRemove(nativeContext, ref);
898+
CApiTransitions.freeNativeStub(ref);
899+
}
900+
}
888901
}
889902
if (pyDateTimeCAPICapsule != null) {
890903
PyDateTimeCAPIWrapper.destroyWrapper(pyDateTimeCAPICapsule);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,7 @@ public static void pollReferenceQueue() {
383383
*/
384384
long stubPointer = HandlePointerConverter.pointerToStub(reference.pointer);
385385
if (subNativeRefCount(stubPointer, PythonAbstractObjectNativeWrapper.MANAGED_REFCNT) == 0) {
386-
LOGGER.fine(() -> PythonUtils.formatJString("freeing native object stub 0x%x", stubPointer));
387-
FreeNode.executeUncached(stubPointer);
386+
freeNativeStub(stubPointer);
388387
} else {
389388
/*
390389
* In this case, the object is no longer referenced from managed but
@@ -422,6 +421,20 @@ public static void disableReferenceQueuePolling(HandleContext handleContext) {
422421
handleContext.referenceQueuePollActive = true;
423422
}
424423

424+
public static boolean isReferenceQueuePollingDisabled(HandleContext handleContext) {
425+
return handleContext.referenceQueuePollActive;
426+
}
427+
428+
private static void freeNativeStub(long stubPointer) {
429+
LOGGER.fine(() -> PythonUtils.formatJString("freeing native object stub 0x%x", stubPointer));
430+
FreeNode.executeUncached(stubPointer);
431+
}
432+
433+
public static void freeNativeStub(PythonObjectReference ref) {
434+
assert HandlePointerConverter.pointsToPyHandleSpace(ref.pointer);
435+
freeNativeStub(HandlePointerConverter.pointerToStub(ref.pointer));
436+
}
437+
425438
/**
426439
* We need to call __dealloc__ for native weakref objects before exit, as some objects might
427440
* need to use capi functions.

0 commit comments

Comments
 (0)