summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorBrandt Bucher <brandtbucher@microsoft.com>2022-03-21 11:11:17 (GMT)
committerGitHub <noreply@github.com>2022-03-21 11:11:17 (GMT)
commit2bde6827ea4f136297b2d882480b981ff26262b6 (patch)
tree8ad0569c15e0f516eaf8547581c6de2ca702b349 /Python/ceval.c
parent08eb754d840696914928355014c2d424131f8835 (diff)
downloadcpython-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.c39
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);
}