summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorL. A. F. Pereira <l.pereira@microsoft.com>2023-01-03 18:49:49 (GMT)
committerGitHub <noreply@github.com>2023-01-03 18:49:49 (GMT)
commite6d44407827490a5345e8393fbdc78fd6c14f5b1 (patch)
tree2f8537e266b484373b806fa7755d9edf40120ca4 /Objects
parentb3722ca058f6a6d6505cf2ea9ffabaf7fb6b6e19 (diff)
downloadcpython-e6d44407827490a5345e8393fbdc78fd6c14f5b1.zip
cpython-e6d44407827490a5345e8393fbdc78fd6c14f5b1.tar.gz
cpython-e6d44407827490a5345e8393fbdc78fd6c14f5b1.tar.bz2
gh-100146: Steal references from stack when building a list (#100147)
When executing the BUILD_LIST opcode, steal the references from the stack, in a manner similar to the BUILD_TUPLE opcode. Implement this by offloading the logic to a new private API, _PyList_FromArraySteal(), that works similarly to _PyTuple_FromArraySteal(). This way, instead of performing multiple stack pointer adjustments while the list is being initialized, the stack is adjusted only once and a fast memory copy operation is performed in one fell swoop.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/listobject.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c
index b093f88..6629775 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -2565,6 +2565,27 @@ PyList_AsTuple(PyObject *v)
return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
}
+PyObject *
+_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n)
+{
+ if (n == 0) {
+ return PyList_New(0);
+ }
+
+ PyListObject *list = (PyListObject *)PyList_New(n);
+ if (list == NULL) {
+ for (Py_ssize_t i = 0; i < n; i++) {
+ Py_DECREF(src[i]);
+ }
+ return NULL;
+ }
+
+ PyObject **dst = list->ob_item;
+ memcpy(dst, src, n * sizeof(PyObject *));
+
+ return (PyObject *)list;
+}
+
/*[clinic input]
list.index