@@ -949,22 +949,38 @@ visit_propagate_alive(PyObject *op, _PyObjectStack *stack)
949949}
950950
951951static 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+
968984static int
969985mark_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