[pypy-commit] pypy stm-gc: Comments and start.
arigo
noreply at buildbot.pypy.org
Thu Feb 16 12:24:37 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52544:e4072231e489
Date: 2012-02-16 11:03 +0100
http://bitbucket.org/pypy/pypy/changeset/e4072231e489/
Log: Comments and start.
diff --git a/pypy/translator/stm/localtracker.py b/pypy/translator/stm/localtracker.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/localtracker.py
@@ -0,0 +1,29 @@
+
+
+RETURNS_LOCAL_POINTER = set([
+ 'malloc', 'malloc_varsize', 'malloc_nonmovable',
+ 'malloc_nonmovable_varsize',
+ ])
+
+
+class StmLocalTracker(object):
+ """Tracker to determine which pointers are statically known to point
+ to local objects. Here, 'local' versus 'global' is meant in the sense
+ of the stmgc: a pointer is 'local' if it goes to the thread-local memory,
+ and 'global' if it points to the shared read-only memory area."""
+
+ def __init__(self, translator):
+ self.translator = translator
+ # a set of variables in the graphs that contain a known-to-be-local
+ # pointer.
+ self.locals = set()
+
+ def track_and_propagate_locals(self):
+ for graph in self.translator.graphs:
+ self.propagate_from_graph(graph)
+
+ def propagate_from_graph(self, graph):
+ for block in graph.iterblocks():
+ for op in block.operations:
+ if op.opname in RETURNS_LOCAL_POINTER:
+ self.locals.add(op.result)
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
@@ -2,12 +2,17 @@
from pypy.translator.translator import TranslationContext, graphof
from pypy.conftest import option
from pypy.rlib.jit import hint
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.annotation import model as annmodel
class TestStmLocalTracker(object):
def translate(self, func, sig):
t = TranslationContext()
+ self.translator = t
+ t._seen_locals = {}
t.buildannotator().build_types(func, sig)
t.buildrtyper().specialize()
if option.view:
@@ -17,6 +22,13 @@
localtracker.track_and_propagate_locals()
return localtracker
+ def check(self, expected_names):
+ got_local_names = set()
+ for name, v in self.translator._seen_locals.items():
+ if v in self.localtracker.locals:
+ got_local_names.add(name)
+ assert got_local_names == set(expected_names)
+
def test_no_local(self):
x = X(42)
@@ -26,21 +38,72 @@
return g(x)
#
localtracker = self.translate(f, [int])
- assert not localtracker.locals
+ self.check([])
def test_freshly_allocated(self):
- z = [42]
+ z = lltype.malloc(S)
def f(n):
- x = [n]
- y = [n+1]
+ x = lltype.malloc(S)
+ x.n = n
+ y = lltype.malloc(S)
+ y.n = n+1
_see(x, 'x')
_see(y, 'y')
_see(z, 'z')
- return x[0], y[0]
+ return x.n, y.n, z.n
#
self.translate(f, [int])
self.check(['x', 'y']) # x and y are locals; z is prebuilt
+ def test_freshly_allocated_in_one_path(self):
+ z = lltype.malloc(S)
+ def f(n):
+ x = lltype.malloc(S)
+ x.n = n
+ if n > 5:
+ y = lltype.malloc(S)
+ y.n = n+1
+ else:
+ y = z
+ _see(x, 'x')
+ _see(y, 'y')
+ return x.n + y.n
+ #
+ self.translate(f, [int])
+ self.check(['x']) # x is local; y not, as it can be equal to z
+
+ def test_freshly_allocated_in_the_other_path(self):
+ z = lltype.malloc(S)
+ def f(n):
+ x = lltype.malloc(S)
+ x.n = n
+ if n > 5:
+ y = z
+ else:
+ y = lltype.malloc(S)
+ y.n = n+1
+ _see(x, 'x')
+ _see(y, 'y')
+ return x.n + y.n
+ #
+ self.translate(f, [int])
+ self.check(['x']) # x is local; y not, as it can be equal to z
+
+ def test_freshly_allocated_in_loop(self):
+ z = lltype.malloc(S)
+ def f(n):
+ while True:
+ x = lltype.malloc(S)
+ x.n = n
+ n -= 1
+ if n < 0:
+ break
+ _see(x, 'x')
+ return x.n
+ #
+ self.translate(f, [int])
+ self.check(['x']) # x is local
+
def test_freshly_allocated_to_g(self):
def g(x):
_see(x, 'x')
@@ -125,9 +188,29 @@
self.check([])
+S = lltype.GcStruct('S', ('n', lltype.Signed))
+
class X:
def __init__(self, n):
self.n = n
class Y(X):
pass
+
+
+def _see(var, name):
+ pass
+
+class Entry(ExtRegistryEntry):
+ _about_ = _see
+
+ def compute_result_annotation(self, s_var, s_name):
+ return annmodel.s_None
+
+ def specialize_call(self, hop):
+ v = hop.inputarg(hop.args_r[0], arg=0)
+ name = hop.args_s[1].const
+ assert name not in hop.rtyper.annotator.translator._seen_locals, (
+ "duplicate name %r" % (name,))
+ hop.rtyper.annotator.translator._seen_locals[name] = v
+ return hop.inputconst(lltype.Void, None)
More information about the pypy-commit
mailing list