From 23e1f48ba38795114e0d7a2811d34a125022333a Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 27 Aug 2023 19:08:49 +0900 Subject: [PATCH 01/15] Revert "gh-107265: Fix initialize/remove_tools for ENTER_EXECUTOR case (gh-108482)" This reverts commit 6cb48f049501c9f8c5be107e52f8eb359b5ac533. --- Python/instrumentation.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 36459687be7936..8c7a3a06c9b938 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -566,13 +566,7 @@ de_instrument(PyCodeObject *code, int i, int event) _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t *opcode_ptr = &instr->op.code; int opcode = *opcode_ptr; - if (opcode == ENTER_EXECUTOR) { - int oparg = instr->op.arg; - _PyExecutorObject *exec = code->co_executors->executors[oparg]; - opcode_ptr = &exec->vm_data.opcode; - opcode = *opcode_ptr; - assert(opcode != ENTER_EXECUTOR); - } + assert(opcode != ENTER_EXECUTOR); if (opcode == INSTRUMENTED_LINE) { opcode_ptr = &code->_co_monitoring->lines[i].original_opcode; opcode = *opcode_ptr; @@ -717,22 +711,7 @@ remove_tools(PyCodeObject * code, int offset, int event, int tools) assert(event != PY_MONITORING_EVENT_LINE); assert(event != PY_MONITORING_EVENT_INSTRUCTION); assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event)); - #ifndef NDEBUG - _Py_CODEUNIT co_instr = _PyCode_CODE(code)[offset]; - uint8_t opcode = co_instr.op.code; - uint8_t oparg = co_instr.op.arg; - if (opcode == ENTER_EXECUTOR) { - _PyExecutorObject *exec = code->co_executors->executors[oparg]; - assert(exec->vm_data.opcode != ENTER_EXECUTOR); - opcode = _PyOpcode_Deopt[exec->vm_data.opcode]; - opcode = exec->vm_data.oparg; - } - else { - opcode = _Py_GetBaseOpcode(code, offset); - } - assert(opcode != ENTER_EXECUTOR); - assert(opcode_has_event(opcode)); - #endif + assert(opcode_has_event(_Py_GetBaseOpcode(code, offset))); _PyCoMonitoringData *monitoring = code->_co_monitoring; if (monitoring && monitoring->tools) { monitoring->tools[offset] &= ~tools; @@ -1303,16 +1282,9 @@ initialize_tools(PyCodeObject *code) for (int i = 0; i < code_len; i++) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; int opcode = instr->op.code; - int oparg = instr->op.arg; - if (opcode == ENTER_EXECUTOR) { - _PyExecutorObject *exec = code->co_executors->executors[oparg]; - opcode = exec->vm_data.opcode; - oparg = exec->vm_data.oparg; - } - else if (opcode == INSTRUMENTED_LINE) { + if (opcode == INSTRUMENTED_LINE) { opcode = code->_co_monitoring->lines[i].original_opcode; } - assert(opcode != ENTER_EXECUTOR); bool instrumented = is_instrumented(opcode); if (instrumented) { opcode = DE_INSTRUMENT[opcode]; @@ -1323,7 +1295,7 @@ initialize_tools(PyCodeObject *code) if (instrumented) { int8_t event; if (opcode == RESUME) { - event = oparg != 0; + event = instr->op.arg != 0; } else { event = EVENT_FOR_OPCODE[opcode]; From 8820df8d90b1631838c00577e8484fcfb62d0f8f Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 27 Aug 2023 20:50:13 +0900 Subject: [PATCH 02/15] gh-107265: Remove all ENTER_EXECUTOR when execute _Py_Instrument --- Include/internal/pycore_code.h | 3 +++ Objects/codeobject.c | 4 ++++ Python/instrumentation.c | 15 +++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index f5127a81144353..830d132d8b0008 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -233,6 +233,9 @@ extern void _PyLineTable_InitAddressRange( extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range); extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); +/** API for executors */ +extern void _PyCode_Clear_Executors(PyCodeObject *code); + #define ENABLE_SPECIALIZATION 1 /* Specialization functions */ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 70a0c2ebd66b24..2c56bf841e61ce 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1479,6 +1479,10 @@ clear_executors(PyCodeObject *co) co->co_executors = NULL; } +void _PyCode_Clear_Executors(PyCodeObject *code) { + clear_executors(code); +} + static void deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions) { diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 8c7a3a06c9b938..c6f7ebbd28142b 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -3,6 +3,7 @@ #include "opcode_ids.h" #include "pycore_call.h" +#include "pycore_code.h" // _PyCode_Clear_Executors() #include "pycore_frame.h" #include "pycore_interp.h" #include "pycore_long.h" @@ -1549,6 +1550,20 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) return 0; } int code_len = (int)Py_SIZE(code); + if (code->co_executors != NULL && code->co_executors->size > 0 ) { + for (int i = 0; i < code_len; i += _PyInstruction_GetLength(code, i)) { + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + int opcode = instr->op.code; + int oparg = instr->op.arg; + if (opcode == ENTER_EXECUTOR) { + _PyExecutorObject *exec = code->co_executors->executors[oparg]; + assert(exec->vm_data.opcode != ENTER_EXECUTOR); + instr->op.code = _PyOpcode_Deopt[exec->vm_data.opcode]; + instr->op.arg = exec->vm_data.oparg; + } + } + _PyCode_Clear_Executors(code); + } if (update_instrumentation_data(code, interp)) { return -1; } From e015f14e25da9fe93c3cf5d32e91924e80980947 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 27 Aug 2023 20:56:51 +0900 Subject: [PATCH 03/15] nit --- Python/instrumentation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index c6f7ebbd28142b..62453e59405f92 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1553,8 +1553,8 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) if (code->co_executors != NULL && code->co_executors->size > 0 ) { for (int i = 0; i < code_len; i += _PyInstruction_GetLength(code, i)) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; - int opcode = instr->op.code; - int oparg = instr->op.arg; + uint8_t opcode = instr->op.code; + uint8_t oparg = instr->op.arg; if (opcode == ENTER_EXECUTOR) { _PyExecutorObject *exec = code->co_executors->executors[oparg]; assert(exec->vm_data.opcode != ENTER_EXECUTOR); From 7612b8ece2a9abab041fbc4661d095c532cdcbc8 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 27 Aug 2023 21:01:00 +0900 Subject: [PATCH 04/15] Add assert --- Python/instrumentation.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 62453e59405f92..79998d0e87c57d 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1291,6 +1291,7 @@ initialize_tools(PyCodeObject *code) opcode = DE_INSTRUMENT[opcode]; assert(opcode != 0); } + assert(opcode != ENTER_EXECUTOR); opcode = _PyOpcode_Deopt[opcode]; if (opcode_has_event(opcode)) { if (instrumented) { From 7d38c77730894a3583cd8ded0f501f3b7e0ecadc Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 27 Aug 2023 21:57:26 +0900 Subject: [PATCH 05/15] nit --- Python/instrumentation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 79998d0e87c57d..2098c514aa23fd 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1559,7 +1559,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) if (opcode == ENTER_EXECUTOR) { _PyExecutorObject *exec = code->co_executors->executors[oparg]; assert(exec->vm_data.opcode != ENTER_EXECUTOR); - instr->op.code = _PyOpcode_Deopt[exec->vm_data.opcode]; + instr->op.code = exec->vm_data.opcode; instr->op.arg = exec->vm_data.oparg; } } From a01354d37956d922d7552f1b30b126a387e35293 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 2 Sep 2023 00:36:36 +0900 Subject: [PATCH 06/15] Address code review --- Objects/codeobject.c | 15 ++++++++++++++- Python/instrumentation.c | 15 ++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 2c56bf841e61ce..a862ffdd3767cb 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1479,7 +1479,20 @@ clear_executors(PyCodeObject *co) co->co_executors = NULL; } -void _PyCode_Clear_Executors(PyCodeObject *code) { +void +_PyCode_Clear_Executors(PyCodeObject *code) { + int code_len = (int)Py_SIZE(code); + for (int i = 0; i < code_len; i+= _PyInstruction_GetLength(code, i)) { + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + uint8_t opcode = instr->op.code; + uint8_t oparg = instr->op.arg; + if (opcode == ENTER_EXECUTOR) { + _PyExecutorObject *exec = code->co_executors->executors[oparg]; + assert(exec->vm_data.opcode != ENTER_EXECUTOR); + instr->op.code = exec->vm_data.opcode; + instr->op.arg = exec->vm_data.oparg; + } + } clear_executors(code); } diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 2098c514aa23fd..1ba7b832960e45 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1550,19 +1550,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) ); return 0; } - int code_len = (int)Py_SIZE(code); - if (code->co_executors != NULL && code->co_executors->size > 0 ) { - for (int i = 0; i < code_len; i += _PyInstruction_GetLength(code, i)) { - _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; - uint8_t opcode = instr->op.code; - uint8_t oparg = instr->op.arg; - if (opcode == ENTER_EXECUTOR) { - _PyExecutorObject *exec = code->co_executors->executors[oparg]; - assert(exec->vm_data.opcode != ENTER_EXECUTOR); - instr->op.code = exec->vm_data.opcode; - instr->op.arg = exec->vm_data.oparg; - } - } + if (code->co_executors != NULL) { _PyCode_Clear_Executors(code); } if (update_instrumentation_data(code, interp)) { @@ -1593,6 +1581,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) return 0; } /* Insert instrumentation */ + int code_len = (int)Py_SIZE(code); for (int i = code->_co_firsttraceable; i < code_len; i+= _PyInstruction_GetLength(code, i)) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; CHECK(instr->op.code != 0); From 9a631d79f6c8e1108b4b2014965b4bed3eb79ff6 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 2 Sep 2023 00:37:51 +0900 Subject: [PATCH 07/15] nit --- Objects/codeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index a862ffdd3767cb..68959d2296f95c 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1482,7 +1482,7 @@ clear_executors(PyCodeObject *co) void _PyCode_Clear_Executors(PyCodeObject *code) { int code_len = (int)Py_SIZE(code); - for (int i = 0; i < code_len; i+= _PyInstruction_GetLength(code, i)) { + for (int i = 0; i < code_len; i+=_PyInstruction_GetLength(code, i)) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t opcode = instr->op.code; uint8_t oparg = instr->op.arg; From 7e81bf01a7c2c55912749e9212e9370dc5852206 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 2 Sep 2023 01:49:36 +0900 Subject: [PATCH 08/15] Add test --- Lib/test/test_monitoring.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index 845185be737eb2..e69c9b2d9917df 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1698,3 +1698,32 @@ def run(): self.assertEqual(caught, "inner") finally: sys.monitoring.set_events(TEST_TOOL, 0) + + +import _testinternalcapi +class TestOptimizer(MonitoringTestBase, unittest.TestCase): + + def setUp(self): + self.old_opt = _testinternalcapi.get_optimizer() + opt = _testinternalcapi.get_counter_optimizer() + super(TestOptimizer, self).setUp() + + def tearDown(self): + super(TestOptimizer, self).tearDown() + _testinternalcapi.set_optimizer(self.old_opt) + + def test_for_loop(self): + def test_func(x): + i = 0 + while i < x: + i += 1 + + code = test_func.__code__ + sys.monitoring.set_local_events(TEST_TOOL, code, E.PY_START) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), E.PY_START) + sys.monitoring.set_local_events(TEST_TOOL2, code, E.PY_START) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL2, code), E.PY_START) + sys.monitoring.set_local_events(TEST_TOOL, code, 0) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), 0) + sys.monitoring.set_local_events(TEST_TOOL2, code, 0) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL2, code), 0) From 05773f94cd9ec95501fab8149ab8b892a57ff2e9 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 2 Sep 2023 02:43:09 +0900 Subject: [PATCH 09/15] Add test --- Lib/test/test_monitoring.py | 9 ++++----- Python/instrumentation.c | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index e69c9b2d9917df..7f1a63fe107178 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1700,15 +1700,17 @@ def run(): sys.monitoring.set_events(TEST_TOOL, 0) -import _testinternalcapi class TestOptimizer(MonitoringTestBase, unittest.TestCase): def setUp(self): + import _testinternalcapi self.old_opt = _testinternalcapi.get_optimizer() opt = _testinternalcapi.get_counter_optimizer() + _testinternalcapi.set_optimizer(opt) super(TestOptimizer, self).setUp() def tearDown(self): + import _testinternalcapi super(TestOptimizer, self).tearDown() _testinternalcapi.set_optimizer(self.old_opt) @@ -1721,9 +1723,6 @@ def test_func(x): code = test_func.__code__ sys.monitoring.set_local_events(TEST_TOOL, code, E.PY_START) self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), E.PY_START) - sys.monitoring.set_local_events(TEST_TOOL2, code, E.PY_START) - self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL2, code), E.PY_START) + test_func(1000) sys.monitoring.set_local_events(TEST_TOOL, code, 0) self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), 0) - sys.monitoring.set_local_events(TEST_TOOL2, code, 0) - self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL2, code), 0) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 1ba7b832960e45..1ebab7be2577e0 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1586,6 +1586,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; CHECK(instr->op.code != 0); int base_opcode = _Py_GetBaseOpcode(code, i); + assert(base_opcode != ENTER_EXECUTOR); if (opcode_has_event(base_opcode)) { int8_t event; if (base_opcode == RESUME) { From 9ddbfe70f35273b1a1013827e277545d1944c9c9 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 2 Sep 2023 02:44:27 +0900 Subject: [PATCH 10/15] Add space between += --- Objects/codeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 68959d2296f95c..47eb2b93279b3f 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1482,7 +1482,7 @@ clear_executors(PyCodeObject *co) void _PyCode_Clear_Executors(PyCodeObject *code) { int code_len = (int)Py_SIZE(code); - for (int i = 0; i < code_len; i+=_PyInstruction_GetLength(code, i)) { + for (int i = 0; i < code_len; i += _PyInstruction_GetLength(code, i)) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; uint8_t opcode = instr->op.code; uint8_t oparg = instr->op.arg; From 1199dfe1b334d150f13eeff31fe6a473d8857f80 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 2 Sep 2023 02:51:28 +0900 Subject: [PATCH 11/15] Return -1 if there is ENTER_EXECUTOR --- Python/instrumentation.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 1ebab7be2577e0..c5c35a07abce8c 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1586,7 +1586,9 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; CHECK(instr->op.code != 0); int base_opcode = _Py_GetBaseOpcode(code, i); - assert(base_opcode != ENTER_EXECUTOR); + if (base_opcode == ENTER_EXECUTOR) { + return -1; + } if (opcode_has_event(base_opcode)) { int8_t event; if (base_opcode == RESUME) { From 12324329f5fc8cc74a80134ca28ad7297357c989 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 2 Sep 2023 08:30:44 +0900 Subject: [PATCH 12/15] Update --- Python/instrumentation.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index c5c35a07abce8c..1ebab7be2577e0 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1586,9 +1586,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; CHECK(instr->op.code != 0); int base_opcode = _Py_GetBaseOpcode(code, i); - if (base_opcode == ENTER_EXECUTOR) { - return -1; - } + assert(base_opcode != ENTER_EXECUTOR); if (opcode_has_event(base_opcode)) { int8_t event; if (base_opcode == RESUME) { From 4a0be4d061222c215a41379f8b73d689fc8f7429 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 6 Sep 2023 12:35:19 +0900 Subject: [PATCH 13/15] fix --- Python/instrumentation.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 38af543c75badd..9c2eb319a1cdd3 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1603,7 +1603,6 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) return 0; } /* Insert instrumentation */ - int code_len = (int)Py_SIZE(code); for (int i = code->_co_firsttraceable; i < code_len; i+= _PyInstruction_GetLength(code, i)) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; CHECK(instr->op.code != 0); From bc251b528cdba234a79eafaa2efdc3655afc3f86 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Thu, 7 Sep 2023 06:27:01 +0900 Subject: [PATCH 14/15] Fix --- Python/instrumentation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 9c2eb319a1cdd3..1d990682409d30 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1303,7 +1303,6 @@ initialize_tools(PyCodeObject *code) opcode = DE_INSTRUMENT[opcode]; assert(opcode != 0); } - assert(opcode != ENTER_EXECUTOR); opcode = _PyOpcode_Deopt[opcode]; if (opcode_has_event(opcode)) { if (instrumented) { @@ -1606,6 +1605,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) for (int i = code->_co_firsttraceable; i < code_len; i+= _PyInstruction_GetLength(code, i)) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; CHECK(instr->op.code != 0); + assert(instr->op.code != ENTER_EXECUTOR); int base_opcode = _Py_GetBaseOpcode(code, i); assert(base_opcode != ENTER_EXECUTOR); if (opcode_has_event(base_opcode)) { From 83d88290a33fc6e6d11433040520f22a07d89068 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Thu, 7 Sep 2023 07:23:12 +0900 Subject: [PATCH 15/15] Address Guido's review --- Python/instrumentation.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 1d990682409d30..acc3278d50a60a 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1295,6 +1295,7 @@ initialize_tools(PyCodeObject *code) for (int i = 0; i < code_len; i++) { _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; int opcode = instr->op.code; + assert(opcode != ENTER_EXECUTOR); if (opcode == INSTRUMENTED_LINE) { opcode = code->_co_monitoring->lines[i].original_opcode; }