diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 5ebe124983b862..56fe74c5c8e94e 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -319,7 +319,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_FATAL_ERROR] = 0, [_DEOPT] = 0, [_ERROR_POP_N] = HAS_ARG_FLAG, - [_TIER2_RESUME_CHECK] = HAS_DEOPT_FLAG, + [_TIER2_RESUME_CHECK] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, }; const uint8_t _PyUop_Replication[MAX_UOP_ID+1] = { diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-05-26-15-17-29.gh-issue-134728.YUJYfF.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-26-15-17-29.gh-issue-134728.YUJYfF.rst new file mode 100644 index 00000000000000..bc262f8e7e2f46 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-26-15-17-29.gh-issue-134728.YUJYfF.rst @@ -0,0 +1 @@ +Handle ``_TIER2_RESUME_CHECK`` in the JIT. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index be22c7446f5402..78971e3738e67f 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -5392,15 +5392,16 @@ dummy_func( GOTO_TIER_ONE(NULL); } - /* Progress is guaranteed if we DEOPT on the eval breaker, because - * ENTER_EXECUTOR will not re-enter tier 2 with the eval breaker set. */ tier2 op(_TIER2_RESUME_CHECK, (--)) { #if defined(__EMSCRIPTEN__) DEOPT_IF(_Py_emscripten_signal_clock == 0); _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); - DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); + if (eval_breaker & _PY_EVAL_EVENTS_MASK) { + int err = _Py_HandlePending(tstate); + ERROR_IF(err != 0); + } assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 40090e692e4a72..948cb95b6c176c 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -7303,8 +7303,12 @@ #endif uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); if (eval_breaker & _PY_EVAL_EVENTS_MASK) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = _Py_HandlePending(tstate); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (err != 0) { + JUMP_TO_ERROR(); + } } assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); break;