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

Skip to content

Commit 698abb3

Browse files
committed
Do not touch permanent generation
1 parent 0b46494 commit 698abb3

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

Python/gc.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,15 +1400,28 @@ expand_region_transitively_reachable(PyGC_Head *container, PyGC_Head *gc, GCStat
14001400

14011401
/* Do bookkeeping for a completed GC cycle */
14021402
static void
1403-
completed_cycle(GCState *gcstate)
1404-
{
1405-
/* Flip spaces */
1406-
int not_visited = gcstate->visited_space;
1407-
int visited = other_space(not_visited);
1408-
gcstate->visited_space = visited;
1409-
/* Make sure all objects have visited bit set correctly */
1410-
gc_list_set_space(&gcstate->young.head, not_visited);
1411-
gc_list_set_space(&gcstate->permanent_generation.head, visited);
1403+
completed_scavenge(GCState *gcstate)
1404+
{
1405+
/* We must observe two invariants:
1406+
* 1. Members of the permanent generation must be marked visited.
1407+
* 2. We cannot touch members of the permanent generation. */
1408+
int visited;
1409+
if (gc_list_is_empty(&gcstate->permanent_generation.head)) {
1410+
/* Permanent generation is empty so we can flip spaces bit */
1411+
int not_visited = gcstate->visited_space;
1412+
visited = other_space(not_visited);
1413+
gcstate->visited_space = visited;
1414+
/* Make sure all objects have visited bit set correctly */
1415+
gc_list_set_space(&gcstate->young.head, not_visited);
1416+
}
1417+
else {
1418+
/* We must move the objects from visited to pending space. */
1419+
visited = gcstate->visited_space;
1420+
int not_visited = other_space(visited);
1421+
assert(gc_list_is_empty(&gcstate->old[not_visited].head));
1422+
gc_list_merge(&gcstate->old[visited].head, &gcstate->old[not_visited].head);
1423+
gc_list_set_space(&gcstate->old[not_visited].head, not_visited);
1424+
}
14121425
assert(gc_list_is_empty(&gcstate->old[visited].head));
14131426
gcstate->work_to_do = 0;
14141427
gcstate->phase = GC_PHASE_MARK;
@@ -1627,7 +1640,7 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
16271640

16281641
add_stats(gcstate, 1, stats);
16291642
if (gc_list_is_empty(not_visited)) {
1630-
completed_cycle(gcstate);
1643+
completed_scavenge(gcstate);
16311644
}
16321645
validate_spaces(gcstate);
16331646
}
@@ -1657,7 +1670,7 @@ gc_collect_full(PyThreadState *tstate,
16571670
gcstate->young.count = 0;
16581671
gcstate->old[0].count = 0;
16591672
gcstate->old[1].count = 0;
1660-
completed_cycle(gcstate);
1673+
completed_scavenge(gcstate);
16611674
_PyGC_ClearAllFreeLists(tstate->interp);
16621675
validate_spaces(gcstate);
16631676
add_stats(gcstate, 2, stats);

0 commit comments

Comments
 (0)