Visitar URL original
gh-135552: Make the GC clear weakrefs later by nascheme · Pull Request #136189 · python/cpython · GitHub
Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Run clear_weakrefs() with world stopped.
  • Loading branch information
nascheme committed Jul 1, 2025
commit 12f0b5c6a495c830dede2e1638f0eab0c9750de9
34 changes: 18 additions & 16 deletions Python/gc_free_threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -2255,11 +2255,28 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
call_weakref_callbacks(state);
finalize_garbage(state);

// Handle any objects that may have resurrected after the finalization.
_PyEval_StopTheWorld(interp);
// Handle any objects that may have resurrected after the finalization.
err = handle_resurrected_objects(state);
// Clear free lists in all threads
_PyGC_ClearAllFreeLists(interp);
if (err == 0) {
// Clear weakrefs to objects in the unreachable set. No Python-level
// code must be allowed to access those unreachable objects. During
// delete_garbage(), finalizers outside the unreachable set might
// run and if those weakrefs were not cleared, that could reveal
// unreachable objects.
//
// We used to clear weakrefs earlier, before calling finalizers.
// That causes at least two problems. First, the finalizers could
// create new weakrefs, that refer to unreachable objects. Those
// would not be cleared and could cause the problem described above
// (see GH-91636 as an example). Second, we need the weakrefs in the
// tp_subclasses to *not* be cleared so that caches based on the type
// version are correctly invalidated (see GH-135552 as a bug caused by
// this).
clear_weakrefs(state);
}
_PyEval_StartTheWorld(interp);

if (err < 0) {
Expand All @@ -2271,21 +2288,6 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
return;
}

// Clear weakrefs to objects in the unreachable set. No Python-level
// code must be allowed to access those unreachable objects. During
// delete_garbage(), finalizers outside the unreachable set might run
// and if those weakrefs were not cleared, that could reveal unreachable
// objects.
//
// We used to clear weakrefs earlier, before calling finalizers. That
// causes at least two problems. First, the finalizers could create
// new weakrefs, that refer to unreachable objects. Those would not be
// cleared and could cause the problem described above (see GH-91636 as
// an example). Second, we need the weakrefs in the tp_subclasses to
// *not* be cleared so that caches based on the type version are correctly
// invalidated (see GH-135552 as a bug caused by this).
clear_weakrefs(state);

// Call tp_clear on objects in the unreachable set. This will cause
// the reference cycles to be broken. It may also cause some objects
// to be freed.
Expand Down