[pypy-commit] pypy stm-thread: Remove the hand-waving uncertainty of gcsource, and instead
arigo
noreply at buildbot.pypy.org
Tue Jun 5 09:58:59 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread
Changeset: r55306:62c2fc45c3a8
Date: 2012-06-04 16:51 +0200
http://bitbucket.org/pypy/pypy/changeset/62c2fc45c3a8/
Log: Remove the hand-waving uncertainty of gcsource, and instead assume
that it is able to find *all* calls to functions with a GC arg or
result. Tentative: this should be true because external calls and
callbacks are always with functions with no GC argument.
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -134,6 +134,9 @@
if self.config.translation.stm:
from pypy.translator.stm import transform
+ self.getentrypointptr() # build the wrapper first
+ # ^^ this is needed to make sure we see the no-GC wrapper function
+ # calling the GC entrypoint function.
transformer = transform.STMTransformer(self.translator)
transformer.transform()
diff --git a/pypy/translator/stm/gcsource.py b/pypy/translator/stm/gcsource.py
--- a/pypy/translator/stm/gcsource.py
+++ b/pypy/translator/stm/gcsource.py
@@ -1,4 +1,4 @@
-from pypy.objspace.flow.model import Variable
+from pypy.objspace.flow.model import Variable, Constant
from pypy.rpython.lltypesystem import lltype, rclass
from pypy.translator.simplify import get_graph
@@ -25,23 +25,23 @@
# We don't have to worry about external calls and callbacks.
# This works by assuming that each graph's calls are fully tracked
# by the last argument to 'indirect_call'. Graphs for which we don't
- # find any call like this are assumed to be called 'from the outside'
- # passing any random arguments to it.
+ # find any call like this are assumed to be not called at all, e.g.
+ # as a result of having been inlined everywhere.
resultlist = []
- was_a_callee = set()
#
def call(graph, args, result):
inputargs = graph.getargs()
assert len(args) == len(inputargs)
for v1, v2 in zip(args, inputargs):
- if is_gc(v2):
- assert is_gc(v1)
+ ig = is_gc(v1)
+ assert ig is is_gc(v2)
+ if ig:
resultlist.append((v1, v2))
- if is_gc(result):
- v = graph.getreturnvar()
- assert is_gc(v)
+ v = graph.getreturnvar()
+ ig = is_gc(result)
+ assert ig is is_gc(v)
+ if ig:
resultlist.append((v, result))
- was_a_callee.add(graph)
#
for graph in translator.graphs:
for block in graph.iterblocks():
@@ -61,6 +61,14 @@
continue
#
if op.opname == 'indirect_call':
+ # any GC argument or result?
+ for v in op.args[:-1]:
+ if is_gc(v):
+ break
+ else:
+ if not is_gc(op.result):
+ continue # no: ignore the indirect_call
+ #
tographs = op.args[-1].value
if tographs is not None:
for tograph in tographs:
@@ -79,34 +87,21 @@
if is_instantiate:
resultlist.append(('instantiate', op.result))
continue
+ #
+ raise Exception("%r: unknown targets, passing GC "
+ "arguments or result" % (op,))
#
if is_gc(op.result):
resultlist.append((op, op.result))
#
for link in block.exits:
for v1, v2 in zip(link.args, link.target.inputargs):
- if is_gc(v2):
- assert is_gc(v1)
+ ig = is_gc(v2)
+ assert ig is is_gc(v1)
+ if ig:
if v1 is link.last_exc_value:
v1 = 'last_exc_value'
resultlist.append((v1, v2))
- #
- # also add as a callee the graphs that are explicitly callees in the
- # callgraph. Useful because some graphs may end up not being called
- # any more, if they were inlined.
- was_originally_a_callee = set()
- for _, graph in translator.callgraph.itervalues():
- was_originally_a_callee.add(graph)
- #
- for graph in translator.graphs:
- if graph not in was_a_callee:
- if graph in was_originally_a_callee:
- src = 'originally_a_callee'
- else:
- src = 'unknown'
- for v in graph.getargs():
- if is_gc(v):
- resultlist.append((src, v))
return resultlist
@@ -130,13 +125,13 @@
return set_of_variables
def _backpropagate(self, variable):
+ if isinstance(variable, Constant):
+ return set([variable]), set()
result = set()
pending = [variable]
seen = set(pending)
for v2 in pending:
- # we get a KeyError here if 'variable' is not found,
- # or if one of the preceeding variables is not found
- for v1 in self._backmapping[v2]:
+ for v1 in self._backmapping.get(v2, ()):
if isinstance(v1, Variable):
if v1 not in seen:
seen.add(v1)
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
@@ -41,17 +41,7 @@
return True
def _could_be_local(self, variable):
- try:
- srcs = self.gsrc[variable]
- except KeyError:
- if isinstance(variable, Constant):
- srcs = [variable]
- else:
- # 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
+ srcs = self.gsrc[variable]
for src in srcs:
if isinstance(src, SpaceOperation):
if src.opname in RETURNS_LOCAL_POINTER:
@@ -66,8 +56,6 @@
return False
elif src == 'instantiate':
pass
- elif src == 'originally_a_callee':
- pass
elif isinstance(src, str):
self.reason = src
return False
diff --git a/pypy/translator/stm/test/test_gcsource.py b/pypy/translator/stm/test/test_gcsource.py
--- a/pypy/translator/stm/test/test_gcsource.py
+++ b/pypy/translator/stm/test/test_gcsource.py
@@ -115,7 +115,7 @@
gsrc = gcsource(main, [lltype.Ptr(lltype.GcStruct('S'))])
v_result = gsrc.translator.graphs[0].getreturnvar()
s = gsrc[v_result]
- assert list(s) == ['unknown']
+ assert list(s) == []
def test_exception():
class FooError(Exception):
More information about the pypy-commit
mailing list