[pypy-svn] r48337 - in pypy/dist/pypy/translator/backendopt: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Nov 6 14:20:28 CET 2007


Author: cfbolz
Date: Tue Nov  6 14:20:27 2007
New Revision: 48337

Modified:
   pypy/dist/pypy/translator/backendopt/coalloc.py
   pypy/dist/pypy/translator/backendopt/test/test_coalloc.py
Log:
don't coallocate things with a __del__


Modified: pypy/dist/pypy/translator/backendopt/coalloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/coalloc.py	(original)
+++ pypy/dist/pypy/translator/backendopt/coalloc.py	Tue Nov  6 14:20:27 2007
@@ -8,6 +8,7 @@
 
 class CreationPoint(object):
     constant = None
+    coallocator = None
     def __init__(self, creation_method, TYPE):
         self.creation_method = creation_method
         self.TYPE = TYPE
@@ -39,6 +40,12 @@
         crepsrepr = (", ".join([repr(crep) for crep in self.creation_points]), )
         return "VarState({%s})" % crepsrepr
 
+    def get_crep(self, checksingle=False):
+        if checksingle:
+            assert len(self.creation_points) == 1
+        for crep in self.creation_points.iterkeys():
+            return crep
+
 class GraphState(object):
     def __init__(self, graph):
         self.graph = graph
@@ -319,7 +326,7 @@
             if len(tovarstate.creation_points) != 1:
                 continue
             fromcreps = set(fromvarstate.creation_points.keys())
-            tocrep = tovarstate.creation_points.keys()[0]
+            tocrep = tovarstate.get_crep()
             if not tocrep.creation_method.startswith("malloc"):
                 continue
             for fromcrep in fromcreps:
@@ -327,7 +334,7 @@
                      break # also recently malloced
             else:
                 #import pdb; pdb.set_trace()
-                num = do_coalloc(adi, graph, op.args[0], block,
+                num = do_coalloc(adi, graph, block, op,
                                  fromcreps, tocrep)
 
                 if num:
@@ -338,9 +345,9 @@
     return total
 
 
-def do_coalloc(adi, graph, fromvar, setblock, fromcreps, tocrep):
+def do_coalloc(adi, graph, setblock, setop, fromcreps, tocrep):
     def find_coalloc_var():
-        if block is setblock:
+        if block is setblock and seen_setvar:
             return fromvar
         for fromcrep in fromcreps:
             if fromcrep.creation_method == "constant":
@@ -348,16 +355,24 @@
         for fromcrep in fromcreps:
             for var in block.inputargs:
                 varstate = adi.getstate(var)
-                assert len(varstate.creation_points) == 1
-                crep = varstate.creation_points.keys()[0]
+                if varstate is None:
+                    continue
+                crep = varstate.get_crep(checksingle=True)
                 if crep is fromcrep:
                     return var
         return None
     result = 0
+    seen_setvar = False
     for block, op in graph.iterblockops():
+        if op.result is setop.args[0]:
+            seen_setvar = True
         if not op.opname.startswith("malloc"):
             continue
-        if adi.getstate(op.result).creation_points.keys()[0] is not tocrep:
+        if adi.getstate(op.result).get_crep(checksingle=True) is not tocrep:
+            continue
+        TYPE = op.result.concretetype.TO
+        # must not remove mallocs of structures that a destructor
+        if hasdestructor(TYPE):
             continue
         coallocvar = find_coalloc_var()
         if coallocvar is None:
@@ -365,8 +380,18 @@
         op.opname = "coalloc" + op.opname[len("malloc"):]
         op.args.insert(1, coallocvar)
         mallocvarstate = adi.getstate(op.result)
-        assert len(mallocvarstate.creation_points) == 1
-        malloccrep = mallocvarstate.creation_points.keys()[0]
+        malloccrep = mallocvarstate.get_crep(checksingle=True)
         malloccrep.creation_method = "coalloc"
         result += 1
     return result
+
+def hasdestructor(STRUCT):
+    if not isinstance(STRUCT, lltype.Struct):
+        return False
+    try:
+        destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
+        if destr_ptr:
+            return True
+    except (ValueError, AttributeError), e:
+        pass
+    return False

Modified: pypy/dist/pypy/translator/backendopt/test/test_coalloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_coalloc.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_coalloc.py	Tue Nov  6 14:20:27 2007
@@ -240,3 +240,27 @@
         g(a)
         return a.length
     t = check_malloc_to_coalloc(f, [int], [8], 8, must_remove=1)
+
+def test_coalloc_in_setblock():
+    class A(object):
+        pass
+    a3 = A()
+    def f():
+        a1 = A()
+        a2 = A()
+        a2.a = a1
+        a3.a = a2
+        return 1
+    # this should really be mustremove=2, but for now I am happy
+    t = check_malloc_to_coalloc(f, [], [], 1, must_remove=1)
+
+def test_nocoalloc_finalizer():
+    class A(object):
+        def __del__(self):
+            pass
+    a = A()
+    def f():
+        n = A()
+        a.next = n
+        return 1
+    check_malloc_to_coalloc(f, [], [], 1, must_remove=0)



More information about the Pypy-commit mailing list