[pypy-commit] pypy stm-gc: Improve the logic.

arigo noreply at buildbot.pypy.org
Thu Feb 16 18:17:46 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52557:c949766e518c
Date: 2012-02-16 18:17 +0100
http://bitbucket.org/pypy/pypy/changeset/c949766e518c/

Log:	Improve the logic.

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
@@ -31,11 +31,14 @@
             assert isinstance(x, Z)
             x.n = n + 2
             x.sub = n + 1
+        x.n *= 2
     #
     graph = get_graph(f1, [int])
     pre_insert_stm_writebarrier(graph)
+    if option.view:
+        graph.show()
     # weak test: check that there are exactly two stm_writebarrier inserted.
     # one should be for 'x.n = n', and one should cover both field assignments
     # to the Z instance.
     sum = summary(graph)
-    assert sum['stm_writebarrier'] == 2
+    assert sum['stm_writebarrier'] == 3
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
@@ -227,36 +227,53 @@
         if block.operations == ():
             continue
         #
-        # figure out the variables on which we want an stm_writebarrier
+        # figure out the variables on which we want an stm_writebarrier;
+        # also track the getfields, on which we don't want a write barrier
+        # but which are still recorded in the dict.
         copies = {}
         wants_a_writebarrier = {}
         for op in block.operations:
             if op.opname in COPIES_POINTER:
                 assert len(op.args) == 1
                 copies[op.result] = op
+            elif (op.opname in ('getfield', 'getarrayitem',
+                                'getinteriorfield') and
+                  op.result.concretetype is not lltype.Void and
+                  op.args[0].concretetype.TO._gckind == 'gc' and
+                  not is_immutable(op)):
+                wants_a_writebarrier.setdefault(op, False)
             elif (op.opname in ('setfield', 'setarrayitem',
                                 'setinteriorfield') and
                   op.args[-1].concretetype is not lltype.Void and
                   op.args[0].concretetype.TO._gckind == 'gc' and
                   not is_immutable(op)):
-                wants_a_writebarrier.setdefault(op.args[0], op)
+                wants_a_writebarrier[op] = True
         #
-        # back-propagate the write barrier locations through the cast_pointers
+        # back-propagate the write barrier's True/False locations through
+        # the cast_pointers
         writebarrier_locations = {}
-        for v, op in wants_a_writebarrier.items():
-            while v in copies:
-                op = copies[v]
-                v = op.args[0]
-            protect = writebarrier_locations.setdefault(op, set())
-            protect.add(v)
+        for op, wants in wants_a_writebarrier.items():
+            while op.args[0] in copies:
+                op = copies[op.args[0]]
+            if op in writebarrier_locations:
+                wants |= writebarrier_locations[op]
+            writebarrier_locations[op] = wants
+        #
+        # to back-propagate the locations even more, if it comes before a
+        # getfield(), we need the following set
+        writebarrier_vars = set()
+        for op, wants in writebarrier_locations.items():
+            if wants:
+                writebarrier_vars.add(op.args[0])
         #
         # now insert the 'stm_writebarrier's
         renames = {}      # {original-var: renamed-var}
         newoperations = []
         for op in block.operations:
-            locs = writebarrier_locations.get(op, None)
-            if locs:
-                for v1 in locs:
+            if op in writebarrier_locations:
+                wants = writebarrier_locations[op]
+                if wants or op.args[0] in writebarrier_vars:
+                    v1 = op.args[0]
                     if v1 not in renames:
                         v2 = varoftype(v1.concretetype)
                         op1 = SpaceOperation('stm_writebarrier', [v1], v2)


More information about the pypy-commit mailing list