File indexing completed on 2025-01-18 10:06:44
0001 #ifndef Py_INTERNAL_GC_H
0002 #define Py_INTERNAL_GC_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006
0007 #ifndef Py_BUILD_CORE
0008 # error "this header requires Py_BUILD_CORE define"
0009 #endif
0010
0011
0012 typedef struct {
0013
0014
0015 uintptr_t _gc_next;
0016
0017
0018
0019 uintptr_t _gc_prev;
0020 } PyGC_Head;
0021
0022 static inline PyGC_Head* _Py_AS_GC(PyObject *op) {
0023 return (_Py_CAST(PyGC_Head*, op) - 1);
0024 }
0025 #define _PyGC_Head_UNUSED PyGC_Head
0026
0027
0028 static inline int _PyObject_GC_IS_TRACKED(PyObject *op) {
0029 PyGC_Head *gc = _Py_AS_GC(op);
0030 return (gc->_gc_next != 0);
0031 }
0032 #define _PyObject_GC_IS_TRACKED(op) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op))
0033
0034
0035
0036 static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
0037 if (!PyObject_IS_GC(obj)) {
0038 return 0;
0039 }
0040 if (PyTuple_CheckExact(obj)) {
0041 return _PyObject_GC_IS_TRACKED(obj);
0042 }
0043 return 1;
0044 }
0045
0046
0047
0048
0049 #define _PyGC_PREV_MASK_FINALIZED (1)
0050
0051 #define _PyGC_PREV_MASK_COLLECTING (2)
0052
0053 #define _PyGC_PREV_SHIFT (2)
0054 #define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT)
0055
0056
0057
0058 static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
0059 uintptr_t next = gc->_gc_next;
0060 return _Py_CAST(PyGC_Head*, next);
0061 }
0062 static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) {
0063 gc->_gc_next = _Py_CAST(uintptr_t, next);
0064 }
0065
0066
0067 static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) {
0068 uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK);
0069 return _Py_CAST(PyGC_Head*, prev);
0070 }
0071 static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) {
0072 uintptr_t uprev = _Py_CAST(uintptr_t, prev);
0073 assert((uprev & ~_PyGC_PREV_MASK) == 0);
0074 gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev);
0075 }
0076
0077 static inline int _PyGCHead_FINALIZED(PyGC_Head *gc) {
0078 return ((gc->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0);
0079 }
0080 static inline void _PyGCHead_SET_FINALIZED(PyGC_Head *gc) {
0081 gc->_gc_prev |= _PyGC_PREV_MASK_FINALIZED;
0082 }
0083
0084 static inline int _PyGC_FINALIZED(PyObject *op) {
0085 PyGC_Head *gc = _Py_AS_GC(op);
0086 return _PyGCHead_FINALIZED(gc);
0087 }
0088 static inline void _PyGC_SET_FINALIZED(PyObject *op) {
0089 PyGC_Head *gc = _Py_AS_GC(op);
0090 _PyGCHead_SET_FINALIZED(gc);
0091 }
0092
0093
0094
0095
0096
0097
0098 #define NUM_GENERATIONS 3
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 struct gc_generation {
0141 PyGC_Head head;
0142 int threshold;
0143 int count;
0144
0145 };
0146
0147
0148 struct gc_generation_stats {
0149
0150 Py_ssize_t collections;
0151
0152 Py_ssize_t collected;
0153
0154 Py_ssize_t uncollectable;
0155 };
0156
0157 struct _gc_runtime_state {
0158
0159
0160 PyObject *trash_delete_later;
0161
0162 int trash_delete_nesting;
0163
0164
0165 int enabled;
0166 int debug;
0167
0168 struct gc_generation generations[NUM_GENERATIONS];
0169 PyGC_Head *generation0;
0170
0171 struct gc_generation permanent_generation;
0172 struct gc_generation_stats generation_stats[NUM_GENERATIONS];
0173
0174 int collecting;
0175
0176 PyObject *garbage;
0177
0178 PyObject *callbacks;
0179
0180
0181
0182
0183
0184
0185 Py_ssize_t long_lived_total;
0186
0187
0188
0189 Py_ssize_t long_lived_pending;
0190 };
0191
0192
0193 extern void _PyGC_InitState(struct _gc_runtime_state *);
0194
0195 extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
0196
0197
0198
0199 extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
0200 extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
0201 extern void _PyList_ClearFreeList(PyInterpreterState *interp);
0202 extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
0203 extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
0204 extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
0205 extern void _Py_ScheduleGC(PyInterpreterState *interp);
0206 extern void _Py_RunGC(PyThreadState *tstate);
0207
0208 #ifdef __cplusplus
0209 }
0210 #endif
0211 #endif