Author: Hakan Ardo <[email protected]>
Branch:
Changeset: r45279:72e8d0b95d88
Date: 2011-07-02 19:19 +0200
http://bitbucket.org/pypy/pypy/changeset/72e8d0b95d88/
Log: Cherry picked the retrace count bugfix from fcbb3a03ff88. The test
is not working anymore. There seems to be two entry bridges created
now, dont know why...
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -765,6 +765,7 @@
"""
short_preamble = None
failed_states = None
+ retraced_count = 0
terminating = False # see TerminatingLoopToken in compile.py
outermost_jitdriver_sd = None
# and more data specified by the backend when the loop is compiled
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py
b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -676,24 +676,28 @@
jumpop = self.optimizer.newoperations.pop()
assert jumpop.getopnum() == rop.JUMP
for guard in extra_guards:
- descr = sh.start_resumedescr.clone_if_mutable()
- self.inliner.inline_descr_inplace(descr)
- guard.setdescr(descr)
+ d = sh.start_resumedescr.clone_if_mutable()
+ self.inliner.inline_descr_inplace(d)
+ guard.setdescr(d)
self.emit_operation(guard)
self.optimizer.newoperations.append(jumpop)
return
- retraced_count = len(short)
- if descr.failed_states:
- retraced_count += len(descr.failed_states)
+ retraced_count = descr.retraced_count
+ descr.retraced_count += 1
limit =
self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
if not self.retraced and retraced_count<limit:
if not descr.failed_states:
+ debug_print("Retracing (%d of %d)" % (retraced_count,
+ limit))
raise RetraceLoop
for failed in descr.failed_states:
if failed.generalization_of(virtual_state):
# Retracing once more will most likely fail again
break
else:
+ debug_print("Retracing (%d of %d)" % (retraced_count,
+ limit))
+
raise RetraceLoop
else:
if not descr.failed_states:
diff --git a/pypy/jit/metainterp/test/test_ajit.py
b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -1676,8 +1676,8 @@
return a1.val + b1.val
res = self.meta_interp(g, [6, 14])
assert res == g(6, 14)
- self.check_loop_count(9)
- self.check_loops(getarrayitem_gc=8, everywhere=True)
+ self.check_loop_count(8)
+ self.check_loops(getarrayitem_gc=7, everywhere=True)
py.test.skip("for the following, we need setarrayitem(varindex)")
self.check_loops(getarrayitem_gc=6, everywhere=True)
@@ -2314,6 +2314,66 @@
assert res == -2
#self.check_loops(getarrayitem_gc=0, setarrayitem_gc=0) -- xxx?
+ def test_retrace_ending_up_retrazing_another_loop(self):
+
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'i', 'sa'])
+ bytecode = "0+sI0+SI"
+ def f(n):
+ myjitdriver.set_param('threshold', 3)
+ myjitdriver.set_param('trace_eagerness', 1)
+ myjitdriver.set_param('retrace_limit', 5)
+ pc = sa = i = 0
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i)
+ n = hint(n, promote=True)
+ op = bytecode[pc]
+ if op == '0':
+ i = 0
+ elif op == '+':
+ i += 1
+ elif op == 's':
+ sa += i
+ elif op == 'S':
+ sa += 2
+ elif op == 'I':
+ if i < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i)
+ continue
+ pc += 1
+ return sa
+
+ def g(n1, n2):
+ for i in range(10):
+ f(n1)
+ for i in range(10):
+ f(n2)
+
+ nn = [10, 3]
+ assert self.meta_interp(g, nn) == g(*nn)
+
+ # The attempts of retracing first loop will end up retracing the
+ # second and thus fail 5 times, saturating the retrace_count. Instead a
+ # bridge back to the preamble of the first loop is produced. A guard in
+ # this bridge is later traced resulting in a retrace of the second
loop.
+ # Thus we end up with:
+ # 1 preamble and 1 specialized version of first loop
+ # 1 preamble and 2 specialized version of second loop
+ self.check_tree_loop_count(2 + 3)
+
+ # FIXME: Add a gloabl retrace counter and test that we are not trying
more than 5 times.
+
+ def g(n):
+ for i in range(n):
+ for j in range(10):
+ f(n-i)
+
+ res = self.meta_interp(g, [10])
+ assert res == g(10)
+ # 1 preamble and 6 speciealized versions of each loop
+ self.check_tree_loop_count(2*(1 + 6))
+
+
class TestOOtype(BasicTests, OOJitMixin):
def test_oohash(self):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit