mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Add Garbage Collection support to new-style classes (not yet to their
instances). Also added GC support to various auxiliary types: super, property, descriptors, wrappers, dictproxy. (Only type objects have a tp_clear field; the other types are.) One change was necessary to the GC infrastructure. We have statically allocated type objects that don't have a GC header (and can't easily be given one) and heap-allocated type objects that do have a GC header. Giving these different metatypes would be really ugly: I tried, and I had to modify pickle.py, cPickle.c, copy.py, add a new invent a new name for the new metatype and make it a built-in, change affected tests... In short, a mess. So instead, we add a new type slot tp_is_gc, which is a simple Boolean function that determines whether a particular instance has GC headers or not. This slot is only relevant for types that have the (new) GC flag bit set. If the tp_is_gc slot is NULL (by far the most common case), all instances of the type are deemed to have GC headers. This slot is called by the PyObject_IS_GC() macro (which is only used twice, both times in gcmodule.c). I also changed the extern declarations for a bunch of GC-related functions (_PyObject_GC_Del etc.): these always exist but objimpl.h only declared them when WITH_CYCLE_GC was defined, but I needed to be able to reference them without #ifdefs. (When WITH_CYCLE_GC is not defined, they do the same as their non-GC counterparts anyway.)
This commit is contained in:
parent
0481d24dd5
commit
048eb75c2d
5 changed files with 237 additions and 39 deletions
|
@ -217,13 +217,18 @@ extern DL_IMPORT(void) _PyObject_Del(PyObject *);
|
|||
/*
|
||||
* Garbage Collection Support
|
||||
* ==========================
|
||||
*
|
||||
* Some of the functions and macros below are always defined; when
|
||||
* WITH_CYCLE_GC is undefined, they simply don't do anything different
|
||||
* than their non-GC counterparts.
|
||||
*/
|
||||
|
||||
/* Test if a type has a GC head */
|
||||
#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
|
||||
|
||||
/* Test if an object has a GC head */
|
||||
#define PyObject_IS_GC(o) PyType_IS_GC((o)->ob_type)
|
||||
#define PyObject_IS_GC(o) (PyType_IS_GC((o)->ob_type) && \
|
||||
((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o)))
|
||||
|
||||
extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, int);
|
||||
extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int);
|
||||
|
@ -231,14 +236,14 @@ extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int);
|
|||
#define PyObject_GC_Resize(type, op, n) \
|
||||
( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) )
|
||||
|
||||
#ifdef WITH_CYCLE_GC
|
||||
|
||||
extern DL_IMPORT(PyObject *) _PyObject_GC_New(PyTypeObject *);
|
||||
extern DL_IMPORT(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, int);
|
||||
extern DL_IMPORT(void) _PyObject_GC_Del(PyObject *);
|
||||
extern DL_IMPORT(void) _PyObject_GC_Track(PyObject *);
|
||||
extern DL_IMPORT(void) _PyObject_GC_UnTrack(PyObject *);
|
||||
|
||||
#ifdef WITH_CYCLE_GC
|
||||
|
||||
/* GC information is stored BEFORE the object structure */
|
||||
typedef struct _gc_head {
|
||||
struct _gc_head *gc_next; /* not NULL if object is tracked */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue