Skip to content

Commit fa068b5

Browse files
committed
gh-113688: Split up gcmodule.c
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.
1 parent e53e0a0 commit fa068b5

File tree

9 files changed

+600
-527
lines changed

9 files changed

+600
-527
lines changed

Include/internal/pycore_gc.h

+31
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,26 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
6464
#define _PyGC_PREV_SHIFT (2)
6565
#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT)
6666

67+
/* set for debugging information */
68+
#define _PyGC_DEBUG_STATS (1<<0) /* print collection statistics */
69+
#define _PyGC_DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
70+
#define _PyGC_DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
71+
#define _PyGC_DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
72+
#define _PyGC_DEBUG_LEAK _PyGC_DEBUG_COLLECTABLE | \
73+
_PyGC_DEBUG_UNCOLLECTABLE | \
74+
_PyGC_DEBUG_SAVEALL
75+
76+
typedef enum {
77+
// GC was triggered by heap allocation
78+
_Py_GC_REASON_HEAP,
79+
80+
// GC was called during shutdown
81+
_Py_GC_REASON_SHUTDOWN,
82+
83+
// GC was called by gc.collect() or PyGC_Collect()
84+
_Py_GC_REASON_MANUAL
85+
} _PyGC_Reason;
86+
6787
// Lowest bit of _gc_next is used for flags only in GC.
6888
// But it is always 0 for normal code.
6989
static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
@@ -203,8 +223,19 @@ struct _gc_runtime_state {
203223

204224
extern void _PyGC_InitState(struct _gc_runtime_state *);
205225

226+
extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation,
227+
_PyGC_Reason reason);
206228
extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
207229

230+
/* Freeze objects tracked by the GC and ignore them in future collections. */
231+
extern void _PyGC_Freeze(PyInterpreterState *interp);
232+
/* Unfreezes objects placing them in the oldest generation */
233+
extern void _PyGC_Unfreeze(PyInterpreterState *interp);
234+
/* Number of frozen objects */
235+
extern Py_ssize_t _PyGC_GetFreezeCount(PyInterpreterState *interp);
236+
237+
extern PyObject *_PyGC_GetObjects(PyInterpreterState *interp, Py_ssize_t generation);
238+
extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs);
208239

209240
// Functions to clear types free lists
210241
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);

Lib/test/test_gc.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ def test_refcount_errors(self):
12251225
p.stderr.close()
12261226
# Verify that stderr has a useful error message:
12271227
self.assertRegex(stderr,
1228-
br'gcmodule\.c:[0-9]+: gc_decref: Assertion "gc_get_refs\(g\) > 0" failed.')
1228+
br'gc\.c:[0-9]+: gc_decref: Assertion "gc_get_refs\(g\) > 0" failed.')
12291229
self.assertRegex(stderr,
12301230
br'refcount is too small')
12311231
# "address : 0x7fb5062efc18"

Makefile.pre.in

+1
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ PYTHON_OBJS= \
417417
Python/frame.o \
418418
Python/frozenmain.o \
419419
Python/future.o \
420+
Python/gc.o \
420421
Python/getargs.o \
421422
Python/getcompiler.o \
422423
Python/getcopyright.o \

0 commit comments

Comments
 (0)