Commit 0fdb241a authored by Stefan Behnel's avatar Stefan Behnel

avoid GIL state temp overhead in sections that do not contain yields

--HG--
extra : rebase_source : 9be74b8a1d6509acf415bf667558a635b38a902f
parent a0618964
...@@ -6479,18 +6479,29 @@ class GILStatNode(NogilTryFinallyStatNode): ...@@ -6479,18 +6479,29 @@ class GILStatNode(NogilTryFinallyStatNode):
# #
# state string 'gil' or 'nogil' # state string 'gil' or 'nogil'
state_temp = None
def __init__(self, pos, state, body): def __init__(self, pos, state, body):
self.state = state self.state = state
self.create_state_temp_if_needed(pos, state, body)
TryFinallyStatNode.__init__(self, pos,
body=body,
finally_clause=GILExitNode(
pos, state=state, state_temp=self.state_temp))
def create_state_temp_if_needed(self, pos, state, body):
from ParseTreeTransforms import YieldNodeCollector
collector = YieldNodeCollector()
collector.visitchildren(body)
if not collector.yields:
return
if state == 'gil': if state == 'gil':
temp_type = PyrexTypes.c_gilstate_type temp_type = PyrexTypes.c_gilstate_type
else: else:
temp_type = PyrexTypes.c_threadstate_ptr_type temp_type = PyrexTypes.c_threadstate_ptr_type
import ExprNodes import ExprNodes
self.state_temp = ExprNodes.TempNode(pos, temp_type) self.state_temp = ExprNodes.TempNode(pos, temp_type)
TryFinallyStatNode.__init__(self, pos,
body=body,
finally_clause=GILExitNode(
pos, state=state, state_temp=self.state_temp))
def analyse_declarations(self, env): def analyse_declarations(self, env):
env._in_with_gil_block = (self.state == 'gil') env._in_with_gil_block = (self.state == 'gil')
...@@ -6511,16 +6522,21 @@ class GILStatNode(NogilTryFinallyStatNode): ...@@ -6511,16 +6522,21 @@ class GILStatNode(NogilTryFinallyStatNode):
def generate_execution_code(self, code): def generate_execution_code(self, code):
code.mark_pos(self.pos) code.mark_pos(self.pos)
code.begin_block() code.begin_block()
self.state_temp.allocate(code) if self.state_temp:
self.state_temp.allocate(code)
variable = self.state_temp.result()
else:
variable = None
if self.state == 'gil': if self.state == 'gil':
code.put_ensure_gil(variable=self.state_temp.result()) code.put_ensure_gil(variable=variable)
else: else:
code.put_release_gil(variable=self.state_temp.result()) code.put_release_gil(variable=variable)
TryFinallyStatNode.generate_execution_code(self, code) TryFinallyStatNode.generate_execution_code(self, code)
self.state_temp.release(code) if self.state_temp:
self.state_temp.release(code)
code.end_block() code.end_block()
......
...@@ -345,3 +345,7 @@ def test_double_with_gil_section(): ...@@ -345,3 +345,7 @@ def test_double_with_gil_section():
for j in range(2): for j in range(2):
with gil: with gil:
yield i*2+j yield i*2+j
with nogil:
pass
with gil:
pass
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment