[pypy-svn] r32348 - in pypy/branch/kill-keepalives/pypy/translator/backendopt: . test

mwh at codespeak.net mwh at codespeak.net
Fri Sep 15 11:52:29 CEST 2006


Author: mwh
Date: Fri Sep 15 11:52:27 2006
New Revision: 32348

Modified:
   pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py
   pypy/branch/kill-keepalives/pypy/translator/backendopt/test/test_malloc.py
Log:
support for malloc removing structures with a special kind of destructor.


Modified: pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py	(original)
+++ pypy/branch/kill-keepalives/pypy/translator/backendopt/malloc.py	Fri Sep 15 11:52:27 2006
@@ -3,6 +3,7 @@
 from pypy.tool.algo.unionfind import UnionFind
 from pypy.rpython.lltypesystem import lltype
 from pypy.translator.simplify import remove_identical_vars
+from pypy.translator.unsimplify import varoftype
 from pypy.translator.backendopt.support import log
 from pypy.translator.backendopt.constfold import constant_fold_graph
 
@@ -211,12 +212,17 @@
         else:
             return False
 
-    # must not remove mallocs of structures that have a RTTI with a destructor
+    # must not remove mallocs of structures that have a RTTI with a
+    # destructor, unless there's a hint that tells us what the
+    # destructor does.
+
+    fields_to_raw_free = ()
 
     try:
         destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
-        if destr_ptr:
+        if destr_ptr and 'autofree_fields' not in STRUCT._hints:
             return False
+        fields_to_raw_free = STRUCT._hints['autofree_fields']
     except (ValueError, AttributeError), e:
         pass
 
@@ -422,16 +428,25 @@
 
             assert block.exitswitch not in vars
 
+            var_exits = False
             for link in block.exits:
                 newargs = []
                 for arg in link.args:
                     if arg in vars:
                         newargs += list_newvars()
                         insert_keepalive = False   # kept alive by the link
+                        var_exits = True
                     else:
                         newargs.append(arg)
                 link.args[:] = newargs
 
+            if not var_exits:
+                for field in fields_to_raw_free:
+                    newops.append(SpaceOperation("flavored_free",
+                                                 [Constant("raw", lltype.Void),
+                                                  newvarsmap[key_for_field_access(STRUCT, field)]],
+                                                 varoftype(lltype.Void)))
+
             if insert_keepalive and last_removed_access is not None:
                 keepalives = []
                 for v in list_newvars():

Modified: pypy/branch/kill-keepalives/pypy/translator/backendopt/test/test_malloc.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/translator/backendopt/test/test_malloc.py	(original)
+++ pypy/branch/kill-keepalives/pypy/translator/backendopt/test/test_malloc.py	Fri Sep 15 11:52:27 2006
@@ -5,7 +5,7 @@
 from pypy.translator.backendopt.all import backend_optimizations
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.translator import simplify
-from pypy.objspace.flow.model import checkgraph, flatten, Block
+from pypy.objspace.flow.model import checkgraph, flatten, Block, summary
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.rpython.lltypesystem import lltype
 from pypy.conftest import option
@@ -45,6 +45,7 @@
     callback(False)
     if must_be_removed:
         check_malloc_removed(graph)
+    return graph
 
 
 def test_fn1():
@@ -277,3 +278,21 @@
         x.u2.b = 6
         return x.u1.b * x.u2.a
     check(fn, [], [], Ellipsis)
+
+def test_simple_destructor():
+    R = lltype.Struct("R", ("x", lltype.Signed))
+    G = lltype.GcStruct("G", ("p", lltype.Ptr(R)),
+                        hints={'autofree_fields':('p',)})
+    def destr(g):
+        lltype.raw_free(g.p)
+    destrptr = lltype.functionptr(lltype.FuncType([lltype.Ptr(G)], lltype.Void),
+                                  "destr",
+                                  _callable=destr)
+    lltype.attachRuntimeTypeInfo(G, destrptr=destrptr)
+    def f():
+        g = lltype.malloc(G)
+        g.p = lltype.malloc(R, flavor='raw')
+        g.p.x = 1
+        return g.p.x
+    graph = check(f, [], [], 1)
+    assert 'flavored_free' in summary(graph)



More information about the Pypy-commit mailing list