Skip to content

Commit

Permalink
Use a single generation in the GC
Browse files Browse the repository at this point in the history
  • Loading branch information
pablogsal committed Dec 21, 2022
1 parent a7715cc commit 663a965
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 268 deletions.
25 changes: 20 additions & 5 deletions Include/internal/pycore_gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static inline void _PyGC_SET_FINALIZED(PyObject *op) {

/* If we change this, we need to change the default value in the
signature of gc.collect. */
#define NUM_GENERATIONS 3
#define NUM_GENERATIONS 1
/*
NOTE: about untracking of mutable objects.
Expand Down Expand Up @@ -165,17 +165,25 @@ struct _gc_runtime_state {
int enabled;
int debug;
/* linked lists of container objects */
struct gc_generation generations[NUM_GENERATIONS];
PyGC_Head *generation0;
PyGC_Head head;
/* a permanent generation which won't be collected */
struct gc_generation permanent_generation;
struct gc_generation_stats generation_stats[NUM_GENERATIONS];
struct gc_generation_stats stats;
/* true if we are currently running the collector */
int collecting;
/* list of uncollectable objects */
PyObject *garbage;
/* a list of callbacks to be invoked when collection is performed */
PyObject *callbacks;
/* the number of live GC objects */
Py_ssize_t gc_live;
/* the threshold at which to trigger a collection */
Py_ssize_t gc_threshold;
/* The ratio used to compute gc_threshold:
gc_threshold = (1 + gc_scale/100) * gc_live
A value of 100 means to collect every time the number of live
objects doubles. */
int gc_scale;

/* This is the number of objects that survived the last full
collection. It approximates the number of long lived objects
tracked by the GC.
Expand All @@ -192,6 +200,13 @@ struct _gc_runtime_state {

extern void _PyGC_InitState(struct _gc_runtime_state *);

static inline int
_PyGC_ShouldCollect(struct _gc_runtime_state *gcstate)
{
Py_ssize_t live = gcstate->gc_live;
return !gcstate->collecting && gcstate->enabled && live >= gcstate->gc_threshold;
}

extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);


Expand Down
8 changes: 4 additions & 4 deletions Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ static inline void _PyObject_GC_TRACK(
filename, lineno, __func__);

PyInterpreterState *interp = _PyInterpreterState_GET();
PyGC_Head *generation0 = interp->gc.generation0;
PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
PyGC_Head *head = &interp->gc.head;
PyGC_Head *last = (PyGC_Head*)(head->_gc_prev);
_PyGCHead_SET_NEXT(last, gc);
_PyGCHead_SET_PREV(gc, last);
_PyGCHead_SET_NEXT(gc, generation0);
generation0->_gc_prev = (uintptr_t)gc;
_PyGCHead_SET_NEXT(gc, head);
head->_gc_prev = (uintptr_t)gc;
}

/* Tell the GC to stop tracking this object.
Expand Down
6 changes: 0 additions & 6 deletions Include/internal/pycore_runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,6 @@ extern "C" {
}, \
.gc = { \
.enabled = 1, \
.generations = { \
/* .head is set in _PyGC_InitState(). */ \
{ .threshold = 700, }, \
{ .threshold = 10, }, \
{ .threshold = 10, }, \
}, \
}, \
.static_objects = { \
.singletons = { \
Expand Down
Loading

0 comments on commit 663a965

Please sign in to comment.