From d49598ed3e6c7b70d936adb643d38ca8e0fd79ff Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Sun, 24 Mar 2024 00:08:09 +0800 Subject: [PATCH 1/4] Remove call sequence when trace stack overflow --- Lib/test/test_capi/test_opt.py | 25 +++++++++++++++++++++++++ Python/optimizer.c | 7 +++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index b0859a382de523..269753e4c1cb83 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -955,6 +955,31 @@ def testfunc(n): _, ex = self._run_with_optimizer(testfunc, 16) self.assertIsNone(ex) + def test_many_nested(self): + # overflow the trace_stack + def dummy_a(x): + return x + def dummy_b(x): + return dummy_a(x) + def dummy_c(x): + return dummy_b(x) + def dummy_d(x): + return dummy_c(x) + def dummy_e(x): + return dummy_d(x) + def dummy_f(x): + return dummy_e(x) + def dummy_g(x): + return dummy_f(x) + def dummy_h(x): + return dummy_g(x) + def testfunc(n): + a = 0 + for _ in range(n): + a += dummy_h(n) + return a + + self._run_with_optimizer(testfunc, 32) if __name__ == "__main__": unittest.main() diff --git a/Python/optimizer.c b/Python/optimizer.c index 177ad343618c37..2ca0be28e7f025 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -475,8 +475,11 @@ BRANCH_TO_GUARD[4][2] = { #define TRACE_STACK_PUSH() \ if (trace_stack_depth >= TRACE_STACK_SIZE) { \ DPRINTF(2, "Trace stack overflow\n"); \ - OPT_STAT_INC(trace_stack_overflow); \ - ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); \ + OPT_STAT_INC(trace_stack_overflow); \ + /* Remove the call sequence */ \ + for (int x = 0; x < i; x++) { \ + trace[trace_length-x].opcode = _NOP; \ + } \ goto done; \ } \ assert(func == NULL || func->func_code == (PyObject *)code); \ From 7a00c9ac815fb82fcc954259c64ddbb397f2ad35 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Sun, 24 Mar 2024 00:10:26 +0800 Subject: [PATCH 2/4] add Peter as co-author Co-Authored-By: Peter Lazorchak --- Lib/test/test_capi/test_opt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 269753e4c1cb83..a1dc03dd3b651b 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -981,5 +981,6 @@ def testfunc(n): self._run_with_optimizer(testfunc, 32) + if __name__ == "__main__": unittest.main() From 70e764424b6d5488d9b78de5464a47009b2ce6ea Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Sun, 24 Mar 2024 05:04:34 +0800 Subject: [PATCH 3/4] Address Guido's review Co-Authored-By: Guido van Rossum --- Python/optimizer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Python/optimizer.c b/Python/optimizer.c index 2ca0be28e7f025..b412ed23b9f838 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -476,10 +476,8 @@ BRANCH_TO_GUARD[4][2] = { if (trace_stack_depth >= TRACE_STACK_SIZE) { \ DPRINTF(2, "Trace stack overflow\n"); \ OPT_STAT_INC(trace_stack_overflow); \ - /* Remove the call sequence */ \ - for (int x = 0; x < i; x++) { \ - trace[trace_length-x].opcode = _NOP; \ - } \ + ADD_TO_TRACE(uop, oparg, operand, target); \ + ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); \ goto done; \ } \ assert(func == NULL || func->func_code == (PyObject *)code); \ From f1256e3e3568ca0ac7201d46b901f132fed01b63 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 23 Mar 2024 14:06:50 -0700 Subject: [PATCH 4/4] Fix whitespace before backslash This shows there's only one changed line. --- Python/optimizer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/optimizer.c b/Python/optimizer.c index b412ed23b9f838..f8c1390a061650 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -475,7 +475,7 @@ BRANCH_TO_GUARD[4][2] = { #define TRACE_STACK_PUSH() \ if (trace_stack_depth >= TRACE_STACK_SIZE) { \ DPRINTF(2, "Trace stack overflow\n"); \ - OPT_STAT_INC(trace_stack_overflow); \ + OPT_STAT_INC(trace_stack_overflow); \ ADD_TO_TRACE(uop, oparg, operand, target); \ ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); \ goto done; \