summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Misc/SpecialBuilds.txt17
-rw-r--r--Objects/object.c17
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)
{