diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2022-03-21 11:11:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-21 11:11:17 (GMT) |
commit | 2bde6827ea4f136297b2d882480b981ff26262b6 (patch) | |
tree | 8ad0569c15e0f516eaf8547581c6de2ca702b349 /Python/ceval.c | |
parent | 08eb754d840696914928355014c2d424131f8835 (diff) | |
download | cpython-2bde6827ea4f136297b2d882480b981ff26262b6.zip cpython-2bde6827ea4f136297b2d882480b981ff26262b6.tar.gz cpython-2bde6827ea4f136297b2d882480b981ff26262b6.tar.bz2 |
bpo-46841: Quicken code in-place (GH-31888)
* Moves the bytecode to the end of the corresponding PyCodeObject, and quickens it in-place.
* Removes the almost-always-unused co_varnames, co_freevars, and co_cellvars member caches
* _PyOpcode_Deopt is a new mapping from all opcodes to their un-quickened forms.
* _PyOpcode_InlineCacheEntries is renamed to _PyOpcode_Caches
* _Py_IncrementCountAndMaybeQuicken is renamed to _PyCode_Warmup
* _Py_Quicken is renamed to _PyCode_Quicken
* _co_quickened is renamed to _co_code_adaptive (and is now a read-only memoryview).
* Do not emit unused nonzero opargs anymore in the compiler.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 39 |
1 files changed, 12 insertions, 27 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 6f449e3..7c6bfd4 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1327,9 +1327,8 @@ eval_frame_handle_pending(PyThreadState *tstate) /* Get opcode and oparg from original instructions, not quickened form. */ #define TRACING_NEXTOPARG() do { \ - _Py_CODEUNIT word = ((_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code))[INSTR_OFFSET()]; \ - opcode = _Py_OPCODE(word); \ - oparg = _Py_OPARG(word); \ + NEXTOPARG(); \ + opcode = _PyOpcode_Deopt[opcode]; \ } while (0) /* OpCode prediction macros @@ -1650,9 +1649,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyCodeObject *co = frame->f_code; \ names = co->co_names; \ consts = co->co_consts; \ - first_instr = co->co_firstinstr; \ + first_instr = _PyCode_CODE(co); \ } \ assert(frame->f_lasti >= -1); \ + /* Jump back to the last instruction executed... */ \ next_instr = first_instr + frame->f_lasti + 1; \ stack_pointer = _PyFrame_GetStackPointer(frame); \ /* Set stackdepth to -1. \ @@ -1722,16 +1722,7 @@ handle_eval_breaker: } TARGET(RESUME) { - int err = _Py_IncrementCountAndMaybeQuicken(frame->f_code); - if (err) { - if (err < 0) { - goto error; - } - /* Update first_instr and next_instr to point to newly quickened code */ - int nexti = INSTR_OFFSET(); - first_instr = frame->f_code->co_firstinstr; - next_instr = first_instr + nexti; - } + _PyCode_Warmup(frame->f_code); JUMP_TO_INSTRUCTION(RESUME_QUICK); } @@ -4067,16 +4058,7 @@ handle_eval_breaker: TARGET(JUMP_ABSOLUTE) { PREDICTED(JUMP_ABSOLUTE); - int err = _Py_IncrementCountAndMaybeQuicken(frame->f_code); - if (err) { - if (err < 0) { - goto error; - } - /* Update first_instr and next_instr to point to newly quickened code */ - int nexti = INSTR_OFFSET(); - first_instr = frame->f_code->co_firstinstr; - next_instr = first_instr + nexti; - } + _PyCode_Warmup(frame->f_code); JUMP_TO_INSTRUCTION(JUMP_ABSOLUTE_QUICK); } @@ -5425,6 +5407,7 @@ handle_eval_breaker: } TARGET(EXTENDED_ARG) { + assert(oparg); int oldoparg = oparg; NEXTOPARG(); oparg |= oldoparg << 8; @@ -6739,8 +6722,8 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, */ initialize_trace_info(&tstate->trace_info, frame); int entry_point = 0; - _Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code); - while (_Py_OPCODE(code[entry_point]) != RESUME) { + _Py_CODEUNIT *code = _PyCode_CODE(frame->f_code); + while (_PyOpcode_Deopt[_Py_OPCODE(code[entry_point])] != RESUME) { entry_point++; } int lastline; @@ -6759,7 +6742,9 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, /* Trace backward edges (except in 'yield from') or if line number has changed */ int trace = line != lastline || (frame->f_lasti < instr_prev && - _Py_OPCODE(frame->f_code->co_firstinstr[frame->f_lasti]) != SEND); + // SEND has no quickened forms, so no need to use _PyOpcode_Deopt + // here: + _Py_OPCODE(_PyCode_CODE(frame->f_code)[frame->f_lasti]) != SEND); if (trace) { result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); } |