@@ -256,18 +256,18 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);
256
256
/* Test if a type has a GC head */
257
257
#define PyType_IS_GC (t ) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
258
258
259
- /* Test if an object has a GC head */
260
- #ifndef Py_LIMITED_API
261
- #define PyObject_IS_GC (o ) (PyType_IS_GC(Py_TYPE(o)) && \
262
- (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
263
- #endif
264
-
265
259
PyAPI_FUNC (PyVarObject * ) _PyObject_GC_Resize (PyVarObject * , Py_ssize_t );
266
260
#define PyObject_GC_Resize (type , op , n ) \
267
261
( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) )
268
262
269
- /* GC information is stored BEFORE the object structure. */
263
+
270
264
#ifndef Py_LIMITED_API
265
+ /* Test if an object has a GC head */
266
+ #define PyObject_IS_GC (o ) \
267
+ (PyType_IS_GC(Py_TYPE(o)) \
268
+ && (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
269
+
270
+ /* GC information is stored BEFORE the object structure. */
271
271
typedef struct {
272
272
// Pointer to next object in the list.
273
273
// 0 means the object is not tracked
@@ -278,10 +278,21 @@ typedef struct {
278
278
uintptr_t _gc_prev ;
279
279
} PyGC_Head ;
280
280
281
- extern PyGC_Head * _PyGC_generation0 ;
282
-
283
281
#define _Py_AS_GC (o ) ((PyGC_Head *)(o)-1)
284
282
283
+ /* True if the object is currently tracked by the GC. */
284
+ #define _PyObject_GC_IS_TRACKED (o ) (_Py_AS_GC(o)->_gc_next != 0)
285
+
286
+ /* True if the object may be tracked by the GC in the future, or already is.
287
+ This can be useful to implement some optimizations. */
288
+ #define _PyObject_GC_MAY_BE_TRACKED (obj ) \
289
+ (PyObject_IS_GC(obj) && \
290
+ (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
291
+ #endif
292
+
293
+
294
+ #if defined(Py_BUILD_CORE ) || defined(Py_BUILD_CORE_BUILTIN )
295
+
285
296
/* Bit flags for _gc_prev */
286
297
/* Bit 0 is set when tp_finalize is called */
287
298
#define _PyGC_PREV_MASK_FINALIZED (1)
@@ -304,38 +315,46 @@ extern PyGC_Head *_PyGC_generation0;
304
315
| ((uintptr_t)(p)); \
305
316
} while (0)
306
317
307
- #define _PyGCHead_FINALIZED (g ) (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)
308
- #define _PyGCHead_SET_FINALIZED (g ) ((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)
318
+ #define _PyGCHead_FINALIZED (g ) \
319
+ (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)
320
+ #define _PyGCHead_SET_FINALIZED (g ) \
321
+ ((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)
309
322
310
- #define _PyGC_FINALIZED (o ) _PyGCHead_FINALIZED(_Py_AS_GC(o))
311
- #define _PyGC_SET_FINALIZED (o ) _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
323
+ #define _PyGC_FINALIZED (o ) \
324
+ _PyGCHead_FINALIZED(_Py_AS_GC(o))
325
+ #define _PyGC_SET_FINALIZED (o ) \
326
+ _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
312
327
313
328
/* Tell the GC to track this object.
314
329
*
315
330
* NB: While the object is tracked by the collector, it must be safe to call the
316
331
* ob_traverse method.
317
332
*
318
- * Internal note: _PyGC_generation0 ->_gc_prev doesn't have any bit flags
333
+ * Internal note: _PyRuntime.gc.generation0 ->_gc_prev doesn't have any bit flags
319
334
* because it's not object header. So we don't use _PyGCHead_PREV() and
320
335
* _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.
336
+ *
337
+ * The PyObject_GC_Track() function is the public version of this macro.
321
338
*/
322
339
#define _PyObject_GC_TRACK (o ) do { \
323
340
PyGC_Head *g = _Py_AS_GC(o); \
324
341
if (g->_gc_next != 0) { \
325
342
Py_FatalError("GC object already tracked"); \
326
343
} \
327
344
assert((g->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0); \
328
- PyGC_Head *last = (PyGC_Head*)(_PyGC_generation0 ->_gc_prev); \
345
+ PyGC_Head *last = (PyGC_Head*)(_PyRuntime.gc.generation0 ->_gc_prev); \
329
346
_PyGCHead_SET_NEXT(last, g); \
330
347
_PyGCHead_SET_PREV(g, last); \
331
- _PyGCHead_SET_NEXT(g, _PyGC_generation0 ); \
332
- _PyGC_generation0 ->_gc_prev = (uintptr_t)g; \
348
+ _PyGCHead_SET_NEXT(g, _PyRuntime.gc.generation0 ); \
349
+ _PyRuntime.gc.generation0 ->_gc_prev = (uintptr_t)g; \
333
350
} while (0);
334
351
335
352
/* Tell the GC to stop tracking this object.
336
353
*
337
354
* Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING must
338
355
* be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept.
356
+ *
357
+ * The PyObject_GC_UnTrack() function is the public version of this macro.
339
358
*/
340
359
#define _PyObject_GC_UNTRACK (o ) do { \
341
360
PyGC_Head *g = _Py_AS_GC(o); \
@@ -347,25 +366,25 @@ extern PyGC_Head *_PyGC_generation0;
347
366
g->_gc_next = 0; \
348
367
g->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; \
349
368
} while (0);
350
-
351
- /* True if the object is currently tracked by the GC. */
352
- #define _PyObject_GC_IS_TRACKED (o ) (_Py_AS_GC(o)->_gc_next != 0)
353
-
354
- /* True if the object may be tracked by the GC in the future, or already is.
355
- This can be useful to implement some optimizations. */
356
- #define _PyObject_GC_MAY_BE_TRACKED (obj ) \
357
- (PyObject_IS_GC(obj) && \
358
- (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
359
- #endif /* Py_LIMITED_API */
369
+ #endif /* defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) */
360
370
361
371
#ifndef Py_LIMITED_API
362
372
PyAPI_FUNC (PyObject * ) _PyObject_GC_Malloc (size_t size );
363
373
PyAPI_FUNC (PyObject * ) _PyObject_GC_Calloc (size_t size );
364
374
#endif /* !Py_LIMITED_API */
365
375
PyAPI_FUNC (PyObject * ) _PyObject_GC_New (PyTypeObject * );
366
376
PyAPI_FUNC (PyVarObject * ) _PyObject_GC_NewVar (PyTypeObject * , Py_ssize_t );
377
+
378
+ /* Tell the GC to track this object.
379
+ *
380
+ * See also private _PyObject_GC_TRACK() macro. */
367
381
PyAPI_FUNC (void ) PyObject_GC_Track (void * );
382
+
383
+ /* Tell the GC to stop tracking this object.
384
+ *
385
+ * See also private _PyObject_GC_UNTRACK() macro. */
368
386
PyAPI_FUNC (void ) PyObject_GC_UnTrack (void * );
387
+
369
388
PyAPI_FUNC (void ) PyObject_GC_Del (void * );
370
389
371
390
#define PyObject_GC_New (type , typeobj ) \
0 commit comments