_Py_INCREF_IMMORTAL_STAT_INC();
return;
}
-#ifdef Py_REF_DEBUG
- _Py_AddRefTotal(_PyThreadState_GET(), n);
-#endif
-#if !defined(Py_GIL_DISABLED)
-#if SIZEOF_VOID_P > 4
- op->ob_refcnt += (PY_UINT32_T)n;
-#else
- op->ob_refcnt += n;
-#endif
+#ifndef Py_GIL_DISABLED
+ Py_ssize_t refcnt = _Py_REFCNT(op);
+ Py_ssize_t new_refcnt = refcnt + n;
+ if (new_refcnt >= (Py_ssize_t)_Py_IMMORTAL_MINIMUM_REFCNT) {
+ new_refcnt = _Py_IMMORTAL_INITIAL_REFCNT;
+ }
+# if SIZEOF_VOID_P > 4
+ op->ob_refcnt = (PY_UINT32_T)new_refcnt;
+# else
+ op->ob_refcnt = new_refcnt;
+# endif
+# ifdef Py_REF_DEBUG
+ _Py_AddRefTotal(_PyThreadState_GET(), new_refcnt - refcnt);
+# endif
#else
if (_Py_IsOwnedByCurrentThread(op)) {
uint32_t local = op->ob_ref_local;
else {
_Py_atomic_add_ssize(&op->ob_ref_shared, (n << _Py_REF_SHARED_SHIFT));
}
+# ifdef Py_REF_DEBUG
+ _Py_AddRefTotal(_PyThreadState_GET(), n);
+# endif
#endif
// Although the ref count was increased by `n` (which may be greater than 1)
// it is only a single increment (i.e. addition) operation, so only 1 refcnt
be done by checking the bit sign flag in the lower 32 bits.
*/
-#define _Py_IMMORTAL_INITIAL_REFCNT (3UL << 30)
+#define _Py_IMMORTAL_INITIAL_REFCNT (3ULL << 30)
+#define _Py_IMMORTAL_MINIMUM_REFCNT (1ULL << 31)
#define _Py_STATIC_FLAG_BITS ((Py_ssize_t)(_Py_STATICALLY_ALLOCATED_FLAG | _Py_IMMORTAL_FLAGS))
#define _Py_STATIC_IMMORTAL_INITIAL_REFCNT (((Py_ssize_t)_Py_IMMORTAL_INITIAL_REFCNT) | (_Py_STATIC_FLAG_BITS << 48))
case SSTATE_INTERNED_MORTAL:
// Restore 2 references held by the interned dict; these will
// be decref'd by clear_interned_dict's PyDict_Clear.
- Py_SET_REFCNT(s, Py_REFCNT(s) + 2);
+ _Py_RefcntAdd(s, 2);
#ifdef Py_REF_DEBUG
/* let's be pedantic with the ref total */
_Py_IncRefTotal(_PyThreadState_GET());