[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.105,2.106
Guido van Rossum
gvanrossum@users.sourceforge.net
2001年10月16日 10:00:50 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv6589
Modified Files:
typeobject.c
Log Message:
Refactored the update_slot() code a bit to be hopefully slightly more
efficient:
- recurse down subclasses only once rather than for each affected
slot;
- short-circuit recursing down subclasses when a subclass has its own
definition of the name that caused the update_slot() calls in the
first place;
- inline collect_ptrs().
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.105
retrieving revision 2.106
diff -C2 -d -r2.105 -r2.106
*** typeobject.c 2001年10月15日 22:03:32 2.105
--- typeobject.c 2001年10月16日 17:00:48 2.106
***************
*** 3765,3816 ****
}
! staticforward int recurse_down_subclasses(PyTypeObject *type, slotdef *p);
static int
! update_one_slot(PyTypeObject *type, slotdef *p0)
{
! slotdef *p = p0;
! PyObject *descr;
! PyWrapperDescrObject *d;
! void *generic = NULL, *specific = NULL;
! int use_generic = 0;
! int offset;
! void **ptr;
! offset = p->offset;
! ptr = slotptr(type, offset);
! if (ptr == NULL)
! return recurse_down_subclasses(type, p);
! do {
! descr = _PyType_Lookup(type, p->name_strobj);
! if (descr == NULL)
continue;
! generic = p->function;
! if (descr->ob_type == &PyWrapperDescr_Type) {
! d = (PyWrapperDescrObject *)descr;
! if (d->d_base->wrapper == p->wrapper &&
! PyType_IsSubtype(type, d->d_type)) {
! if (specific == NULL ||
! specific == d->d_wrapped)
! specific = d->d_wrapped;
! else
! use_generic = 1;
}
! }
else
! use_generic = 1;
! } while ((++p)->offset == offset);
! if (specific && !use_generic)
! *ptr = specific;
! else
! *ptr = generic;
! return recurse_down_subclasses(type, p0);
}
static int
! recurse_down_subclasses(PyTypeObject *type, slotdef *p)
{
PyTypeObject *subclass;
! PyObject *ref, *subclasses;
int i, n;
--- 3765,3818 ----
}
! staticforward int recurse_down_subclasses(PyTypeObject *type,
! slotdef **pp, PyObject *name);
static int
! update_these_slots(PyTypeObject *type, slotdef **pp0, PyObject *name)
{
! slotdef **pp;
! for (pp = pp0; *pp; pp++) {
! slotdef *p = *pp;
! PyObject *descr;
! PyWrapperDescrObject *d;
! void *generic = NULL, *specific = NULL;
! int use_generic = 0;
! int offset = p->offset;
! void **ptr = slotptr(type, offset);
! if (ptr == NULL)
continue;
! do {
! descr = _PyType_Lookup(type, p->name_strobj);
! if (descr == NULL)
! continue;
! generic = p->function;
! if (descr->ob_type == &PyWrapperDescr_Type) {
! d = (PyWrapperDescrObject *)descr;
! if (d->d_base->wrapper == p->wrapper &&
! PyType_IsSubtype(type, d->d_type)) {
! if (specific == NULL ||
! specific == d->d_wrapped)
! specific = d->d_wrapped;
! else
! use_generic = 1;
! }
}
! else
! use_generic = 1;
! } while ((++p)->offset == offset);
! if (specific && !use_generic)
! *ptr = specific;
else
! *ptr = generic;
! }
! return recurse_down_subclasses(type, pp0, name);
}
static int
! recurse_down_subclasses(PyTypeObject *type, slotdef **pp, PyObject *name)
{
PyTypeObject *subclass;
! PyObject *ref, *subclasses, *dict;
int i, n;
***************
*** 3827,3831 ****
continue;
assert(PyType_Check(subclass));
! if (update_one_slot(subclass, p) < 0)
return -1;
}
--- 3829,3838 ----
continue;
assert(PyType_Check(subclass));
! /* Avoid recursing down into unaffected classes */
! dict = subclass->tp_dict;
! if (dict != NULL && PyDict_Check(dict) &&
! PyDict_GetItem(dict, name) != NULL)
! continue;
! if (update_these_slots(subclass, pp, name) < 0)
return -1;
}
***************
*** 3857,3877 ****
Py_FatalError("XXX ouch");
}
! qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef), slotdef_cmp);
initialized = 1;
}
- static void
- collect_ptrs(PyObject *name, slotdef *ptrs[])
- {
- slotdef *p;
-
- init_slotdefs();
- for (p = slotdefs; p->name; p++) {
- if (name == p->name_strobj)
- *ptrs++ = p;
- }
- *ptrs = NULL;
- }
-
static int
update_slot(PyTypeObject *type, PyObject *name)
--- 3864,3872 ----
Py_FatalError("XXX ouch");
}
! qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef),
! slotdef_cmp);
initialized = 1;
}
static int
update_slot(PyTypeObject *type, PyObject *name)
***************
*** 3880,3893 ****
slotdef *p;
slotdef **pp;
! collect_ptrs(name, ptrs);
for (pp = ptrs; *pp; pp++) {
p = *pp;
! while (p > slotdefs && p->offset == (p-1)->offset)
--p;
! if (update_one_slot(type, p) < 0)
! return -1;
}
! return 0;
}
--- 3875,3896 ----
slotdef *p;
slotdef **pp;
+ int offset;
! init_slotdefs();
! pp = ptrs;
! for (p = slotdefs; p->name; p++) {
! /* XXX assume name is interned! */
! if (p->name_strobj == name)
! *pp++ = p;
! }
! *pp = NULL;
for (pp = ptrs; *pp; pp++) {
p = *pp;
! offset = p->offset;
! while (p > slotdefs && (p-1)->offset == offset)
--p;
! *pp = p;
}
! return update_these_slots(type, ptrs, name);
}
***************
*** 3922,3926 ****
descr = NULL;
for (i = 0; i < n; i++) {
! base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
assert(PyType_Check(base));
descr = PyDict_GetItem(
--- 3925,3930 ----
descr = NULL;
for (i = 0; i < n; i++) {
! base = (PyTypeObject *)
! PyTuple_GET_ITEM(mro, i);
assert(PyType_Check(base));
descr = PyDict_GetItem(