summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects/listobject.c
diff options
context:
space:
mode:
authorshadchin <[email protected]>2022-04-18 12:39:32 +0300
committershadchin <[email protected]>2022-04-18 12:39:32 +0300
commitd4be68e361f4258cf0848fc70018dfe37a2acc24 (patch)
tree153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Objects/listobject.c
parent260c02f5ccf242d9d9b8a873afaf6588c00237d6 (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.c125
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 */