@@ -15,6 +15,30 @@ extern "C" {
15
15
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED
16
16
#include "pycore_pystate.h" // _PyInterpreterState_GET()
17
17
18
+
19
+ #define _Py_IMMORTAL_REFCNT_LOOSE ((_Py_IMMORTAL_REFCNT >> 1) + 1)
20
+
21
+ // gh-121528, gh-118997: Similar to _Py_IsImmortal() but be more loose when
22
+ // comparing the reference count to stay compatible with C extensions built
23
+ // with the stable ABI 3.11 or older. Such extensions implement INCREF/DECREF
24
+ // as refcnt++ and refcnt-- without taking in account immortal objects. For
25
+ // example, the reference count of an immortal object can change from
26
+ // _Py_IMMORTAL_REFCNT to _Py_IMMORTAL_REFCNT+1 (INCREF) or
27
+ // _Py_IMMORTAL_REFCNT-1 (DECREF).
28
+ //
29
+ // This function should only be used in assertions. Otherwise, _Py_IsImmortal()
30
+ // must be used instead.
31
+ static inline int _Py_IsImmortalLoose (PyObject * op )
32
+ {
33
+ #if defined(Py_GIL_DISABLED )
34
+ return _Py_IsImmortal (op );
35
+ #else
36
+ return (op -> ob_refcnt >= _Py_IMMORTAL_REFCNT_LOOSE );
37
+ #endif
38
+ }
39
+ #define _Py_IsImmortalLoose (op ) _Py_IsImmortalLoose(_PyObject_CAST(op))
40
+
41
+
18
42
/* Check if an object is consistent. For example, ensure that the reference
19
43
counter is greater than or equal to 1, and ensure that ob_type is not NULL.
20
44
@@ -134,7 +158,7 @@ PyAPI_FUNC(void) _Py_SetImmortalUntracked(PyObject *op);
134
158
static inline void _Py_SetMortal (PyObject * op , Py_ssize_t refcnt )
135
159
{
136
160
if (op ) {
137
- assert (_Py_IsImmortal (op ));
161
+ assert (_Py_IsImmortalLoose (op ));
138
162
#ifdef Py_GIL_DISABLED
139
163
op -> ob_tid = _Py_UNOWNED_TID ;
140
164
op -> ob_ref_local = 0 ;
@@ -266,7 +290,7 @@ _PyObject_Init(PyObject *op, PyTypeObject *typeobj)
266
290
{
267
291
assert (op != NULL );
268
292
Py_SET_TYPE (op , typeobj );
269
- assert (_PyType_HasFeature (typeobj , Py_TPFLAGS_HEAPTYPE ) || _Py_IsImmortal (typeobj ));
293
+ assert (_PyType_HasFeature (typeobj , Py_TPFLAGS_HEAPTYPE ) || _Py_IsImmortalLoose (typeobj ));
270
294
Py_INCREF (typeobj );
271
295
_Py_NewReference (op );
272
296
}
0 commit comments