summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-05-12 11:21:20 (GMT)
committerGitHub <noreply@github.com>2023-05-12 11:21:20 (GMT)
commit45f5aa8fc73acf516071d52ef8213532f0381316 (patch)
treebc1f7219305185a7befef7003688d7a4359f98e4 /Python/ceval.c
parent19ee53d52e8adf267dfd588c2142967734a3b65a (diff)
downloadcpython-45f5aa8fc73acf516071d52ef8213532f0381316.zip
cpython-45f5aa8fc73acf516071d52ef8213532f0381316.tar.gz
cpython-45f5aa8fc73acf516071d52ef8213532f0381316.tar.bz2
GH-103082: Filter LINE events in VM, to simplify tool implementation. (GH-104387)
When monitoring LINE events, instrument all instructions that can have a predecessor on a different line. Then check that the a new line has been hit in the instrumentation code. This brings the behavior closer to that of 3.11, simplifying implementation and porting of tools.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 56a3b12..e8534ec 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -775,6 +775,41 @@ handle_eval_breaker:
#include "generated_cases.c.h"
+ /* INSTRUMENTED_LINE has to be here, rather than in bytecodes.c,
+ * because it needs to capture frame->prev_instr before it is updated,
+ * as happens in the standard instruction prologue.
+ */
+#if USE_COMPUTED_GOTOS
+ TARGET_INSTRUMENTED_LINE:
+#else
+ case INSTRUMENTED_LINE:
+#endif
+ {
+ _Py_CODEUNIT *prev = frame->prev_instr;
+ _Py_CODEUNIT *here = frame->prev_instr = 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->prev_instr;
+ if (next_instr != here) {
+ DISPATCH();
+ }
+ if (_PyOpcode_Caches[original_opcode]) {
+ _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1);
+ /* Prevent the underlying instruction from specializing
+ * and overwriting the instrumentation. */
+ INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ }
+ opcode = original_opcode;
+ DISPATCH_GOTO();
+ }
+
+
#if USE_COMPUTED_GOTOS
_unknown_opcode:
#else