@@ -2255,11 +2255,28 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
2255
2255
call_weakref_callbacks (state );
2256
2256
finalize_garbage (state );
2257
2257
2258
- // Handle any objects that may have resurrected after the finalization.
2259
2258
_PyEval_StopTheWorld (interp );
2259
+ // Handle any objects that may have resurrected after the finalization.
2260
2260
err = handle_resurrected_objects (state );
2261
2261
// Clear free lists in all threads
2262
2262
_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
+ }
2263
2280
_PyEval_StartTheWorld (interp );
2264
2281
2265
2282
if (err < 0 ) {
@@ -2271,21 +2288,6 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
2271
2288
return ;
2272
2289
}
2273
2290
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
-
2289
2291
// Call tp_clear on objects in the unreachable set. This will cause
2290
2292
// the reference cycles to be broken. It may also cause some objects
2291
2293
// to be freed.
0 commit comments