From d7163bb35d1ed46bde9affcd4eb267dfd0b703dd Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Mar 2022 12:57:50 +0000 Subject: bpo-42197: Don't create `f_locals` dictionary unless we actually need it. (GH-32055) * `PyFrame_FastToLocalsWithError` and `PyFrame_LocalsToFast` are no longer called during profile and tracing. (Contributed by Fabio Zadrozny) * Make accesses to a frame's `f_locals` safe from C code, not relying on calls to `PyFrame_FastToLocals` or `PyFrame_LocalsToFast`. * Document new `PyFrame_GetLocals` C-API function. --- Python/sysmodule.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'Python/sysmodule.c') diff --git a/Python/sysmodule.c b/Python/sysmodule.c index c89f81f689..6322af5f5c 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -924,15 +924,19 @@ static PyObject * call_trampoline(PyThreadState *tstate, PyObject* callback, PyFrameObject *frame, int what, PyObject *arg) { - if (PyFrame_FastToLocalsWithError(frame) < 0) { - return NULL; - } PyObject *stack[3]; stack[0] = (PyObject *)frame; stack[1] = whatstrings[what]; stack[2] = (arg != NULL) ? arg : Py_None; + /* Discard any previous modifications the frame's fast locals */ + if (frame->f_fast_as_locals) { + if (PyFrame_FastToLocalsWithError(frame) < 0) { + return NULL; + } + } + /* call the Python-level function */ PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3); -- cgit v1.2.1