diff options
author | Christian Heimes <christian@python.org> | 2021-10-21 13:12:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-21 13:12:20 (GMT) |
commit | 9942f42a93ccda047fd3558c47b822e99afe10c0 (patch) | |
tree | 5a28ecf799a90b9225530c12acd7c38c1935f156 /Objects/frameobject.c | |
parent | 5a14f71fe869d4a62dcdeb9a8fbbb5884c75060c (diff) | |
download | cpython-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.c | 23 |
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 } |