Skip to content

Commit 413ad5e

Browse files
committed
gh-159437: Avoid resetting discarded resurrection list
1 parent bb3b661 commit 413ad5e

1 file changed

Lines changed: 18 additions & 4 deletions

File tree

‎Python/gc.c‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)