diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 1c4c3e30fd2f6d..0b686b416ec193 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -135,15 +135,20 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) _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; @@ -160,6 +165,9 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) 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 diff --git a/Include/refcount.h b/Include/refcount.h index e66e4aaace3140..ba14bc6965ce3e 100644 --- a/Include/refcount.h +++ b/Include/refcount.h @@ -42,7 +42,8 @@ beyond the refcount limit. Immortality checks for reference count decreases will 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)) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 21ccb01f86bc61..085944cd6bd989 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15982,7 +15982,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) 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()); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy