Skip to content

Commit eb970e0

Browse files
specialization and deopt fixes
1 parent ccc7893 commit eb970e0

File tree

6 files changed

+767
-12
lines changed

6 files changed

+767
-12
lines changed

Include/internal/pycore_interp_structs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,14 +759,15 @@ typedef _Py_CODEUNIT *(*_PyJitEntryFuncPtr)(struct _PyExecutorObject *exec, _PyI
759759

760760
typedef struct _PyJitTracerState {
761761
bool dependencies_still_valid;
762-
bool do_not_specialize;
763762
bool dynamic_jump_taken;
763+
bool prev_instr_is_super;
764764
int code_max_size;
765765
int code_curr_size;
766766
int initial_stack_depth;
767767
int initial_chain_depth;
768768
int prev_instr_oparg;
769769
int prev_instr_stacklevel;
770+
int specialize_counter;
770771
_PyUOpInstruction *code_buffer;
771772
_Py_CODEUNIT *insert_exec_instr;
772773
_Py_CODEUNIT *close_loop_instr;

Python/bytecodes.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5229,10 +5229,21 @@ dummy_func(
52295229
ERROR_IF(err < 0);
52305230
DISPATCH_GOTO_NON_TRACING();
52315231
}
5232-
tstate->interp->jit_state.do_not_specialize = false;
5232+
// Super instructions. Instruction deopted, There's a mismatch in what the stack expects
5233+
// in the optimizer. So we have to reflect in the trace correctly.
5234+
if ((tstate->interp->jit_state.prev_instr->op.code == CALL_LIST_APPEND &&
5235+
opcode == POP_TOP) ||
5236+
(tstate->interp->jit_state.prev_instr->op.code == BINARY_OP_INPLACE_ADD_UNICODE &&
5237+
opcode == STORE_FAST)) {
5238+
tstate->interp->jit_state.prev_instr_is_super = true;
5239+
}
5240+
else {
5241+
tstate->interp->jit_state.prev_instr = next_instr;
5242+
}
5243+
tstate->interp->jit_state.specialize_counter = 0;
52335244
PyCodeObject *prev_code = (PyCodeObject *)Py_NewRef(_PyFrame_GetCode(frame));
52345245
Py_SETREF(tstate->interp->jit_state.prev_instr_code, prev_code);
5235-
tstate->interp->jit_state.prev_instr = next_instr;
5246+
52365247
tstate->interp->jit_state.prev_instr_frame = frame;
52375248
tstate->interp->jit_state.prev_instr_oparg = oparg;
52385249
tstate->interp->jit_state.prev_instr_stacklevel = STACK_LEVEL();

Python/ceval_macros.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@
135135

136136
#if (_Py_TAIL_CALL_INTERP || USE_COMPUTED_GOTOS) && _Py_TIER2
137137
# define IS_JIT_TRACING() (DISPATCH_TABLE_VAR == TRACING_DISPATCH_TABLE)
138-
// Required to not get stuck in infinite pecialization loops due to specialization failure.
139-
# define IS_JIT_TRACING_MAKING_PROGRESS() (IS_JIT_TRACING() && !tstate->interp->jit_state.do_not_specialize)
138+
// Required to not get stuck in infinite specialization loops due to specialization failure.
139+
# define IS_JIT_TRACING_MAKING_PROGRESS() (IS_JIT_TRACING() && tstate->interp->jit_state.specialize_counter <= 2)
140140
# define ENTER_TRACING() \
141141
DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE;
142142
# define LEAVE_TRACING() \
@@ -195,7 +195,7 @@ do { \
195195
#if _Py_TIER2
196196
#define DISPATCH_SAME_OPARG() \
197197
{ \
198-
tstate->interp->jit_state.do_not_specialize = true; \
198+
tstate->interp->jit_state.specialize_counter++; \
199199
opcode = next_instr->op.code; \
200200
PRE_DISPATCH_GOTO(); \
201201
DISPATCH_GOTO_NON_TRACING(); \

0 commit comments

Comments
 (0)