summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2020-04-26 23:48:42 +0200
committerStefan Behnel <stefan_ml@behnel.de>2020-04-26 23:57:04 +0200
commit872919215ee732c82d1560a8fb3cfdd195d49816 (patch)
tree836cd1d2664e9c7a6b75ad5b3fe17aad46ad9852
parentaedcf9a76a1cfc727bbe67a000731fcc5bd5ecc0 (diff)
downloadcython-872919215ee732c82d1560a8fb3cfdd195d49816.tar.gz
Avoid generating dead "assure GIL" code if we generated a "goto".
Add a comment explaining why the different code generation paths end up with the same GIL state.
-rw-r--r--Cython/Compiler/Nodes.py19
1 files changed, 12 insertions, 7 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index 600b0ea90..bef5db2e8 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -2066,14 +2066,15 @@ class FuncDefNode(StatNode, BlockNode):
# jump past it if we have an error. The if-test below determine
# whether this section is used.
if buffers_present or is_getbuffer_slot or return_type.is_memoryviewslice:
+ # In all three cases, we already called assure_gil('error') and own the GIL.
code.put_goto(code.return_from_error_cleanup_label)
-
- # align error and success state
- if gil_owned['success']:
- assure_gil('error')
- elif gil_owned['error']:
- code.put_release_ensured_gil()
- gil_owned['error'] = False
+ else:
+ # align error and success GIL state
+ if gil_owned['success']:
+ assure_gil('error')
+ elif gil_owned['error']:
+ code.put_release_ensured_gil()
+ gil_owned['error'] = False
# ----- Non-error return cleanup
code.put_label(code.return_label)
@@ -2102,6 +2103,10 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Return cleanup for both error and no-error return
code.put_label(code.return_from_error_cleanup_label)
+ # If we jumped here from the error path, then we own the GIL.
+ # If we came through the success path, we took the same decisions as for jumping.
+ # If we came through the error path and did not jump, we aligned both paths above.
+ # In the end, all three paths are aligned from this point on.
for entry in lenv.var_entries:
if not entry.used or entry.in_closure: