diff options
| author | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
|---|---|---|
| committer | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
| commit | d4be68e361f4258cf0848fc70018dfe37a2acc24 (patch) | |
| tree | 153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Objects/listobject.c | |
| parent | 260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff) | |
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Objects/listobject.c')
| -rw-r--r-- | contrib/tools/python3/src/Objects/listobject.c | 125 |
1 files changed, 69 insertions, 56 deletions
diff --git a/contrib/tools/python3/src/Objects/listobject.c b/contrib/tools/python3/src/Objects/listobject.c index 1e868b43c09..533ee7436d3 100644 --- a/contrib/tools/python3/src/Objects/listobject.c +++ b/contrib/tools/python3/src/Objects/listobject.c @@ -1,10 +1,10 @@ /* List object implementation */ #include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_object.h" -#include "pycore_tupleobject.h" -#include "pycore_accu.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_interp.h" // PyInterpreterState.list +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_tuple.h" // _PyTuple_FromArray() #ifdef STDC_HEADERS #include <stddef.h> @@ -19,6 +19,15 @@ class list "PyListObject *" "&PyList_Type" #include "clinic/listobject.c.h" + +static struct _Py_list_state * +get_list_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->list; +} + + /* Ensure ob_item has room for at least newsize elements, and set * ob_size to newsize. If newsize > ob_size on entry, the content * of the new slots at exit is undefined heap trash; it's the caller's @@ -60,7 +69,7 @@ list_resize(PyListObject *self, Py_ssize_t newsize) * is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t. */ new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3; - /* Do not overallocate if the new size is closer to overalocated size + /* Do not overallocate if the new size is closer to overallocated size * than to the old size. */ if (newsize - Py_SIZE(self) > (Py_ssize_t)(new_allocated - newsize)) @@ -96,59 +105,65 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) return 0; } -/* Empty list reuse scheme to save calls to malloc and free */ -#ifndef PyList_MAXFREELIST -# define PyList_MAXFREELIST 80 -#endif - -static PyListObject *free_list[PyList_MAXFREELIST]; -static int numfree = 0; - void -_PyList_ClearFreeList(void) +_PyList_ClearFreeList(PyInterpreterState *interp) { - while (numfree) { - PyListObject *op = free_list[--numfree]; + struct _Py_list_state *state = &interp->list; + while (state->numfree) { + PyListObject *op = state->free_list[--state->numfree]; assert(PyList_CheckExact(op)); PyObject_GC_Del(op); } } void -_PyList_Fini(void) +_PyList_Fini(PyInterpreterState *interp) { - _PyList_ClearFreeList(); + _PyList_ClearFreeList(interp); +#ifdef Py_DEBUG + struct _Py_list_state *state = &interp->list; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ void _PyList_DebugMallocStats(FILE *out) { + struct _Py_list_state *state = get_list_state(); _PyDebugAllocatorStats(out, "free PyListObject", - numfree, sizeof(PyListObject)); + state->numfree, sizeof(PyListObject)); } PyObject * PyList_New(Py_ssize_t size) { - PyListObject *op; - if (size < 0) { PyErr_BadInternalCall(); return NULL; } - if (numfree) { - numfree--; - op = free_list[numfree]; + + struct _Py_list_state *state = get_list_state(); + PyListObject *op; +#ifdef Py_DEBUG + // PyList_New() must not be called after _PyList_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree) { + state->numfree--; + op = state->free_list[state->numfree]; _Py_NewReference((PyObject *)op); - } else { + } + else { op = PyObject_GC_New(PyListObject, &PyList_Type); - if (op == NULL) + if (op == NULL) { return NULL; + } } - if (size <= 0) + if (size <= 0) { op->ob_item = NULL; + } else { op->ob_item = (PyObject **) PyMem_Calloc(size, sizeof(PyObject *)); if (op->ob_item == NULL) { @@ -256,12 +271,8 @@ ins1(PyListObject *self, Py_ssize_t where, PyObject *v) PyErr_BadInternalCall(); return -1; } - if (n == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to list"); - return -1; - } + assert((size_t)n + 1 < PY_SSIZE_T_MAX); if (list_resize(self, n+1) < 0) return -1; @@ -296,12 +307,7 @@ app1(PyListObject *self, PyObject *v) Py_ssize_t n = PyList_GET_SIZE(self); assert (v != NULL); - if (n == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to list"); - return -1; - } - + assert((size_t)n + 1 < PY_SSIZE_T_MAX); if (list_resize(self, n+1) < 0) return -1; @@ -336,12 +342,19 @@ list_dealloc(PyListObject *op) while (--i >= 0) { Py_XDECREF(op->ob_item[i]); } - PyMem_FREE(op->ob_item); + PyMem_Free(op->ob_item); } - if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) - free_list[numfree++] = op; - else + struct _Py_list_state *state = get_list_state(); +#ifdef Py_DEBUG + // list_dealloc() must not be called after _PyList_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) { + state->free_list[state->numfree++] = op; + } + else { Py_TYPE(op)->tp_free((PyObject *)op); + } Py_TRASHCAN_END } @@ -501,8 +514,7 @@ list_concat(PyListObject *a, PyObject *bb) return NULL; } #define b ((PyListObject *)bb) - if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) - return PyErr_NoMemory(); + assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX); size = Py_SIZE(a) + Py_SIZE(b); if (size == 0) { return PyList_New(0); @@ -587,7 +599,7 @@ _list_clear(PyListObject *a) while (--i >= 0) { Py_XDECREF(item[i]); } - PyMem_FREE(item); + PyMem_Free(item); } /* Never fails; the return value can be ignored. Note that there is no guarantee that the list is actually empty @@ -663,7 +675,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) /* If norig == 0, item might be NULL, in which case we may not memcpy from it. */ if (s) { if (s > sizeof(recycle_on_stack)) { - recycle = (PyObject **)PyMem_MALLOC(s); + recycle = (PyObject **)PyMem_Malloc(s); if (recycle == NULL) { PyErr_NoMemory(); goto Error; @@ -701,7 +713,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) result = 0; Error: if (recycle != recycle_on_stack) - PyMem_FREE(recycle); + PyMem_Free(recycle); Py_XDECREF(v_as_SF); return result; #undef b @@ -2225,7 +2237,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) /* Leverage stack space we allocated but won't otherwise use */ keys = &ms.temparray[saved_ob_size+1]; else { - keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size); + keys = PyMem_Malloc(sizeof(PyObject *) * saved_ob_size); if (keys == NULL) { PyErr_NoMemory(); goto keyfunc_fail; @@ -2238,7 +2250,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) for (i=i-1 ; i>=0 ; i--) Py_DECREF(keys[i]); if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) - PyMem_FREE(keys); + PyMem_Free(keys); goto keyfunc_fail; } } @@ -2409,7 +2421,7 @@ fail: for (i = 0; i < saved_ob_size; i++) Py_DECREF(keys[i]); if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) - PyMem_FREE(keys); + PyMem_Free(keys); } if (self->allocated != -1 && result != NULL) { @@ -2437,7 +2449,7 @@ keyfunc_fail: while (--i >= 0) { Py_XDECREF(final_ob_item[i]); } - PyMem_FREE(final_ob_item); + PyMem_Free(final_ob_item); } Py_XINCREF(result); return result; @@ -2903,7 +2915,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) } garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyMem_Malloc(slicelength*sizeof(PyObject*)); if (!garbage) { PyErr_NoMemory(); return -1; @@ -2944,7 +2956,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) for (i = 0; i < slicelength; i++) { Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyMem_Free(garbage); return res; } @@ -2985,7 +2997,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) } garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyMem_Malloc(slicelength*sizeof(PyObject*)); if (!garbage) { Py_DECREF(seq); PyErr_NoMemory(); @@ -3006,7 +3018,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyMem_Free(garbage); Py_DECREF(seq); return 0; @@ -3047,7 +3059,8 @@ PyTypeObject PyList_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS | + _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE, /* tp_flags */ list___init____doc__, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ (inquiry)_list_clear, /* tp_clear */ |
