Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e2d5918

Browse files
committed
gc list function cleanup.
Introduced gc_list_move(), which captures the common gc_list_remove() + gc_list_append() sequence. In fact, no uses of gc_list_append() remained (they were all in a gc_list_move() sequence), so commented that one out. gc_list_merge(): assert that `from` != `to`; that was an implicit precondition, now verified in a debug build. Others: added comments about their purpose.
1 parent cc2a866 commit e2d5918

1 file changed

Lines changed: 31 additions & 15 deletions

File tree

Modules/gcmodule.c

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ gc_list_is_empty(PyGC_Head *list)
139139
return (list->gc.gc_next == list);
140140
}
141141

142+
#if 0
143+
/* This became unused after gc_list_move() was introduced. */
144+
/* Append `node` to `list`. */
142145
static void
143146
gc_list_append(PyGC_Head *node, PyGC_Head *list)
144147
{
@@ -147,7 +150,9 @@ gc_list_append(PyGC_Head *node, PyGC_Head *list)
147150
node->gc.gc_prev->gc.gc_next = node;
148151
list->gc.gc_prev = node;
149152
}
153+
#endif
150154

155+
/* Remove `node` from the gc list it's currently in. */
151156
static void
152157
gc_list_remove(PyGC_Head *node)
153158
{
@@ -156,11 +161,29 @@ gc_list_remove(PyGC_Head *node)
156161
node->gc.gc_next = NULL; /* object is not currently tracked */
157162
}
158163

159-
/* append a list onto another list, from becomes an empty list */
164+
/* Move `node` from the gc list it's currently in (which is not explicitly
165+
* named here) to the end of `list`. This is semantically the same as
166+
* gc_list_remove(node) followed by gc_list_append(node, list).
167+
*/
168+
static void
169+
gc_list_move(PyGC_Head *node, PyGC_Head *list)
170+
{
171+
PyGC_Head *current_prev = node->gc.gc_prev;
172+
PyGC_Head *current_next = node->gc.gc_next;
173+
PyGC_Head *new_prev = list->gc.gc_prev;
174+
current_prev->gc.gc_next = current_next;
175+
current_next->gc.gc_prev = current_prev;
176+
node->gc.gc_next = list;
177+
node->gc.gc_prev = new_prev;
178+
new_prev->gc.gc_next = list->gc.gc_prev = node;
179+
}
180+
181+
/* append list `from` onto list `to`; `from` becomes an empty list */
160182
static void
161183
gc_list_merge(PyGC_Head *from, PyGC_Head *to)
162184
{
163185
PyGC_Head *tail;
186+
assert(from != to);
164187
if (!gc_list_is_empty(from)) {
165188
tail = to->gc.gc_prev;
166189
tail->gc.gc_next = from->gc.gc_next;
@@ -295,8 +318,7 @@ visit_reachable(PyObject *op, PyGC_Head *reachable)
295318
* and move_unreachable will eventually get to it
296319
* again.
297320
*/
298-
gc_list_remove(gc);
299-
gc_list_append(gc, reachable);
321+
gc_list_move(gc, reachable);
300322
gc->gc.gc_refs = 1;
301323
}
302324
/* Else there's nothing to do.
@@ -368,8 +390,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
368390
* young if that's so, and we'll see it again.
369391
*/
370392
next = gc->gc.gc_next;
371-
gc_list_remove(gc);
372-
gc_list_append(gc, unreachable);
393+
gc_list_move(gc, unreachable);
373394
gc->gc.gc_refs = GC_TENTATIVELY_UNREACHABLE;
374395
}
375396
gc = next;
@@ -416,8 +437,7 @@ move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
416437
next = gc->gc.gc_next;
417438

418439
if (has_finalizer(op)) {
419-
gc_list_remove(gc);
420-
gc_list_append(gc, finalizers);
440+
gc_list_move(gc, finalizers);
421441
gc->gc.gc_refs = GC_REACHABLE;
422442
}
423443
}
@@ -430,8 +450,7 @@ visit_move(PyObject *op, PyGC_Head *tolist)
430450
if (PyObject_IS_GC(op)) {
431451
if (IS_TENTATIVELY_UNREACHABLE(op)) {
432452
PyGC_Head *gc = AS_GC(op);
433-
gc_list_remove(gc);
434-
gc_list_append(gc, tolist);
453+
gc_list_move(gc, tolist);
435454
gc->gc.gc_refs = GC_REACHABLE;
436455
}
437456
}
@@ -559,8 +578,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
559578
assert(wrasgc != next); /* wrasgc is reachable, but
560579
next isn't, so they can't
561580
be the same */
562-
gc_list_remove(wrasgc);
563-
gc_list_append(wrasgc, &wrcb_to_call);
581+
gc_list_move(wrasgc, &wrcb_to_call);
564582
}
565583
}
566584

@@ -600,8 +618,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
600618
Py_DECREF(op);
601619
if (wrcb_to_call.gc.gc_next == gc) {
602620
/* object is still alive -- move it */
603-
gc_list_remove(gc);
604-
gc_list_append(gc, old);
621+
gc_list_move(gc, old);
605622
}
606623
else
607624
++num_freed;
@@ -694,8 +711,7 @@ delete_garbage(PyGC_Head *collectable, PyGC_Head *old)
694711
}
695712
if (collectable->gc.gc_next == gc) {
696713
/* object is still alive, move it, it may die later */
697-
gc_list_remove(gc);
698-
gc_list_append(gc, old);
714+
gc_list_move(gc, old);
699715
gc->gc.gc_refs = GC_REACHABLE;
700716
}
701717
}

0 commit comments

Comments
 (0)