Skip to content

Commit 3d873ba

Browse files
committed
Try to avoid resurrecting objects on upcalls from tp_dealloc
1 parent c83b633 commit 3d873ba

File tree

1 file changed

+20
-4
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions

1 file changed

+20
-4
lines changed

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,8 +1583,15 @@ Object doNonWrapper(long pointer, boolean stealing,
15831583
private static final int TP_REFCNT_OFFSET = 0;
15841584

15851585
private static long addNativeRefCount(long pointer, long refCntDelta) {
1586+
return addNativeRefCount(pointer, refCntDelta, false);
1587+
}
1588+
1589+
private static long addNativeRefCount(long pointer, long refCntDelta, boolean ignoreIfDead) {
15861590
assert PythonContext.get(null).isNativeAccessAllowed();
15871591
long refCount = UNSAFE.getLong(pointer + TP_REFCNT_OFFSET);
1592+
if (ignoreIfDead && refCount == 0) {
1593+
return 0;
1594+
}
15881595
assert (refCount & 0xFFFFFFFF00000000L) == 0 : String.format("suspicious refcnt value during managed adjustment for %016x (%d %016x + %d)\n", pointer, refCount, refCount, refCntDelta);
15891596
assert (refCount + refCntDelta) > 0 : String.format("refcnt reached zero during managed adjustment for %016x (%d %016x + %d)\n", pointer, refCount, refCount, refCntDelta);
15901597

@@ -1629,11 +1636,20 @@ private static Object createAbstractNativeObject(HandleContext handleContext, Ob
16291636

16301637
pollReferenceQueue();
16311638
PythonAbstractNativeObject result = new PythonAbstractNativeObject(obj);
1632-
NativeObjectReference ref = new NativeObjectReference(handleContext, result, pointer);
1633-
nativeLookupPut(getContext(), pointer, ref);
1634-
16351639
long refCntDelta = MANAGED_REFCNT - (transfer ? 1 : 0);
1636-
addNativeRefCount(pointer, refCntDelta);
1640+
/*
1641+
* Some APIs might be called from tp_dealloc/tp_del/tp_finalize where the refcount is 0. In
1642+
* that case we don't want to create a new reference, since that would resurrect the object
1643+
* and we would end up deallocating it twice.
1644+
*/
1645+
long refCount = addNativeRefCount(pointer, refCntDelta, true);
1646+
if (refCount > 0) {
1647+
NativeObjectReference ref = new NativeObjectReference(handleContext, result, pointer);
1648+
nativeLookupPut(getContext(), pointer, ref);
1649+
} else if (LOGGER.isLoggable(Level.FINE)) {
1650+
LOGGER.fine(PythonUtils.formatJString("createAbstractNativeObject: creating PythonAbstractNativeObject for a dying object (refcount 0): 0x%x", pointer));
1651+
}
1652+
16371653
return result;
16381654
}
16391655

0 commit comments

Comments
 (0)