Skip to content

Commit 17392fb

Browse files
committed
[GR-72218] Clarify GraalPy gcmodule assertions
PullRequest: graalpython/4336
2 parents d57e889 + 8ee1a25 commit 17392fb

File tree

1 file changed

+21
-4
lines changed
  • graalpython/com.oracle.graal.python.cext/src

1 file changed

+21
-4
lines changed

graalpython/com.oracle.graal.python.cext/src/gcmodule.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,11 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable,
891891
// GraalPy change: this branch, else branch is original CPython code
892892
cycle.head = NULL;
893893
cycle.n = 0;
894-
// TODO: [GR-72218] assert (cycle.reachable == weak_candidates );
894+
/* GraalPy change: visit_collect_managed_referents forwards to
895+
* visit_reachable(cycle->reachable), and 'cycle' is initialized
896+
* with 'young'.
897+
*/
898+
assert(cycle.reachable == young);
895899
/* visit_collect_managed_referents is visit_reachable + capture the references into "cycle" */
896900
CALL_TRAVERSE(traverse, op, visit_collect_managed_referents, (void *)&cycle);
897901

@@ -979,12 +983,25 @@ move_weak_reachable(PyGC_Head *young, PyGC_Head *weak_candidates)
979983
while (gc != young) {
980984
Py_ssize_t gc_refcnt = gc_get_refs(gc);
981985

982-
// TODO: [GR-72218] assert(gc_is_collecting(gc));
983-
986+
/* GraalPy change: unlike CPython's single-phase flow, objects moved to
987+
* 'weak_candidates' already had PREV_MASK_COLLECTING cleared in
988+
* move_unreachable() before this phase runs. visit_weak_reachable()
989+
* depends on that state so it can rescue weak candidates without
990+
* moving them through visit_reachable() again, so gc_is_collecting(gc)
991+
* is not a valid invariant here.
992+
*/
993+
// assert(gc_is_collecting(gc));
984994
/* This phase is done after 'move_unreachable' and so all object
985995
* remaining in 'young' must have a non-zero gc_refcnt.
986996
*/
987-
// TODO: [GR-72218] assert(gc_refcnt);
997+
/* GraalPy change: gc_refcnt is also not a stable CPython-style
998+
* invariant here. During the weak-candidate flow we reuse '_gc_prev'
999+
* for list linkage, so native gc_refs information for rescued objects
1000+
* is recovered via update_refs()/subtract_refs() and
1001+
* is_referenced_from_managed(), not by requiring gc_refcnt != 0 for
1002+
* every object we encounter in this phase.
1003+
*/
1004+
// assert(gc_refcnt);
9881005
/* If gc_refcnt s not MANAGED_REFCNT, then we know that this object is
9891006
* referenced from native (e.g. stored in a global field). In case that
9901007
* 'gc_refcnt == MANAGED_REFCNT' we don't know if the object is only

0 commit comments

Comments
 (0)