🌐 AI搜索 & 代理 主页
Skip to content

Commit ebf3427

Browse files
gh-141976: Protect against non-progressing specializations in tracing JIT (GH-141989)
1 parent 4629567 commit ebf3427

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

Include/cpython/pystats.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ typedef struct _optimization_stats {
142142
uint64_t recursive_call;
143143
uint64_t low_confidence;
144144
uint64_t unknown_callee;
145+
uint64_t trace_immediately_deopts;
145146
uint64_t executors_invalidated;
146147
UOpStats opcode[PYSTATS_MAX_UOP_ID + 1];
147148
uint64_t unsupported_opcode[256];
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Protect against specialization failures in the tracing JIT compiler for performance reasons.

Python/optimizer.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,25 @@ _PyJit_translate_single_bytecode_to_trace(
610610
target--;
611611
}
612612

613+
if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]] > 0) {
614+
uint16_t backoff = (this_instr + 1)->counter.value_and_backoff;
615+
// adaptive_counter_cooldown is a fresh specialization.
616+
// trigger_backoff_counter is what we set during tracing.
617+
// All tracing backoffs should be freshly specialized or untouched.
618+
// If not, that indicates a deopt during tracing, and
619+
// thus the "actual" instruction executed is not the one that is
620+
// in the instruction stream, but rather the deopt.
621+
// It's important we check for this, as some specializations might make
622+
// no progress (they can immediately deopt after specializing).
623+
// We do this to improve performance, as otherwise a compiled trace
624+
// will just deopt immediately.
625+
if (backoff != adaptive_counter_cooldown().value_and_backoff &&
626+
backoff != trigger_backoff_counter().value_and_backoff) {
627+
OPT_STAT_INC(trace_immediately_deopts);
628+
opcode = _PyOpcode_Deopt[opcode];
629+
}
630+
}
631+
613632
int old_stack_level = _tstate->jit_tracer_state.prev_state.instr_stacklevel;
614633

615634
// Strange control-flow

0 commit comments

Comments
 (0)