summaryrefslogtreecommitdiffstats
path: root/Objects/listobject.c
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2021-10-21 13:12:20 (GMT)
committerGitHub <noreply@github.com>2021-10-21 13:12:20 (GMT)
commit9942f42a93ccda047fd3558c47b822e99afe10c0 (patch)
tree5a28ecf799a90b9225530c12acd7c38c1935f156 /Objects/listobject.c
parent5a14f71fe869d4a62dcdeb9a8fbbb5884c75060c (diff)
downloadcpython-9942f42a93ccda047fd3558c47b822e99afe10c0.zip
cpython-9942f42a93ccda047fd3558c47b822e99afe10c0.tar.gz
cpython-9942f42a93ccda047fd3558c47b822e99afe10c0.tar.bz2
bpo-45522: Allow to disable freelists on build time (GH-29056)
Freelists for object structs can now be disabled. A new ``configure`` option ``--without-freelists`` can be used to disable all freelists except empty tuple singleton. Internal Py*_MAXFREELIST macros can now be defined as 0 without causing compiler warnings and segfaults. Signed-off-by: Christian Heimes <christian@python.org>
Diffstat (limited to 'Objects/listobject.c')
-rw-r--r--Objects/listobject.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c
index ed53241..e0cae87 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -19,13 +19,14 @@ class list "PyListObject *" "&PyList_Type"
#include "clinic/listobject.c.h"
-
+#if PyList_MAXFREELIST > 0
static struct _Py_list_state *
get_list_state(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return &interp->list;
}
+#endif
/* Ensure ob_item has room for at least newsize elements, and set
@@ -108,19 +109,21 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
void
_PyList_ClearFreeList(PyInterpreterState *interp)
{
+#if PyList_MAXFREELIST > 0
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);
}
+#endif
}
void
_PyList_Fini(PyInterpreterState *interp)
{
_PyList_ClearFreeList(interp);
-#ifdef Py_DEBUG
+#if defined(Py_DEBUG) && PyList_MAXFREELIST > 0
struct _Py_list_state *state = &interp->list;
state->numfree = -1;
#endif
@@ -130,32 +133,38 @@ _PyList_Fini(PyInterpreterState *interp)
void
_PyList_DebugMallocStats(FILE *out)
{
+#if PyList_MAXFREELIST > 0
struct _Py_list_state *state = get_list_state();
_PyDebugAllocatorStats(out,
"free PyListObject",
state->numfree, sizeof(PyListObject));
+#endif
}
PyObject *
PyList_New(Py_ssize_t size)
{
+ PyListObject *op;
+
if (size < 0) {
PyErr_BadInternalCall();
return NULL;
}
+#if PyList_MAXFREELIST > 0
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) {
+ if (PyList_MAXFREELIST && state->numfree) {
state->numfree--;
op = state->free_list[state->numfree];
_Py_NewReference((PyObject *)op);
}
- else {
+ else
+#endif
+ {
op = PyObject_GC_New(PyListObject, &PyList_Type);
if (op == NULL) {
return NULL;
@@ -344,6 +353,7 @@ list_dealloc(PyListObject *op)
}
PyMem_Free(op->ob_item);
}
+#if PyList_MAXFREELIST > 0
struct _Py_list_state *state = get_list_state();
#ifdef Py_DEBUG
// list_dealloc() must not be called after _PyList_Fini()
@@ -352,7 +362,9 @@ list_dealloc(PyListObject *op)
if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) {
state->free_list[state->numfree++] = op;
}
- else {
+ else
+#endif
+ {
Py_TYPE(op)->tp_free((PyObject *)op);
}
Py_TRASHCAN_END