Author: Remi Meier <[email protected]>
Branch: stmgc-c8
Changeset: r80951:1ef4c06a3f69
Date: 2015-11-25 17:00 +0100
http://bitbucket.org/pypy/pypy/changeset/1ef4c06a3f69/

Log:    more cleaning while searching for a bug

        the bug, however, seems to be in gcc when vectorizing loops

diff --git a/rpython/memory/gctransform/framework.py 
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -93,6 +93,7 @@
         insets = self._in_states
         #
         # get input variables and their states:
+        assert len(insets[block]) == len(block.inputargs)
         writeable = {}
         for v, state in zip(block.inputargs, insets[block]):
             writeable[v] = state
@@ -125,8 +126,7 @@
                     writeable[op.result] = True
                 #
             elif op.opname in ("cast_pointer", "same_as"):
-                if writeable.get(op.args[0], False):
-                    writeable[op.result] = True
+                writeable[op.result] = writeable.get(op.args[0], False)
                 #
             elif op.opname in ('setfield', 'setarrayitem', 'setinteriorfield', 
'raw_store'):
                 # generic_set case
@@ -134,7 +134,7 @@
                     # always ignore setfields of Void type
                     self.clean_ops.add(op)
                 elif not var_needsgc(op.args[0]):
-                    # raw setfields don't need a barrier
+                    # setfields on raw don't need a barrier
                     if (var_needsgc(op.args[-1]) and
                         'is_excdata' not in op.args[0].concretetype.TO._hints):
                         raise Exception("%s: GC pointer written into a non-GC 
location"
@@ -146,37 +146,34 @@
                     if var_needsgc(op.args[-1]):
                         raise Exception("in stm_ignored block: write of a gc 
pointer")
                     self.clean_ops.add(op)
-                elif self._set_into_gc_array_part(op) is not None:
-                    # things that need partial write barriers (card marking)
+                else:
+                    # we need a (partial) write barrier if arg0 is not 
writeable
                     if writeable.get(op.args[0], False):
                         self.clean_ops.add(op)
                     elif op in self.clean_ops:
                         self.clean_ops.remove(op)
-                else:
-                    # full write barrier possibly required
-                    if writeable.get(op.args[0], False):
-                        self.clean_ops.add(op)
-                    elif op in self.clean_ops:
-                        self.clean_ops.remove(op)
-                    # always writeable after this op
-                    writeable[op.args[0]] = True
+                    #
+                    if self._set_into_gc_array_part(op) is None:
+                        # this will do a full write barrier, not card marking
+                        # arg0 is always writeable afterwards
+                        writeable[op.args[0]] = True
         #
         # update in_states of all successors
-        updated = set()
+        to_do = set()
         for link in block.exits:
             succ = link.target
             outset = [writeable.get(v, False) for v in link.args]
             if succ in insets:
-                to_merge = [insets[succ], outset]
-                new = self._merge_out_states(to_merge)
-                if new != insets[succ]:
-                    updated.add(succ)
+                old = insets[succ]
+                new = self._merge_out_states([old, outset])
+                if new != old:
+                    to_do.add(succ)
                     insets[succ] = new
             else:
                 # block not processed yet
                 insets[succ] = outset
-                updated.add(succ)
-        return updated
+                to_do.add(succ)
+        return to_do
 
 
     def collect(self):
@@ -187,8 +184,7 @@
         graph = self.graph
         #
         # initialize blocks
-        self._in_states = {}
-        self._in_states[graph.startblock] = [False] * 
len(graph.startblock.inputargs)
+        self._in_states = {graph.startblock: [False] * 
len(graph.startblock.inputargs)}
         #
         # fixpoint iteration
         # XXX: reverse postorder traversal
diff --git a/rpython/memory/gctransform/test/test_framework.py 
b/rpython/memory/gctransform/test/test_framework.py
--- a/rpython/memory/gctransform/test/test_framework.py
+++ b/rpython/memory/gctransform/test/test_framework.py
@@ -618,6 +618,34 @@
     print "\n".join(map(str,wbc.clean_ops))
     assert len(wbc.clean_ops) == 11
 
+def test_write_barrier_collector_stm_inevitable_interaction():
+    from rpython.translator.c.genc import CStandaloneBuilder
+    from rpython.flowspace.model import summary
+    #
+    rS = lltype.Struct('rS', ('i', lltype.Signed))
+    S = lltype.GcStruct('S', ('i', lltype.Signed))
+    def f():
+        rs = lltype.malloc(rS, flavor='raw')
+        s = lltype.malloc(S, flavor='gc')
+        rs.i = 5 # become_inevitable setfield on 'raw'
+        s.i = 6 # become_inevitable canmalloc -> needs WB
+    def g(argv):
+        f()
+        return 0
+    t = rtype(g, [s_list_of_strings])
+    t.config.translation.stm = True
+    gcpolicy = StmFrameworkGcPolicy
+    t.config.translation.gc = "stmgc"
+    cbuild = CStandaloneBuilder(t, g, t.config,
+                                gcpolicy=gcpolicy)
+    db = cbuild.generate_graphs_for_llinterp()
+
+    ff = graphof(t, f)
+    #ff.show()
+    assert summary(ff)['stm_write'] == 1
+
+
+
 def test_write_barrier_collector_loops():
     class A(object):
         pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to