From 83f4943df09d359659075c819549385d232c42a0 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 2 Apr 2019 20:11:06 +0100 Subject: [PATCH 1/6] Use vector call for list() --- Objects/listobject.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Objects/listobject.c b/Objects/listobject.c index 46bc7779218bcb..d932f9b35e3f87 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2717,6 +2717,34 @@ list___init___impl(PyListObject *self, PyObject *iterable) return 0; } +static PyObject * +list_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + if (kwnames && PyTuple_GET_SIZE(kwnames) != 0) { + PyErr_Format(PyExc_TypeError, "list() takes no keyword arguments"); + return NULL; + } + size_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs > 1) { + PyErr_Format(PyExc_TypeError, "list() expected at most 1 argument, got %zu", nargs); + return NULL; + } + + assert(PyType_Check(type)); + PyObject *list = PyType_GenericAlloc((PyTypeObject *)type, 0); + if (list == NULL) { + return NULL; + } + PyObject *iterator = nargs ? args[0] : NULL; + if (list___init___impl((PyListObject *)list, iterator)) { + Py_DECREF(list); + return NULL; + } + return list; +} + + /*[clinic input] list.__sizeof__ @@ -3032,6 +3060,7 @@ PyTypeObject PyList_Type = { PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = list_vectorcall, }; /*********************** List Iterator **************************/ From c586da5c1e80e580db8ee86652a6fd7ae3df969f Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 18 Feb 2020 16:22:24 +0100 Subject: [PATCH 2/6] Add news entry --- .../Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst new file mode 100644 index 00000000000000..fc49ea760b6a03 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst @@ -0,0 +1,2 @@ +Speed up calls to ``list()`` by using the PEP 590 ``vectorcall`` +calling convention. Patch by Mark Shannon. From 9d53274b742f18290f6741d56cb95dfb6ea5ecd9 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 18 Feb 2020 16:29:36 +0100 Subject: [PATCH 3/6] Use Py_ssize_t for argument count --- Objects/listobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index d932f9b35e3f87..7a57914024db4a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2725,9 +2725,9 @@ list_vectorcall(PyObject *type, PyObject * const*args, PyErr_Format(PyExc_TypeError, "list() takes no keyword arguments"); return NULL; } - size_t nargs = PyVectorcall_NARGS(nargsf); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (nargs > 1) { - PyErr_Format(PyExc_TypeError, "list() expected at most 1 argument, got %zu", nargs); + PyErr_Format(PyExc_TypeError, "list() expected at most 1 argument, got %zd", nargs); return NULL; } From 0418c6b2023a18d1add93ca463b53d7fb320127e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 18 Feb 2020 16:46:29 +0100 Subject: [PATCH 4/6] list_vectorcall: Only fill the list if an argument is given --- Objects/listobject.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 7a57914024db4a..c3d5dd4d1f2c36 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2736,10 +2736,11 @@ list_vectorcall(PyObject *type, PyObject * const*args, if (list == NULL) { return NULL; } - PyObject *iterator = nargs ? args[0] : NULL; - if (list___init___impl((PyListObject *)list, iterator)) { - Py_DECREF(list); - return NULL; + if (nargs) { + if (list___init___impl((PyListObject *)list, args[0])) { + Py_DECREF(list); + return NULL; + } } return list; } From 84e88ca25d50219adf6585456ceb56dcbc7e9b03 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Mar 2020 15:02:35 +0100 Subject: [PATCH 5/6] NEWS: Update ReST syntax Co-Authored-By: Dong-hee Na --- .../Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst index fc49ea760b6a03..b6d0236db4635c 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-09-10-54-31.bpo-37207.bLjgLS.rst @@ -1,2 +1,2 @@ -Speed up calls to ``list()`` by using the PEP 590 ``vectorcall`` +Speed up calls to ``list()`` by using the :pep:`590` ``vectorcall`` calling convention. Patch by Mark Shannon. From 47aba6d9d104a74cf263d767da188391c0f3c1ca Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 17 Mar 2020 14:26:40 +0100 Subject: [PATCH 6/6] Use helper functions to validate arguments --- Objects/listobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index c3d5dd4d1f2c36..9afd9e529110f1 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2721,13 +2721,11 @@ static PyObject * list_vectorcall(PyObject *type, PyObject * const*args, size_t nargsf, PyObject *kwnames) { - if (kwnames && PyTuple_GET_SIZE(kwnames) != 0) { - PyErr_Format(PyExc_TypeError, "list() takes no keyword arguments"); + if (!_PyArg_NoKwnames("list", kwnames)) { return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (nargs > 1) { - PyErr_Format(PyExc_TypeError, "list() expected at most 1 argument, got %zd", nargs); + if (!_PyArg_CheckPositional("list", nargs, 0, 1)) { return NULL; }