[pypy-commit] pypy stm-gc: A hint that crashes if a variable is not proven local. Use it to check
arigo
noreply at buildbot.pypy.org
Sun Feb 19 14:46:35 CET 2012
Author: Armin Rigo <arigo at 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)
More information about the pypy-commit
mailing list