diff options
author | Mark Shannon <mark@hotpy.org> | 2021-08-25 12:44:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-25 12:44:20 (GMT) |
commit | f9242d50b18572ef0d584a1c815ed08d1a38e4f4 (patch) | |
tree | 0c7c137c701b1dd69f89227dee85aaee95ff5dfb /Python/frame.c | |
parent | 214c2e5d916d3ce5e7b1db800210b93001850bbb (diff) | |
download | cpython-f9242d50b18572ef0d584a1c815ed08d1a38e4f4.zip cpython-f9242d50b18572ef0d584a1c815ed08d1a38e4f4.tar.gz cpython-f9242d50b18572ef0d584a1c815ed08d1a38e4f4.tar.bz2 |
bpo-44990: Change layout of evaluation frames. "Layout B" (GH-27933)
Places the locals between the specials and stack. This is the more "natural" layout for a C struct, makes the code simpler and gives a slight speedup (~1%)
Diffstat (limited to 'Python/frame.c')
-rw-r--r-- | Python/frame.c | 32 |
1 files changed, 12 insertions, 20 deletions
diff --git a/Python/frame.c b/Python/frame.c index ae42843..3d2415f 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -14,13 +14,11 @@ _PyFrame_Traverse(InterpreterFrame *frame, visitproc visit, void *arg) Py_VISIT(frame->f_code); /* locals */ PyObject **locals = _PyFrame_GetLocalsArray(frame); - for (int i = 0; i < frame->nlocalsplus; i++) { + int i = 0; + /* locals and stack */ + for (; i <frame->stacktop; i++) { Py_VISIT(locals[i]); } - /* stack */ - for (int i = 0; i <frame->stackdepth; i++) { - Py_VISIT(frame->stack[i]); - } return 0; } @@ -47,17 +45,15 @@ _PyFrame_MakeAndSetFrameObject(InterpreterFrame *frame) static InterpreterFrame * copy_frame_to_heap(InterpreterFrame *frame) { - - Py_ssize_t size = ((char*)&frame->stack[frame->stackdepth]) - (char *)_PyFrame_GetLocalsArray(frame); - PyObject **copy = PyMem_Malloc(size); + assert(frame->stacktop >= frame->f_code->co_nlocalsplus); + Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame; + InterpreterFrame *copy = PyMem_Malloc(size); if (copy == NULL) { PyErr_NoMemory(); return NULL; } - PyObject **locals = _PyFrame_GetLocalsArray(frame); - memcpy(copy, locals, size); - InterpreterFrame *res = (InterpreterFrame *)(copy + frame->nlocalsplus); - return res; + memcpy(copy, frame, size); + return copy; } static inline void @@ -103,7 +99,6 @@ take_ownership(PyFrameObject *f, InterpreterFrame *frame) int _PyFrame_Clear(InterpreterFrame * frame, int take) { - PyObject **localsarray = ((PyObject **)frame)-frame->nlocalsplus; if (frame->frame_obj) { PyFrameObject *f = frame->frame_obj; frame->frame_obj = NULL; @@ -120,16 +115,13 @@ _PyFrame_Clear(InterpreterFrame * frame, int take) } Py_DECREF(f); } - for (int i = 0; i < frame->nlocalsplus; i++) { - Py_XDECREF(localsarray[i]); - } - assert(frame->stackdepth >= 0); - for (int i = 0; i < frame->stackdepth; i++) { - Py_DECREF(frame->stack[i]); + assert(_PyFrame_GetStackPointer(frame) >= _PyFrame_Stackbase(frame)); + for (int i = 0; i < frame->stacktop; i++) { + Py_XDECREF(frame->localsplus[i]); } clear_specials(frame); if (take) { - PyMem_Free(_PyFrame_GetLocalsArray(frame)); + PyMem_Free(frame); } return 0; } |