Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r50175:5abc8457062e Date: 2011-12-05 19:05 +0100 http://bitbucket.org/pypy/pypy/changeset/5abc8457062e/
Log: Fix the test. diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -298,7 +298,7 @@ pass class ResumeGuardDescr(ResumeDescr): - _counter = 0 # if < 0, there is one counter per value; + _counter = 0 # on a GUARD_VALUE, there is one counter per value; _counters = None # they get stored in _counters then. # this class also gets the following attributes stored by resume.py code @@ -309,10 +309,13 @@ rd_virtuals = None rd_pendingfields = lltype.nullptr(PENDINGFIELDSP.TO) - CNT_INT = -0x20000000 - CNT_REF = -0x40000000 - CNT_FLOAT = -0x60000000 - CNT_MASK = 0x1FFFFFFF + CNT_BASE_MASK = 0x0FFFFFFF # the base counter value + CNT_BUSY_FLAG = 0x10000000 # if set, busy tracing from the guard + CNT_TYPE_MASK = 0x60000000 # mask for the type + + CNT_INT = 0x20000000 + CNT_REF = 0x40000000 + CNT_FLOAT = 0x60000000 def store_final_boxes(self, guard_op, boxes): guard_op.setfailargs(boxes) @@ -326,6 +329,8 @@ except ValueError: return # xxx probably very rare else: + if i > self.CNT_BASE_MASK: + return # probably never, but better safe than sorry if box.type == history.INT: cnt = self.CNT_INT elif box.type == history.REF: @@ -334,14 +339,17 @@ cnt = self.CNT_FLOAT else: assert 0, box.type - # we build the following value for _counter, which is always - # a negative value + assert cnt > self.CNT_BASE_MASK self._counter = cnt | i def handle_fail(self, metainterp_sd, jitdriver_sd): if self.must_compile(metainterp_sd, jitdriver_sd): - return self._trace_and_compile_from_bridge(metainterp_sd, - jitdriver_sd) + self.start_compiling() + try: + return self._trace_and_compile_from_bridge(metainterp_sd, + jitdriver_sd) + finally: + self.done_compiling() else: from pypy.jit.metainterp.blackhole import resume_in_blackhole resume_in_blackhole(metainterp_sd, jitdriver_sd, self) @@ -359,12 +367,22 @@ def must_compile(self, metainterp_sd, jitdriver_sd): trace_eagerness = jitdriver_sd.warmstate.trace_eagerness - if self._counter >= 0: + # + if self._counter <= self.CNT_BASE_MASK: + # simple case: just counting from 0 to trace_eagerness self._counter += 1 return self._counter >= trace_eagerness - else: - index = self._counter & self.CNT_MASK - typetag = self._counter & ~ self.CNT_MASK + # + # do we have the BUSY flag? If so, we're tracing right now, e.g. in an + # outer invocation of the same function, so don't trace again for now. + elif self._counter & self.CNT_BUSY_FLAG: + return False + # + else: # we have a GUARD_VALUE that fails. Make a _counters instance + # (only now, when the guard is actually failing at least once), + # and use it to record some statistics about the failing values. + index = self._counter & self.CNT_BASE_MASK + typetag = self._counter & self.CNT_TYPE_MASK counters = self._counters if typetag == self.CNT_INT: intvalue = metainterp_sd.cpu.get_latest_value_int(index) @@ -391,7 +409,16 @@ assert 0, typetag return counter >= trace_eagerness - def reset_counter_from_failure(self): + def start_compiling(self): + # start tracing and compiling from this guard. + self._counter |= self.CNT_BUSY_FLAG + + def done_compiling(self): + # done tracing and compiling from this guard. Either the bridge has + # been successfully compiled, in which case whatever value we store + # in self._counter will not be seen any more, or not, in which case + # we should reset the counter to 0, in order to wait a bit until the + # next attempt. if self._counter >= 0: self._counter = 0 self._counters = None @@ -608,9 +635,6 @@ metainterp.set_compiled_merge_points(self.original_greenkey, old_loop_tokens) - def reset_counter_from_failure(self): - pass - def compile_new_bridge(metainterp, old_loop_tokens, resumekey, retraced=False): """Try to compile a new bridge leading from the beginning of the history diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -1790,7 +1790,6 @@ self.staticdata.profiler.count(reason) debug_print('~~~ ABORTING TRACING') self.staticdata.stats.aborted() - self.resumekey.reset_counter_from_failure() def blackhole_if_trace_too_long(self): warmrunnerstate = self.jitdriver_sd.warmstate diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py --- a/pypy/jit/metainterp/test/test_recursive.py +++ b/pypy/jit/metainterp/test/test_recursive.py @@ -1255,11 +1255,12 @@ if i <= 0: # <- guard continue # first make a loop else: - # then we fail the guard above, doing a recursive call + # then we fail the guard above, doing a recursive call, + # which will itself fail the same guard above, and so on return portal(level + 1) self.meta_interp(portal, [0]) - assert self.check_loop_count_at_most(3) # and not, e.g., 24 + self.check_loop_count_at_most(2) # and not, e.g., 24 class TestLLtype(RecursiveTests, LLJitMixin): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit