From f53cd9d529209319541159dcea43b1227f49abf8 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 6 Jul 2022 06:45:06 +0100 Subject: [PATCH 1/6] gh-92228: disable the compiler's 'small exit block inlining' optimization --- Python/compile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Python/compile.c b/Python/compile.c index 77176893f60c5c..860af08e449266 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -8981,7 +8981,8 @@ jump_thread(struct instr *inst, struct instr *target, int opcode) } /* Maximum size of basic block that should be copied in optimizer */ -#define MAX_COPY_SIZE 4 +/* Set to 0 to disable to optimisation - see gh-92228 */ +#define MAX_COPY_SIZE 0 /* Optimization */ static int From 8adfcb99ca73e6ea14c2a9b488bc7d3d9d6a2e2b Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 6 Jul 2022 14:54:07 +0100 Subject: [PATCH 2/6] copy blocks that don't have line number. Fix tests --- Lib/test/test_dis.py | 27 +++++++-------------------- Lib/test/test_peepholer.py | 2 ++ Python/compile.c | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 256004855d4a6e..440e4ed5eacfb0 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -360,13 +360,13 @@ def bug42562(): --> BINARY_OP 11 (/) POP_TOP -%3d LOAD_FAST_CHECK 1 (tb) +%3d >> LOAD_FAST_CHECK 1 (tb) RETURN_VALUE >> PUSH_EXC_INFO %3d LOAD_GLOBAL 0 (Exception) CHECK_EXC_MATCH - POP_JUMP_FORWARD_IF_FALSE 23 (to 82) + POP_JUMP_FORWARD_IF_FALSE 22 (to 80) STORE_FAST 0 (e) %3d LOAD_FAST 0 (e) @@ -376,9 +376,7 @@ def bug42562(): LOAD_CONST 0 (None) STORE_FAST 0 (e) DELETE_FAST 0 (e) - -%3d LOAD_FAST 1 (tb) - RETURN_VALUE + JUMP_BACKWARD 29 (to 14) >> LOAD_CONST 0 (None) STORE_FAST 0 (e) DELETE_FAST 0 (e) @@ -396,7 +394,6 @@ def bug42562(): TRACEBACK_CODE.co_firstlineno + 5, TRACEBACK_CODE.co_firstlineno + 3, TRACEBACK_CODE.co_firstlineno + 4, - TRACEBACK_CODE.co_firstlineno + 5, TRACEBACK_CODE.co_firstlineno + 3) def _fstring(a, b, c, d): @@ -443,7 +440,7 @@ def _with(c): CALL 2 POP_TOP -%3d LOAD_CONST 2 (2) +%3d >> LOAD_CONST 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -456,11 +453,7 @@ def _with(c): POP_EXCEPT POP_TOP POP_TOP - -%3d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - LOAD_CONST 0 (None) - RETURN_VALUE + JUMP_BACKWARD 13 (to 30) >> COPY 3 POP_EXCEPT RERAISE 1 @@ -472,7 +465,6 @@ def _with(c): _with.__code__.co_firstlineno + 1, _with.__code__.co_firstlineno + 3, _with.__code__.co_firstlineno + 1, - _with.__code__.co_firstlineno + 3, ) async def _asyncwith(c): @@ -510,7 +502,7 @@ async def _asyncwith(c): JUMP_BACKWARD_NO_INTERRUPT 4 (to 48) >> POP_TOP -%3d LOAD_CONST 2 (2) +%3d >> LOAD_CONST 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -529,11 +521,7 @@ async def _asyncwith(c): POP_EXCEPT POP_TOP POP_TOP - -%3d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - LOAD_CONST 0 (None) - RETURN_VALUE + JUMP_BACKWARD 19 (to 58) >> COPY 3 POP_EXCEPT RERAISE 1 @@ -545,7 +533,6 @@ async def _asyncwith(c): _asyncwith.__code__.co_firstlineno + 1, _asyncwith.__code__.co_firstlineno + 3, _asyncwith.__code__.co_firstlineno + 1, - _asyncwith.__code__.co_firstlineno + 3, ) diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 2c3b1ab65a8f9d..e03c42c2f823dc 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -345,6 +345,8 @@ def f(x): self.assertEqual(len(returns), 1) self.check_lnotab(f) + @unittest.skip("Following gh-92228 the return has two predecessors " + "and that prevents jump elimination.") def test_elim_jump_to_return(self): # JUMP_FORWARD to RETURN --> RETURN def f(cond, true_value, false_value): diff --git a/Python/compile.c b/Python/compile.c index 860af08e449266..daafab3ab18fd3 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -8982,7 +8982,7 @@ jump_thread(struct instr *inst, struct instr *target, int opcode) /* Maximum size of basic block that should be copied in optimizer */ /* Set to 0 to disable to optimisation - see gh-92228 */ -#define MAX_COPY_SIZE 0 +#define MAX_COPY_SIZE 4 /* Optimization */ static int @@ -9225,6 +9225,16 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts) return -1; } +static bool +basicblock_has_lineno(const basicblock *bb) { + for (int i = 0; i < bb->b_iused; i++) { + if (bb->b_instr[i].i_loc.lineno > 0) { + return true; + } + } + return false; +} + /* If this block ends with an unconditional jump to an exit block, * then remove the jump and extend this block with the target. */ @@ -9241,6 +9251,10 @@ extend_block(basicblock *bb) { } if (basicblock_exits_scope(last->i_target) && last->i_target->b_iused <= MAX_COPY_SIZE) { basicblock *to_copy = last->i_target; + if (basicblock_has_lineno(to_copy)) { + /* copy only blocks without line number (like implicit 'return None's) */ + return 0; + } last->i_opcode = NOP; for (int i = 0; i < to_copy->b_iused; i++) { int index = basicblock_next_instr(bb); From 66f3f12a7cf9e0fdbaaa4832210b63aedc9dad08 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 14:02:28 +0000 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst new file mode 100644 index 00000000000000..109a827677637e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst @@ -0,0 +1 @@ +Disable the compiler's inline-small-exit-blocks optimization for exit blocks that are associated with source code lines. This fixes a bug where the debugger cannot tell where an exception handler starts and the following code block begins. From 7254f0db20620f805be1cbb0d78913460ad1970e Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 6 Jul 2022 15:22:43 +0100 Subject: [PATCH 4/6] add unit test for the new bug --- Lib/test/test_sys_settrace.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 7ec290dbf04ad5..f03b03e19a2528 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -2042,6 +2042,15 @@ def test_no_jump_within_except_block(output): output.append(6) output.append(7) + @jump_test(6, 1, [1, 5, 1, 5]) + def test_jump_over_try_except(output): + output.append(1) + try: + 1 / 0 + except ZeroDivisionError as e: + output.append(5) + x = 42 # has to be a two-instruction block + @jump_test(2, 4, [1, 4, 5, -4]) def test_jump_across_with(output): output.append(1) From b1400bfc096b28c8c54928a843f3736a194bdc51 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Wed, 6 Jul 2022 15:28:06 +0100 Subject: [PATCH 5/6] Remove incorrect comment --- Python/compile.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/compile.c b/Python/compile.c index daafab3ab18fd3..f36a6e85a54c20 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -8981,7 +8981,6 @@ jump_thread(struct instr *inst, struct instr *target, int opcode) } /* Maximum size of basic block that should be copied in optimizer */ -/* Set to 0 to disable to optimisation - see gh-92228 */ #define MAX_COPY_SIZE 4 /* Optimization */ From 29f76b70857fd6efa7d4a87d6451040da6c91d76 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Wed, 6 Jul 2022 15:40:28 +0100 Subject: [PATCH 6/6] typo --- .../2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst index 109a827677637e..458ad897cefcb6 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-06-14-02-26.gh-issue-92228.44Cbly.rst @@ -1 +1 @@ -Disable the compiler's inline-small-exit-blocks optimization for exit blocks that are associated with source code lines. This fixes a bug where the debugger cannot tell where an exception handler starts and the following code block begins. +Disable the compiler's inline-small-exit-blocks optimization for exit blocks that are associated with source code lines. This fixes a bug where the debugger cannot tell where an exception handler ends and the following code block begins.