Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/python3.14/internal/pycore_gc.h
1 #ifndef Py_INTERNAL_GC_H 2 #define Py_INTERNAL_GC_H 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #ifndef Py_BUILD_CORE 8 # error "this header requires Py_BUILD_CORE define" 9 #endif 10 11 #include "pycore_interp_structs.h" // PyGC_Head 12 #include "pycore_pystate.h" // _PyInterpreterState_GET() 13 #include "pycore_typedefs.h" // _PyInterpreterFrame 14 15 16 /* Get an object's GC head */ 17 static inline PyGC_Head* _Py_AS_GC(PyObject *op) { 18 char *gc = ((char*)op) - sizeof(PyGC_Head); 19 return (PyGC_Head*)gc; 20 } 21 22 /* Get the object given the GC head */ 23 static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) { 24 char *op = ((char *)gc) + sizeof(PyGC_Head); 25 return (PyObject *)op; 26 } 27 28 29 /* Bit flags for ob_gc_bits (in Py_GIL_DISABLED builds) 30 * 31 * Setting the bits requires a relaxed store. The per-object lock must also be 32 * held, except when the object is only visible to a single thread (e.g. during 33 * object initialization or destruction). 34 * 35 * Reading the bits requires using a relaxed load, but does not require holding 36 * the per-object lock. 37 */ 38 #ifdef Py_GIL_DISABLED 39 # define _PyGC_BITS_TRACKED (1<<0) // Tracked by the GC 40 # define _PyGC_BITS_FINALIZED (1<<1) // tp_finalize was called 41 # define _PyGC_BITS_UNREACHABLE (1<<2) 42 # define _PyGC_BITS_FROZEN (1<<3) 43 # define _PyGC_BITS_SHARED (1<<4) 44 # define _PyGC_BITS_ALIVE (1<<5) // Reachable from a known root. 45 # define _PyGC_BITS_DEFERRED (1<<6) // Use deferred reference counting 46 #endif 47 48 #ifdef Py_GIL_DISABLED 49 50 static inline void 51 _PyObject_SET_GC_BITS(PyObject *op, uint8_t new_bits) 52 { 53 uint8_t bits = _Py_atomic_load_uint8_relaxed(&op->ob_gc_bits); 54 _Py_atomic_store_uint8_relaxed(&op->ob_gc_bits, bits | new_bits); 55 } 56 57 static inline int 58 _PyObject_HAS_GC_BITS(PyObject *op, uint8_t bits) 59 { 60 return (_Py_atomic_load_uint8_relaxed(&op->ob_gc_bits) & bits) != 0; 61 } 62 63 static inline void 64 _PyObject_CLEAR_GC_BITS(PyObject *op, uint8_t bits_to_clear) 65 { 66 uint8_t bits = _Py_atomic_load_uint8_relaxed(&op->ob_gc_bits); 67 _Py_atomic_store_uint8_relaxed(&op->ob_gc_bits, bits & ~bits_to_clear); 68 } 69 70 #endif 71 72 /* True if the object is currently tracked by the GC. */ 73 static inline int _PyObject_GC_IS_TRACKED(PyObject *op) { 74 #ifdef Py_GIL_DISABLED 75 return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_TRACKED); 76 #else 77 PyGC_Head *gc = _Py_AS_GC(op); 78 return (gc->_gc_next != 0); 79 #endif 80 } 81 #define _PyObject_GC_IS_TRACKED(op) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op)) 82 83 /* True if the object may be tracked by the GC in the future, or already is. 84 This can be useful to implement some optimizations. */ 85 static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) { 86 if (!PyObject_IS_GC(obj)) { 87 return 0; 88 } 89 if (PyTuple_CheckExact(obj)) { 90 return _PyObject_GC_IS_TRACKED(obj); 91 } 92 return 1; 93 } 94 95 #ifdef Py_GIL_DISABLED 96 97 /* True if memory the object references is shared between 98 * multiple threads and needs special purpose when freeing 99 * those references due to the possibility of in-flight 100 * lock-free reads occurring. The object is responsible 101 * for calling _PyMem_FreeDelayed on the referenced 102 * memory. */ 103 static inline int _PyObject_GC_IS_SHARED(PyObject *op) { 104 return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_SHARED); 105 } 106 #define _PyObject_GC_IS_SHARED(op) _PyObject_GC_IS_SHARED(_Py_CAST(PyObject*, op)) 107 108 static inline void _PyObject_GC_SET_SHARED(PyObject *op) { 109 _PyObject_SET_GC_BITS(op, _PyGC_BITS_SHARED); 110 } 111 #define _PyObject_GC_SET_SHARED(op) _PyObject_GC_SET_SHARED(_Py_CAST(PyObject*, op)) 112 113 #endif 114 115 /* Bit flags for _gc_prev */ 116 /* Bit 0 is set when tp_finalize is called */ 117 #define _PyGC_PREV_MASK_FINALIZED ((uintptr_t)1) 118 /* Bit 1 is set when the object is in generation which is GCed currently. */ 119 #define _PyGC_PREV_MASK_COLLECTING ((uintptr_t)2) 120 121 /* Bit 0 in _gc_next is the old space bit. 122 * It is set as follows: 123 * Young: gcstate->visited_space 124 * old[0]: 0 125 * old[1]: 1 126 * permanent: 0 127 * 128 * During a collection all objects handled should have the bit set to 129 * gcstate->visited_space, as objects are moved from the young gen 130 * and the increment into old[gcstate->visited_space]. 131 * When object are moved from the pending space, old[gcstate->visited_space^1] 132 * into the increment, the old space bit is flipped. 133 */ 134 #define _PyGC_NEXT_MASK_OLD_SPACE_1 1 135 136 #define _PyGC_PREV_SHIFT 2 137 #define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT) 138 139 /* set for debugging information */ 140 #define _PyGC_DEBUG_STATS (1<<0) /* print collection statistics */ 141 #define _PyGC_DEBUG_COLLECTABLE (1<<1) /* print collectable objects */ 142 #define _PyGC_DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */ 143 #define _PyGC_DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */ 144 #define _PyGC_DEBUG_LEAK _PyGC_DEBUG_COLLECTABLE | \ 145 _PyGC_DEBUG_UNCOLLECTABLE | \ 146 _PyGC_DEBUG_SAVEALL 147 148 typedef enum { 149 // GC was triggered by heap allocation 150 _Py_GC_REASON_HEAP, 151 152 // GC was called during shutdown 153 _Py_GC_REASON_SHUTDOWN, 154 155 // GC was called by gc.collect() or PyGC_Collect() 156 _Py_GC_REASON_MANUAL 157 } _PyGC_Reason; 158 159 // Lowest bit of _gc_next is used for flags only in GC. 160 // But it is always 0 for normal code. 161 static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) { 162 uintptr_t next = gc->_gc_next & _PyGC_PREV_MASK; 163 return (PyGC_Head*)next; 164 } 165 static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) { 166 uintptr_t unext = (uintptr_t)next; 167 assert((unext & ~_PyGC_PREV_MASK) == 0); 168 gc->_gc_next = (gc->_gc_next & ~_PyGC_PREV_MASK) | unext; 169 } 170 171 // Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags. 172 static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) { 173 uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK); 174 return (PyGC_Head*)prev; 175 } 176 177 static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) { 178 uintptr_t uprev = (uintptr_t)prev; 179 assert((uprev & ~_PyGC_PREV_MASK) == 0); 180 gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev); 181 } 182 183 static inline int _PyGC_FINALIZED(PyObject *op) { 184 #ifdef Py_GIL_DISABLED 185 return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_FINALIZED); 186 #else 187 PyGC_Head *gc = _Py_AS_GC(op); 188 return ((gc->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0); 189 #endif 190 } 191 static inline void _PyGC_SET_FINALIZED(PyObject *op) { 192 #ifdef Py_GIL_DISABLED 193 _PyObject_SET_GC_BITS(op, _PyGC_BITS_FINALIZED); 194 #else 195 PyGC_Head *gc = _Py_AS_GC(op); 196 gc->_gc_prev |= _PyGC_PREV_MASK_FINALIZED; 197 #endif 198 } 199 static inline void _PyGC_CLEAR_FINALIZED(PyObject *op) { 200 #ifdef Py_GIL_DISABLED 201 _PyObject_CLEAR_GC_BITS(op, _PyGC_BITS_FINALIZED); 202 #else 203 PyGC_Head *gc = _Py_AS_GC(op); 204 gc->_gc_prev &= ~_PyGC_PREV_MASK_FINALIZED; 205 #endif 206 } 207 208 extern void _Py_ScheduleGC(PyThreadState *tstate); 209 210 #ifndef Py_GIL_DISABLED 211 extern void _Py_TriggerGC(struct _gc_runtime_state *gcstate); 212 #endif 213 214 215 /* Tell the GC to track this object. 216 * 217 * The object must not be tracked by the GC. 218 * 219 * NB: While the object is tracked by the collector, it must be safe to call the 220 * ob_traverse method. 221 * 222 * Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags 223 * because it's not object header. So we don't use _PyGCHead_PREV() and 224 * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. 225 * 226 * See also the public PyObject_GC_Track() function. 227 */ 228 static inline void _PyObject_GC_TRACK( 229 // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined 230 #ifndef NDEBUG 231 const char *filename, int lineno, 232 #endif 233 PyObject *op) 234 { 235 _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op), 236 "object already tracked by the garbage collector", 237 filename, lineno, __func__); 238 #ifdef Py_GIL_DISABLED 239 _PyObject_SET_GC_BITS(op, _PyGC_BITS_TRACKED); 240 #else 241 PyGC_Head *gc = _Py_AS_GC(op); 242 _PyObject_ASSERT_FROM(op, 243 (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0, 244 "object is in generation which is garbage collected", 245 filename, lineno, __func__); 246 247 struct _gc_runtime_state *gcstate = &_PyInterpreterState_GET()->gc; 248 PyGC_Head *generation0 = &gcstate->young.head; 249 PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); 250 _PyGCHead_SET_NEXT(last, gc); 251 _PyGCHead_SET_PREV(gc, last); 252 uintptr_t not_visited = 1 ^ gcstate->visited_space; 253 gc->_gc_next = ((uintptr_t)generation0) | not_visited; 254 generation0->_gc_prev = (uintptr_t)gc; 255 gcstate->young.count++; /* number of tracked GC objects */ 256 gcstate->heap_size++; 257 if (gcstate->young.count > gcstate->young.threshold) { 258 _Py_TriggerGC(gcstate); 259 } 260 #endif 261 } 262 263 /* Tell the GC to stop tracking this object. 264 * 265 * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING 266 * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept. 267 * 268 * The object must be tracked by the GC. 269 * 270 * See also the public PyObject_GC_UnTrack() which accept an object which is 271 * not tracked. 272 */ 273 static inline void _PyObject_GC_UNTRACK( 274 // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined 275 #ifndef NDEBUG 276 const char *filename, int lineno, 277 #endif 278 PyObject *op) 279 { 280 _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op), 281 "object not tracked by the garbage collector", 282 filename, lineno, __func__); 283 284 #ifdef Py_GIL_DISABLED 285 _PyObject_CLEAR_GC_BITS(op, _PyGC_BITS_TRACKED); 286 #else 287 PyGC_Head *gc = _Py_AS_GC(op); 288 PyGC_Head *prev = _PyGCHead_PREV(gc); 289 PyGC_Head *next = _PyGCHead_NEXT(gc); 290 _PyGCHead_SET_NEXT(prev, next); 291 _PyGCHead_SET_PREV(next, prev); 292 gc->_gc_next = 0; 293 gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; 294 struct _gc_runtime_state *gcstate = &_PyInterpreterState_GET()->gc; 295 if (gcstate->young.count > 0) { 296 gcstate->young.count--; 297 } 298 gcstate->heap_size--; 299 #endif 300 } 301 302 303 304 /* 305 NOTE: about untracking of mutable objects. 306 307 Certain types of container cannot participate in a reference cycle, and 308 so do not need to be tracked by the garbage collector. Untracking these 309 objects reduces the cost of garbage collections. However, determining 310 which objects may be untracked is not free, and the costs must be 311 weighed against the benefits for garbage collection. 312 313 There are two possible strategies for when to untrack a container: 314 315 i) When the container is created. 316 ii) When the container is examined by the garbage collector. 317 318 Tuples containing only immutable objects (integers, strings etc, and 319 recursively, tuples of immutable objects) do not need to be tracked. 320 The interpreter creates a large number of tuples, many of which will 321 not survive until garbage collection. It is therefore not worthwhile 322 to untrack eligible tuples at creation time. 323 324 Instead, all tuples except the empty tuple are tracked when created. 325 During garbage collection it is determined whether any surviving tuples 326 can be untracked. A tuple can be untracked if all of its contents are 327 already not tracked. Tuples are examined for untracking in all garbage 328 collection cycles. It may take more than one cycle to untrack a tuple. 329 330 Dictionaries containing only immutable objects also do not need to be 331 tracked. Dictionaries are untracked when created. If a tracked item is 332 inserted into a dictionary (either as a key or value), the dictionary 333 becomes tracked. During a full garbage collection (all generations), 334 the collector will untrack any dictionaries whose contents are not 335 tracked. 336 337 The module provides the python function is_tracked(obj), which returns 338 the CURRENT tracking status of the object. Subsequent garbage 339 collections may change the tracking status of the object. 340 341 Untracking of certain containers was introduced in issue #4688, and 342 the algorithm was refined in response to issue #14775. 343 */ 344 345 extern void _PyGC_InitState(struct _gc_runtime_state *); 346 347 extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason); 348 extern void _PyGC_CollectNoFail(PyThreadState *tstate); 349 350 /* Freeze objects tracked by the GC and ignore them in future collections. */ 351 extern void _PyGC_Freeze(PyInterpreterState *interp); 352 /* Unfreezes objects placing them in the oldest generation */ 353 extern void _PyGC_Unfreeze(PyInterpreterState *interp); 354 /* Number of frozen objects */ 355 extern Py_ssize_t _PyGC_GetFreezeCount(PyInterpreterState *interp); 356 357 extern PyObject *_PyGC_GetObjects(PyInterpreterState *interp, int generation); 358 extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs); 359 360 // Functions to clear types free lists 361 extern void _PyGC_ClearAllFreeLists(PyInterpreterState *interp); 362 extern void _Py_RunGC(PyThreadState *tstate); 363 364 union _PyStackRef; 365 366 // GC visit callback for tracked interpreter frames 367 extern int _PyGC_VisitFrameStack(_PyInterpreterFrame *frame, visitproc visit, void *arg); 368 extern int _PyGC_VisitStackRef(union _PyStackRef *ref, visitproc visit, void *arg); 369 370 #ifdef Py_GIL_DISABLED 371 extern void _PyGC_VisitObjectsWorldStopped(PyInterpreterState *interp, 372 gcvisitobjects_t callback, void *arg); 373 #endif 374 375 #ifdef __cplusplus 376 } 377 #endif 378 #endif /* !Py_INTERNAL_GC_H */