Author: Armin Rigo <ar...@tunes.org> Branch: stm-gc Changeset: r52632:a0bf9b1b1049 Date: 2012-02-19 14:46 +0100 http://bitbucket.org/pypy/pypy/changeset/a0bf9b1b1049/
Log: A hint that crashes if a variable is not proven local. Use it to check that propagation of localness of the PyFrame works (which doesn't seem to be the case right now). diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -197,11 +197,13 @@ # stack manipulation helpers def pushvalue(self, w_object): + hint(self, stm_assert_local=True) depth = self.valuestackdepth self.locals_stack_w[depth] = w_object self.valuestackdepth = depth + 1 def popvalue(self): + hint(self, stm_assert_local=True) depth = self.valuestackdepth - 1 assert depth >= self.pycode.co_nlocals, "pop from empty value stack" w_object = self.locals_stack_w[depth] diff --git a/pypy/translator/stm/localtracker.py b/pypy/translator/stm/localtracker.py --- a/pypy/translator/stm/localtracker.py +++ b/pypy/translator/stm/localtracker.py @@ -27,6 +27,7 @@ # XXX we shouldn't get here, but we do translating the whole # pypy. We should investigate at some point. In the meantime # returning False is always safe. + self.reason = 'variable not in gsrc!' return False for src in srcs: if isinstance(src, SpaceOperation): @@ -34,14 +35,25 @@ continue if src.opname == 'hint' and 'stm_write' in src.args[1].value: continue + self.reason = src return False elif isinstance(src, Constant): if src.value: # a NULL pointer is still valid as local + self.reason = src return False elif src is None: + self.reason = 'found a None' return False elif src == 'instantiate': pass else: raise AssertionError(repr(src)) return True + + def assert_local(self, variable, graph='?'): + if self.is_local(variable): + return # fine + else: + raise AssertionError( + "assert_local() failed (%s, %s):\n%r" % (variable, graph, + self.reason)) diff --git a/pypy/translator/stm/test/test_localtracker.py b/pypy/translator/stm/test/test_localtracker.py --- a/pypy/translator/stm/test/test_localtracker.py +++ b/pypy/translator/stm/test/test_localtracker.py @@ -27,6 +27,7 @@ for name, v in self.translator._seen_locals.items(): if self.localtracker.is_local(v): got_local_names.add(name) + self.localtracker.assert_local(v, 'foo') assert got_local_names == set(expected_names) diff --git a/pypy/translator/stm/test/test_transform.py b/pypy/translator/stm/test/test_transform.py --- a/pypy/translator/stm/test/test_transform.py +++ b/pypy/translator/stm/test/test_transform.py @@ -41,7 +41,7 @@ pre_insert_stm_writebarrier(graph) if option.view: graph.show() - # weak test: check that there are exactly two stm_writebarrier inserted. + # weak test: check that there are exactly 3 stm_writebarrier inserted. # one should be for 'x.n = n', one should cover both field assignments # to the Z instance, and the 3rd one is in the block 'x.n *= 2'. sum = summary(graph) diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py --- a/pypy/translator/stm/transform.py +++ b/pypy/translator/stm/transform.py @@ -79,8 +79,10 @@ self.current_block = None def transform_graph(self, graph): + self.graph = graph for block in graph.iterblocks(): self.transform_block(block) + del self.graph # ---------- @@ -170,6 +172,10 @@ op = SpaceOperation('stm_writebarrier', [op.args[0]], op.result) self.stt_stm_writebarrier(newoperations, op) return + if 'stm_assert_local' in op.args[1].value: + self.localtracker.assert_local(op.args[0], + getattr(self, 'graph', None)) + return newoperations.append(op) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit