mirror of
https://github.com/python/cpython.git
synced 2025-08-23 10:16:01 +00:00
GH-120024: Remove CHECK_EVAL_BREAKER
macro. (GH-122968)
* Factor some instructions into micro-ops to isolate CHECK_EVAL_BREAKER for escape analysis * Eliminate CHECK_EVAL_BREAKER macro
This commit is contained in:
parent
315a933a5b
commit
eec7bdaf01
16 changed files with 821 additions and 518 deletions
|
@ -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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue