summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/object.c50
-rw-r--r--Objects/typeobject.c5
2 files changed, 37 insertions, 18 deletions
diff --git a/Objects/object.c b/Objects/object.c
index 059b36a..0a8d2f1 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -18,19 +18,42 @@ int Py_DivisionWarningFlag;
Do not call them otherwise, they do not initialize the object! */
#ifdef Py_TRACE_REFS
-/* Head of doubly-linked list of all objects. */
+/* Head of circular doubly-linked list of all objects. These are linked
+ * together via the _ob_prev and _ob_next members of a PyObject, which
+ * exist only in a Py_TRACE_REFS build.
+ */
static PyObject refchain = {&refchain, &refchain};
-/* Insert op at the fron of the doubly-linked list of all objects. */
+/* Insert op at the front of the list of all objects. If force is true,
+ * op is added even if _ob_prev and _ob_next are non-NULL already. If
+ * force is false amd _ob_prev or _ob_next are non-NULL, do nothing.
+ * force should be true if and only if op points to freshly allocated,
+ * uninitialized memory, or you've unlinked op from the list and are
+ * relinking it into the font.
+ * Note that objects are normally added to the list via _Py_NewReference,
+ * which is called by PyObject_Init. Not all objects are initialized that
+ * way, though; exceptions include statically allocated type objects, and
+ * statically allocated singletons (like Py_True and Py_None).
+ */
void
-_Py_AddToAllObjects(PyObject *op)
+_Py_AddToAllObjects(PyObject *op, int force)
{
- op->_ob_next = refchain._ob_next;
- op->_ob_prev = &refchain;
- refchain._ob_next->_ob_prev = op;
- refchain._ob_next = op;
-}
+#ifdef Py_DEBUG
+ if (!force) {
+ /* If it's initialized memory, op must be in or out of
+ * the list unambiguously.
+ */
+ assert((op->_ob_prev == NULL) == (op->_ob_next == NULL));
+ }
#endif
+ if (force || op->_ob_prev == NULL) {
+ op->_ob_next = refchain._ob_next;
+ op->_ob_prev = &refchain;
+ refchain._ob_next->_ob_prev = op;
+ refchain._ob_next = op;
+ }
+}
+#endif /* Py_TRACE_REFS */
#ifdef COUNT_ALLOCS
static PyTypeObject *type_list;
@@ -100,11 +123,10 @@ inc_count(PyTypeObject *tp)
Py_INCREF(tp);
type_list = tp;
#ifdef Py_TRACE_REFS
- /* Also insert in the doubly-linked list of all objects. */
- if (tp->_ob_prev == NULL) {
- assert(tp->_ob_next == NULL);
- _Py_AddToAllObjects((PyObject *)tp);
- }
+ /* Also insert in the doubly-linked list of all objects,
+ * if not already there.
+ */
+ _Py_AddToAllObjects((PyObject *)tp, 0);
#endif
}
tp->tp_allocs++;
@@ -1963,7 +1985,7 @@ _Py_NewReference(PyObject *op)
{
_Py_INC_REFTOTAL;
op->ob_refcnt = 1;
- _Py_AddToAllObjects(op);
+ _Py_AddToAllObjects(op, 1);
_Py_INC_TPALLOCS(op);
}
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 8dfb939..4acee5a 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3058,10 +3058,7 @@ PyType_Ready(PyTypeObject *type)
* to get type objects into the doubly-linked list of all objects.
* Still, not all type objects go thru PyType_Ready.
*/
- if (type->_ob_next == NULL) {
- assert(type->_ob_prev == NULL);
- _Py_AddToAllObjects((PyObject *)type);
- }
+ _Py_AddToAllObjects((PyObject *)type, 0);
#endif
/* Initialize tp_base (defaults to BaseObject unless that's us) */