From ce40742dac28f66762a0222f41933345a0b23371 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 28 Feb 2024 07:21:42 -0800 Subject: [PATCH 1/6] gh-107674: Improve performance of `sys.settrace` (GH-114986) --- ...-02-04-07-45-29.gh-issue-107674.q8mCmi.rst | 1 + Python/bytecodes.c | 33 ++++++++++--------- Python/ceval.c | 28 +++++++++------- Python/ceval_macros.h | 16 +++++---- Python/executor_cases.c.h | 2 +- Python/generated_cases.c.h | 33 ++++++++++--------- Python/instrumentation.c | 4 +-- 7 files changed, 64 insertions(+), 53 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-02-04-07-45-29.gh-issue-107674.q8mCmi.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-04-07-45-29.gh-issue-107674.q8mCmi.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-04-07-45-29.gh-issue-107674.q8mCmi.rst new file mode 100644 index 00000000000000..f9b96788bfad94 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-02-04-07-45-29.gh-issue-107674.q8mCmi.rst @@ -0,0 +1 @@ +Improved the performance of :func:`sys.settrace` significantly diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 476975d2fbc3c2..ec5af43452d4bf 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -145,22 +145,23 @@ dummy_func( tier1 inst(RESUME, (--)) { assert(frame == tstate->current_frame); - uintptr_t global_version = - _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & - ~_PY_EVAL_EVENTS_MASK; - uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; - assert((code_version & 255) == 0); - if (code_version != global_version) { - int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); - ERROR_IF(err, error); - next_instr = this_instr; - } - else { - if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { - CHECK_EVAL_BREAKER(); + if (tstate->tracing == 0) { + uintptr_t global_version = + _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & + ~_PY_EVAL_EVENTS_MASK; + uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + assert((code_version & 255) == 0); + if (code_version != global_version) { + int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); + ERROR_IF(err, error); + next_instr = this_instr; + DISPATCH(); } - this_instr->op.code = RESUME_CHECK; } + if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { + CHECK_EVAL_BREAKER(); + } + this_instr->op.code = RESUME_CHECK; } inst(RESUME_CHECK, (--)) { @@ -171,13 +172,13 @@ dummy_func( uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; assert((version & _PY_EVAL_EVENTS_MASK) == 0); - DEOPT_IF(eval_breaker != version); + DEOPT_IF(eval_breaker != version && tstate->tracing == 0); } inst(INSTRUMENTED_RESUME, (--)) { uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK; uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; - if (code_version != global_version) { + if (code_version != global_version && tstate->tracing == 0) { if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) { GOTO_ERROR(error); } diff --git a/Python/ceval.c b/Python/ceval.c index b35a321c943123..389336352d427d 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -806,17 +806,23 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int { _Py_CODEUNIT *prev = frame->instr_ptr; _Py_CODEUNIT *here = frame->instr_ptr = next_instr; - _PyFrame_SetStackPointer(frame, stack_pointer); - int original_opcode = _Py_call_instrumentation_line( - tstate, frame, here, prev); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (original_opcode < 0) { - next_instr = here+1; - goto error; - } - next_instr = frame->instr_ptr; - if (next_instr != here) { - DISPATCH(); + int original_opcode = 0; + if (tstate->tracing) { + PyCodeObject *code = _PyFrame_GetCode(frame); + original_opcode = code->_co_monitoring->lines[(int)(here - _PyCode_CODE(code))].original_opcode; + } else { + _PyFrame_SetStackPointer(frame, stack_pointer); + original_opcode = _Py_call_instrumentation_line( + tstate, frame, here, prev); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (original_opcode < 0) { + next_instr = here+1; + goto error; + } + next_instr = frame->instr_ptr; + if (next_instr != here) { + DISPATCH(); + } } if (_PyOpcode_Caches[original_opcode]) { _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1); diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 22992aa09e1f38..b024b510cfda1f 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -347,12 +347,16 @@ do { \ // for an exception handler, displaying the traceback, and so on #define INSTRUMENTED_JUMP(src, dest, event) \ do { \ - _PyFrame_SetStackPointer(frame, stack_pointer); \ - next_instr = _Py_call_instrumentation_jump(tstate, event, frame, src, dest); \ - stack_pointer = _PyFrame_GetStackPointer(frame); \ - if (next_instr == NULL) { \ - next_instr = (dest)+1; \ - goto error; \ + if (tstate->tracing) {\ + next_instr = dest; \ + } else { \ + _PyFrame_SetStackPointer(frame, stack_pointer); \ + next_instr = _Py_call_instrumentation_jump(tstate, event, frame, src, dest); \ + stack_pointer = _PyFrame_GetStackPointer(frame); \ + if (next_instr == NULL) { \ + next_instr = (dest)+1; \ + goto error; \ + } \ } \ } while (0); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index a55daa2c344944..3da2b1cc830696 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -20,7 +20,7 @@ uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; assert((version & _PY_EVAL_EVENTS_MASK) == 0); - if (eval_breaker != version) goto deoptimize; + if (eval_breaker != version && tstate->tracing == 0) goto deoptimize; break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 2996ee72e7f2c6..4eded98a51b681 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3266,7 +3266,7 @@ INSTRUCTION_STATS(INSTRUMENTED_RESUME); uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK; uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; - if (code_version != global_version) { + if (code_version != global_version && tstate->tracing == 0) { if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) { GOTO_ERROR(error); } @@ -4937,22 +4937,23 @@ _Py_CODEUNIT *this_instr = next_instr - 1; (void)this_instr; assert(frame == tstate->current_frame); - uintptr_t global_version = - _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & - ~_PY_EVAL_EVENTS_MASK; - uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; - assert((code_version & 255) == 0); - if (code_version != global_version) { - int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); - if (err) goto error; - next_instr = this_instr; - } - else { - if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { - CHECK_EVAL_BREAKER(); + if (tstate->tracing == 0) { + uintptr_t global_version = + _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & + ~_PY_EVAL_EVENTS_MASK; + uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version; + assert((code_version & 255) == 0); + if (code_version != global_version) { + int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); + if (err) goto error; + next_instr = this_instr; + DISPATCH(); } - this_instr->op.code = RESUME_CHECK; } + if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { + CHECK_EVAL_BREAKER(); + } + this_instr->op.code = RESUME_CHECK; DISPATCH(); } @@ -4968,7 +4969,7 @@ uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; assert((version & _PY_EVAL_EVENTS_MASK) == 0); - DEOPT_IF(eval_breaker != version, RESUME); + DEOPT_IF(eval_breaker != version && tstate->tracing == 0, RESUME); DISPATCH(); } diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 018cd662b1561a..217c8d49cc7d47 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1164,15 +1164,13 @@ int _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev) { PyCodeObject *code = _PyFrame_GetCode(frame); + assert(tstate->tracing == 0); assert(is_version_up_to_date(code, tstate->interp)); assert(instrumentation_cross_checks(tstate->interp, code)); int i = (int)(instr - _PyCode_CODE(code)); _PyCoMonitoringData *monitoring = code->_co_monitoring; _PyCoLineInstrumentationData *line_data = &monitoring->lines[i]; - if (tstate->tracing) { - goto done; - } PyInterpreterState *interp = tstate->interp; int8_t line_delta = line_data->line_delta; int line = compute_line(code, i, line_delta); From 104fb6c26129469d0f3786f111973621c8efc49b Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 21 Mar 2024 11:27:09 -0700 Subject: [PATCH 2/6] Check tracing in RESUME_CHECK --- Python/bytecodes.c | 6 +++++- Python/executor_cases.c.h | 6 +++++- Python/generated_cases.c.h | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ec5af43452d4bf..e69d197fd7046c 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -172,7 +172,11 @@ dummy_func( uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; assert((version & _PY_EVAL_EVENTS_MASK) == 0); - DEOPT_IF(eval_breaker != version && tstate->tracing == 0); + if (tstate->tracing == 0) { + DEOPT_IF(eval_breaker != version); + } else { + DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); + } } inst(INSTRUMENTED_RESUME, (--)) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 3da2b1cc830696..27eb1abb320cc4 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -20,7 +20,11 @@ uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; assert((version & _PY_EVAL_EVENTS_MASK) == 0); - if (eval_breaker != version && tstate->tracing == 0) goto deoptimize; + if (tstate->tracing == 0) { + if (eval_breaker != version) goto deoptimize; + } else { + if (eval_breaker & _PY_EVAL_EVENTS_MASK) goto deoptimize; + } break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 4eded98a51b681..53cbfee9fd9f84 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4969,7 +4969,11 @@ uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version; assert((version & _PY_EVAL_EVENTS_MASK) == 0); - DEOPT_IF(eval_breaker != version && tstate->tracing == 0, RESUME); + if (tstate->tracing == 0) { + DEOPT_IF(eval_breaker != version, RESUME); + } else { + DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK, RESUME); + } DISPATCH(); } From 49545b7f2f00af017eec46d26aeb67dc9921d4d1 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Mon, 29 Apr 2024 10:55:09 -0700 Subject: [PATCH 3/6] Remove the optimization in RESUME_CHECK --- Python/bytecodes.c | 6 +----- Python/executor_cases.c.h | 13 +++---------- Python/generated_cases.c.h | 6 +----- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 54a9426ec8744b..f1b14a506d62f5 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -176,11 +176,7 @@ dummy_func( uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); assert((version & _PY_EVAL_EVENTS_MASK) == 0); - if (tstate->tracing == 0) { - DEOPT_IF(eval_breaker != version); - } else { - DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); - } + DEOPT_IF(eval_breaker != version); } inst(INSTRUMENTED_RESUME, (--)) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 28767834db9ada..df87f9178f17cf 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -23,16 +23,9 @@ uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); assert((version & _PY_EVAL_EVENTS_MASK) == 0); - if (tstate->tracing == 0) { - if (eval_breaker != version) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } - } else { - if (eval_breaker & _PY_EVAL_EVENTS_MASK) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } + if (eval_breaker != version) { + UOP_STAT_INC(uopcode, miss); + JUMP_TO_JUMP_TARGET(); } break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 9beab2728ac220..be056add94a063 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4964,11 +4964,7 @@ uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); uintptr_t version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); assert((version & _PY_EVAL_EVENTS_MASK) == 0); - if (tstate->tracing == 0) { - DEOPT_IF(eval_breaker != version, RESUME); - } else { - DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK, RESUME); - } + DEOPT_IF(eval_breaker != version, RESUME); DISPATCH(); } From 0307e486d0b5da99c0930783ee65ca93ebb918c7 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 2 May 2024 12:49:50 -0700 Subject: [PATCH 4/6] Fix merge errors --- Python/bytecodes.c | 19 +++++++++---------- Python/generated_cases.c.h | 19 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index a5071744ecef6c..9fe7c9d9705ee7 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -161,20 +161,19 @@ dummy_func( 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(); } - this_instr->op.code = RESUME_CHECK; + 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 */ + } } inst(RESUME_CHECK, (--)) { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index fc65b0657c58a1..114091f7b5ea14 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4961,20 +4961,19 @@ 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(); } - this_instr->op.code = RESUME_CHECK; + 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 */ + } DISPATCH(); } From d3fbd295e1465db336fbe62f00ff1f4f7f98c165 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Thu, 2 May 2024 13:19:09 -0700 Subject: [PATCH 5/6] Only change to RESUME_CHECK if not tracing --- Python/bytecodes.c | 18 +++++++++--------- Python/generated_cases.c.h | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 9fe7c9d9705ee7..4bfbe51b87c8f5 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -161,19 +161,19 @@ dummy_func( 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(); } - 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 */ - } } inst(RESUME_CHECK, (--)) { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 114091f7b5ea14..800d19229e3d6a 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4961,19 +4961,19 @@ 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(); } - 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 */ - } DISPATCH(); } From 968a5f3f380de271342a06437409060e12ead3f1 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 3 May 2024 14:59:44 +0100 Subject: [PATCH 6/6] Fix assert --- Python/bytecodes.c | 2 +- Python/executor_cases.c.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4bfbe51b87c8f5..e8383eda6a9d49 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4285,7 +4285,7 @@ dummy_func( #endif uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); - assert(eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); + assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); } // END BYTECODES // diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 03db9b623cbd86..c3ee6e9039c900 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -4346,7 +4346,7 @@ UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } - assert(eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); + assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); break; }