@@ -274,9 +274,16 @@ gc_list_move(PyGC_Head *node, PyGC_Head *list)
274274 _PyGCHead_SET_NEXT (node , list );
275275}
276276
277- /* append list `from` onto list `to`; `from` becomes an empty list */
278- static void
279- gc_list_merge (PyGC_Head * from , PyGC_Head * to )
277+ /* Append all members of `from` to `to` in order.
278+ *
279+ * `from`: Source GC list with untagged _gc_next links.
280+ * `to`: Distinct, disjoint GC list with untagged _gc_next links.
281+ *
282+ * `to` remains valid and _gc_prev flags are preserved. The source head must
283+ * be discarded or reinitialized with gc_list_init() before any list operation.
284+ */
285+ static inline void
286+ gc_list_splice (PyGC_Head * from , PyGC_Head * to )
280287{
281288 assert (from != to );
282289 if (!gc_list_is_empty (from )) {
@@ -292,6 +299,13 @@ gc_list_merge(PyGC_Head *from, PyGC_Head *to)
292299 _PyGCHead_SET_NEXT (from_tail , to );
293300 _PyGCHead_SET_PREV (to , from_tail );
294301 }
302+ }
303+
304+ /* append list `from` onto list `to`; `from` becomes an empty list */
305+ static void
306+ gc_list_merge (PyGC_Head * from , PyGC_Head * to )
307+ {
308+ gc_list_splice (from , to );
295309 gc_list_init (from );
296310}
297311
@@ -1416,7 +1430,7 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable,
14161430 deduce_unreachable (resurrected , still_unreachable , false, & reachable , & unused_legacy_finalizer_count );
14171431
14181432 // Move the resurrected objects to the old generation for future collection.
1419- gc_list_merge (resurrected , old_generation );
1433+ gc_list_splice (resurrected , old_generation );
14201434}
14211435
14221436
0 commit comments