summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2023-03-21 17:46:09 (GMT)
committerGitHub <noreply@github.com>2023-03-21 17:46:09 (GMT)
commit743687434c5baf01c266320b34c7a828726702a6 (patch)
tree6d26f4fcb5aaa2b606b433aecad939e9f36734f9 /Python
parent4bb1dd3c5c14338c9d9cea5988431c858b3b76e0 (diff)
downloadcpython-743687434c5baf01c266320b34c7a828726702a6.zip
cpython-743687434c5baf01c266320b34c7a828726702a6.tar.gz
cpython-743687434c5baf01c266320b34c7a828726702a6.tar.bz2
gh-102304: Move the Total Refcount to PyInterpreterState (gh-102545)
Moving it valuable with a per-interpreter GIL. However, it is also useful without one, since it allows us to identify refleaks within a single interpreter or where references are escaping an interpreter. This becomes more important as we move the obmalloc state to PyInterpreterState. https://github.com/python/cpython/issues/102304
Diffstat (limited to 'Python')
-rw-r--r--Python/pylifecycle.c5
-rw-r--r--Python/pystate.c10
-rw-r--r--Python/sysmodule.c2
3 files changed, 15 insertions, 2 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 8b58a14..0d546d5 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -802,6 +802,11 @@ pycore_interp_init(PyThreadState *tstate)
PyStatus status;
PyObject *sysmod = NULL;
+ // This is a temporary fix until we have immortal objects.
+ // (See _PyType_InitCache() in typeobject.c.)
+ extern void _PyType_FixCacheRefcounts(void);
+ _PyType_FixCacheRefcounts();
+
// Create singletons before the first PyType_Ready() call, since
// PyType_Ready() uses singletons like the Unicode empty string (tp_doc)
// and the empty tuple singletons (tp_bases).
diff --git a/Python/pystate.c b/Python/pystate.c
index 60adb54..b17efdb 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -483,8 +483,8 @@ void
_PyRuntimeState_Fini(_PyRuntimeState *runtime)
{
#ifdef Py_REF_DEBUG
- /* The reftotal is cleared by _Py_FinalizeRefTotal(). */
- assert(runtime->object_state.reftotal == 0);
+ /* The count is cleared by _Py_FinalizeRefTotal(). */
+ assert(runtime->object_state.interpreter_leaks == 0);
#endif
if (gilstate_tss_initialized(runtime)) {
@@ -904,6 +904,12 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
_PyEval_FiniState(&interp->ceval);
+#ifdef Py_REF_DEBUG
+ // XXX This call should be done at the end of clear_interpreter(),
+ // but currently some objects get decref'ed after that.
+ _PyInterpreterState_FinalizeRefTotal(interp);
+#endif
+
HEAD_LOCK(runtime);
PyInterpreterState **p;
for (p = &interpreters->head; ; p = &(*p)->next) {
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 2076173..4afb0f1 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1854,6 +1854,8 @@ static Py_ssize_t
sys_gettotalrefcount_impl(PyObject *module)
/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
{
+ /* It may make sense to return the total for the current interpreter
+ or have a second function that does so. */
return _Py_GetGlobalRefTotal();
}