@@ -24,7 +24,7 @@ typedef struct _gc_runtime_state GCState;
2424#endif
2525
2626// Define this when debugging the GC
27- // #define GC_EXTRA_DEBUG
27+ #define GC_EXTRA_DEBUG
2828
2929
3030#define GC_NEXT _PyGCHead_NEXT
@@ -1308,6 +1308,7 @@ gc_collect_young(PyThreadState *tstate,
13081308
13091309 PyGC_Head survivors ;
13101310 gc_list_init (& survivors );
1311+ gc_list_set_space (young , gcstate -> visited_space );
13111312 gc_collect_region (tstate , young , & survivors , stats );
13121313 Py_ssize_t survivor_count = 0 ;
13131314 if (gcstate -> visited_space ) {
@@ -1385,6 +1386,7 @@ expand_region_transitively_reachable(PyGC_Head *container, PyGC_Head *gc, GCStat
13851386 * have been marked as visited */
13861387 assert (IS_IN_VISITED (gc , gcstate -> visited_space ));
13871388 PyObject * op = FROM_GC (gc );
1389+ assert (_PyObject_GC_IS_TRACKED (op ));
13881390 if (_Py_IsImmortal (op )) {
13891391 PyGC_Head * next = GC_NEXT (gc );
13901392 gc_list_move (gc , & get_gc_state ()-> permanent_generation .head );
@@ -1404,17 +1406,16 @@ expand_region_transitively_reachable(PyGC_Head *container, PyGC_Head *gc, GCStat
14041406static void
14051407completed_cycle (GCState * gcstate )
14061408{
1407- #ifdef Py_DEBUG
1408- PyGC_Head * not_visited = & gcstate -> old [gcstate -> visited_space ^1 ].head ;
1409- assert (gc_list_is_empty (not_visited ));
1410- #endif
1409+ int not_visited = flip_old_space (gcstate -> visited_space );
1410+ assert (gc_list_is_empty (& gcstate -> old [not_visited ].head ));
1411+ gcstate -> visited_space = not_visited ;
14111412 gcstate -> visited_space = flip_old_space (gcstate -> visited_space );
14121413 /* Make sure all young objects have old space bit set correctly */
14131414 PyGC_Head * young = & gcstate -> young .head ;
14141415 PyGC_Head * gc = GC_NEXT (young );
14151416 while (gc != young ) {
14161417 PyGC_Head * next = GC_NEXT (gc );
1417- gc_set_old_space (gc , gcstate -> visited_space );
1418+ gc_set_old_space (gc , not_visited );
14181419 gc = next ;
14191420 }
14201421 gcstate -> work_to_do = 0 ;
@@ -1433,6 +1434,7 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
14331434 if (scale_factor < 1 ) {
14341435 scale_factor = 1 ;
14351436 }
1437+ gc_list_set_space (& gcstate -> young .head , gcstate -> visited_space );
14361438 gc_list_merge (& gcstate -> young .head , & increment );
14371439 gcstate -> young .count = 0 ;
14381440 gc_list_validate_space (& increment , gcstate -> visited_space );
@@ -1444,6 +1446,7 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
14441446 PyGC_Head * gc = _PyGCHead_NEXT (not_visited );
14451447 gc_list_move (gc , & increment );
14461448 increment_size ++ ;
1449+ assert (!_Py_IsImmortal (FROM_GC (gc )));
14471450 gc_set_old_space (gc , gcstate -> visited_space );
14481451 increment_size += expand_region_transitively_reachable (& increment , gc , gcstate );
14491452 }
@@ -1465,7 +1468,6 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
14651468 }
14661469}
14671470
1468-
14691471static void
14701472gc_collect_full (PyThreadState * tstate ,
14711473 struct gc_collection_stats * stats )
@@ -1477,9 +1479,9 @@ gc_collect_full(PyThreadState *tstate,
14771479 PyGC_Head * pending = & gcstate -> old [gcstate -> visited_space ^1 ].head ;
14781480 PyGC_Head * visited = & gcstate -> old [gcstate -> visited_space ].head ;
14791481 /* merge all generations into visited */
1480- gc_list_validate_space (young , gcstate -> visited_space );
1481- gc_list_set_space (pending , gcstate -> visited_space );
14821482 gc_list_merge (young , pending );
1483+ gc_list_validate_space (pending , 1 - gcstate -> visited_space );
1484+ gc_list_set_space (pending , gcstate -> visited_space );
14831485 gcstate -> young .count = 0 ;
14841486 gc_list_merge (pending , visited );
14851487
@@ -1488,7 +1490,7 @@ gc_collect_full(PyThreadState *tstate,
14881490 gcstate -> young .count = 0 ;
14891491 gcstate -> old [0 ].count = 0 ;
14901492 gcstate -> old [1 ].count = 0 ;
1491-
1493+ completed_cycle ( gcstate );
14921494 gcstate -> work_to_do = - gcstate -> young .threshold * 2 ;
14931495 _PyGC_ClearAllFreeLists (tstate -> interp );
14941496 validate_old (gcstate );
@@ -1734,9 +1736,10 @@ _PyGC_Freeze(PyInterpreterState *interp)
17341736{
17351737 GCState * gcstate = & interp -> gc ;
17361738 /* The permanent_generation has its old space bit set to zero */
1737- if (gcstate -> visited_space ) {
1739+ if (gcstate -> visited_space == 0 ) {
17381740 gc_list_set_space (& gcstate -> young .head , 0 );
17391741 }
1742+ gc_list_validate_space (& gcstate -> young .head , 0 );
17401743 gc_list_merge (& gcstate -> young .head , & gcstate -> permanent_generation .head );
17411744 gcstate -> young .count = 0 ;
17421745 PyGC_Head * old0 = & gcstate -> old [0 ].head ;
0 commit comments