From 5d858465b6ebdafa05f86309457848cc26913b6a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 20 Nov 2016 10:16:47 +0200 Subject: Added the const qualifier to char* variables that refer to readonly internal UTF-8 represenatation of Unicode objects. --- Python/bltinmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index a49cb9d103..5c925452e6 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1893,7 +1893,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) char *s = NULL; PyObject *stdin_encoding = NULL, *stdin_errors = NULL; PyObject *stdout_encoding = NULL, *stdout_errors = NULL; - char *stdin_encoding_str, *stdin_errors_str; + const char *stdin_encoding_str, *stdin_errors_str; PyObject *result; size_t len; @@ -1914,7 +1914,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) Py_DECREF(tmp); if (prompt != NULL) { /* We have a prompt, encode it as stdout would */ - char *stdout_encoding_str, *stdout_errors_str; + const char *stdout_encoding_str, *stdout_errors_str; PyObject *stringpo; stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors); -- cgit v1.2.1 From 366f4ee4da4420842eac26b3fa00c2b01d4515a6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 1 Dec 2016 14:43:22 +0100 Subject: Replace PyObject_CallFunctionObjArgs() with fastcall * PyObject_CallFunctionObjArgs(func, NULL) => _PyObject_CallNoArg(func) * PyObject_CallFunctionObjArgs(func, arg, NULL) => _PyObject_CallArg1(func, arg) PyObject_CallFunctionObjArgs() allocates 40 bytes on the C stack and requires extra work to "parse" C arguments to build a C array of PyObject*. _PyObject_CallNoArg() and _PyObject_CallArg1() are simpler and don't allocate memory on the C stack. This change is part of the fastcall project. The change on listsort() is related to the issue #23507. --- Python/bltinmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 5c925452e6..1b53897e2d 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -469,7 +469,7 @@ filter_next(filterobject *lz) ok = PyObject_IsTrue(item); } else { PyObject *good; - good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); + good = _PyObject_CallArg1(lz->func, item); if (good == NULL) { Py_DECREF(item); return NULL; @@ -1519,7 +1519,7 @@ min_max(PyObject *args, PyObject *kwds, int op) while (( item = PyIter_Next(it) )) { /* get the value from the key function */ if (keyfunc != NULL) { - val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL); + val = _PyObject_CallArg1(keyfunc, item); if (val == NULL) goto Fail_it_item; } @@ -2044,9 +2044,9 @@ builtin_round(PyObject *self, PyObject *args, PyObject *kwds) } if (ndigits == NULL || ndigits == Py_None) - result = PyObject_CallFunctionObjArgs(round, NULL); + result = _PyObject_CallNoArg(round); else - result = PyObject_CallFunctionObjArgs(round, ndigits, NULL); + result = _PyObject_CallArg1(round, ndigits); Py_DECREF(round); return result; } -- cgit v1.2.1 From 39ae5bedd90f9caf9a78efa82f4d11e838933b3a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 4 Dec 2016 22:59:09 +0100 Subject: Backed out changeset b9c9691c72c5 Issue #28858: The change b9c9691c72c5 introduced a regression. It seems like _PyObject_CallArg1() uses more stack memory than PyObject_CallFunctionObjArgs(). --- Python/bltinmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 1b53897e2d..5c925452e6 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -469,7 +469,7 @@ filter_next(filterobject *lz) ok = PyObject_IsTrue(item); } else { PyObject *good; - good = _PyObject_CallArg1(lz->func, item); + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; @@ -1519,7 +1519,7 @@ min_max(PyObject *args, PyObject *kwds, int op) while (( item = PyIter_Next(it) )) { /* get the value from the key function */ if (keyfunc != NULL) { - val = _PyObject_CallArg1(keyfunc, item); + val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL); if (val == NULL) goto Fail_it_item; } @@ -2044,9 +2044,9 @@ builtin_round(PyObject *self, PyObject *args, PyObject *kwds) } if (ndigits == NULL || ndigits == Py_None) - result = _PyObject_CallNoArg(round); + result = PyObject_CallFunctionObjArgs(round, NULL); else - result = _PyObject_CallArg1(round, ndigits); + result = PyObject_CallFunctionObjArgs(round, ndigits, NULL); Py_DECREF(round); return result; } -- cgit v1.2.1 From a95a307d2cbb7fc1c778691f142e0c21c05fd5bc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 6 Dec 2016 18:46:19 +0100 Subject: Use _PyObject_CallNoArg() Replace: PyObject_CallFunctionObjArgs(callable, NULL) with: _PyObject_CallNoArg(callable) --- Python/bltinmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index d0ba4e1315..5e1f5624b9 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2074,7 +2074,7 @@ builtin_round(PyObject *self, PyObject *args, PyObject *kwds) } if (ndigits == NULL || ndigits == Py_None) - result = PyObject_CallFunctionObjArgs(round, NULL); + result = _PyObject_CallNoArg(round); else result = PyObject_CallFunctionObjArgs(round, ndigits, NULL); Py_DECREF(round); -- cgit v1.2.1 From cff69a956b4ce78ad7c4318ada06f07959dd8023 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 15 Dec 2016 12:40:53 +0100 Subject: Add _PY_FASTCALL_SMALL_STACK constant 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. --- Python/bltinmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 5e1f5624b9..292a7bc2a0 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -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; -- cgit v1.2.1 From 39c529ee7093240a5b79bdde6cca813218d41b81 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 16 Jan 2017 23:46:26 +0100 Subject: __build_class__() builtin uses METH_FASTCALL --- Python/bltinmodule.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 292a7bc2a0..31538c634e 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -52,51 +52,45 @@ _Py_IDENTIFIER(stderr); /* AC: cannot convert yet, waiting for *args support */ static PyObject * -builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) +builtin___build_class__(PyObject *self, PyObject **args, Py_ssize_t nargs, + PyObject *kwnames) { PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns; PyObject *cls = NULL, *cell = NULL; - Py_ssize_t nargs; int isclass = 0; /* initialize to prevent gcc warning */ - assert(args != NULL); - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "__build_class__: args is not a tuple"); - return NULL; - } - nargs = PyTuple_GET_SIZE(args); if (nargs < 2) { PyErr_SetString(PyExc_TypeError, "__build_class__: not enough arguments"); return NULL; } - func = PyTuple_GET_ITEM(args, 0); /* Better be callable */ + func = args[0]; /* Better be callable */ if (!PyFunction_Check(func)) { PyErr_SetString(PyExc_TypeError, "__build_class__: func must be a function"); return NULL; } - name = PyTuple_GET_ITEM(args, 1); + name = args[1]; if (!PyUnicode_Check(name)) { PyErr_SetString(PyExc_TypeError, "__build_class__: name is not a string"); return NULL; } - bases = PyTuple_GetSlice(args, 2, nargs); + bases = _PyStack_AsTupleSlice(args, nargs, 2, nargs); if (bases == NULL) return NULL; - if (kwds == NULL) { + if (kwnames == NULL) { meta = NULL; mkw = NULL; } else { - mkw = PyDict_Copy(kwds); /* Don't modify kwds passed in! */ + mkw = _PyStack_AsDict(args + nargs, kwnames); if (mkw == NULL) { Py_DECREF(bases); return NULL; } + meta = _PyDict_GetItemId(mkw, &PyId_metaclass); if (meta != NULL) { Py_INCREF(meta); @@ -2612,7 +2606,7 @@ PyTypeObject PyZip_Type = { static PyMethodDef builtin_methods[] = { {"__build_class__", (PyCFunction)builtin___build_class__, - METH_VARARGS | METH_KEYWORDS, build_class_doc}, + METH_FASTCALL, build_class_doc}, {"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, BUILTIN_ABS_METHODDEF BUILTIN_ALL_METHODDEF -- cgit v1.2.1 From 782bee438e8b93c8e7474c1fe133bcbc9f594ab5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 03:52:27 +0100 Subject: getattr() uses METH_FASTCALL --- Python/bltinmodule.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 31538c634e..b269937684 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -993,14 +993,19 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, /* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * -builtin_getattr(PyObject *self, PyObject *args) +builtin_getattr(PyObject *self, PyObject **args, Py_ssize_t nargs, + PyObject *kwnames) { PyObject *v, *result, *dflt = NULL; PyObject *name; - if (!PyArg_UnpackTuple(args, "getattr", 2, 3, &v, &name, &dflt)) + if (!_PyArg_UnpackStack(args, nargs, "getattr", 2, 3, &v, &name, &dflt)) return NULL; + if (!_PyArg_NoStackKeywords("getattr", kwnames)) { + return NULL; + } + if (!PyUnicode_Check(name)) { PyErr_SetString(PyExc_TypeError, "getattr(): attribute name must be string"); @@ -2622,7 +2627,7 @@ static PyMethodDef builtin_methods[] = { BUILTIN_EVAL_METHODDEF BUILTIN_EXEC_METHODDEF BUILTIN_FORMAT_METHODDEF - {"getattr", builtin_getattr, METH_VARARGS, getattr_doc}, + {"getattr", (PyCFunction)builtin_getattr, METH_FASTCALL, getattr_doc}, BUILTIN_GLOBALS_METHODDEF BUILTIN_HASATTR_METHODDEF BUILTIN_HASH_METHODDEF -- cgit v1.2.1 From 2695f58748d3d3d0c30f6df9a3b59b904d43ff9f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 04:09:14 +0100 Subject: next() uses FASTCALL --- Python/bltinmodule.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index b269937684..9487a5364a 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1303,13 +1303,19 @@ PyTypeObject PyMap_Type = { /* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * -builtin_next(PyObject *self, PyObject *args) +builtin_next(PyObject *self, PyObject **args, Py_ssize_t nargs, + PyObject *kwnames) { PyObject *it, *res; PyObject *def = NULL; - if (!PyArg_UnpackTuple(args, "next", 1, 2, &it, &def)) + if (!_PyArg_UnpackStack(args, nargs, "next", 1, 2, &it, &def)) return NULL; + + if (!_PyArg_NoStackKeywords("next", kwnames)) { + return NULL; + } + if (!PyIter_Check(it)) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not an iterator", @@ -2641,7 +2647,7 @@ static PyMethodDef builtin_methods[] = { BUILTIN_LOCALS_METHODDEF {"max", (PyCFunction)builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", (PyCFunction)builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, - {"next", (PyCFunction)builtin_next, METH_VARARGS, next_doc}, + {"next", (PyCFunction)builtin_next, METH_FASTCALL, next_doc}, BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF BUILTIN_POW_METHODDEF -- cgit v1.2.1 From 94fec294a4d2d2b93b66d07b0717544674dcee74 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 15:17:49 +0100 Subject: sorted() uses METH_FASTCALL --- Python/bltinmodule.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9487a5364a..cde2b75829 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2121,20 +2121,20 @@ PyDoc_STRVAR(builtin_sorted__doc__, "reverse flag can be set to request the result in descending order."); #define BUILTIN_SORTED_METHODDEF \ - {"sorted", (PyCFunction)builtin_sorted, METH_VARARGS|METH_KEYWORDS, builtin_sorted__doc__}, + {"sorted", (PyCFunction)builtin_sorted, METH_FASTCALL, builtin_sorted__doc__}, static PyObject * -builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) +builtin_sorted(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *newlist, *v, *seq, *keyfunc=NULL, **newargs; + PyObject *newlist, *v, *seq, *keyfunc=NULL; PyObject *callable; - static char *kwlist[] = {"iterable", "key", "reverse", 0}; + static const char * const kwlist[] = {"iterable", "key", "reverse", 0}; + /* args 1-3 should match listsort in Objects/listobject.c */ + static _PyArg_Parser parser = {"O|Oi:sorted", kwlist, 0}; int reverse; - Py_ssize_t nargs; - /* args 1-3 should match listsort in Objects/listobject.c */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:sorted", - kwlist, &seq, &keyfunc, &reverse)) + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &parser, + &seq, &keyfunc, &reverse)) return NULL; newlist = PySequence_List(seq); @@ -2147,9 +2147,7 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - newargs = &PyTuple_GET_ITEM(args, 1); - nargs = PyTuple_GET_SIZE(args) - 1; - v = _PyObject_FastCallDict(callable, newargs, nargs, kwds); + v = _PyObject_FastCallKeywords(callable, args + 1, nargs - 1, kwnames); Py_DECREF(callable); if (v == NULL) { Py_DECREF(newlist); -- cgit v1.2.1 From 01939eaa796ffc91b1784042c57123c7a2a35a3d Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Thu, 19 Jan 2017 12:50:34 +0100 Subject: Issue #29296: convert print() to METH_FASTCALL * Replace PyArg_ParseTupleAndKeywords() with _PyArg_ParseStackAndKeywords() which is more efficient to parse keywords, since it decodes only keywords (char*) from UTF-8 once, instead of decoding at each call. * METH_FASTCALL avoids the creation of a temporary tuple to pass positional arguments. Patch written by INADA Naoki, pushed by Victor Stinner. --- Python/bltinmodule.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index cde2b75829..ab029ce0aa 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1747,18 +1747,19 @@ builtin_pow_impl(PyObject *module, PyObject *x, PyObject *y, PyObject *z) /* AC: cannot convert yet, waiting for *args support */ static PyObject * -builtin_print(PyObject *self, PyObject *args, PyObject *kwds) +builtin_print(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - static char *kwlist[] = {"sep", "end", "file", "flush", 0}; - static PyObject *dummy_args; + static const char * const _keywords[] = {"sep", "end", "file", "flush", 0}; + static struct _PyArg_Parser _parser = {"|OOOO:print", _keywords, 0}; PyObject *sep = NULL, *end = NULL, *file = NULL, *flush = NULL; int i, err; - if (dummy_args == NULL && !(dummy_args = PyTuple_New(0))) - return NULL; - if (!PyArg_ParseTupleAndKeywords(dummy_args, kwds, "|OOOO:print", - kwlist, &sep, &end, &file, &flush)) + if (kwnames != NULL && + !_PyArg_ParseStackAndKeywords(args + nargs, 0, kwnames, &_parser, + &sep, &end, &file, &flush)) { return NULL; + } + if (file == NULL || file == Py_None) { file = _PySys_GetObjectId(&PyId_stdout); if (file == NULL) { @@ -1790,7 +1791,7 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - for (i = 0; i < PyTuple_Size(args); i++) { + for (i = 0; i < nargs; i++) { if (i > 0) { if (sep == NULL) err = PyFile_WriteString(" ", file); @@ -1800,8 +1801,7 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) if (err) return NULL; } - err = PyFile_WriteObject(PyTuple_GetItem(args, i), file, - Py_PRINT_RAW); + err = PyFile_WriteObject(args[i], file, Py_PRINT_RAW); if (err) return NULL; } @@ -2649,7 +2649,7 @@ static PyMethodDef builtin_methods[] = { BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF BUILTIN_POW_METHODDEF - {"print", (PyCFunction)builtin_print, METH_VARARGS | METH_KEYWORDS, print_doc}, + {"print", (PyCFunction)builtin_print, METH_FASTCALL, print_doc}, BUILTIN_REPR_METHODDEF {"round", (PyCFunction)builtin_round, METH_VARARGS | METH_KEYWORDS, round_doc}, BUILTIN_SETATTR_METHODDEF -- cgit v1.2.1 From 8f993e3ac6565928b14ffc0fcef23775f1b1e3f5 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 21 Jan 2017 23:05:00 +0200 Subject: Issue #29331: Simplified argument parsing in sorted() and list.sort(). --- Python/bltinmodule.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 6df8af4733..3473cc322c 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2126,15 +2126,11 @@ PyDoc_STRVAR(builtin_sorted__doc__, static PyObject * builtin_sorted(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *newlist, *v, *seq, *keyfunc=NULL; - PyObject *callable; - static const char * const kwlist[] = {"", "key", "reverse", 0}; - /* args 1-3 should match listsort in Objects/listobject.c */ - static _PyArg_Parser parser = {"O|Oi:sorted", kwlist, 0}; - int reverse; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &parser, - &seq, &keyfunc, &reverse)) + PyObject *newlist, *v, *seq, *callable; + + /* Keyword arguments are passed through list.sort() which will check + them. */ + if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq)) return NULL; newlist = PySequence_List(seq); -- cgit v1.2.1 From bfeec6d871e3db2e0ddfdef01387913bc19cadd4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 23 Jan 2017 09:47:21 +0200 Subject: Issue #28999: Use Py_RETURN_NONE, Py_RETURN_TRUE and Py_RETURN_FALSE wherever possible. Patch is writen with Coccinelle. --- Python/bltinmodule.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Python/bltinmodule.c') diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 3473cc322c..220434437d 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1369,8 +1369,7 @@ builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, { if (PyObject_SetAttr(obj, name, value) != 0) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } @@ -1392,8 +1391,7 @@ builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name) { if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -- cgit v1.2.1