[Python-checkins] python/dist/src/Python ceval.c,2.326,2.327

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
Fri, 16 Aug 2002 11:36:14 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv15213

Modified Files:
	ceval.c 
Log Message:
Inline fast_cfunction() in new call_function().

Also, don't handle METH_OLDARGS on the fast path.  All the interesting
builtins have been converted to use METH_NOARGS, METH_O, or
METH_VARARGS.

Result is another 1-2% speedup.  If I can cobble together 10 of these,
it might make a difference.


Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.326
retrieving revision 2.327
diff -C2 -d -r2.326 -r2.327
*** ceval.c	16 Aug 2002 17:47:26 -0000	2.326
--- ceval.c	16 Aug 2002 18:36:11 -0000	2.327
***************
*** 36,40 ****
  static PyObject *call_function(PyObject ***, int);
  static PyObject *fast_function(PyObject *, PyObject ***, int, int, int);
- static PyObject *fast_cfunction(PyObject *, PyObject ***, int);
  static PyObject *do_call(PyObject *, PyObject ***, int, int);
  static PyObject *ext_do_call(PyObject *, PyObject ***, int, int, int);
--- 36,39 ----
***************
*** 3147,3150 ****
--- 3146,3164 ----
  #define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
  
+ void
+ err_args(PyObject *func, int flags, int nargs)
+ {
+ 	if (flags & METH_NOARGS)
+ 		PyErr_Format(PyExc_TypeError, 
+ 			     "%.200s() takes 1 argument (%d given)",
+ 			     ((PyCFunctionObject *)func)->m_ml->ml_name, 
+ 			     nargs);
+ 	else
+ 		PyErr_Format(PyExc_TypeError, 
+ 			     "%.200s() takes no arguments (%d given)",
+ 			     ((PyCFunctionObject *)func)->m_ml->ml_name, 
+ 			     nargs);
+ }
+ 
  static PyObject *
  call_function(PyObject ***pp_stack, int oparg)
***************
*** 3163,3173 ****
  	if (PyCFunction_Check(func) && nk == 0) {
  		int flags = PyCFunction_GET_FLAGS(func);
! 		if (flags  & (METH_VARARGS | METH_KEYWORDS)) {
  			PyObject *callargs;
  			callargs = load_args(pp_stack, na);
  			x = PyCFunction_Call(func, callargs, NULL);
  			Py_XDECREF(callargs); 
! 		} else
! 			x = fast_cfunction(func, pp_stack, na);
  	} else {
  		if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
--- 3177,3201 ----
  	if (PyCFunction_Check(func) && nk == 0) {
  		int flags = PyCFunction_GET_FLAGS(func);
! 		if (flags & (METH_NOARGS | METH_O)) {
! 			PyCFunction meth = PyCFunction_GET_FUNCTION(func);
! 			PyObject *self = PyCFunction_GET_SELF(func);
! 			if (flags & METH_NOARGS && na == 0) 
! 				x = (*meth)(self, NULL);
! 			else if (flags & METH_O && na == 1) {
! 				PyObject *arg = EXT_POP(*pp_stack);
! 				x = (*meth)(self, arg);
! 				Py_DECREF(arg);
! 			}
! 			else {
! 				err_args(func, flags, na);
! 				x = NULL;
! 			}
! 		}
! 		else {
  			PyObject *callargs;
  			callargs = load_args(pp_stack, na);
  			x = PyCFunction_Call(func, callargs, NULL);
  			Py_XDECREF(callargs); 
! 		} 
  	} else {
  		if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
***************
*** 3197,3253 ****
  }
  
! /* The two fast_xxx() functions optimize calls for which no argument
     tuple is necessary; the objects are passed directly from the stack.
-    fast_cfunction() is called for METH_OLDARGS functions.
-    fast_function() is for functions with no special argument handling.
  */
- 
- static PyObject *
- fast_cfunction(PyObject *func, PyObject ***pp_stack, int na)
- {
- 	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
- 	PyObject *self = PyCFunction_GET_SELF(func);
- 	int flags = PyCFunction_GET_FLAGS(func);
- 
- 	switch (flags) {
- 	case METH_OLDARGS:
- 		if (na == 0)
- 			return (*meth)(self, NULL);
- 		else if (na == 1) {
- 			PyObject *arg = EXT_POP(*pp_stack);
- 			PyObject *result =  (*meth)(self, arg);
- 			Py_DECREF(arg);
- 			return result;
- 		} else {
- 			PyObject *args = load_args(pp_stack, na);
- 			PyObject *result = (*meth)(self, args);
- 			Py_DECREF(args);
- 			return result;
- 		}
- 	case METH_NOARGS:
- 		if (na == 0)
- 			return (*meth)(self, NULL);
- 		PyErr_Format(PyExc_TypeError,
- 			     "%.200s() takes no arguments (%d given)",
- 			     ((PyCFunctionObject*)func)->m_ml->ml_name, na);
- 		return NULL;
- 	case METH_O:
- 		if (na == 1) {
- 			PyObject *arg = EXT_POP(*pp_stack);
- 			PyObject *result = (*meth)(self, arg);
- 			Py_DECREF(arg);
- 			return result;
- 		}
- 		PyErr_Format(PyExc_TypeError,
- 			     "%.200s() takes exactly one argument (%d given)",
- 			     ((PyCFunctionObject*)func)->m_ml->ml_name, na);
- 		return NULL;
- 	default:
- 		fprintf(stderr, "%.200s() flags = %d\n", 
- 			((PyCFunctionObject*)func)->m_ml->ml_name, flags);
- 		PyErr_BadInternalCall();
- 		return NULL;
- 	}		
- }
  
  static PyObject *
--- 3225,3231 ----
  }
  
! /* The fast_function() function optimize calls for which no argument
     tuple is necessary; the objects are passed directly from the stack.
  */
  
  static PyObject *