From 80a6c0c2b3708bd7a994bfb64b5f3f80fe5fe709 Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Tue, 19 Feb 2019 13:03:26 +0500 Subject: [PATCH] bpo-36030: Add an internal _PyTuple_NewUnsafe() function --- Include/internal/pycore_tupleobject.h | 1 + Objects/call.c | 8 +++---- Objects/listobject.c | 3 ++- Objects/tupleobject.c | 32 ++++++++++++++++++--------- Python/ceval.c | 2 +- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Include/internal/pycore_tupleobject.h b/Include/internal/pycore_tupleobject.h index fdd741467665c9c..f35c54e38eecb68 100644 --- a/Include/internal/pycore_tupleobject.h +++ b/Include/internal/pycore_tupleobject.h @@ -11,6 +11,7 @@ extern "C" { #include "tupleobject.h" #define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item) +PyAPI_FUNC(PyObject *) _PyTuple_NewUnsafe(Py_ssize_t size); #ifdef __cplusplus } diff --git a/Objects/call.c b/Objects/call.c index be8e90d03d66116..c82fa0f60dc324c 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -339,7 +339,7 @@ _PyFunction_FastCallDict(PyObject *func, PyObject *const *args, Py_ssize_t nargs /* bpo-29318, bpo-27840: Caller and callee functions must not share the dictionary: kwargs must be copied. */ - kwtuple = PyTuple_New(2 * nk); + kwtuple = _PyTuple_NewUnsafe(2 * nk); if (kwtuple == NULL) { return NULL; } @@ -1279,7 +1279,7 @@ _PyStack_AsTuple(PyObject *const *stack, Py_ssize_t nargs) PyObject *args; Py_ssize_t i; - args = PyTuple_New(nargs); + args = _PyTuple_NewUnsafe(nargs); if (args == NULL) { return NULL; } @@ -1304,7 +1304,7 @@ _PyStack_AsTupleSlice(PyObject *const *stack, Py_ssize_t nargs, assert(end <= nargs); assert(start <= end); - args = PyTuple_New(end - start); + args = _PyTuple_NewUnsafe(end - start); if (args == NULL) { return NULL; } @@ -1375,7 +1375,7 @@ _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, return -1; } - kwnames = PyTuple_New(nkwargs); + kwnames = _PyTuple_NewUnsafe(nkwargs); if (kwnames == NULL) { PyMem_Free(stack); return -1; diff --git a/Objects/listobject.c b/Objects/listobject.c index e11a3fdd1358de9..82fdcdd9895c0f7 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -4,6 +4,7 @@ #include "pycore_object.h" #include "pycore_pystate.h" #include "pycore_accu.h" +#include "pycore_tupleobject.h" #ifdef STDC_HEADERS #include @@ -2502,7 +2503,7 @@ PyList_AsTuple(PyObject *v) return NULL; } n = Py_SIZE(v); - w = PyTuple_New(n); + w = _PyTuple_NewUnsafe(n); if (w == NULL) return NULL; p = ((PyTupleObject *)w)->ob_item; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 9cf3f3dd66eeeb3..806d801257137be 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -76,11 +76,10 @@ _PyTuple_DebugMallocStats(FILE *out) #endif } -PyObject * -PyTuple_New(Py_ssize_t size) +static PyObject * +tuple_new_internal(Py_ssize_t size, int initialize) { PyTupleObject *op; - Py_ssize_t i; if (size < 0) { PyErr_BadInternalCall(); return NULL; @@ -119,8 +118,9 @@ PyTuple_New(Py_ssize_t size) if (op == NULL) return NULL; } - for (i=0; i < size; i++) - op->ob_item[i] = NULL; + if (initialize) { + memset(op->ob_item, 0, sizeof(PyObject *) * size); + } #if PyTuple_MAXSAVESIZE > 0 if (size == 0) { free_list[0] = op; @@ -135,6 +135,18 @@ PyTuple_New(Py_ssize_t size) return (PyObject *) op; } +PyObject * +_PyTuple_NewUnsafe(Py_ssize_t size) +{ + return tuple_new_internal(size, 0); +} + +PyObject * +PyTuple_New(Py_ssize_t size) +{ + return tuple_new_internal(size, 1); +} + Py_ssize_t PyTuple_Size(PyObject *op) { @@ -216,7 +228,7 @@ PyTuple_Pack(Py_ssize_t n, ...) va_list vargs; va_start(vargs, n); - result = PyTuple_New(n); + result = _PyTuple_NewUnsafe(n); if (result == NULL) { va_end(vargs); return NULL; @@ -438,7 +450,7 @@ tupleslice(PyTupleObject *a, Py_ssize_t ilow, return (PyObject *)a; } len = ihigh - ilow; - np = (PyTupleObject *)PyTuple_New(len); + np = (PyTupleObject *)_PyTuple_NewUnsafe(len); if (np == NULL) return NULL; src = a->ob_item + ilow; @@ -486,7 +498,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb) if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) return PyErr_NoMemory(); size = Py_SIZE(a) + Py_SIZE(b); - np = (PyTupleObject *) PyTuple_New(size); + np = (PyTupleObject *) _PyTuple_NewUnsafe(size); if (np == NULL) { return NULL; } @@ -530,7 +542,7 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n) if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) return PyErr_NoMemory(); size = Py_SIZE(a) * n; - np = (PyTupleObject *) PyTuple_New(size); + np = (PyTupleObject *) _PyTuple_NewUnsafe(size); if (np == NULL) return NULL; p = np->ob_item; @@ -773,7 +785,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) return (PyObject *)self; } else { - result = PyTuple_New(slicelength); + result = _PyTuple_NewUnsafe(slicelength); if (!result) return NULL; src = self->ob_item; diff --git a/Python/ceval.c b/Python/ceval.c index 3db7c7c92a0e04c..5e3d91772081578 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2407,7 +2407,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } case TARGET(BUILD_TUPLE): { - PyObject *tup = PyTuple_New(oparg); + PyObject *tup = _PyTuple_NewUnsafe(oparg); if (tup == NULL) goto error; while (--oparg >= 0) {