[pypy-svn] r26759 - in pypy/dist/pypy: rpython/memory translator/c/test

arigo at codespeak.net arigo at codespeak.net
Thu May 4 14:29:53 CEST 2006


Author: arigo
Date: Thu May  4 14:29:42 2006
New Revision: 26759

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/translator/c/test/test_newgc.py
Log:
(arigo, cfbolz): test + fix for a case where the calculation of what needs to be
saved accross a call was wrong. delete the whole special casing in framework gc
transformer. This should be implemented more generally.


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Thu May  4 14:29:42 2006
@@ -1009,36 +1009,7 @@
         return newgcdependencies
 
     def protect_roots(self, op, livevars, block, index=-1):
-        livevars = dict.fromkeys(
-            [var for var in livevars if not var_ispyobj(var)], True)
-        if not needs_conservative_livevar_calculation(block):
-            not_needed = {}
-            if index == -1:
-                index = block.operations.index(op) # XXX hum
-            needed = {}
-            for before_op in block.operations[:index]:
-                if before_op.result not in livevars:
-                    continue
-                if before_op.opname in ("cast_pointer", "same_as"):
-                    not_needed[before_op.result] = True
-                elif before_op.opname in ("getfield", "getarrayitem"):
-                    if (before_op.args[0] in livevars or
-                        isinstance(before_op.args[0], Constant)):
-                        not_needed[before_op.result] = True
-            for after_op in block.operations[index:]:
-                for arg in after_op.args:
-                    needed[arg] = True
-                needed[after_op.result] = True
-            for exit in block.exits:
-                for arg in exit.args:
-                    needed[arg] = True
-            newlivevars = []
-            for var in livevars:
-                if var in needed and var not in not_needed:
-                    newlivevars.append(var)
-            livevars = newlivevars
-        else:
-            livevars = livevars.keys()
+        livevars = [var for var in livevars if not var_ispyobj(var)]
         newops = list(self.push_roots(livevars))
         index = len(newops)
         newops.append(op)

Modified: pypy/dist/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_newgc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_newgc.py	Thu May  4 14:29:42 2006
@@ -332,6 +332,34 @@
         assert res == 42
         assert len([op for op in startblock.operations if op.opname == "gc_reload_possibly_moved"]) == 0
 
+    def test_framework_protect_getfield(self):
+        class A(object):
+            pass
+        class B(object):
+            pass
+        def prepare(b, n):
+            a = A()
+            a.value = n
+            b.a = a
+            b.othervalue = 5
+        def g(a):
+            # this should trigger 3 collections
+            for i in range(1000000):
+                prepare(B(), -1)
+            # we need to prevent it getting inlined
+            if not a:
+                g(A())
+            return a.value
+        def f():
+            b = B()
+            prepare(b, 123)
+            a = b.a
+            b.a = None
+            return g(a) + b.othervalue
+        fn = self.getcompiled(f)
+        res = fn()
+        assert res == 128
+
     def test_framework_varsized(self):
         S = lltype.GcStruct("S", ('x', lltype.Signed))
         T = lltype.GcStruct("T", ('y', lltype.Signed),



More information about the Pypy-commit mailing list