@@ -41,6 +41,10 @@ having all the lower 32 bits set, which will avoid the reference count to go
4141beyond the refcount limit. Immortality checks for reference count decreases will
4242be done by checking the bit sign flag in the lower 32 bits.
4343
44+ To ensure that once an object becomes immortal, it remains immortal, the threshold
45+ for omitting increfs is much higher than for omitting decrefs. Consequently, once
46+ the refcount for an object exceeds _Py_IMMORTAL_MINIMUM_REFCNT it will gradually
47+ increase over time until it reaches _Py_IMMORTAL_INITIAL_REFCNT.
4448*/
4549#define _Py_IMMORTAL_INITIAL_REFCNT (3ULL << 30)
4650#define _Py_IMMORTAL_MINIMUM_REFCNT (1ULL << 31)
@@ -288,7 +292,7 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
288292 }
289293#elif SIZEOF_VOID_P > 4
290294 PY_UINT32_T cur_refcnt = op -> ob_refcnt ;
291- if ((( int32_t ) cur_refcnt ) < 0 ) {
295+ if (cur_refcnt >= _Py_IMMORTAL_INITIAL_REFCNT ) {
292296 // the object is immortal
293297 _Py_INCREF_IMMORTAL_STAT_INC ();
294298 return ;
@@ -303,7 +307,10 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
303307#endif
304308 _Py_INCREF_STAT_INC ();
305309#ifdef Py_REF_DEBUG
306- _Py_INCREF_IncRefTotal ();
310+ // Don't count the incref if the object is immortal.
311+ if (!_Py_IsImmortal (op )) {
312+ _Py_INCREF_IncRefTotal ();
313+ }
307314#endif
308315#endif
309316}
@@ -387,42 +394,6 @@ static inline void Py_DECREF(PyObject *op)
387394#define Py_DECREF (op ) Py_DECREF(_PyObject_CAST(op))
388395
389396#elif defined(Py_REF_DEBUG )
390- static inline void Py_DECREF_MORTAL (const char * filename , int lineno , PyObject * op )
391- {
392- if (op -> ob_refcnt <= 0 ) {
393- _Py_NegativeRefcount (filename , lineno , op );
394- }
395- _Py_DECREF_STAT_INC ();
396- assert (!_Py_IsStaticImmortal (op ));
397- if (!_Py_IsImmortal (op )) {
398- _Py_DECREF_DecRefTotal ();
399- }
400- if (-- op -> ob_refcnt == 0 ) {
401- _Py_Dealloc (op );
402- }
403- }
404- #define Py_DECREF_MORTAL (op ) Py_DECREF_MORTAL(__FILE__, __LINE__, _PyObject_CAST(op))
405-
406-
407-
408- static inline void _Py_DECREF_MORTAL_SPECIALIZED (const char * filename , int lineno , PyObject * op , destructor destruct )
409- {
410- if (op -> ob_refcnt <= 0 ) {
411- _Py_NegativeRefcount (filename , lineno , op );
412- }
413- _Py_DECREF_STAT_INC ();
414- assert (!_Py_IsStaticImmortal (op ));
415- if (!_Py_IsImmortal (op )) {
416- _Py_DECREF_DecRefTotal ();
417- }
418- if (-- op -> ob_refcnt == 0 ) {
419- #ifdef Py_TRACE_REFS
420- _Py_ForgetReference (op );
421- #endif
422- destruct (op );
423- }
424- }
425- #define Py_DECREF_MORTAL_SPECIALIZED (op , destruct ) _Py_DECREF_MORTAL_SPECIALIZED(__FILE__, __LINE__, op, destruct)
426397
427398static inline void Py_DECREF (const char * filename , int lineno , PyObject * op )
428399{
@@ -448,28 +419,6 @@ static inline void Py_DECREF(const char *filename, int lineno, PyObject *op)
448419#define Py_DECREF (op ) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
449420
450421#else
451- static inline void Py_DECREF_MORTAL (PyObject * op )
452- {
453- assert (!_Py_IsStaticImmortal (op ));
454- _Py_DECREF_STAT_INC ();
455- if (-- op -> ob_refcnt == 0 ) {
456- _Py_Dealloc (op );
457- }
458- }
459- #define Py_DECREF_MORTAL (op ) Py_DECREF_MORTAL(_PyObject_CAST(op))
460-
461- static inline void Py_DECREF_MORTAL_SPECIALIZED (PyObject * op , destructor destruct )
462- {
463- assert (!_Py_IsStaticImmortal (op ));
464- _Py_DECREF_STAT_INC ();
465- if (-- op -> ob_refcnt == 0 ) {
466- #ifdef Py_TRACE_REFS
467- _Py_ForgetReference (op );
468- #endif
469- destruct (op );
470- }
471- }
472- #define Py_DECREF_MORTAL_SPECIALIZED (op , destruct ) Py_DECREF_MORTAL_SPECIALIZED(_PyObject_CAST(op), destruct)
473422
474423static inline Py_ALWAYS_INLINE void Py_DECREF (PyObject * op )
475424{
0 commit comments