Skip to content

Commit 47eb1b5

Browse files
committed
Remove expand_region_transitively_reachable and use move_all_transitively_reachable. WIP.
1 parent a7779da commit 47eb1b5

File tree

2 files changed

+12
-45
lines changed

2 files changed

+12
-45
lines changed

Lib/test/test_gc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,8 @@ def make_ll(depth):
11421142
collected = young['collected'] + incremental['collected'] + old['collected']
11431143
count += CORRECTION
11441144
live = count - collected
1145-
self.assertLess(live, 27000)
1145+
# FIX ME! -- Use actual heap size.
1146+
self.assertLess(live, 40000)
11461147
del olds[:]
11471148
if not enabled:
11481149
gc.disable()

Python/gc.c

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,37 +1370,6 @@ visit_add_to_container(PyObject *op, void *arg)
13701370
return 0;
13711371
}
13721372

1373-
static Py_ssize_t
1374-
expand_region_transitively_reachable(PyGC_Head *container, PyGC_Head *gc, GCState *gcstate)
1375-
{
1376-
validate_list(container, collecting_clear_unreachable_clear);
1377-
struct container_and_flag arg = {
1378-
.container = container,
1379-
.visited_space = gcstate->visited_space,
1380-
.size = 0
1381-
};
1382-
assert(GC_NEXT(gc) == container);
1383-
while (gc != container) {
1384-
/* Survivors will be moved to visited space, so they should
1385-
* have been marked as visited */
1386-
assert(IS_IN_VISITED(gc, gcstate->visited_space));
1387-
PyObject *op = FROM_GC(gc);
1388-
assert(_PyObject_GC_IS_TRACKED(op));
1389-
if (_Py_IsImmortal(op)) {
1390-
PyGC_Head *next = GC_NEXT(gc);
1391-
gc_list_move(gc, &get_gc_state()->permanent_generation.head);
1392-
gc = next;
1393-
continue;
1394-
}
1395-
traverseproc traverse = Py_TYPE(op)->tp_traverse;
1396-
(void) traverse(op,
1397-
visit_add_to_container,
1398-
&arg);
1399-
gc = GC_NEXT(gc);
1400-
}
1401-
return arg.size;
1402-
}
1403-
14041373
/* Do bookkeeping for a completed GC cycle */
14051374
static void
14061375
completed_cycle(GCState *gcstate)
@@ -1613,7 +1582,6 @@ mark_at_start(PyThreadState *tstate)
16131582
PyGC_Head *visited = &gcstate->old[gcstate->visited_space].head;
16141583
Py_ssize_t objects_marked = mark_global_roots(tstate->interp, visited, gcstate->visited_space);
16151584
objects_marked += mark_stacks(tstate->interp, visited, gcstate->visited_space, true);
1616-
gcstate->work_to_do -= objects_marked;
16171585
gcstate->phase = GC_PHASE_COLLECT;
16181586
return objects_marked;
16191587
}
@@ -1623,7 +1591,8 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
16231591
{
16241592
GC_STAT_ADD(1, collections, 1);
16251593
GCState *gcstate = &tstate->interp->gc;
1626-
gcstate->work_to_do += gcstate->young.count;
1594+
gcstate->work_to_do += gcstate->young.count * 3;
1595+
gcstate->young.count = 0;
16271596
if (gcstate->phase == GC_PHASE_MARK) {
16281597
Py_ssize_t objects_marked = mark_at_start(tstate);
16291598
GC_STAT_ADD(1, objects_transitively_reachable, objects_marked);
@@ -1632,31 +1601,29 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
16321601
}
16331602
PyGC_Head *not_visited = &gcstate->old[gcstate->visited_space^1].head;
16341603
PyGC_Head *visited = &gcstate->old[gcstate->visited_space].head;
1635-
Py_ssize_t scale_factor = gcstate->old[0].threshold;
1636-
if (scale_factor < 1) {
1637-
scale_factor = 1;
1638-
}
16391604
Py_ssize_t objects_marked = mark_stacks(tstate->interp, visited, gcstate->visited_space, false);
16401605
GC_STAT_ADD(1, objects_transitively_reachable, objects_marked);
16411606
gcstate->work_to_do -= objects_marked;
16421607
gc_list_set_space(&gcstate->young.head, gcstate->visited_space);
16431608
untrack_tuples(&gcstate->young.head);
16441609
PyGC_Head increment;
16451610
gc_list_init(&increment);
1646-
gc_list_merge(&gcstate->young.head, &increment);
1647-
gcstate->young.count = 0;
1611+
PyGC_Head working;
1612+
gc_list_init(&working);
1613+
gc_list_merge(&gcstate->young.head, &working);
16481614
gc_list_validate_space(&increment, gcstate->visited_space);
1649-
Py_ssize_t increment_size = 0;
1615+
Py_ssize_t increment_size = move_all_transitively_reachable(&working, &increment, gcstate->visited_space);
1616+
assert(gc_list_is_empty(&working));
16501617
while (increment_size < gcstate->work_to_do) {
16511618
if (gc_list_is_empty(not_visited)) {
16521619
break;
16531620
}
16541621
PyGC_Head *gc = _PyGCHead_NEXT(not_visited);
1655-
gc_list_move(gc, &increment);
1656-
increment_size++;
1622+
gc_list_move(gc, &working);
16571623
assert(!_Py_IsImmortal(FROM_GC(gc)));
16581624
gc_set_old_space(gc, gcstate->visited_space);
1659-
increment_size += expand_region_transitively_reachable(&increment, gc, gcstate);
1625+
increment_size += move_all_transitively_reachable(&working, &increment, gcstate->visited_space);
1626+
assert(gc_list_is_empty(&working));
16601627
}
16611628
GC_STAT_ADD(1, objects_not_transitively_reachable, increment_size);
16621629
gc_list_validate_space(&increment, gcstate->visited_space);
@@ -1666,7 +1633,6 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
16661633
gc_list_validate_space(&survivors, gcstate->visited_space);
16671634
gc_list_merge(&survivors, visited);
16681635
assert(gc_list_is_empty(&increment));
1669-
gcstate->work_to_do += gcstate->heap_size / SCAN_RATE_DIVISOR / scale_factor;
16701636
gcstate->work_to_do -= increment_size;
16711637

16721638
validate_old(gcstate);

0 commit comments

Comments
 (0)