mirror of
https://github.com/python/cpython.git
synced 2025-09-02 15:07:53 +00:00
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.
This commit is contained in:
parent
08eb754d84
commit
2bde6827ea
18 changed files with 832 additions and 688 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue