summaryrefslogtreecommitdiffstats
path: root/Objects/frameobject.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/frameobject.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/frameobject.c')
-rw-r--r--Objects/frameobject.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 5271790..ffe19b3 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -19,12 +19,14 @@ static PyMemberDef frame_memberlist[] = {
{NULL} /* Sentinel */
};
+#if PyFrame_MAXFREELIST > 0
static struct _Py_frame_state *
get_frame_state(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return &interp->frame;
}
+#endif
static PyObject *
@@ -607,9 +609,6 @@ static PyGetSetDef frame_getsetlist[] = {
f_back next item on free list, or NULL
*/
-/* max value for numfree */
-#define PyFrame_MAXFREELIST 200
-
static void _Py_HOT_FUNCTION
frame_dealloc(PyFrameObject *f)
{
@@ -638,6 +637,7 @@ frame_dealloc(PyFrameObject *f)
}
Py_CLEAR(f->f_back);
Py_CLEAR(f->f_trace);
+#if PyFrame_MAXFREELIST > 0
struct _Py_frame_state *state = get_frame_state();
#ifdef Py_DEBUG
// frame_dealloc() must not be called after _PyFrame_Fini()
@@ -648,7 +648,9 @@ frame_dealloc(PyFrameObject *f)
f->f_back = state->free_list;
state->free_list = f;
}
- else {
+ else
+#endif
+ {
PyObject_GC_Del(f);
}
@@ -801,8 +803,10 @@ static inline PyFrameObject*
frame_alloc(InterpreterFrame *frame, int owns)
{
PyFrameObject *f;
+#if PyFrame_MAXFREELIST > 0
struct _Py_frame_state *state = get_frame_state();
if (state->free_list == NULL)
+#endif
{
f = PyObject_GC_New(PyFrameObject, &PyFrame_Type);
if (f == NULL) {
@@ -816,7 +820,9 @@ frame_alloc(InterpreterFrame *frame, int owns)
return NULL;
}
}
- else {
+#if PyFrame_MAXFREELIST > 0
+ else
+ {
#ifdef Py_DEBUG
// frame_alloc() must not be called after _PyFrame_Fini()
assert(state->numfree != -1);
@@ -827,6 +833,7 @@ frame_alloc(InterpreterFrame *frame, int owns)
state->free_list = state->free_list->f_back;
_Py_NewReference((PyObject *)f);
}
+#endif
f->f_frame = frame;
f->f_own_locals_memory = owns;
return f;
@@ -1069,6 +1076,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
void
_PyFrame_ClearFreeList(PyInterpreterState *interp)
{
+#if PyFrame_MAXFREELIST > 0
struct _Py_frame_state *state = &interp->frame;
while (state->free_list != NULL) {
PyFrameObject *f = state->free_list;
@@ -1077,13 +1085,14 @@ _PyFrame_ClearFreeList(PyInterpreterState *interp)
--state->numfree;
}
assert(state->numfree == 0);
+#endif
}
void
_PyFrame_Fini(PyInterpreterState *interp)
{
_PyFrame_ClearFreeList(interp);
-#ifdef Py_DEBUG
+#if defined(Py_DEBUG) && PyFrame_MAXFREELIST > 0
struct _Py_frame_state *state = &interp->frame;
state->numfree = -1;
#endif
@@ -1093,10 +1102,12 @@ _PyFrame_Fini(PyInterpreterState *interp)
void
_PyFrame_DebugMallocStats(FILE *out)
{
+#if PyFrame_MAXFREELIST > 0
struct _Py_frame_state *state = get_frame_state();
_PyDebugAllocatorStats(out,
"free PyFrameObject",
state->numfree, sizeof(PyFrameObject));
+#endif
}