8000 gh-135552: Make the GC clear weakrefs later. by nascheme · Pull Request #136189 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-135552: Make the GC clear weakrefs later. #136189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
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.
9E0D // 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
Loading
0