@@ -2255,11 +2255,28 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
22552255 call_weakref_callbacks (state );
22562256 finalize_garbage (state );
22572257
2258- // Handle any objects that may have resurrected after the finalization.
22592258 _PyEval_StopTheWorld (interp );
2259+ // Handle any objects that may have resurrected after the finalization.
22602260 err = handle_resurrected_objects (state );
22612261 // Clear free lists in all threads
22622262 _PyGC_ClearAllFreeLists (interp );
2263+ if (err == 0 ) {
2264+ // Clear weakrefs to objects in the unreachable set. No Python-level
2265+ // code must be allowed to access those unreachable objects. During
2266+ // delete_garbage(), finalizers outside the unreachable set might
2267+ // run and if those weakrefs were not cleared, that could reveal
2268+ // unreachable objects.
2269+ //
2270+ // We used to clear weakrefs earlier, before calling finalizers.
2271+ // That causes at least two problems. First, the finalizers could
2272+ // create new weakrefs, that refer to unreachable objects. Those
2273+ // would not be cleared and could cause the problem described above
2274+ // (see GH-91636 as an example). Second, we need the weakrefs in the
2275+ // tp_subclasses to *not* be cleared so that caches based on the type
2276+ // version are correctly invalidated (see GH-135552 as a bug caused by
2277+ // this).
2278+ clear_weakrefs (state );
2279+ }
22632280 _PyEval_StartTheWorld (interp );
22642281
22652282 if (err < 0 ) {
@@ -2271,21 +2288,6 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
22712288 return ;
22722289 }
22732290
2274- // Clear weakrefs to objects in the unreachable set. No Python-level
2275- // code must be allowed to access those unreachable objects. During
2276- // delete_garbage(), finalizers outside the unreachable set might run
2277- // and if those weakrefs were not cleared, that could reveal unreachable
2278- // objects.
2279- //
2280- // We used to clear weakrefs earlier, before calling finalizers. That
2281- // causes at least two problems. First, the finalizers could create
2282- // new weakrefs, that refer to unreachable objects. Those would not be
2283- // cleared and could cause the problem described above (see GH-91636 as
2284- // an example). Second, we need the weakrefs in the tp_subclasses to
2285- // *not* be cleared so that caches based on the type version are correctly
2286- // invalidated (see GH-135552 as a bug caused by this).
2287- clear_weakrefs (state );
2288-
22892291 // Call tp_clear on objects in the unreachable set. This will cause
22902292 // the reference cycles to be broken. It may also cause some objects
22912293 // to be freed.
0 commit comments