bpo-35081: Make some _PyGC macros internal (GH-10507) · python/cpython@1a6be91 (original) (raw)
`@@ -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) \
`