Skip to content

Commit b8b5d0f

Browse files
author
Neil Schemenauer
committed
wip: mark more roots
1 parent a111bff commit b8b5d0f

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

Python/gc_free_threading.c

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -949,22 +949,38 @@ visit_propagate_alive(PyObject *op, _PyObjectStack *stack)
949949
}
950950

951951
static int
952-
propagate_alive_bits(PyObject *op)
952+
propagate_alive_bits(_PyObjectStack *stack)
953953
{
954-
_PyObjectStack stack = { NULL };
955-
do {
954+
for (;;) {
955+
PyObject *op = _PyObjectStack_Pop(stack);
956+
if (op == NULL) {
957+
break;
958+
}
956959
assert(_PyObject_GC_IS_TRACKED(op));
957960
assert(gc_is_alive(op));
958961
traverseproc traverse = Py_TYPE(op)->tp_traverse;
959-
if (traverse(op, (visitproc)&visit_propagate_alive, &stack) < 0) {
960-
_PyObjectStack_Clear(&stack);
962+
if (traverse(op, (visitproc)&visit_propagate_alive, stack) < 0) {
963+
_PyObjectStack_Clear(stack);
961964
return -1;
962965
}
963-
op = _PyObjectStack_Pop(&stack);
964-
} while (op != NULL);
966+
}
965967
return 0;
966968
}
967969

970+
static bool
971+
mark_stack_push(_PyObjectStack *stack, PyObject *op)
972+
{
973+
if (op == NULL) {
974+
return true;
975+
}
976+
assert(!gc_is_alive(op));
977+
gc_set_alive(op);
978+
if (_PyObjectStack_Push(stack, Py_NewRef(op)) < 0) {
979+
return false;
980+
}
981+
return true;
982+
}
983+
968984
static int
969985
mark_root_reachable(PyInterpreterState *interp,
970986
struct collection_state *state)
@@ -978,10 +994,20 @@ mark_root_reachable(PyInterpreterState *interp,
978994
// Check that all objects don't have ALIVE bits set
979995
gc_visit_heaps(interp, &validate_alive_bits, &state->base);
980996
#endif
981-
PyObject *root = interp->sysdict;
982-
assert(!gc_is_alive(root));
983-
gc_set_alive(root);
984-
propagate_alive_bits(root);
997+
_PyObjectStack stack = { NULL };
998+
mark_stack_push(&stack, interp->sysdict);
999+
mark_stack_push(&stack, interp->builtins);
1000+
mark_stack_push(&stack, interp->dict);
1001+
struct types_state *types = &interp->types;
1002+
for (int i = 0; i < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES; i++) {
1003+
mark_stack_push(&stack, types->builtins.initialized[i].tp_dict);
1004+
mark_stack_push(&stack, types->builtins.initialized[i].tp_subclasses);
1005+
}
1006+
for (int i = 0; i < _Py_MAX_MANAGED_STATIC_EXT_TYPES; i++) {
1007+
mark_stack_push(&stack, types->for_extensions.initialized[i].tp_dict);
1008+
mark_stack_push(&stack, types->for_extensions.initialized[i].tp_subclasses);
1009+
}
1010+
propagate_alive_bits(&stack);
9851011

9861012
#if WITH_GC_TIMING_STATS
9871013
PyTime_t t2;
@@ -1014,7 +1040,7 @@ deduce_unreachable_heap(PyInterpreterState *interp,
10141040
gc_visit_heaps(interp, &update_refs, &state->base);
10151041

10161042
#if WITH_GC_TIMING_STATS
1017-
//fprintf(stderr, "gc alive %d immortal %d checked %d gc %d\n", num_alive, num_immortal, num_checked, num_gc);
1043+
fprintf(stderr, "gc alive %d immortal %d checked %d gc %d\n", num_alive, num_immortal, num_checked, num_gc);
10181044
#endif
10191045

10201046
#ifdef GC_DEBUG

0 commit comments

Comments
 (0)