@@ -584,6 +584,56 @@ gc_visit_thread_stacks(PyInterpreterState *interp)
584584 _Py_FOR_EACH_TSTATE_END (interp );
585585}
586586
587+ static bool
588+ mark_stack_push (_PyObjectStack * stack , PyObject * op )
589+ {
590+ if (op == NULL ) {
591+ return true;
592+ }
593+ assert (!gc_is_alive (op ));
594+ gc_set_alive (op );
595+ //gc_maybe_merge_refcount(op);
596+ if (_PyObjectStack_Push (stack , op ) < 0 ) {
597+ return false;
598+ }
599+ return true;
600+ }
601+
602+ static inline void
603+ gc_visit_stackref_mark_alive (_PyObjectStack * stack , _PyStackRef stackref )
604+ {
605+ // Note: we MUST check that it is deferred before checking the rest.
606+ // Otherwise we might read into invalid memory due to non-deferred references
607+ // being dead already.
608+ if (PyStackRef_IsDeferred (stackref ) && !PyStackRef_IsNull (stackref )) {
609+ PyObject * obj = PyStackRef_AsPyObjectBorrow (stackref );
610+ if (_PyObject_GC_IS_TRACKED (obj ) && !gc_is_frozen (obj )) {
611+ mark_stack_push (stack , obj );
612+ }
613+ }
614+ }
615+
616+ static void
617+ gc_visit_thread_stacks_mark_alive (PyInterpreterState * interp , _PyObjectStack * stack )
618+ {
619+ _Py_FOR_EACH_TSTATE_BEGIN (interp , p ) {
620+ for (_PyInterpreterFrame * f = p -> current_frame ; f != NULL ; f = f -> previous ) {
621+ PyObject * executable = PyStackRef_AsPyObjectBorrow (f -> f_executable );
622+ if (executable == NULL || !PyCode_Check (executable )) {
623+ continue ;
624+ }
625+
626+ PyCodeObject * co = (PyCodeObject * )executable ;
627+ int max_stack = co -> co_nlocalsplus + co -> co_stacksize ;
628+ gc_visit_stackref (f -> f_executable );
629+ for (int i = 0 ; i < max_stack ; i ++ ) {
630+ gc_visit_stackref_mark_alive (stack , f -> localsplus [i ]);
631+ }
632+ }
633+ }
634+ _Py_FOR_EACH_TSTATE_END (interp );
635+ }
636+
587637static void
588638queue_untracked_obj_decref (PyObject * op , struct collection_state * state )
589639{
@@ -968,21 +1018,6 @@ propagate_alive_bits(_PyObjectStack *stack)
9681018 return 0 ;
9691019}
9701020
971- static bool
972- mark_stack_push (_PyObjectStack * stack , PyObject * op )
973- {
974- if (op == NULL ) {
975- return true;
976- }
977- assert (!gc_is_alive (op ));
978- gc_set_alive (op );
979- //gc_maybe_merge_refcount(op);
980- if (_PyObjectStack_Push (stack , op ) < 0 ) {
981- return false;
982- }
983- return true;
984- }
985-
9861021static int
9871022mark_root_reachable (PyInterpreterState * interp ,
9881023 struct collection_state * state )
@@ -997,6 +1032,7 @@ mark_root_reachable(PyInterpreterState *interp,
9971032 gc_visit_heaps (interp , & validate_alive_bits , & state -> base );
9981033#endif
9991034 _PyObjectStack stack = { NULL };
1035+ gc_visit_thread_stacks_mark_alive (interp , & stack );
10001036 mark_stack_push (& stack , interp -> sysdict );
10011037 mark_stack_push (& stack , interp -> builtins );
10021038 mark_stack_push (& stack , interp -> dict );
0 commit comments