Skip to content

Commit 337c143

Browse files
committed
Ignore the references to the dummy objects used as deleted keys
in dicts and sets when computing the total number of references.
1 parent 17cfe2b commit 337c143

5 files changed

Lines changed: 28 additions & 6 deletions

File tree

‎Include/object.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ environment the global variable trick is not safe.)
556556
PyAPI_DATA(long) _Py_RefTotal;
557557
PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname,
558558
int lineno, PyObject *op);
559+
PyAPI_FUNC(PyObject *) _PyDict_Dummy(void);
560+
PyAPI_FUNC(long) _Py_GetRefTotal(void);
559561
#define _Py_INC_REFTOTAL _Py_RefTotal++
560562
#define _Py_DEC_REFTOTAL _Py_RefTotal--
561563
#define _Py_REF_DEBUG_COMMA ,

‎Objects/dictobject.c‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ equally good collision statistics, needed less code & used less memory.
115115
/* Object used as dummy key to fill deleted entries */
116116
static PyObject *dummy; /* Initialized by first call to newdictobject() */
117117

118+
#ifdef Py_REF_DEBUG
119+
PyObject *
120+
_PyDict_Dummy(void)
121+
{
122+
return dummy;
123+
}
124+
#endif
125+
118126
/* forward declarations */
119127
static dictentry *
120128
lookdict_string(dictobject *mp, PyObject *key, long hash);

‎Objects/object.c‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,20 @@
55

66
#ifdef Py_REF_DEBUG
77
long _Py_RefTotal;
8-
#endif
8+
long
9+
_Py_GetRefTotal(void)
10+
{
11+
PyObject *o;
12+
long total = _Py_RefTotal;
13+
/* ignore the references to the dummy object of the dicts
14+
because they are not reliable and not useful (now that the
15+
hash table code is well-tested) */
16+
o = _PyDict_Dummy();
17+
if (o != NULL)
18+
total -= o->ob_refcnt;
19+
return total;
20+
}
21+
#endif /* Py_REF_DEBUG */
922

1023
int Py_DivisionWarningFlag;
1124

‎Python/pythonrun.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ Py_Finalize(void)
379379
#endif
380380

381381
#ifdef Py_REF_DEBUG
382-
fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
382+
fprintf(stderr, "[%ld refs]\n", _Py_GetRefTotal());
383383
#endif
384384

385385
#ifdef Py_TRACE_REFS
@@ -694,7 +694,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag
694694
for (;;) {
695695
ret = PyRun_InteractiveOneFlags(fp, filename, flags);
696696
#ifdef Py_REF_DEBUG
697-
fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
697+
fprintf(stderr, "[%ld refs]\n", _Py_GetRefTotal());
698698
#endif
699699
if (ret == E_EOF)
700700
return 0;

‎Python/sysmodule.c‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,10 +604,9 @@ sys_getrefcount(PyObject *self, PyObject *arg)
604604
static PyObject *
605605
sys_gettotalrefcount(PyObject *self)
606606
{
607-
return PyInt_FromLong(_Py_RefTotal);
607+
return PyInt_FromLong(_Py_GetRefTotal());
608608
}
609-
610-
#endif /* Py_TRACE_REFS */
609+
#endif /* Py_REF_DEBUG */
611610

612611
PyDoc_STRVAR(getrefcount_doc,
613612
"getrefcount(object) -> integer\n\

0 commit comments

Comments
 (0)