diff options
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 133 |
1 files changed, 76 insertions, 57 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ffa53bb..757c3f9 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -10,6 +10,7 @@ #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_backoff.h" #include "pycore_cell.h" // PyCell_GetRef() +#include "pycore_ceval.h" #include "pycore_code.h" #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_function.h" @@ -146,36 +147,54 @@ dummy_func( RESUME_CHECK, }; - tier1 inst(RESUME, (--)) { - assert(frame == tstate->current_frame); + op(_CHECK_PERIODIC, (--)) { + _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); + QSBR_QUIESCENT_STATE(tstate); \ + if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + int err = _Py_HandlePending(tstate); + ERROR_IF(err != 0, error); + } + } + + op(_CHECK_PERIODIC_IF_NOT_YIELD_FROM, (--)) { + if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { + _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); + QSBR_QUIESCENT_STATE(tstate); \ + if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + int err = _Py_HandlePending(tstate); + ERROR_IF(err != 0, error); + } + } + } + + op(_QUICKEN_RESUME, (--)) { + #if ENABLE_SPECIALIZATION + if (tstate->tracing == 0 && this_instr->op.code == RESUME) { + FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK); + } + #endif /* ENABLE_SPECIALIZATION */ + } + + tier1 op(_MAYBE_INSTRUMENT, (--)) { if (tstate->tracing == 0) { - uintptr_t global_version = - _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & - ~_PY_EVAL_EVENTS_MASK; - PyCodeObject* code = _PyFrame_GetCode(frame); - uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(code->_co_instrumentation_version); - assert((code_version & 255) == 0); + uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK; + uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); if (code_version != global_version) { int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); - ERROR_IF(err, error); + if (err) { + ERROR_NO_POP(); + } next_instr = this_instr; DISPATCH(); } - assert(this_instr->op.code == RESUME || - this_instr->op.code == RESUME_CHECK || - this_instr->op.code == INSTRUMENTED_RESUME || - this_instr->op.code == ENTER_EXECUTOR); - if (this_instr->op.code == RESUME) { - #if ENABLE_SPECIALIZATION - FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK); - #endif /* ENABLE_SPECIALIZATION */ - } - } - if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { - CHECK_EVAL_BREAKER(); } } + macro(RESUME) = + _MAYBE_INSTRUMENT + + _QUICKEN_RESUME + + _CHECK_PERIODIC_IF_NOT_YIELD_FROM; + inst(RESUME_CHECK, (--)) { #if defined(__EMSCRIPTEN__) DEOPT_IF(_Py_emscripten_signal_clock == 0); @@ -187,33 +206,23 @@ dummy_func( DEOPT_IF(eval_breaker != version); } - inst(INSTRUMENTED_RESUME, (--)) { - uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK; - uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); - if (code_version != global_version && tstate->tracing == 0) { - int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); - if (err) { - ERROR_NO_POP(); - } - next_instr = this_instr; - } - else { - if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { - CHECK_EVAL_BREAKER(); - } - _PyFrame_SetStackPointer(frame, stack_pointer); - int err = _Py_call_instrumentation( - tstate, oparg > 0, frame, this_instr); - stack_pointer = _PyFrame_GetStackPointer(frame); - ERROR_IF(err, error); - if (frame->instr_ptr != this_instr) { - /* Instrumentation has jumped */ - next_instr = frame->instr_ptr; - DISPATCH(); - } + op(_MONITOR_RESUME, (--)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = _Py_call_instrumentation( + tstate, oparg > 0, frame, this_instr); + stack_pointer = _PyFrame_GetStackPointer(frame); + ERROR_IF(err, error); + if (frame->instr_ptr != this_instr) { + /* Instrumentation has jumped */ + next_instr = frame->instr_ptr; } } + macro(INSTRUMENTED_RESUME) = + _MAYBE_INSTRUMENT + + _CHECK_PERIODIC_IF_NOT_YIELD_FROM + + _MONITOR_RESUME; + pseudo(LOAD_CLOSURE, (-- unused)) = { LOAD_FAST, }; @@ -2486,8 +2495,7 @@ dummy_func( JUMPBY(oparg); } - tier1 inst(JUMP_BACKWARD, (unused/1 --)) { - CHECK_EVAL_BREAKER(); + tier1 op(_JUMP_BACKWARD, (the_counter/1 --)) { assert(oparg <= INSTR_OFFSET()); JUMPBY(-oparg); #ifdef _Py_TIER2 @@ -2519,6 +2527,10 @@ dummy_func( #endif /* _Py_TIER2 */ } + macro(JUMP_BACKWARD) = + _CHECK_PERIODIC + + _JUMP_BACKWARD; + pseudo(JUMP, (--)) = { JUMP_FORWARD, JUMP_BACKWARD, @@ -3265,10 +3277,6 @@ dummy_func( res = PyStackRef_FromPyObjectSteal(res_o); } - op(_CHECK_PERIODIC, (--)) { - CHECK_EVAL_BREAKER(); - } - op(_MONITOR_CALL, (func, maybe_self, args[oparg] -- func, maybe_self, args[oparg])) { int is_meth = !PyStackRef_IsNull(maybe_self); PyObject *function = PyStackRef_AsPyObjectBorrow(func); @@ -4012,7 +4020,7 @@ dummy_func( GO_TO_INSTRUCTION(CALL_KW); } - inst(CALL_KW, (callable, self_or_null, args[oparg], kwnames -- res)) { + op(_DO_CALL_KW, (callable, self_or_null, args[oparg], kwnames -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames); @@ -4094,14 +4102,17 @@ dummy_func( } ERROR_IF(res_o == NULL, error); res = PyStackRef_FromPyObjectSteal(res_o); - CHECK_EVAL_BREAKER(); } + macro(CALL_KW) = + _DO_CALL_KW + + _CHECK_PERIODIC; + inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) { GO_TO_INSTRUCTION(CALL_FUNCTION_EX); } - inst(CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) { + inst(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) { PyObject *func = PyStackRef_AsPyObjectBorrow(func_st); PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st); PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st); @@ -4175,9 +4186,13 @@ dummy_func( DECREF_INPUTS(); assert(PyStackRef_AsPyObjectBorrow(PEEK(2 + (oparg & 1))) == NULL); ERROR_IF(PyStackRef_IsNull(result), error); - CHECK_EVAL_BREAKER(); } + macro(CALL_FUNCTION_EX) = + _DO_CALL_FUNCTION_EX + + _CHECK_PERIODIC; + + inst(MAKE_FUNCTION, (codeobj_st -- func)) { PyObject *codeobj = PyStackRef_AsPyObjectBorrow(codeobj_st); @@ -4381,11 +4396,15 @@ dummy_func( INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP); } - inst(INSTRUMENTED_JUMP_BACKWARD, (unused/1 -- )) { - CHECK_EVAL_BREAKER(); + op(_MONITOR_JUMP_BACKWARD, (-- )) { INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP); } + macro(INSTRUMENTED_JUMP_BACKWARD) = + unused/1 + + _CHECK_PERIODIC + + _MONITOR_JUMP_BACKWARD; + inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) { _PyStackRef cond = POP(); assert(PyStackRef_BoolCheck(cond)); |