From e170937af6463d92e95cea907964a23dff521f31 Mon Sep 17 00:00:00 2001 From: Armin Rigo Date: Wed, 12 Apr 2006 17:06:05 +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 | 3 +++ Objects/dictobject.c | 8 ++++++++ Objects/object.c | 19 ++++++++++++++++++- Objects/setobject.c | 8 ++++++++ Python/pythonrun.c | 2 +- Python/sysmodule.c | 5 ++--- 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Include/object.h b/Include/object.h index 131812f..924480f 100644 --- a/Include/object.h +++ b/Include/object.h @@ -578,6 +578,9 @@ environment the global variable trick is not safe.) PyAPI_DATA(Py_ssize_t) _Py_RefTotal; PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname, int lineno, PyObject *op); +PyAPI_FUNC(PyObject *) _PyDict_Dummy(void); +PyAPI_FUNC(PyObject *) _PySet_Dummy(void); +PyAPI_FUNC(Py_ssize_t) _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 f6fa1eb..31ef958e 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 = NULL; /* 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 e15218f..0ce4332 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -5,7 +5,24 @@ #ifdef Py_REF_DEBUG Py_ssize_t _Py_RefTotal; -#endif + +Py_ssize_t +_Py_GetRefTotal(void) +{ + PyObject *o; + Py_ssize_t total = _Py_RefTotal; + /* ignore the references to the dummy object of the dicts and sets + 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; + o = _PySet_Dummy(); + if (o != NULL) + total -= o->ob_refcnt; + return total; +} +#endif /* Py_REF_DEBUG */ int Py_DivisionWarningFlag; diff --git a/Objects/setobject.c b/Objects/setobject.c index edc43df..e7f6e09 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -16,6 +16,14 @@ /* Object used as dummy key to fill deleted entries */ static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */ +#ifdef Py_REF_DEBUG +PyObject * +_PySet_Dummy(void) +{ + return dummy; +} +#endif + #define INIT_NONZERO_SET_SLOTS(so) do { \ (so)->table = (so)->smalltable; \ (so)->mask = PySet_MINSIZE - 1; \ diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1aa6930..818c760 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -34,7 +34,7 @@ #else /* Py_REF_DEBUG */ #define PRINT_TOTAL_REFS() fprintf(stderr, \ "[%" PY_FORMAT_SIZE_T "d refs]\n", \ - _Py_RefTotal) + _Py_GetRefTotal()) #endif extern char *Py_GetPath(void); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 4a52742..cbf0d8f 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_FromSsize_t(_Py_RefTotal); + return PyInt_FromSsize_t(_Py_GetRefTotal()); } - -#endif /* Py_TRACE_REFS */ +#endif /* Py_REF_DEBUG */ PyDoc_STRVAR(getrefcount_doc, "getrefcount(object) -> integer\n\ -- cgit v0.12