From: Thomas Wouters Date: Sat, 15 Apr 2006 21:47:09 +0000 (+0000) Subject: Use Py_VISIT in all tp_traverse methods, instead of traversing manually or X-Git-Tag: v2.5a2~203 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6e55068cad6f2178981eec4f0a0a583b8bba21a;p=python 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 --- diff --git a/Modules/_csv.c b/Modules/_csv.c index 500d36e039..67d5d9f8fb 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -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; } diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 4324f39f84..4551342f45 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -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; } diff --git a/Modules/cPickle.c b/Modules/cPickle.c index 1d99fcb76a..18df599b9e 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -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; } diff --git a/Modules/operator.c b/Modules/operator.c index 53144f164f..25b3999946 100644 --- a/Modules/operator.c +++ b/Modules/operator.c @@ -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; } diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index fbef4e14ca..16f0137610 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -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; } diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 3e376562f3..d59ebd804a 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -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; } diff --git a/Objects/cellobject.c b/Objects/cellobject.c index e617e5e5f3..da48dea745 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -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; } diff --git a/Objects/classobject.c b/Objects/classobject.c index 474c666c28..a723bd6012 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -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; } diff --git a/Objects/descrobject.c b/Objects/descrobject.c index bfa25e98f6..561ba4a5f0 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -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; } diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 31ef958e63..f5799ee09f 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -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; } diff --git a/Objects/enumobject.c b/Objects/enumobject.c index cd31dc15d5..a8f43e0738 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -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; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index b86319cad8..59cb519507 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -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) - return 0; - return visit(cm->cm_callable, arg); + Py_VISIT(cm->cm_callable); + return 0; } static int @@ -806,9 +772,8 @@ sm_dealloc(staticmethod *sm) static int sm_traverse(staticmethod *sm, visitproc visit, void *arg) { - if (!sm->sm_callable) - return 0; - return visit(sm->sm_callable, arg); + Py_VISIT(sm->sm_callable); + return 0; } static int diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 14cacc6938..cf839f4781 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -38,9 +38,8 @@ iter_dealloc(seqiterobject *it) static int iter_traverse(seqiterobject *it, visitproc visit, void *arg) { - if (it->it_seq == NULL) - return 0; - return visit(it->it_seq, arg); + Py_VISIT(it->it_seq); + return 0; } 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; } diff --git a/Objects/listobject.c b/Objects/listobject.c index 1debd23791..78961f33da 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -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) - return 0; - return visit((PyObject *)it->it_seq, arg); + Py_VISIT(it->it_seq); + return 0; } 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) - return 0; - return visit((PyObject *)it->it_seq, arg); + Py_VISIT(it->it_seq); + return 0; } static PyObject * diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 8e3bf867ca..ecc9a0ab52 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -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; } diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 812496806b..e454fcf321 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -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; } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 10b7aaffbf..2161ab9ec1 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -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) - return 0; - return visit((PyObject *)it->it_seq, arg); + Py_VISIT(it->it_seq); + return 0; } static PyObject * diff --git a/Objects/typeobject.c b/Objects/typeobject.c index a0af2c9b42..43f04694f9 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -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; } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index a116efc863..a8ab56ecd8 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -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; } diff --git a/Python/traceback.c b/Python/traceback.c index cdbec2b470..cfbd83361f 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -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