Skip to content

Commit

Permalink
pythongh-113688: Split up gcmodule.c (pythongh-113715)
Browse files Browse the repository at this point in the history
This splits part of Modules/gcmodule.c of into Python/gc.c, which
now contains the core garbage collection implementation. The Python
module remain in the Modules/gcmodule.c file.
  • Loading branch information
colesbury authored and Glyphack committed Jan 27, 2024
1 parent 41c71be commit 4eef188
Show file tree
Hide file tree
Showing 9 changed files with 2,036 additions and 1,965 deletions.
31 changes: 31 additions & 0 deletions Include/internal/pycore_gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
#define _PyGC_PREV_SHIFT (2)
#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT)

/* set for debugging information */
#define _PyGC_DEBUG_STATS (1<<0) /* print collection statistics */
#define _PyGC_DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
#define _PyGC_DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
#define _PyGC_DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
#define _PyGC_DEBUG_LEAK _PyGC_DEBUG_COLLECTABLE | \
_PyGC_DEBUG_UNCOLLECTABLE | \
_PyGC_DEBUG_SAVEALL

typedef enum {
// GC was triggered by heap allocation
_Py_GC_REASON_HEAP,

// GC was called during shutdown
_Py_GC_REASON_SHUTDOWN,

// GC was called by gc.collect() or PyGC_Collect()
_Py_GC_REASON_MANUAL
} _PyGC_Reason;

// Lowest bit of _gc_next is used for flags only in GC.
// But it is always 0 for normal code.
static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
Expand Down Expand Up @@ -203,8 +223,19 @@ struct _gc_runtime_state {

extern void _PyGC_InitState(struct _gc_runtime_state *);

extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation,
_PyGC_Reason reason);
extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);

/* Freeze objects tracked by the GC and ignore them in future collections. */
extern void _PyGC_Freeze(PyInterpreterState *interp);
/* Unfreezes objects placing them in the oldest generation */
extern void _PyGC_Unfreeze(PyInterpreterState *interp);
/* Number of frozen objects */
extern Py_ssize_t _PyGC_GetFreezeCount(PyInterpreterState *interp);

extern PyObject *_PyGC_GetObjects(PyInterpreterState *interp, Py_ssize_t generation);
extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs);

// Functions to clear types free lists
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_gc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ def test_refcount_errors(self):
p.stderr.close()
# Verify that stderr has a useful error message:
self.assertRegex(stderr,
br'gcmodule\.c:[0-9]+: gc_decref: Assertion "gc_get_refs\(g\) > 0" failed.')
br'gc\.c:[0-9]+: gc_decref: Assertion "gc_get_refs\(g\) > 0" failed.')
self.assertRegex(stderr,
br'refcount is too small')
# "address : 0x7fb5062efc18"
Expand Down
1 change: 1 addition & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ PYTHON_OBJS= \
Python/frame.o \
Python/frozenmain.o \
Python/future.o \
Python/gc.o \
Python/getargs.o \
Python/getcompiler.o \
Python/getcopyright.o \
Expand Down
Loading

0 comments on commit 4eef188

Please sign in to comment.