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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy