From 337c143b4a1dd06aac882febcee80d9af7342493 Mon Sep 17 00:00:00 2001 From: Armin Rigo Date: Wed, 12 Apr 2006 17:06:58 +0000 Subject: Ignore the references to the dummy objects used as deleted keys in dicts and sets when computing the total number of references. --- Include/object.h | 2 ++ Objects/dictobject.c | 8 ++++++++ Objects/object.c | 15 ++++++++++++++- Python/pythonrun.c | 4 ++-- Python/sysmodule.c | 5 ++--- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Include/object.h b/Include/object.h index fd7c235..2706d97 100644 --- a/Include/object.h +++ b/Include/object.h @@ -556,6 +556,8 @@ environment the global variable trick is not safe.) PyAPI_DATA(long) _Py_RefTotal; PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname, int lineno, PyObject *op); +PyAPI_FUNC(PyObject *) _PyDict_Dummy(void); +PyAPI_FUNC(long) _Py_GetRefTotal(void); #define _Py_INC_REFTOTAL _Py_RefTotal++ #define _Py_DEC_REFTOTAL _Py_RefTotal-- #define _Py_REF_DEBUG_COMMA , diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 4e9d183..18d8d5c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -115,6 +115,14 @@ equally good collision statistics, needed less code & used less memory. /* Object used as dummy key to fill deleted entries */ static PyObject *dummy; /* Initialized by first call to newdictobject() */ +#ifdef Py_REF_DEBUG +PyObject * +_PyDict_Dummy(void) +{ + return dummy; +} +#endif + /* forward declarations */ static dictentry * lookdict_string(dictobject *mp, PyObject *key, long hash); diff --git a/Objects/object.c b/Objects/object.c index 7dbd554..7cc0ab7 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -5,7 +5,20 @@ #ifdef Py_REF_DEBUG long _Py_RefTotal; -#endif +long +_Py_GetRefTotal(void) +{ + PyObject *o; + long total = _Py_RefTotal; + /* ignore the references to the dummy object of the dicts + because they are not reliable and not useful (now that the + hash table code is well-tested) */ + o = _PyDict_Dummy(); + if (o != NULL) + total -= o->ob_refcnt; + return total; +} +#endif /* Py_REF_DEBUG */ int Py_DivisionWarningFlag; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3317e55..e093dc5 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -379,7 +379,7 @@ Py_Finalize(void) #endif #ifdef Py_REF_DEBUG - fprintf(stderr, "[%ld refs]\n", _Py_RefTotal); + fprintf(stderr, "[%ld refs]\n", _Py_GetRefTotal()); #endif #ifdef Py_TRACE_REFS @@ -694,7 +694,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag for (;;) { ret = PyRun_InteractiveOneFlags(fp, filename, flags); #ifdef Py_REF_DEBUG - fprintf(stderr, "[%ld refs]\n", _Py_RefTotal); + fprintf(stderr, "[%ld refs]\n", _Py_GetRefTotal()); #endif if (ret == E_EOF) return 0; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 0775bb8..1ce016f 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -604,10 +604,9 @@ sys_getrefcount(PyObject *self, PyObject *arg) static PyObject * sys_gettotalrefcount(PyObject *self) { - return PyInt_FromLong(_Py_RefTotal); + return PyInt_FromLong(_Py_GetRefTotal()); } - -#endif /* Py_TRACE_REFS */ +#endif /* Py_REF_DEBUG */ PyDoc_STRVAR(getrefcount_doc, "getrefcount(object) -> integer\n\ -- cgit v0.12