summaryrefslogtreecommitdiffstats
path: root/Include/objimpl.h
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-07-02 00:52:30 (GMT)
committerTim Peters <tim.peters@gmail.com>2002-07-02 00:52:30 (GMT)
commitea405639bff00b4c177026b474a9d75207c0bf1b (patch)
tree60c5deaa5a010c28c3784cbf93f9add8af42ad7d /Include/objimpl.h
parent7c75bf2090c58ac0d2bb57220c41327285bf7c1a (diff)
downloadcpython-ea405639bff00b4c177026b474a9d75207c0bf1b.zip
cpython-ea405639bff00b4c177026b474a9d75207c0bf1b.tar.gz
cpython-ea405639bff00b4c177026b474a9d75207c0bf1b.tar.bz2
Reserved another gc_refs value for untracked objects. Every live gc
object should now have a well-defined gc_refs value, with clear transitions among gc_refs states. As a result, none of the visit_XYZ traversal callbacks need to check IS_TRACKED() anymore, and those tests were removed. (They were already looking for objects with specific gc_refs states, and the gc_refs state of an untracked object can no longer match any other gc_refs state by accident.) Added more asserts. I expect that the gc_next == NULL indicator for an untracked object is now redundant and can also be removed, but I ran out of time for this.
Diffstat (limited to 'Include/objimpl.h')
-rw-r--r--Include/objimpl.h12
1 files changed, 10 insertions, 2 deletions
diff --git a/Include/objimpl.h b/Include/objimpl.h
index e037322..28f3661 100644
--- a/Include/objimpl.h
+++ b/Include/objimpl.h
@@ -262,12 +262,18 @@ extern PyGC_Head *_PyGC_generation0;
#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)
+#define _PyGC_REFS_UNTRACKED (-2)
+#define _PyGC_REFS_REACHABLE (-3)
+#define _PyGC_REFS_TENTATIVELY_UNREACHABLE (-4)
+
/* Tell the GC to track this object. NB: While the object is tracked the
* collector it must be safe to call the ob_traverse method. */
#define _PyObject_GC_TRACK(o) do { \
PyGC_Head *g = _Py_AS_GC(o); \
- if (g->gc.gc_next != NULL) \
- Py_FatalError("GC object already in linked list"); \
+ if (g->gc.gc_refs != _PyGC_REFS_UNTRACKED) \
+ Py_FatalError("GC object already tracked"); \
+ assert(g->gc.gc_refs == _PyGC_REFS_UNTRACKED); \
+ g->gc.gc_refs = _PyGC_REFS_REACHABLE; \
g->gc.gc_next = _PyGC_generation0; \
g->gc.gc_prev = _PyGC_generation0->gc.gc_prev; \
g->gc.gc_prev->gc.gc_next = g; \
@@ -277,6 +283,8 @@ extern PyGC_Head *_PyGC_generation0;
/* Tell the GC to stop tracking this object. */
#define _PyObject_GC_UNTRACK(o) do { \
PyGC_Head *g = _Py_AS_GC(o); \
+ assert(g->gc.gc_refs != _PyGC_REFS_UNTRACKED); \
+ g->gc.gc_refs = _PyGC_REFS_UNTRACKED; \
g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \
g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \
g->gc.gc_next = NULL; \