mirror of
https://github.com/python/cpython.git
synced 2025-08-01 15:43:13 +00:00
Use Py_VISIT in all tp_traverse methods, instead of traversing manually or
using a custom, nearly-identical macro. This probably changes how some of these functions are compiled, which may result in fractionally slower (or faster) execution. Considering the nature of traversal, visiting much of the address space in unpredictable patterns, I'd argue the code readability and maintainability is well worth it ;P
This commit is contained in:
parent
447d095976
commit
c6e55068ca
20 changed files with 108 additions and 339 deletions
|
@ -48,7 +48,16 @@ module instead.
|
|||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef Py_VISIT
|
||||
#define Py_VISIT(op) \
|
||||
do { \
|
||||
if (op) { \
|
||||
int vret = visit((PyObject *)(op), arg); \
|
||||
if (vret) \
|
||||
return vret; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* end 2.2 compatibility macros */
|
||||
|
||||
|
@ -825,16 +834,9 @@ Reader_dealloc(ReaderObj *self)
|
|||
static int
|
||||
Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
#define VISIT(SLOT) \
|
||||
if (SLOT) { \
|
||||
err = visit((PyObject *)(SLOT), arg); \
|
||||
if (err) \
|
||||
return err; \
|
||||
}
|
||||
VISIT(self->dialect);
|
||||
VISIT(self->input_iter);
|
||||
VISIT(self->fields);
|
||||
Py_VISIT(self->dialect);
|
||||
Py_VISIT(self->input_iter);
|
||||
Py_VISIT(self->fields);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1255,15 +1257,8 @@ Writer_dealloc(WriterObj *self)
|
|||
static int
|
||||
Writer_traverse(WriterObj *self, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
#define VISIT(SLOT) \
|
||||
if (SLOT) { \
|
||||
err = visit((PyObject *)(SLOT), arg); \
|
||||
if (err) \
|
||||
return err; \
|
||||
}
|
||||
VISIT(self->dialect);
|
||||
VISIT(self->writeline);
|
||||
Py_VISIT(self->dialect);
|
||||
Py_VISIT(self->writeline);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2061,8 +2061,7 @@ arrayiter_dealloc(arrayiterobject *it)
|
|||
static int
|
||||
arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
if (it->ao != NULL)
|
||||
return visit((PyObject *)(it->ao), arg);
|
||||
Py_VISIT(it->ao);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2909,22 +2909,14 @@ Pickler_dealloc(Picklerobject *self)
|
|||
static int
|
||||
Pickler_traverse(Picklerobject *self, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
#define VISIT(SLOT) \
|
||||
if (SLOT) { \
|
||||
err = visit((PyObject *)(SLOT), arg); \
|
||||
if (err) \
|
||||
return err; \
|
||||
}
|
||||
VISIT(self->write);
|
||||
VISIT(self->memo);
|
||||
VISIT(self->fast_memo);
|
||||
VISIT(self->arg);
|
||||
VISIT(self->file);
|
||||
VISIT(self->pers_func);
|
||||
VISIT(self->inst_pers_func);
|
||||
VISIT(self->dispatch_table);
|
||||
#undef VISIT
|
||||
Py_VISIT(self->write);
|
||||
Py_VISIT(self->memo);
|
||||
Py_VISIT(self->fast_memo);
|
||||
Py_VISIT(self->arg);
|
||||
Py_VISIT(self->file);
|
||||
Py_VISIT(self->pers_func);
|
||||
Py_VISIT(self->inst_pers_func);
|
||||
Py_VISIT(self->dispatch_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5258,24 +5250,15 @@ Unpickler_dealloc(Unpicklerobject *self)
|
|||
static int
|
||||
Unpickler_traverse(Unpicklerobject *self, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
|
||||
#define VISIT(SLOT) \
|
||||
if (SLOT) { \
|
||||
err = visit((PyObject *)(SLOT), arg); \
|
||||
if (err) \
|
||||
return err; \
|
||||
}
|
||||
VISIT(self->readline);
|
||||
VISIT(self->read);
|
||||
VISIT(self->file);
|
||||
VISIT(self->memo);
|
||||
VISIT(self->stack);
|
||||
VISIT(self->pers_func);
|
||||
VISIT(self->arg);
|
||||
VISIT(self->last_string);
|
||||
VISIT(self->find_class);
|
||||
#undef VISIT
|
||||
Py_VISIT(self->readline);
|
||||
Py_VISIT(self->read);
|
||||
Py_VISIT(self->file);
|
||||
Py_VISIT(self->memo);
|
||||
Py_VISIT(self->stack);
|
||||
Py_VISIT(self->pers_func);
|
||||
Py_VISIT(self->arg);
|
||||
Py_VISIT(self->last_string);
|
||||
Py_VISIT(self->find_class);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -358,8 +358,7 @@ itemgetter_dealloc(itemgetterobject *ig)
|
|||
static int
|
||||
itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
|
||||
{
|
||||
if (ig->item)
|
||||
return visit(ig->item, arg);
|
||||
Py_VISIT(ig->item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -497,8 +496,7 @@ attrgetter_dealloc(attrgetterobject *ag)
|
|||
static int
|
||||
attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
|
||||
{
|
||||
if (ag->attr)
|
||||
return visit(ag->attr, arg);
|
||||
Py_VISIT(ag->attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1655,13 +1655,8 @@ static int
|
|||
xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
|
||||
{
|
||||
int i, err;
|
||||
for (i = 0; handler_info[i].name != NULL; i++) {
|
||||
if (!op->handlers[i])
|
||||
continue;
|
||||
err = visit(op->handlers[i], arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
for (i = 0; handler_info[i].name != NULL; i++)
|
||||
Py_VISIT(op->handlers[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,13 +170,7 @@ static int
|
|||
zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
|
||||
{
|
||||
ZipImporter *self = (ZipImporter *)obj;
|
||||
int err;
|
||||
|
||||
if (self->files != NULL) {
|
||||
err = visit(self->files, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(self->files);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,7 @@ cell_repr(PyCellObject *op)
|
|||
static int
|
||||
cell_traverse(PyCellObject *op, visitproc visit, void *arg)
|
||||
{
|
||||
if (op->ob_ref)
|
||||
return visit(op->ob_ref, arg);
|
||||
Py_VISIT(op->ob_ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -404,37 +404,12 @@ class_str(PyClassObject *op)
|
|||
static int
|
||||
class_traverse(PyClassObject *o, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
if (o->cl_bases) {
|
||||
err = visit(o->cl_bases, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (o->cl_dict) {
|
||||
err = visit(o->cl_dict, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (o->cl_name) {
|
||||
err = visit(o->cl_name, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (o->cl_getattr) {
|
||||
err = visit(o->cl_getattr, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (o->cl_setattr) {
|
||||
err = visit(o->cl_setattr, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (o->cl_delattr) {
|
||||
err = visit(o->cl_delattr, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(o->cl_bases);
|
||||
Py_VISIT(o->cl_dict);
|
||||
Py_VISIT(o->cl_name);
|
||||
Py_VISIT(o->cl_getattr);
|
||||
Py_VISIT(o->cl_setattr);
|
||||
Py_VISIT(o->cl_delattr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -979,17 +954,8 @@ instance_hash(PyInstanceObject *inst)
|
|||
static int
|
||||
instance_traverse(PyInstanceObject *o, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
if (o->in_class) {
|
||||
err = visit((PyObject *)(o->in_class), arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (o->in_dict) {
|
||||
err = visit(o->in_dict, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(o->in_class);
|
||||
Py_VISIT(o->in_dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2348,22 +2314,9 @@ instancemethod_hash(PyMethodObject *a)
|
|||
static int
|
||||
instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
if (im->im_func) {
|
||||
err = visit(im->im_func, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (im->im_self) {
|
||||
err = visit(im->im_self, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (im->im_class) {
|
||||
err = visit(im->im_class, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(im->im_func);
|
||||
Py_VISIT(im->im_self);
|
||||
Py_VISIT(im->im_class);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -377,13 +377,7 @@ static int
|
|||
descr_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
PyDescrObject *descr = (PyDescrObject *)self;
|
||||
int err;
|
||||
|
||||
if (descr->d_type) {
|
||||
err = visit((PyObject *)(descr->d_type), arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(descr->d_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -814,13 +808,7 @@ static int
|
|||
proxy_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
proxyobject *pp = (proxyobject *)self;
|
||||
int err;
|
||||
|
||||
if (pp->dict) {
|
||||
err = visit(pp->dict, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(pp->dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -999,18 +987,8 @@ static int
|
|||
wrapper_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
wrapperobject *wp = (wrapperobject *)self;
|
||||
int err;
|
||||
|
||||
if (wp->descr) {
|
||||
err = visit((PyObject *)(wp->descr), arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (wp->self) {
|
||||
err = visit(wp->self, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(wp->descr);
|
||||
Py_VISIT(wp->self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1237,20 +1215,10 @@ static int
|
|||
property_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
propertyobject *pp = (propertyobject *)self;
|
||||
int err;
|
||||
|
||||
#define VISIT(SLOT) \
|
||||
if (pp->SLOT) { \
|
||||
err = visit((PyObject *)(pp->SLOT), arg); \
|
||||
if (err) \
|
||||
return err; \
|
||||
}
|
||||
|
||||
VISIT(prop_get);
|
||||
VISIT(prop_set);
|
||||
VISIT(prop_del);
|
||||
VISIT(prop_doc);
|
||||
|
||||
Py_VISIT(pp->prop_get);
|
||||
Py_VISIT(pp->prop_set);
|
||||
Py_VISIT(pp->prop_del);
|
||||
Py_VISIT(pp->prop_doc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1732,17 +1732,12 @@ static int
|
|||
dict_traverse(PyObject *op, visitproc visit, void *arg)
|
||||
{
|
||||
Py_ssize_t i = 0;
|
||||
int err;
|
||||
PyObject *pk;
|
||||
PyObject *pv;
|
||||
|
||||
while (PyDict_Next(op, &i, &pk, &pv)) {
|
||||
err = visit(pk, arg);
|
||||
if (err)
|
||||
return err;
|
||||
err = visit(pv, arg);
|
||||
if (err)
|
||||
return err;
|
||||
Py_VISIT(pk);
|
||||
Py_VISIT(pv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -49,18 +49,8 @@ enum_dealloc(enumobject *en)
|
|||
static int
|
||||
enum_traverse(enumobject *en, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (en->en_sit) {
|
||||
err = visit(en->en_sit, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (en->en_result) {
|
||||
err = visit(en->en_result, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(en->en_sit);
|
||||
Py_VISIT(en->en_result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -205,8 +195,7 @@ reversed_dealloc(reversedobject *ro)
|
|||
static int
|
||||
reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
|
||||
{
|
||||
if (ro->seq)
|
||||
return visit((PyObject *)(ro->seq), arg);
|
||||
Py_VISIT(ro->seq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -466,47 +466,14 @@ func_repr(PyFunctionObject *op)
|
|||
static int
|
||||
func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
if (f->func_code) {
|
||||
err = visit(f->func_code, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f->func_globals) {
|
||||
err = visit(f->func_globals, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f->func_module) {
|
||||
err = visit(f->func_module, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f->func_defaults) {
|
||||
err = visit(f->func_defaults, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f->func_doc) {
|
||||
err = visit(f->func_doc, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f->func_name) {
|
||||
err = visit(f->func_name, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f->func_dict) {
|
||||
err = visit(f->func_dict, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (f->func_closure) {
|
||||
err = visit(f->func_closure, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(f->func_code);
|
||||
Py_VISIT(f->func_globals);
|
||||
Py_VISIT(f->func_module);
|
||||
Py_VISIT(f->func_defaults);
|
||||
Py_VISIT(f->func_doc);
|
||||
Py_VISIT(f->func_name);
|
||||
Py_VISIT(f->func_dict);
|
||||
Py_VISIT(f->func_closure);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -647,9 +614,8 @@ cm_dealloc(classmethod *cm)
|
|||
static int
|
||||
cm_traverse(classmethod *cm, visitproc visit, void *arg)
|
||||
{
|
||||
if (!cm->cm_callable)
|
||||
Py_VISIT(cm->cm_callable);
|
||||
return 0;
|
||||
return visit(cm->cm_callable, arg);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -806,9 +772,8 @@ sm_dealloc(staticmethod *sm)
|
|||
static int
|
||||
sm_traverse(staticmethod *sm, visitproc visit, void *arg)
|
||||
{
|
||||
if (!sm->sm_callable)
|
||||
Py_VISIT(sm->sm_callable);
|
||||
return 0;
|
||||
return visit(sm->sm_callable, arg);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -38,9 +38,8 @@ iter_dealloc(seqiterobject *it)
|
|||
static int
|
||||
iter_traverse(seqiterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
if (it->it_seq == NULL)
|
||||
Py_VISIT(it->it_seq);
|
||||
return 0;
|
||||
return visit(it->it_seq, arg);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -162,11 +161,8 @@ calliter_dealloc(calliterobject *it)
|
|||
static int
|
||||
calliter_traverse(calliterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
if (it->it_callable != NULL && (err = visit(it->it_callable, arg)))
|
||||
return err;
|
||||
if (it->it_sentinel != NULL && (err = visit(it->it_sentinel, arg)))
|
||||
return err;
|
||||
Py_VISIT(it->it_callable);
|
||||
Py_VISIT(it->it_sentinel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2276,14 +2276,8 @@ list_traverse(PyListObject *o, visitproc visit, void *arg)
|
|||
Py_ssize_t i;
|
||||
PyObject *x;
|
||||
|
||||
for (i = o->ob_size; --i >= 0; ) {
|
||||
x = o->ob_item[i];
|
||||
if (x != NULL) {
|
||||
int err = visit(x, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
for (i = o->ob_size; --i >= 0; )
|
||||
Py_VISIT(o->ob_item[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2779,9 +2773,8 @@ listiter_dealloc(listiterobject *it)
|
|||
static int
|
||||
listiter_traverse(listiterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
if (it->it_seq == NULL)
|
||||
Py_VISIT(it->it_seq);
|
||||
return 0;
|
||||
return visit((PyObject *)it->it_seq, arg);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -2898,9 +2891,8 @@ listreviter_dealloc(listreviterobject *it)
|
|||
static int
|
||||
listreviter_traverse(listreviterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
if (it->it_seq == NULL)
|
||||
Py_VISIT(it->it_seq);
|
||||
return 0;
|
||||
return visit((PyObject *)it->it_seq, arg);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
|
@ -149,17 +149,8 @@ meth_get__name__(PyCFunctionObject *m, void *closure)
|
|||
static int
|
||||
meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
if (m->m_self != NULL) {
|
||||
err = visit(m->m_self, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (m->m_module != NULL) {
|
||||
err = visit(m->m_module, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(m->m_self);
|
||||
Py_VISIT(m->m_module);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -204,8 +204,7 @@ module_repr(PyModuleObject *m)
|
|||
static int
|
||||
module_traverse(PyModuleObject *m, visitproc visit, void *arg)
|
||||
{
|
||||
if (m->md_dict != NULL)
|
||||
return visit(m->md_dict, arg);
|
||||
Py_VISIT(m->md_dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,16 +438,9 @@ static int
|
|||
tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
PyObject *x;
|
||||
|
||||
for (i = o->ob_size; --i >= 0; ) {
|
||||
x = o->ob_item[i];
|
||||
if (x != NULL) {
|
||||
int err = visit(x, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
for (i = o->ob_size; --i >= 0; )
|
||||
Py_VISIT(o->ob_item[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -802,9 +795,8 @@ tupleiter_dealloc(tupleiterobject *it)
|
|||
static int
|
||||
tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
if (it->it_seq == NULL)
|
||||
Py_VISIT(it->it_seq);
|
||||
return 0;
|
||||
return visit((PyObject *)it->it_seq, arg);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
|
@ -525,21 +525,15 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg)
|
|||
|
||||
if (type->tp_dictoffset != base->tp_dictoffset) {
|
||||
PyObject **dictptr = _PyObject_GetDictPtr(self);
|
||||
if (dictptr && *dictptr) {
|
||||
int err = visit(*dictptr, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (dictptr && *dictptr)
|
||||
Py_VISIT(*dictptr);
|
||||
}
|
||||
|
||||
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
|
||||
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
|
||||
/* For a heaptype, the instances count as references
|
||||
to the type. Traverse the type so the collector
|
||||
can find cycles involving this link. */
|
||||
int err = visit((PyObject *)type, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
Py_VISIT(type);
|
||||
|
||||
if (basetraverse)
|
||||
return basetraverse(self, visit, arg);
|
||||
|
@ -2198,32 +2192,21 @@ PyDoc_STRVAR(type_doc,
|
|||
static int
|
||||
type_traverse(PyTypeObject *type, visitproc visit, void *arg)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Because of type_is_gc(), the collector only calls this
|
||||
for heaptypes. */
|
||||
assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
|
||||
|
||||
#define VISIT(SLOT) \
|
||||
if (SLOT) { \
|
||||
err = visit((PyObject *)(SLOT), arg); \
|
||||
if (err) \
|
||||
return err; \
|
||||
}
|
||||
|
||||
VISIT(type->tp_dict);
|
||||
VISIT(type->tp_cache);
|
||||
VISIT(type->tp_mro);
|
||||
VISIT(type->tp_bases);
|
||||
VISIT(type->tp_base);
|
||||
Py_VISIT(type->tp_dict);
|
||||
Py_VISIT(type->tp_cache);
|
||||
Py_VISIT(type->tp_mro);
|
||||
Py_VISIT(type->tp_bases);
|
||||
Py_VISIT(type->tp_base);
|
||||
|
||||
/* There's no need to visit type->tp_subclasses or
|
||||
((PyHeapTypeObject *)type)->ht_slots, because they can't be involved
|
||||
in cycles; tp_subclasses is a list of weak references,
|
||||
and slots is a tuple of strings. */
|
||||
|
||||
#undef VISIT
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5805,20 +5788,10 @@ static int
|
|||
super_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
superobject *su = (superobject *)self;
|
||||
int err;
|
||||
|
||||
#define VISIT(SLOT) \
|
||||
if (SLOT) { \
|
||||
err = visit((PyObject *)(SLOT), arg); \
|
||||
if (err) \
|
||||
return err; \
|
||||
}
|
||||
|
||||
VISIT(su->obj);
|
||||
VISIT(su->type);
|
||||
VISIT(su->obj_type);
|
||||
|
||||
#undef VISIT
|
||||
Py_VISIT(su->obj);
|
||||
Py_VISIT(su->type);
|
||||
Py_VISIT(su->obj_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -109,8 +109,7 @@ weakref_dealloc(PyObject *self)
|
|||
static int
|
||||
gc_traverse(PyWeakReference *self, visitproc visit, void *arg)
|
||||
{
|
||||
if (self->wr_callback != NULL)
|
||||
return visit(self->wr_callback, arg);
|
||||
Py_VISIT(self->wr_callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,15 +39,9 @@ tb_dealloc(PyTracebackObject *tb)
|
|||
static int
|
||||
tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
|
||||
{
|
||||
int err = 0;
|
||||
if (tb->tb_next) {
|
||||
err = visit((PyObject *)tb->tb_next, arg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (tb->tb_frame)
|
||||
err = visit((PyObject *)tb->tb_frame, arg);
|
||||
return err;
|
||||
Py_VISIT(tb->tb_next);
|
||||
Py_VISIT(tb->tb_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue