Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Include/internal/pycore_bytesobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ _PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack,
//
// Export for 'array' shared extension.
PyAPI_FUNC(void)
_PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
_PyBytes_RepeatBuffer(char* dest, Py_ssize_t len_dest,
const char* src, Py_ssize_t len_src);

PyAPI_FUNC(PyObject *) _PyBytes_Repeat(PyObject *self, Py_ssize_t n);

/* _PyBytesObject_SIZE gives the basic size of a bytes object; any memory allocation
for a bytes object of length n should request PyBytesObject_SIZE + n bytes.

Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ PyAPI_FUNC(PyObject *)_PyTuple_FromStackRefStealOnSuccess(const union _PyStackRe
PyAPI_FUNC(PyObject *)_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t);
PyAPI_FUNC(PyObject *) _PyTuple_BinarySlice(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) _PyTuple_Concat(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) _PyTuple_Repeat(PyObject *self, Py_ssize_t n);

PyAPI_FUNC(PyObject *) _PyTuple_FromPair(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) _PyTuple_FromPairSteal(PyObject *, PyObject *);
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_unicodeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern PyObject* _PyUnicode_ResizeCompact(
Py_ssize_t length);
extern PyObject* _PyUnicode_GetEmpty(void);
PyAPI_FUNC(PyObject*) _PyUnicode_BinarySlice(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) _PyUnicode_Repeat(PyObject *str, Py_ssize_t len);


/* Generic helper macro to convert characters of different types.
Expand Down
6 changes: 3 additions & 3 deletions Modules/arraymodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#endif

#include "Python.h"
#include "pycore_bytesobject.h" // _PyBytes_Repeat
#include "pycore_bytesobject.h" // _PyBytes_RepeatBuffer
#include "pycore_call.h" // _PyObject_CallMethod()
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_floatobject.h" // _PY_FLOAT_BIG_ENDIAN
Expand Down Expand Up @@ -1148,7 +1148,7 @@ array_repeat(PyObject *op, Py_ssize_t n)

const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize;
const Py_ssize_t newbytes = oldbytes * n;
_PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes);
_PyBytes_RepeatBuffer(np->ob_item, newbytes, a->ob_item, oldbytes);

return (PyObject *)np;
}
Expand Down Expand Up @@ -1305,7 +1305,7 @@ array_inplace_repeat(PyObject *op, Py_ssize_t n)
if (array_resize(self, n * array_size) == -1)
return NULL;

_PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size);
_PyBytes_RepeatBuffer(self->ob_item, n*size, self->ob_item, size);
}
return Py_NewRef(self);
}
Expand Down
4 changes: 2 additions & 2 deletions Objects/bytearrayobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count)
PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
const char* buf = PyByteArray_AS_STRING(self);
if (result != NULL && size != 0) {
_PyBytes_Repeat(result->ob_bytes, size, buf, mysize);
_PyBytes_RepeatBuffer(result->ob_bytes, size, buf, mysize);
}
return (PyObject *)result;
}
Expand Down Expand Up @@ -439,7 +439,7 @@ bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count)
}

char* buf = PyByteArray_AS_STRING(self);
_PyBytes_Repeat(buf, size, buf, mysize);
_PyBytes_RepeatBuffer(buf, size, buf, mysize);

return Py_NewRef(self);
}
Expand Down
12 changes: 6 additions & 6 deletions Objects/bytesobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "Python.h"
#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_bytes_methods.h" // _Py_bytes_startswith()
#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat()
#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_RepeatBuffer()
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_format.h" // F_LJUST
Expand Down Expand Up @@ -1581,8 +1581,8 @@ _PyBytes_Concat(PyObject *a, PyObject *b)
return result;
}

static PyObject *
bytes_repeat(PyObject *self, Py_ssize_t n)
PyObject *
_PyBytes_Repeat(PyObject *self, Py_ssize_t n)
{
PyBytesObject *a = _PyBytes_CAST(self);
if (n < 0)
Expand Down Expand Up @@ -1613,7 +1613,7 @@ bytes_repeat(PyObject *self, Py_ssize_t n)
set_ob_shash(op, -1);
op->ob_sval[size] = '\0';

_PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a));
_PyBytes_RepeatBuffer(op->ob_sval, size, a->ob_sval, Py_SIZE(a));

return (PyObject *) op;
}
Expand Down Expand Up @@ -1805,7 +1805,7 @@ bytes_buffer_getbuffer(PyObject *op, Py_buffer *view, int flags)
static PySequenceMethods bytes_as_sequence = {
bytes_length, /*sq_length*/
_PyBytes_Concat, /*sq_concat*/
bytes_repeat, /*sq_repeat*/
_PyBytes_Repeat, /*sq_repeat*/
bytes_item, /*sq_item*/
0, /*sq_slice*/
0, /*sq_ass_item*/
Expand Down Expand Up @@ -3555,7 +3555,7 @@ bytes_iter(PyObject *seq)


void
_PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
_PyBytes_RepeatBuffer(char* dest, Py_ssize_t len_dest,
const char* src, Py_ssize_t len_src)
{
if (len_dest == 0) {
Expand Down
6 changes: 3 additions & 3 deletions Objects/tupleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,8 @@ _PyTuple_Concat(PyObject *aa, PyObject *bb)
return (PyObject *)np;
}

static PyObject *
tuple_repeat(PyObject *self, Py_ssize_t n)
PyObject *
_PyTuple_Repeat(PyObject *self, Py_ssize_t n)
{
PyTupleObject *a = _PyTuple_CAST(self);
const Py_ssize_t input_size = Py_SIZE(a);
Expand Down Expand Up @@ -865,7 +865,7 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
static PySequenceMethods tuple_as_sequence = {
tuple_length, /* sq_length */
_PyTuple_Concat, /* sq_concat */
tuple_repeat, /* sq_repeat */
_PyTuple_Repeat, /* sq_repeat */
tuple_item, /* sq_item */
0, /* sq_slice */
0, /* sq_ass_item */
Expand Down
10 changes: 5 additions & 5 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "Python.h"
#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_bytes_methods.h" // _Py_bytes_lower()
#include "pycore_bytesobject.h" // _PyBytes_Repeat()
#include "pycore_bytesobject.h" // _PyBytes_RepeatBuffer()
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_codecs.h" // _PyCodec_Lookup()
#include "pycore_critical_section.h" // Py_*_CRITICAL_SECTION_SEQUENCE_FAST
Expand Down Expand Up @@ -12494,8 +12494,8 @@ unicode_rstrip_impl(PyObject *self, PyObject *chars)
}


static PyObject*
unicode_repeat(PyObject *str, Py_ssize_t len)
PyObject *
_PyUnicode_Repeat(PyObject *str, Py_ssize_t len)
{
PyObject *u;
Py_ssize_t nchars, n;
Expand Down Expand Up @@ -12540,7 +12540,7 @@ unicode_repeat(PyObject *str, Py_ssize_t len)
else {
Py_ssize_t char_size = PyUnicode_KIND(str);
char *to = (char *) PyUnicode_DATA(u);
_PyBytes_Repeat(to, nchars * char_size, PyUnicode_DATA(str),
_PyBytes_RepeatBuffer(to, nchars * char_size, PyUnicode_DATA(str),
PyUnicode_GET_LENGTH(str) * char_size);
}

Expand Down Expand Up @@ -13726,7 +13726,7 @@ static PyNumberMethods unicode_as_number = {
static PySequenceMethods unicode_as_sequence = {
unicode_length, /* sq_length */
PyUnicode_Concat, /* sq_concat */
unicode_repeat, /* sq_repeat */
_PyUnicode_Repeat, /* sq_repeat */
unicode_getitem, /* sq_item */
0, /* sq_slice */
0, /* sq_ass_item */
Expand Down
60 changes: 35 additions & 25 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -2122,54 +2122,64 @@ is_compactlong(PyObject *v)
_PyLong_IsCompact((PyLongObject *)v);
}

/* sequence * int helpers: bypass PyNumber_Multiply dispatch overhead
by calling sq_repeat directly with PyLong_AsSsize_t. */

static inline PyObject *
seq_int_multiply(PyObject *seq, PyObject *n,
ssizeargfunc repeat)
static PyObject *
str_int_multiply(PyObject *lhs, PyObject *rhs)
{
Py_ssize_t count = PyLong_AsSsize_t(n);
Py_ssize_t count = PyLong_AsSsize_t(rhs);
if (count == -1 && PyErr_Occurred()) {
return NULL;
}
return repeat(seq, count);
}

static PyObject *
str_int_multiply(PyObject *lhs, PyObject *rhs)
{
return seq_int_multiply(lhs, rhs, PyUnicode_Type.tp_as_sequence->sq_repeat);
return _PyUnicode_Repeat(lhs, count);
}

static PyObject *
int_str_multiply(PyObject *lhs, PyObject *rhs)
{
return seq_int_multiply(rhs, lhs, PyUnicode_Type.tp_as_sequence->sq_repeat);
Py_ssize_t count = PyLong_AsSsize_t(lhs);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is repeated a couple of times, we could use a macro to define the methods (similar to FLOAT_LONG_ACTION). But current form is also fine with me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. 17 insertions(+), 59 deletions(-).

if (count == -1 && PyErr_Occurred()) {
return NULL;
}
return _PyUnicode_Repeat(rhs, count);
}

static PyObject *
bytes_int_multiply(PyObject *lhs, PyObject *rhs)
{
return seq_int_multiply(lhs, rhs, PyBytes_Type.tp_as_sequence->sq_repeat);
Py_ssize_t count = PyLong_AsSsize_t(rhs);
if (count == -1 && PyErr_Occurred()) {
return NULL;
}
return _PyBytes_Repeat(lhs, count);
}

static PyObject *
int_bytes_multiply(PyObject *lhs, PyObject *rhs)
{
return seq_int_multiply(rhs, lhs, PyBytes_Type.tp_as_sequence->sq_repeat);
Py_ssize_t count = PyLong_AsSsize_t(lhs);
if (count == -1 && PyErr_Occurred()) {
return NULL;
}
return _PyBytes_Repeat(rhs, count);
}

static PyObject *
tuple_int_multiply(PyObject *lhs, PyObject *rhs)
{
return seq_int_multiply(lhs, rhs, PyTuple_Type.tp_as_sequence->sq_repeat);
Py_ssize_t count = PyLong_AsSsize_t(rhs);
if (count == -1 && PyErr_Occurred()) {
return NULL;
}
return _PyTuple_Repeat(lhs, count);
}

static PyObject *
int_tuple_multiply(PyObject *lhs, PyObject *rhs)
{
return seq_int_multiply(rhs, lhs, PyTuple_Type.tp_as_sequence->sq_repeat);
Py_ssize_t count = PyLong_AsSsize_t(lhs);
if (count == -1 && PyErr_Occurred()) {
return NULL;
}
return _PyTuple_Repeat(rhs, count);
}

static int
Expand Down Expand Up @@ -2290,8 +2300,8 @@ static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = {
to be a freshly allocated object. */
{NB_ADD, NULL, _PyTuple_Concat, &PyTuple_Type, 0, &PyTuple_Type, &PyTuple_Type},

/* str * int / int * str: call unicode_repeat directly.
unicode_repeat returns the original when n == 1. */
/* str * int / int * str: call _PyUnicode_Repeat directly.
_PyUnicode_Repeat returns the original when n == 1. */
{NB_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
{NB_MULTIPLY, NULL, int_str_multiply, &PyUnicode_Type, 0, &PyLong_Type, &PyUnicode_Type},
{NB_INPLACE_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
Expand All @@ -2302,15 +2312,15 @@ static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = {
{NB_ADD, NULL, _PyBytes_Concat, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},
{NB_INPLACE_ADD, NULL, _PyBytes_Concat, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},

/* bytes * int / int * bytes: call bytes_repeat directly.
bytes_repeat returns the original when n == 1. */
/* bytes * int / int * bytes: call _PyBytes_Repeat directly.
_PyBytes_Repeat returns the original when n == 1. */
{NB_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
{NB_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},
{NB_INPLACE_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
{NB_INPLACE_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},

/* tuple * int / int * tuple: call tuple_repeat directly.
tuple_repeat returns the original when n == 1. */
/* tuple * int / int * tuple: call _PyTuple_Repeat directly.
_PyTuple_Repeat returns the original when n == 1. */
{NB_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},
{NB_MULTIPLY, NULL, int_tuple_multiply, &PyTuple_Type, 0, &PyLong_Type, &PyTuple_Type},
{NB_INPLACE_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},
Expand Down
Loading