180 lines
8.5 KiB
Diff
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):
|