There was an error while loading. Please reload this page.
1 parent 4629567 commit ebf3427Copy full SHA for ebf3427
3 files changed
Include/cpython/pystats.h
@@ -142,6 +142,7 @@ typedef struct _optimization_stats {
142
uint64_t recursive_call;
143
uint64_t low_confidence;
144
uint64_t unknown_callee;
145
+ uint64_t trace_immediately_deopts;
146
uint64_t executors_invalidated;
147
UOpStats opcode[PYSTATS_MAX_UOP_ID + 1];
148
uint64_t unsupported_opcode[256];
Misc/NEWS.d/next/Core_and_Builtins/2025-11-26-20-01-07.gh-issue-141976.K8NDmR.rst
@@ -0,0 +1 @@
1
+Protect against specialization failures in the tracing JIT compiler for performance reasons.
Python/optimizer.c
@@ -610,6 +610,25 @@ _PyJit_translate_single_bytecode_to_trace(
610
target--;
611
}
612
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
+
632
int old_stack_level = _tstate->jit_tracer_state.prev_state.instr_stacklevel;
633
634
// Strange control-flow
0 commit comments