@@ -1583,8 +1583,15 @@ Object doNonWrapper(long pointer, boolean stealing,
1583
1583
private static final int TP_REFCNT_OFFSET = 0 ;
1584
1584
1585
1585
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 ) {
1586
1590
assert PythonContext .get (null ).isNativeAccessAllowed ();
1587
1591
long refCount = UNSAFE .getLong (pointer + TP_REFCNT_OFFSET );
1592
+ if (ignoreIfDead && refCount == 0 ) {
1593
+ return 0 ;
1594
+ }
1588
1595
assert (refCount & 0xFFFFFFFF00000000L ) == 0 : String .format ("suspicious refcnt value during managed adjustment for %016x (%d %016x + %d)\n " , pointer , refCount , refCount , refCntDelta );
1589
1596
assert (refCount + refCntDelta ) > 0 : String .format ("refcnt reached zero during managed adjustment for %016x (%d %016x + %d)\n " , pointer , refCount , refCount , refCntDelta );
1590
1597
@@ -1629,11 +1636,20 @@ private static Object createAbstractNativeObject(HandleContext handleContext, Ob
1629
1636
1630
1637
pollReferenceQueue ();
1631
1638
PythonAbstractNativeObject result = new PythonAbstractNativeObject (obj );
1632
- NativeObjectReference ref = new NativeObjectReference (handleContext , result , pointer );
1633
- nativeLookupPut (getContext (), pointer , ref );
1634
-
1635
1639
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
+
1637
1653
return result ;
1638
1654
}
1639
1655
0 commit comments