]> granicus.if.org Git - python/commitdiff
Add _PY_FASTCALL_SMALL_STACK constant
authorVictor Stinner <victor.stinner@gmail.com>
Thu, 15 Dec 2016 11:40:53 +0000 (12:40 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Thu, 15 Dec 2016 11:40:53 +0000 (12:40 +0100)
Issue #28870: Add a new _PY_FASTCALL_SMALL_STACK constant, size of "small
stacks" allocated on the C stack to pass positional arguments to
_PyObject_FastCall().

_PyObject_Call_Prepend() now uses a small stack of 5 arguments (40 bytes)
instead of 8 (64 bytes), since it is modified to use _PY_FASTCALL_SMALL_STACK.

Include/abstract.h
Objects/abstract.c
Python/bltinmodule.c

index 8c1e45bb267f722d4ed04225ecfc14de43c1a3fa..f6dfc675853af6cbf5c77c41b17330b4e9e689bf 100644 (file)
@@ -303,6 +303,17 @@ PyAPI_FUNC(PyObject **) _PyStack_UnpackDict(
     PyObject **kwnames,
     PyObject *func);
 
+/* Suggested size (number of positional arguments) for arrays of PyObject*
+   allocated on a C stack to avoid allocating memory on the heap memory. Such
+   array is used to pass positional arguments to call functions of the
+   _PyObject_FastCall() family.
+
+   The size is chosen to not abuse the C stack and so limit the risk of stack
+   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
+
 /* Call the callable object 'callable' with the "fast call" calling convention:
    args is a C array for positional arguments (nargs is the number of
    positional arguments), kwargs is a dictionary for keyword arguments.
index 7da97ac8a8db10f97d7ecc8dd83e3b53c91876a1..351c6eb56b2ddf52a0c543a7c479cd2d349a0770 100644 (file)
@@ -2337,7 +2337,7 @@ PyObject *
 _PyObject_Call_Prepend(PyObject *callable,
                        PyObject *obj, PyObject *args, PyObject *kwargs)
 {
-    PyObject *small_stack[8];
+    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
     PyObject **stack;
     Py_ssize_t argcount;
     PyObject *result;
@@ -2523,7 +2523,7 @@ static PyObject *
 _PyObject_CallFunctionVa(PyObject *callable, const char *format,
                          va_list va, int is_size_t)
 {
-    PyObject* small_stack[5];
+    PyObject* small_stack[_PY_FASTCALL_SMALL_STACK];
     const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack);
     PyObject **stack;
     Py_ssize_t nargs, i;
@@ -2704,7 +2704,7 @@ _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name,
 PyObject *
 _PyObject_VaCallFunctionObjArgs(PyObject *callable, va_list vargs)
 {
-    PyObject *small_stack[5];
+    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
     PyObject **stack;
     Py_ssize_t nargs;
     PyObject *result;
index 5e1f5624b96c1831c456c97eb69924f6b4fe69f4..292a7bc2a06aabbf4a58399e6d38fc7310004092 100644 (file)
@@ -1186,7 +1186,7 @@ map_traverse(mapobject *lz, visitproc visit, void *arg)
 static PyObject *
 map_next(mapobject *lz)
 {
-    PyObject *small_stack[5];
+    PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
     PyObject **stack;
     Py_ssize_t niters, nargs, i;
     PyObject *result = NULL;