diff options
-rw-r--r-- | Misc/SpecialBuilds.txt | 17 | ||||
-rw-r--r-- | Objects/object.c | 17 |
2 files changed, 28 insertions, 6 deletions
diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt index a4226c92ae..a3d35586f4 100644 --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -34,10 +34,14 @@ Py_TRACE_REFS introduced in 1.4 Turn on heavy reference debugging. This is major surgery. Every PyObject grows two more pointers, to maintain a doubly-linked list of all live -heap-allocated objects (note that, e.g., most builtin type objects are not -in this list, as they're statically allocated). Note that because the -fundamental PyObject layout changes, Python modules compiled with -Py_TRACE_REFS are incompatible with modules compiled without it. +heap-allocated objects. Most builtin type objects are not in this list, +as they're statically allocated. Starting in Python 2.3, if COUNT_ALLOCS +(see below) is also defined, a static type object T does appear in this +list if at least one object of type T has been created. + +Note that because the fundamental PyObject layout changes, Python modules +compiled with Py_TRACE_REFS are incompatible with modules compiled without +it. Py_TRACE_REFS implies Py_REF_DEBUG. @@ -171,6 +175,11 @@ because of this; this was fixed in 2.2.2. Use of COUNT_ALLOCS makes all heap-allocated type objects immortal, except for those for which no object of that type is ever allocated. +Starting with Python 2.3, If Py_TRACE_REFS is also defined, COUNT_ALLOCS +arranges to ensure that the type object for each allocated object +appears in the doubly-linked list of all objects maintained by +Py_TRACE_REFS. + Special gimmicks: sys.getcounts() diff --git a/Objects/object.c b/Objects/object.c index 9ce3de7e06..2332df837d 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -17,6 +17,11 @@ int Py_DivisionWarningFlag; These are used by the individual routines for object creation. Do not call them otherwise, they do not initialize the object! */ +#ifdef Py_TRACE_REFS +/* Head of doubly-linked list of all objects. */ +static PyObject refchain = {&refchain, &refchain}; +#endif + #ifdef COUNT_ALLOCS static PyTypeObject *type_list; extern int tuple_zero_allocs, fast_tuple_allocs; @@ -84,6 +89,16 @@ inc_count(PyTypeObject *tp) */ Py_INCREF(tp); type_list = tp; +#ifdef Py_REF_DEBUG + /* Also insert in the doubly-linked list of all objects. */ + if (tp->_ob_next == NULL) { + PyObject *op = (PyObject *)tp; + op->_ob_next = refchain._ob_next; + op->_ob_prev = &refchain; + refchain._ob_next->_ob_prev = op; + refchain._ob_next = op; + } +#endif } tp->tp_allocs++; if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc) @@ -1936,8 +1951,6 @@ _Py_ReadyTypes(void) #ifdef Py_TRACE_REFS -static PyObject refchain = {&refchain, &refchain}; - void _Py_NewReference(PyObject *op) { |