mirror of
https://github.com/python/cpython.git
synced 2025-11-25 21:11:09 +00:00
bpo-44590: Lazily allocate frame objects (GH-27077)
* Convert "specials" array to InterpreterFrame struct, adding f_lasti, f_state and other non-debug FrameObject fields to it. * Refactor, calls pushing the call to the interpreter upward toward _PyEval_Vector. * Compute f_back when on thread stack, only filling in value when frame object outlives stack invocation. * Move ownership of InterpreterFrame in generator from frame object to generator object. * Do not create frame objects for Python calls. * Do not create frame objects for generators.
This commit is contained in:
parent
0363a4014d
commit
ae0a2b7562
27 changed files with 1037 additions and 619 deletions
|
|
@ -240,7 +240,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
|
|||
assert(tb_next == NULL || PyTraceBack_Check(tb_next));
|
||||
assert(frame != NULL);
|
||||
|
||||
return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti*2,
|
||||
return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_frame->f_lasti*2,
|
||||
PyFrame_GetLineNumber(frame));
|
||||
}
|
||||
|
||||
|
|
@ -521,7 +521,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent, i
|
|||
* When displaying a new traceback line, for certain syntactical constructs
|
||||
* (e.g a subscript, an arithmetic operation) we try to create a representation
|
||||
* that separates the primary source of error from the rest.
|
||||
*
|
||||
*
|
||||
* Example specialization of BinOp nodes:
|
||||
* Traceback (most recent call last):
|
||||
* File "/home/isidentical/cpython/cpython/t.py", line 10, in <module>
|
||||
|
|
@ -710,7 +710,7 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen
|
|||
}
|
||||
|
||||
int code_offset = tb->tb_lasti;
|
||||
PyCodeObject* code = _PyFrame_GetCode(frame);
|
||||
PyCodeObject* code = frame->f_frame->f_code;
|
||||
|
||||
int start_line;
|
||||
int end_line;
|
||||
|
|
@ -1024,9 +1024,9 @@ _Py_DumpASCII(int fd, PyObject *text)
|
|||
This function is signal safe. */
|
||||
|
||||
static void
|
||||
dump_frame(int fd, PyFrameObject *frame)
|
||||
dump_frame(int fd, InterpreterFrame *frame)
|
||||
{
|
||||
PyCodeObject *code = PyFrame_GetCode(frame);
|
||||
PyCodeObject *code = frame->f_code;
|
||||
PUTS(fd, " File ");
|
||||
if (code->co_filename != NULL
|
||||
&& PyUnicode_Check(code->co_filename))
|
||||
|
|
@ -1038,7 +1038,7 @@ dump_frame(int fd, PyFrameObject *frame)
|
|||
PUTS(fd, "???");
|
||||
}
|
||||
|
||||
int lineno = PyFrame_GetLineNumber(frame);
|
||||
int lineno = PyCode_Addr2Line(code, frame->f_lasti*2);
|
||||
PUTS(fd, ", line ");
|
||||
if (lineno >= 0) {
|
||||
_Py_DumpDecimal(fd, (size_t)lineno);
|
||||
|
|
@ -1057,20 +1057,19 @@ dump_frame(int fd, PyFrameObject *frame)
|
|||
}
|
||||
|
||||
PUTS(fd, "\n");
|
||||
Py_DECREF(code);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_traceback(int fd, PyThreadState *tstate, int write_header)
|
||||
{
|
||||
PyFrameObject *frame;
|
||||
InterpreterFrame *frame;
|
||||
unsigned int depth;
|
||||
|
||||
if (write_header) {
|
||||
PUTS(fd, "Stack (most recent call first):\n");
|
||||
}
|
||||
|
||||
frame = PyThreadState_GetFrame(tstate);
|
||||
frame = tstate->frame;
|
||||
if (frame == NULL) {
|
||||
PUTS(fd, "<no Python frame>\n");
|
||||
return;
|
||||
|
|
@ -1079,22 +1078,14 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header)
|
|||
depth = 0;
|
||||
while (1) {
|
||||
if (MAX_FRAME_DEPTH <= depth) {
|
||||
Py_DECREF(frame);
|
||||
PUTS(fd, " ...\n");
|
||||
break;
|
||||
}
|
||||
if (!PyFrame_Check(frame)) {
|
||||
Py_DECREF(frame);
|
||||
break;
|
||||
}
|
||||
dump_frame(fd, frame);
|
||||
PyFrameObject *back = PyFrame_GetBack(frame);
|
||||
Py_DECREF(frame);
|
||||
|
||||
if (back == NULL) {
|
||||
frame = frame->previous;
|
||||
if (frame == NULL) {
|
||||
break;
|
||||
}
|
||||
frame = back;
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue