@@ -1369,36 +1369,6 @@ visit_add_to_container(PyObject *op, void *arg)
13691369 return 0 ;
13701370}
13711371
1372- static Py_ssize_t
1373- expand_region_transitively_reachable (PyGC_Head * container , PyGC_Head * gc , GCState * gcstate )
1374- {
1375- struct container_and_flag arg = {
1376- .container = container ,
1377- .visited_space = gcstate -> visited_space ,
1378- .size = 0
1379- };
1380- assert (GC_NEXT (gc ) == container );
1381- while (gc != container ) {
1382- /* Survivors will be moved to visited space, so they should
1383- * have been marked as visited */
1384- assert (IS_IN_VISITED (gc , gcstate -> visited_space ));
1385- PyObject * op = FROM_GC (gc );
1386- assert (_PyObject_GC_IS_TRACKED (op ));
1387- if (_Py_IsImmortal (op )) {
1388- PyGC_Head * next = GC_NEXT (gc );
1389- gc_list_move (gc , & get_gc_state ()-> permanent_generation .head );
1390- gc = next ;
1391- continue ;
1392- }
1393- traverseproc traverse = Py_TYPE (op )-> tp_traverse ;
1394- (void ) traverse (op ,
1395- visit_add_to_container ,
1396- & arg );
1397- gc = GC_NEXT (gc );
1398- }
1399- return arg .size ;
1400- }
1401-
14021372/* Do bookkeeping for a completed GC cycle */
14031373static void
14041374completed_cycle (GCState * gcstate )
@@ -1611,7 +1581,6 @@ mark_at_start(PyThreadState *tstate)
16111581 PyGC_Head * visited = & gcstate -> old [gcstate -> visited_space ].head ;
16121582 Py_ssize_t objects_marked = mark_global_roots (tstate -> interp , visited , gcstate -> visited_space );
16131583 objects_marked += mark_stacks (tstate -> interp , visited , gcstate -> visited_space , true);
1614- gcstate -> work_to_do -= objects_marked ;
16151584 gcstate -> phase = GC_PHASE_COLLECT ;
16161585 return objects_marked ;
16171586}
@@ -1675,19 +1644,22 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
16751644 gc_list_set_space (& gcstate -> young .head , gcstate -> visited_space );
16761645 PyGC_Head increment ;
16771646 gc_list_init (& increment );
1678- gc_list_merge (& gcstate -> young .head , & increment );
1647+ PyGC_Head working ;
1648+ gc_list_init (& working );
1649+ gc_list_merge (& gcstate -> young .head , & working );
16791650 gc_list_validate_space (& increment , gcstate -> visited_space );
1680- Py_ssize_t increment_size = 0 ;
1651+ Py_ssize_t increment_size = move_all_transitively_reachable (& working , & increment , gcstate -> visited_space );
1652+ assert (gc_list_is_empty (& working ));
16811653 while (increment_size < gcstate -> work_to_do ) {
16821654 if (gc_list_is_empty (not_visited )) {
16831655 break ;
16841656 }
16851657 PyGC_Head * gc = _PyGCHead_NEXT (not_visited );
1686- gc_list_move (gc , & increment );
1687- increment_size ++ ;
1658+ gc_list_move (gc , & working );
16881659 assert (!_Py_IsImmortal (FROM_GC (gc )));
16891660 gc_set_old_space (gc , gcstate -> visited_space );
1690- increment_size += expand_region_transitively_reachable (& increment , gc , gcstate );
1661+ increment_size += move_all_transitively_reachable (& working , & increment , gcstate -> visited_space );
1662+ assert (gc_list_is_empty (& working ));
16911663 }
16921664 GC_STAT_ADD (1 , objects_not_transitively_reachable , increment_size );
16931665 gc_list_validate_space (& increment , gcstate -> visited_space );
0 commit comments