[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