]> granicus.if.org Git - python/commitdiff
visit_reachable: replace release-mode test with an assert. (GH-16866)
authorTim Peters <tim.peters@gmail.com>
Mon, 21 Oct 2019 16:21:35 +0000 (11:21 -0500)
committerGitHub <noreply@github.com>
Mon, 21 Oct 2019 16:21:35 +0000 (11:21 -0500)
It should be impossible for an untracked object to have the collecting
flag set.  Back when state was stored in gc_refs, it obviously was
impossible (gc_refs couldn't possibly have a positive & negative value
simultaneously).  While the _implementation_ of "state" has gotten much
more complicated, it's still _logically_ just as impossible.

Modules/gcmodule.c

index 9750d2a6f3fb2ada295266091a2e8b33166b7c97..1307aa3dc12fde8b06f9b57849bf143b4a79d01f 100644 (file)
@@ -468,13 +468,16 @@ visit_reachable(PyObject *op, PyGC_Head *reachable)
     PyGC_Head *gc = AS_GC(op);
     const Py_ssize_t gc_refs = gc_get_refs(gc);
 
-    // Ignore untracked objects and objects in other generation.
+    // Ignore objects in other generation.
     // This also skips objects "to the left" of the current position in
     // move_unreachable's scan of the 'young' list - they've already been
     // traversed, and no longer have the PREV_MASK_COLLECTING flag.
-    if (gc->_gc_next == 0 || !gc_is_collecting(gc)) {
+    if (gc_is_collecting(gc)) {
         return 0;
     }
+    // It would be a logic error elsewhere if the collecting flag were set on
+    // an untracked object.
+    assert(gc->_gc_next != 0);
 
     if (gc->_gc_next & NEXT_MASK_UNREACHABLE) {
         /* This had gc_refs = 0 when move_unreachable got