diff options
author | Mark Shannon <mark@hotpy.org> | 2022-03-25 12:57:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-25 12:57:50 (GMT) |
commit | d7163bb35d1ed46bde9affcd4eb267dfd0b703dd (patch) | |
tree | 50ced5b75c3e1579c4e23fd7c404ac33c53b7fc3 /Objects/frameobject.c | |
parent | b68431fadb3150134ac6ccbf501cdfeaf4c75678 (diff) | |
download | cpython-d7163bb35d1ed46bde9affcd4eb267dfd0b703dd.zip cpython-d7163bb35d1ed46bde9affcd4eb267dfd0b703dd.tar.gz cpython-d7163bb35d1ed46bde9affcd4eb267dfd0b703dd.tar.bz2 |
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.
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 5c6a8bc..13dfbf6 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -840,6 +840,7 @@ _PyFrame_New_NoTrack(PyCodeObject *code) f->f_trace = NULL; f->f_trace_lines = 1; f->f_trace_opcodes = 0; + f->f_fast_as_locals = 0; f->f_lineno = 0; return f; } @@ -1004,7 +1005,11 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f) PyErr_BadInternalCall(); return -1; } - return _PyFrame_FastToLocalsWithError(f->f_frame); + int err = _PyFrame_FastToLocalsWithError(f->f_frame); + if (err == 0) { + f->f_fast_as_locals = 1; + } + return err; } void @@ -1028,8 +1033,9 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) PyObject *error_type, *error_value, *error_traceback; PyCodeObject *co; locals = frame->f_locals; - if (locals == NULL) + if (locals == NULL) { return; + } fast = _PyFrame_GetLocalsArray(frame); co = frame->f_code; @@ -1088,13 +1094,12 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) void PyFrame_LocalsToFast(PyFrameObject *f, int clear) { - if (f == NULL || _PyFrame_GetState(f) == FRAME_CLEARED) { - return; + if (f && f->f_fast_as_locals && _PyFrame_GetState(f) != FRAME_CLEARED) { + _PyFrame_LocalsToFast(f->f_frame, clear); + f->f_fast_as_locals = 0; } - _PyFrame_LocalsToFast(f->f_frame, clear); } - PyCodeObject * PyFrame_GetCode(PyFrameObject *frame) { @@ -1119,6 +1124,12 @@ PyFrame_GetBack(PyFrameObject *frame) } PyObject* +PyFrame_GetLocals(PyFrameObject *frame) +{ + return frame_getlocals(frame, NULL); +} + +PyObject* _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) { PyObject *builtins = PyDict_GetItemWithError(globals, &_Py_ID(__builtins__)); |