@@ -203,7 +203,6 @@ extern DL_IMPORT(void) _PyObject_Del Py_PROTO((PyObject *));
203203( (type *) PyObject_InitVar( \
204204 (PyVarObject *) PyObject_MALLOC( _PyObject_VAR_SIZE((typeobj),(n)) ),\
205205 (typeobj), (n)) )
206- #define PyObject_DEL (op ) PyObject_FREE(op)
207206
208207/* This example code implements an object constructor with a custom
209208 allocator, where PyObject_New is inlined, and shows the important
@@ -234,11 +233,67 @@ extern DL_IMPORT(void) _PyObject_Del Py_PROTO((PyObject *));
234233 the 1st step is performed automatically for you, so in a C++ class
235234 constructor you would start directly with PyObject_Init/InitVar. */
236235
236+ /*
237+ * Garbage Collection Support
238+ * ==========================
239+ */
237240
241+ /* To make a new object participate in garbage collection use
242+ PyObject_{New, VarNew, Del} to manage the memory. Set the type flag
243+ Py_TPFLAGS_GC and define the type method tp_recurse. You should also
244+ add the method tp_clear if your object is mutable. Include
245+ PyGC_INFO_SIZE in the calculation of tp_basicsize. Call
246+ PyObject_GC_Init after the pointers followed by tp_recurse become
247+ valid (usually just before returning the object from the allocation
248+ method. Call PyObject_GC_Fini before those pointers become invalid
249+ (usually at the top of the deallocation method). */
238250
239251#ifndef WITH_CYCLE_GC
240- #define PyGC_INFO_SIZE 0
241- #endif
252+
253+ #define PyGC_HEAD_SIZE 0
254+ #define PyObject_GC_Init (op )
255+ #define PyObject_GC_Fini (op )
256+ #define PyObject_AS_GC (op ) (op)
257+ #define PyObject_FROM_GC (op ) (op)
258+ #define PyObject_DEL (op ) PyObject_FREE(op)
259+
260+ #else
261+
262+ /* Add the object into the container set */
263+ extern DL_IMPORT (void ) _PyGC_Insert Py_PROTO ((PyObject * ) );
264+
265+ /* Remove the object from the container set */
266+ extern DL_IMPORT (void ) _PyGC_Remove Py_PROTO ((PyObject * ) );
267+
268+ #define PyObject_GC_Init (op ) _PyGC_Insert((PyObject *)op)
269+ #define PyObject_GC_Fini (op ) _PyGC_Remove((PyObject *)op)
270+
271+ /* Structure *prefixed* to container objects participating in GC */
272+ typedef struct _gc_head {
273+ struct _gc_head * gc_next ;
274+ struct _gc_head * gc_prev ;
275+ int gc_refs ;
276+ } PyGC_Head ;
277+
278+ #define PyGC_HEAD_SIZE sizeof(PyGC_Head)
279+
280+ /* Test if a type has a GC head */
281+ #define PyType_IS_GC (t ) PyType_HasFeature((t), Py_TPFLAGS_GC)
282+
283+ /* Test if an object has a GC head */
284+ #define PyObject_IS_GC (o ) PyType_IS_GC((o)->ob_type)
285+
286+ /* Get an object's GC head */
287+ #define PyObject_AS_GC (o ) ((PyGC_Head *)(o)-1)
288+
289+ /* Get the object given the PyGC_Head */
290+ #define PyObject_FROM_GC (g ) ((PyObject *)(((PyGC_Head *)g)+1))
291+
292+ #define PyObject_DEL (op ) PyObject_FREE( PyObject_IS_GC(op) ? \
293+ (ANY *)PyObject_AS_GC(op) : \
294+ (ANY *)(op) )
295+
296+ #endif /* WITH_CYCLE_GC */
242297
243298#ifdef __cplusplus
244299}
0 commit comments