pypy3.10/008-maximum-recursion-depth...

180 lines
8.5 KiB
Diff

diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
index 9b14943..b9d1c4c 100644
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1052,35 +1052,45 @@ class BlackholeInterpreter(object):
@arguments("cpu", "i", "R", "d", returns="i")
def bhimpl_residual_call_r_i(cpu, func, args_r, calldescr):
+ workaround2200.active = True
return cpu.bh_call_i(func, None, args_r, None, calldescr)
@arguments("cpu", "i", "R", "d", returns="r")
def bhimpl_residual_call_r_r(cpu, func, args_r, calldescr):
+ workaround2200.active = True
return cpu.bh_call_r(func, None, args_r, None, calldescr)
@arguments("cpu", "i", "R", "d")
def bhimpl_residual_call_r_v(cpu, func, args_r, calldescr):
+ workaround2200.active = True
return cpu.bh_call_v(func, None, args_r, None, calldescr)
@arguments("cpu", "i", "I", "R", "d", returns="i")
def bhimpl_residual_call_ir_i(cpu, func, args_i, args_r, calldescr):
+ workaround2200.active = True
return cpu.bh_call_i(func, args_i, args_r, None, calldescr)
@arguments("cpu", "i", "I", "R", "d", returns="r")
def bhimpl_residual_call_ir_r(cpu, func, args_i, args_r, calldescr):
+ workaround2200.active = True
return cpu.bh_call_r(func, args_i, args_r, None, calldescr)
@arguments("cpu", "i", "I", "R", "d")
def bhimpl_residual_call_ir_v(cpu, func, args_i, args_r, calldescr):
+ workaround2200.active = True
return cpu.bh_call_v(func, args_i, args_r, None, calldescr)
@arguments("cpu", "i", "I", "R", "F", "d", returns="i")
def bhimpl_residual_call_irf_i(cpu, func, args_i,args_r,args_f,calldescr):
+ workaround2200.active = True
return cpu.bh_call_i(func, args_i, args_r, args_f, calldescr)
@arguments("cpu", "i", "I", "R", "F", "d", returns="r")
def bhimpl_residual_call_irf_r(cpu, func, args_i,args_r,args_f,calldescr):
+ workaround2200.active = True
return cpu.bh_call_r(func, args_i, args_r, args_f, calldescr)
@arguments("cpu", "i", "I", "R", "F", "d", returns="f")
def bhimpl_residual_call_irf_f(cpu, func, args_i,args_r,args_f,calldescr):
+ workaround2200.active = True
return cpu.bh_call_f(func, args_i, args_r, args_f, calldescr)
@arguments("cpu", "i", "I", "R", "F", "d")
def bhimpl_residual_call_irf_v(cpu, func, args_i,args_r,args_f,calldescr):
+ workaround2200.active = True
return cpu.bh_call_v(func, args_i, args_r, args_f, calldescr)
# conditional calls - note that they cannot return stuff
@@ -1108,44 +1118,54 @@ class BlackholeInterpreter(object):
@arguments("cpu", "j", "R", returns="i")
def bhimpl_inline_call_r_i(cpu, jitcode, args_r):
+ workaround2200.active = True
return cpu.bh_call_i(jitcode.get_fnaddr_as_int(),
None, args_r, None, jitcode.calldescr)
@arguments("cpu", "j", "R", returns="r")
def bhimpl_inline_call_r_r(cpu, jitcode, args_r):
+ workaround2200.active = True
return cpu.bh_call_r(jitcode.get_fnaddr_as_int(),
None, args_r, None, jitcode.calldescr)
@arguments("cpu", "j", "R")
def bhimpl_inline_call_r_v(cpu, jitcode, args_r):
+ workaround2200.active = True
return cpu.bh_call_v(jitcode.get_fnaddr_as_int(),
None, args_r, None, jitcode.calldescr)
@arguments("cpu", "j", "I", "R", returns="i")
def bhimpl_inline_call_ir_i(cpu, jitcode, args_i, args_r):
+ workaround2200.active = True
return cpu.bh_call_i(jitcode.get_fnaddr_as_int(),
args_i, args_r, None, jitcode.calldescr)
@arguments("cpu", "j", "I", "R", returns="r")
def bhimpl_inline_call_ir_r(cpu, jitcode, args_i, args_r):
+ workaround2200.active = True
return cpu.bh_call_r(jitcode.get_fnaddr_as_int(),
args_i, args_r, None, jitcode.calldescr)
@arguments("cpu", "j", "I", "R")
def bhimpl_inline_call_ir_v(cpu, jitcode, args_i, args_r):
+ workaround2200.active = True
return cpu.bh_call_v(jitcode.get_fnaddr_as_int(),
args_i, args_r, None, jitcode.calldescr)
@arguments("cpu", "j", "I", "R", "F", returns="i")
def bhimpl_inline_call_irf_i(cpu, jitcode, args_i, args_r, args_f):
+ workaround2200.active = True
return cpu.bh_call_i(jitcode.get_fnaddr_as_int(),
args_i, args_r, args_f, jitcode.calldescr)
@arguments("cpu", "j", "I", "R", "F", returns="r")
def bhimpl_inline_call_irf_r(cpu, jitcode, args_i, args_r, args_f):
+ workaround2200.active = True
return cpu.bh_call_r(jitcode.get_fnaddr_as_int(),
args_i, args_r, args_f, jitcode.calldescr)
@arguments("cpu", "j", "I", "R", "F", returns="f")
def bhimpl_inline_call_irf_f(cpu, jitcode, args_i, args_r, args_f):
+ workaround2200.active = True
return cpu.bh_call_f(jitcode.get_fnaddr_as_int(),
args_i, args_r, args_f, jitcode.calldescr)
@arguments("cpu", "j", "I", "R", "F")
def bhimpl_inline_call_irf_v(cpu, jitcode, args_i, args_r, args_f):
+ workaround2200.active = True
return cpu.bh_call_v(jitcode.get_fnaddr_as_int(),
args_i, args_r, args_f, jitcode.calldescr)
@@ -1438,6 +1458,8 @@ class BlackholeInterpreter(object):
if not self.nextblackholeinterp:
self._exit_frame_with_exception(current_exc)
return current_exc
+ finally:
+ workaround2200.active = False
#
# pass the frame's return value to the caller
caller = self.nextblackholeinterp
@@ -1656,3 +1678,10 @@ def convert_and_run_from_pyjitpl(metainterp, raising_exception=False):
current_exc = lltype.nullptr(rclass.OBJECTPTR.TO)
#
_run_forever(firstbh, current_exc)
+
+# ____________________________________________________________
+
+class WorkaroundIssue2200(object):
+ pass
+workaround2200 = WorkaroundIssue2200()
+workaround2200.active = False
diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py
index ad81456..c820185 100644
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -4044,3 +4044,30 @@ class TestLLtype(BaseLLtypeTests, LLJitMixin):
res = self.interp_operations(f, [17])
assert res == 42
self.check_operations_history(guard_true=1, guard_false=0)
+
+ def test_issue2200_recursion(self):
+ # Reproduces issue #2200. This test contains no recursion,
+ # but due to an unlikely combination of factors it ends up
+ # creating an RPython-level recursion, one per loop iteration.
+ # The recursion is: blackhole interp from the failing guard ->
+ # does the call to enter() as a normal call -> enter() runs
+ # can_enter_jit() as if we're interpreted -> we enter the JIT
+ # again from the start of the loop -> the guard fails again
+ # during the next iteration -> blackhole interp. All arrows
+ # in the previous sentence are one or more levels of RPython
+ # function calls.
+ driver = JitDriver(greens=[], reds=["i"])
+ def enter(i):
+ driver.can_enter_jit(i=i)
+ def f():
+ set_param(None, 'trace_eagerness', 999999)
+ i = 0
+ while True:
+ driver.jit_merge_point(i=i)
+ i += 1
+ if i >= 300:
+ return i
+ promote(i + 1) # a failing guard
+ enter(i)
+
+ self.meta_interp(f, [])
diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py
index 805933e..ca47f03 100644
--- a/rpython/jit/metainterp/warmstate.py
+++ b/rpython/jit/metainterp/warmstate.py
@@ -405,6 +405,14 @@ class WarmEnterState(object):
bound_reached(hash, None, *args)
return
+ # Workaround for issue #2200, maybe temporary. This is not
+ # a proper fix, but only a hack that should work well enough
+ # for PyPy's main jitdriver... See test_issue2200_recursion
+ from rpython.jit.metainterp.blackhole import workaround2200
+ if workaround2200.active:
+ workaround2200.active = False
+ return
+
# Here, we have found 'cell'.
#
if cell.flags & (JC_TRACING | JC_TEMPORARY):