From 5c9b80dbbf121f9b1966eb3f8586f5373f06a28b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 9 Jun 2022 17:38:40 +0100 Subject: [PATCH 1/4] Allow interpreter to run at full speed in tracing functions. --- Python/ceval.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 47dd1008c35ced..82320b569f829c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5612,9 +5612,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int case DO_TRACING: #endif { - if (tstate->tracing == 0 && - INSTR_OFFSET() >= frame->f_code->_co_firsttraceable - ) { + assert(cframe.use_tracing); + assert(tstate->tracing == 0); + if (INSTR_OFFSET() >= frame->f_code->_co_firsttraceable) { int instr_prev = _PyInterpreterFrame_LASTI(frame); frame->prev_instr = next_instr; TRACING_NEXTOPARG(); @@ -6824,12 +6824,17 @@ void PyThreadState_EnterTracing(PyThreadState *tstate) { tstate->tracing++; + tstate->cframe->use_tracing = 0; } void PyThreadState_LeaveTracing(PyThreadState *tstate) { + assert(tstate->tracing > 0 && tstate->cframe->use_tracing == 0); tstate->tracing--; + if (tstate->tracing == 0) { + _PyThreadState_UpdateTracingState(tstate); + } } static int From 0cbcddb74d11bdfb908b9dc0b7dcf34ba0c1161e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 27 Jul 2022 14:22:06 +0100 Subject: [PATCH 2/4] Add news. --- .../2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst new file mode 100644 index 00000000000000..a3be34c175af6e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-27-14-21-57.gh-issue-90081.HVAS5x.rst @@ -0,0 +1,2 @@ +Run Python code in tracer/profiler function at full speed. Fixes slowdown in +earlier versions of 3.11. From 420e295f727966e98b7390cc62f49395bd9b65e4 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 27 Jul 2022 16:24:40 +0100 Subject: [PATCH 3/4] Make sure to always account for tstate->tracing when updating cframe.use_tracing. --- Include/internal/pycore_pystate.h | 5 +++-- Python/ceval.c | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index b4a39b62b76a1d..51d119c23e731b 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -131,8 +131,9 @@ PyAPI_FUNC(void) _PyThreadState_DeleteExcept( static inline void _PyThreadState_UpdateTracingState(PyThreadState *tstate) { - int use_tracing = (tstate->c_tracefunc != NULL - || tstate->c_profilefunc != NULL); + bool use_tracing = + (tstate->tracing == 0) && + (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); tstate->cframe->use_tracing = (use_tracing ? 255 : 0); } diff --git a/Python/ceval.c b/Python/ceval.c index 16d174db8fd787..17d38b81420fa5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5631,7 +5631,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(oparg); oparg <<= 8; oparg |= _Py_OPARG(*next_instr); - // We might be tracing. To avoid breaking tracing guarantees in + // We might be tracing. To avoid breaking tracing guarantees in // quickened instructions, always deoptimize the next opcode: opcode = _PyOpcode_Deopt[_Py_OPCODE(*next_instr)]; PRE_DISPATCH_GOTO(); @@ -6883,9 +6883,7 @@ PyThreadState_LeaveTracing(PyThreadState *tstate) { assert(tstate->tracing > 0 && tstate->cframe->use_tracing == 0); tstate->tracing--; - if (tstate->tracing == 0) { - _PyThreadState_UpdateTracingState(tstate); - } + _PyThreadState_UpdateTracingState(tstate); } static int @@ -6924,7 +6922,6 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) int save_tracing = tstate->tracing; int save_use_tracing = tstate->cframe->use_tracing; tstate->tracing = 0; - // Call the tracing function PyObject *result = PyObject_Call(func, args, NULL); From f82b56078371521c415d8193acd9e415b57501dd Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 28 Jul 2022 09:46:07 +0100 Subject: [PATCH 4/4] Re-insert blank line --- Python/ceval.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/ceval.c b/Python/ceval.c index 17d38b81420fa5..7ad26a70dd18c6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -6922,6 +6922,7 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) int save_tracing = tstate->tracing; int save_use_tracing = tstate->cframe->use_tracing; tstate->tracing = 0; + // Call the tracing function PyObject *result = PyObject_Call(func, args, NULL);