diff -r 71876e4abce4 Include/abstract.h --- a/Include/abstract.h Thu Dec 15 12:40:53 2016 +0100 +++ b/Include/abstract.h Thu Dec 15 14:43:04 2016 +0100 @@ -312,7 +312,7 @@ PyAPI_FUNC(PyObject **) _PyStack_UnpackD overflow. The size is also chosen to allow using the small stack for most function calls of the Python standard library. On 64-bit CPU, it allocates 40 bytes on the stack. */ -#define _PY_FASTCALL_SMALL_STACK 5 +#define _PY_FASTCALL_SMALL_STACK 3 /* Call the callable object 'callable' with the "fast call" calling convention: args is a C array for positional arguments (nargs is the number of diff -r 71876e4abce4 Objects/abstract.c --- a/Objects/abstract.c Thu Dec 15 12:40:53 2016 +0100 +++ b/Objects/abstract.c Thu Dec 15 14:43:04 2016 +0100 @@ -2701,21 +2701,12 @@ PyObject * return retval; } -PyObject * -_PyObject_VaCallFunctionObjArgs(PyObject *callable, va_list vargs) +static Py_ssize_t +count_vargs(va_list vargs) { - PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; - PyObject **stack; + va_list countva; Py_ssize_t nargs; - PyObject *result; - Py_ssize_t i; - va_list countva; - - if (callable == NULL) { - return null_error(); - } - - /* Count the number of arguments */ + va_copy(countva, vargs); nargs = 0; while (1) { @@ -2727,9 +2718,29 @@ PyObject * } va_end(countva); - /* Copy arguments */ - if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { - stack = small_stack; + return nargs; +} + +Py_LOCAL_INLINE(PyObject *) +object_vacall(PyObject *callable, va_list vargs) +{ + Py_ssize_t nargs; + PyObject **stack; + Py_ssize_t i; + PyObject *result; + + if (callable == NULL) { + return null_error(); + } + + nargs = count_vargs(vargs); + + if (nargs == 0) { + return _PyObject_CallNoArg(callable); + } + + if (nargs <= _PY_FASTCALL_SMALL_STACK) { + stack = alloca(nargs * sizeof(PyObject*)); } else { stack = PyMem_Malloc(nargs * sizeof(stack[0])); @@ -2743,16 +2754,21 @@ PyObject * stack[i] = va_arg(vargs, PyObject *); } - /* Call the function */ result = _PyObject_FastCall(callable, stack, nargs); - if (stack != small_stack) { + if (nargs > _PY_FASTCALL_SMALL_STACK) { PyMem_Free(stack); } return result; } PyObject * +_PyObject_VaCallFunctionObjArgs(PyObject *callable, va_list vargs) +{ + return object_vacall(callable, vargs); +} + +PyObject * PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) { va_list vargs; @@ -2768,7 +2784,7 @@ PyObject_CallMethodObjArgs(PyObject *cal } va_start(vargs, name); - result = _PyObject_VaCallFunctionObjArgs(callable, vargs); + result = object_vacall(callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -2792,7 +2808,7 @@ PyObject * } va_start(vargs, name); - result = _PyObject_VaCallFunctionObjArgs(callable, vargs); + result = object_vacall(callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -2806,7 +2822,7 @@ PyObject_CallFunctionObjArgs(PyObject *c PyObject *result; va_start(vargs, callable); - result = _PyObject_VaCallFunctionObjArgs(callable, vargs); + result = object_vacall(callable, vargs); va_end(vargs); return result;