diff options
author | Guido van Rossum <guido@python.org> | 2001-10-02 21:24:57 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-10-02 21:24:57 (GMT) |
commit | 048eb75c2dca8bf6d483b290c901a53510c9b78a (patch) | |
tree | 4ffa13f63991488114f0e5c0d57983c0d80481e3 /Include | |
parent | 0481d24dd51bf3a346b432e1c065ed027bccb5c4 (diff) | |
download | cpython-048eb75c2dca8bf6d483b290c901a53510c9b78a.zip cpython-048eb75c2dca8bf6d483b290c901a53510c9b78a.tar.gz cpython-048eb75c2dca8bf6d483b290c901a53510c9b78a.tar.bz2 |
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.)
Diffstat (limited to 'Include')
-rw-r--r-- | Include/object.h | 1 | ||||
-rw-r--r-- | Include/objimpl.h | 11 |
2 files changed, 9 insertions, 3 deletions
diff --git a/Include/object.h b/Include/object.h index 4529b61..400e65751 100644 --- a/Include/object.h +++ b/Include/object.h @@ -285,6 +285,7 @@ typedef struct _typeobject { allocfunc tp_alloc; newfunc tp_new; destructor tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ PyObject *tp_defined; diff --git a/Include/objimpl.h b/Include/objimpl.h index 89e1c0a..0fd6652 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -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 */ |