[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(

AltStyle によって変換されたページ (->オリジナル) /