Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

finally blocks are duplicated by the compiler unnecessarily #92619

Closed
iritkatriel opened this issue May 10, 2022 · 0 comments · Fixed by #92620
Closed

finally blocks are duplicated by the compiler unnecessarily #92619

iritkatriel opened this issue May 10, 2022 · 0 comments · Fixed by #92620
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage type-bug An unexpected behavior, bug, or error

Comments

@iritkatriel
Copy link
Member

Bug report

Input:

def f():
   try:
     x = "try"
   except:
     x = "except"
   finally:
     x = "finally"
     return x

import dis
dis.dis(f)

Output:

  1           0 RESUME                   0

  2           2 NOP

  3           4 LOAD_CONST               1 ('try')
              6 STORE_FAST               0 (x)
              8 JUMP_FORWARD             9 (to 28)
        >>   10 PUSH_EXC_INFO

  4          12 POP_TOP

  5          14 LOAD_CONST               2 ('except')
             16 STORE_FAST               0 (x)
             18 POP_EXCEPT
             20 JUMP_FORWARD             8 (to 38)
        >>   22 COPY                     3
             24 POP_EXCEPT
             26 RERAISE                  1

  3     >>   28 NOP

  7          30 LOAD_CONST               3 ('finally')
             32 STORE_FAST               0 (x)

  8          34 LOAD_FAST                0 (x)
             36 RETURN_VALUE

  5     >>   38 NOP

  7          40 LOAD_CONST               3 ('finally')
             42 STORE_FAST               0 (x)

  8          44 LOAD_FAST                0 (x)
             46 RETURN_VALUE
        >>   48 PUSH_EXC_INFO

  7          50 LOAD_CONST               3 ('finally')
             52 STORE_FAST               0 (x)

  8          54 LOAD_FAST                0 (x)
             56 SWAP                     2
             58 POP_TOP
             60 SWAP                     2
             62 POP_EXCEPT
             64 RETURN_VALUE
        >>   66 COPY                     3
             68 POP_EXCEPT
             70 RERAISE                  1
ExceptionTable:
  4 to 6 -> 10 [0]
  8 to 8 -> 48 [0]
  10 to 16 -> 22 [1] lasti
  18 to 26 -> 48 [0]
  48 to 60 -> 66 [1] lasti

Lines 28-36 are exactly the same as lines 38-46. The reason they got duplicated is because of duplicate_exits_without_lineno, which makes copies of exit blocks that don't have a line number, and can be reached from more than one place (because line numbers are static).

However, the check is "is it an exit block and does the first instruction have a lineno". In our case, the first instruction is a virtual POP_BLOCK (which eventually becomes a NOP). The virtual instruction doesn't have a line number, but the following instructions (the finally body) do. Note that what we really care about is whether the last instruction has a line number.

@iritkatriel iritkatriel added type-bug An unexpected behavior, bug, or error performance Performance or resource usage interpreter-core (Objects, Python, Grammar, and Parser dirs) labels May 10, 2022
@iritkatriel iritkatriel self-assigned this May 10, 2022
iritkatriel added a commit to iritkatriel/cpython that referenced this issue May 10, 2022
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 10, 2022
…ecessarily (pythonGH-92620)

(cherry picked from commit 7c6b7ad)

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
iritkatriel added a commit that referenced this issue May 10, 2022
…rily (GH-92620) (GH-92621)

(cherry picked from commit 7c6b7ad)

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant