diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2023-03-20 16:03:04 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-20 16:03:04 (GMT) |
commit | ad77d16a6252c2e616bf41b981a6d919c1122b4d (patch) | |
tree | 17a73242035ac8da8c0096effe17d665cdfe843b /Objects | |
parent | 96e05b62e827a6dee6c658fea9b4976dfd8d30e3 (diff) | |
download | cpython-ad77d16a6252c2e616bf41b981a6d919c1122b4d.zip cpython-ad77d16a6252c2e616bf41b981a6d919c1122b4d.tar.gz cpython-ad77d16a6252c2e616bf41b981a6d919c1122b4d.tar.bz2 |
gh-102304: Move _Py_RefTotal to _PyRuntimeState (gh-102543)
The essentially eliminates the global variable, with the associated benefits. This is also a precursor to isolating this bit of state to PyInterpreterState.
Folks that currently read _Py_RefTotal directly would have to start using _Py_GetGlobalRefTotal() instead.
https://github.com/python/cpython/issues/102304
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/object.c | 101 |
1 files changed, 76 insertions, 25 deletions
diff --git a/Objects/object.c b/Objects/object.c index dff5e2a..95f7c96 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -54,37 +54,71 @@ _PyObject_CheckConsistency(PyObject *op, int check_content) #ifdef Py_REF_DEBUG +/* We keep the legacy symbol around for backward compatibility. */ Py_ssize_t _Py_RefTotal; +static inline Py_ssize_t +get_legacy_reftotal(void) +{ + return _Py_RefTotal; +} +#endif + +#ifdef Py_REF_DEBUG + +# define REFTOTAL(runtime) \ + (runtime)->object_state.reftotal + +static inline void +reftotal_increment(_PyRuntimeState *runtime) +{ + REFTOTAL(runtime)++; +} + static inline void -reftotal_increment(void) +reftotal_decrement(_PyRuntimeState *runtime) { - _Py_RefTotal++; + REFTOTAL(runtime)--; } static inline void -reftotal_decrement(void) +reftotal_add(_PyRuntimeState *runtime, Py_ssize_t n) { - _Py_RefTotal--; + REFTOTAL(runtime) += n; } +static inline Py_ssize_t get_global_reftotal(_PyRuntimeState *); + +/* We preserve the number of refs leaked during runtime finalization, + so they can be reported if the runtime is initialized again. */ +// XXX We don't lose any information by dropping this, +// so we should consider doing so. +static Py_ssize_t last_final_reftotal = 0; + void -_Py_AddRefTotal(Py_ssize_t n) +_Py_FinalizeRefTotal(_PyRuntimeState *runtime) { - _Py_RefTotal += n; + last_final_reftotal = get_global_reftotal(runtime); + REFTOTAL(runtime) = 0; } -Py_ssize_t -_Py_GetRefTotal(void) +static inline Py_ssize_t +get_global_reftotal(_PyRuntimeState *runtime) { - return _Py_RefTotal; + /* For an update from _Py_RefTotal first. */ + Py_ssize_t legacy = get_legacy_reftotal(); + return REFTOTAL(runtime) + legacy + last_final_reftotal; } +#undef REFTOTAL + void _PyDebug_PrintTotalRefs(void) { + _PyRuntimeState *runtime = &_PyRuntime; fprintf(stderr, "[%zd refs, %zd blocks]\n", - _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); + get_global_reftotal(runtime), _Py_GetAllocatedBlocks()); + /* It may be helpful to also print the "legacy" reftotal separately. */ } #endif /* Py_REF_DEBUG */ @@ -139,30 +173,50 @@ _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op) filename, lineno, __func__); } -/* This is exposed strictly for use in Py_INCREF(). */ -PyAPI_FUNC(void) +/* This is used strictly by Py_INCREF(). */ +void _Py_IncRefTotal_DO_NOT_USE_THIS(void) { - reftotal_increment(); + reftotal_increment(&_PyRuntime); } -/* This is exposed strictly for use in Py_DECREF(). */ -PyAPI_FUNC(void) +/* This is used strictly by Py_DECREF(). */ +void _Py_DecRefTotal_DO_NOT_USE_THIS(void) { - reftotal_decrement(); + reftotal_decrement(&_PyRuntime); } void _Py_IncRefTotal(void) { - reftotal_increment(); + reftotal_increment(&_PyRuntime); } void _Py_DecRefTotal(void) { - reftotal_decrement(); + reftotal_decrement(&_PyRuntime); +} + +void +_Py_AddRefTotal(Py_ssize_t n) +{ + reftotal_add(&_PyRuntime, n); +} + +/* This includes the legacy total + and any carried over from the last runtime init/fini cycle. */ +Py_ssize_t +_Py_GetGlobalRefTotal(void) +{ + return get_global_reftotal(&_PyRuntime); +} + +Py_ssize_t +_Py_GetLegacyRefTotal(void) +{ + return get_legacy_reftotal(); } #endif /* Py_REF_DEBUG */ @@ -182,21 +236,18 @@ Py_DecRef(PyObject *o) void _Py_IncRef(PyObject *o) { -#ifdef Py_REF_DEBUG - reftotal_increment(); -#endif Py_INCREF(o); } void _Py_DecRef(PyObject *o) { -#ifdef Py_REF_DEBUG - reftotal_decrement(); -#endif Py_DECREF(o); } + +/**************************************/ + PyObject * PyObject_Init(PyObject *op, PyTypeObject *tp) { @@ -2077,7 +2128,7 @@ void _Py_NewReference(PyObject *op) { #ifdef Py_REF_DEBUG - reftotal_increment(); + reftotal_increment(&_PyRuntime); #endif new_reference(op); } |