summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2023-03-20 16:03:04 (GMT)
committerGitHub <noreply@github.com>2023-03-20 16:03:04 (GMT)
commitad77d16a6252c2e616bf41b981a6d919c1122b4d (patch)
tree17a73242035ac8da8c0096effe17d665cdfe843b /Objects
parent96e05b62e827a6dee6c658fea9b4976dfd8d30e3 (diff)
downloadcpython-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.c101
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);
}