aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Objects/tupleobject.c
diff options
context:
space:
mode:
authorPieter Eendebak <pieter.eendebak@gmail.com>2022-07-26 04:10:23 +0200
committerGitHub <noreply@github.com>2022-07-25 22:10:23 -0400
commit2ef73be891eb95064e268341e38e81d008add480 (patch)
tree895e2343dbbfc3c155d08301cf540deebd1bb259 /Objects/tupleobject.c
parent27055d766ab0ee5ddcfbd1fb51fb47419af1ddba (diff)
downloadcpython-2ef73be891eb95064e268341e38e81d008add480.tar.gz
cpython-2ef73be891eb95064e268341e38e81d008add480.zip
gh-91247: Use memcpy for list and tuple repeat (#91482)
* Add _Py_memory_repeat function to pycore_list * Add _Py_RefcntAdd function to pycore_object * Use the new functions in tuplerepeat, list_repeat, and list_inplace_repeat
Diffstat (limited to 'Objects/tupleobject.c')
-rw-r--r--Objects/tupleobject.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index dfb8597b876..240af0a9075 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -495,9 +495,8 @@ tupleconcat(PyTupleObject *a, PyObject *bb)
static PyObject *
tuplerepeat(PyTupleObject *a, Py_ssize_t n)
{
- Py_ssize_t size;
- PyTupleObject *np;
- if (Py_SIZE(a) == 0 || n == 1) {
+ const Py_ssize_t input_size = Py_SIZE(a);
+ if (input_size == 0 || n == 1) {
if (PyTuple_CheckExact(a)) {
/* Since tuples are immutable, we can return a shared
copy in this case */
@@ -505,42 +504,38 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
return (PyObject *)a;
}
}
- if (Py_SIZE(a) == 0 || n <= 0) {
+ if (input_size == 0 || n <= 0) {
return tuple_get_empty();
}
- if (n > PY_SSIZE_T_MAX / Py_SIZE(a))
+ assert(n>0);
+
+ if (input_size > PY_SSIZE_T_MAX / n)
return PyErr_NoMemory();
- size = Py_SIZE(a) * n;
- np = tuple_alloc(size);
+ Py_ssize_t output_size = input_size * n;
+
+ PyTupleObject *np = tuple_alloc(output_size);
if (np == NULL)
return NULL;
+
PyObject **dest = np->ob_item;
- PyObject **dest_end = dest + size;
- if (Py_SIZE(a) == 1) {
+ if (input_size == 1) {
PyObject *elem = a->ob_item[0];
- Py_SET_REFCNT(elem, Py_REFCNT(elem) + n);
-#ifdef Py_REF_DEBUG
- _Py_RefTotal += n;
-#endif
+ _Py_RefcntAdd(elem, n);
+ PyObject **dest_end = dest + output_size;
while (dest < dest_end) {
*dest++ = elem;
}
}
else {
PyObject **src = a->ob_item;
- PyObject **src_end = src + Py_SIZE(a);
+ PyObject **src_end = src + input_size;
while (src < src_end) {
- Py_SET_REFCNT(*src, Py_REFCNT(*src) + n);
-#ifdef Py_REF_DEBUG
- _Py_RefTotal += n;
-#endif
- *dest++ = *src++;
- }
- // Now src chases after dest in the same buffer
- src = np->ob_item;
- while (dest < dest_end) {
+ _Py_RefcntAdd(*src, n);
*dest++ = *src++;
}
+
+ _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size,
+ sizeof(PyObject *)*input_size);
}
_PyObject_GC_TRACK(np);
return (PyObject *) np;