diff options
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 38 |
1 files changed, 13 insertions, 25 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 002b5a3..b1be40d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2410,20 +2410,21 @@ dummy_func( tier1 inst(ENTER_EXECUTOR, (--)) { #ifdef _Py_TIER2 - int prevoparg = oparg; - CHECK_EVAL_BREAKER(); - if (this_instr->op.code != ENTER_EXECUTOR || - this_instr->op.arg != prevoparg) { - next_instr = this_instr; - DISPATCH(); - } - PyCodeObject *code = _PyFrame_GetCode(frame); _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; assert(executor->vm_data.index == INSTR_OFFSET() - 1); assert(executor->vm_data.code == code); assert(executor->vm_data.valid); assert(tstate->previous_executor == NULL); + /* If the eval breaker is set then stay in tier 1. + * This avoids any potentially infinite loops + * involving _RESUME_CHECK */ + if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + opcode = executor->vm_data.opcode; + oparg = (oparg & ~255) | executor->vm_data.oparg; + next_instr = this_instr; + DISPATCH_GOTO(); + } tstate->previous_executor = Py_None; Py_INCREF(executor); GOTO_TIER_TWO(executor); @@ -4111,7 +4112,6 @@ dummy_func( #ifndef _Py_JIT next_uop = ¤t_executor->trace[1]; #endif - CHECK_EVAL_BREAKER(); } tier2 op(_SET_IP, (instr_ptr/4 --)) { @@ -4277,30 +4277,18 @@ dummy_func( GOTO_UNWIND(); } - - /* Special version of RESUME_CHECK that (when paired with _EVAL_BREAKER_EXIT) - * is safe for tier 2. Progress is guaranteed because _EVAL_BREAKER_EXIT calls - * _Py_HandlePending which clears the eval_breaker so that _TIER2_RESUME_CHECK - * will not exit if it is immediately executed again. */ + /* 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__) - EXIT_IF(_Py_emscripten_signal_clock == 0); + 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); - EXIT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); + DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); assert(eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); } - tier2 op(_EVAL_BREAKER_EXIT, (--)) { - _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); - QSBR_QUIESCENT_STATE(tstate); - if (_Py_HandlePending(tstate) != 0) { - GOTO_UNWIND(); - } - EXIT_TO_TRACE(); - } - // END BYTECODES // } |