[pypy-svn] r23321 - in pypy: branch/genc-gc-refactoring dist/pypy/rpython/memory dist/pypy/rpython/memory/test

mwh at codespeak.net mwh at codespeak.net
Tue Feb 14 13:49:25 CET 2006


Author: mwh
Date: Tue Feb 14 13:49:23 2006
New Revision: 23321

Modified:
   pypy/branch/genc-gc-refactoring/gc.py
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
changes to the interface of gctransformer -- instead of providing graphs
of deallocators it now provides function pointers to deallocators.

also fix a rather embarrassing bug in my last change to gctransformer.



Modified: pypy/branch/genc-gc-refactoring/gc.py
==============================================================================
--- pypy/branch/genc-gc-refactoring/gc.py	(original)
+++ pypy/branch/genc-gc-refactoring/gc.py	Tue Feb 14 13:49:23 2006
@@ -81,11 +81,8 @@
     def struct_setup(self, structdefnode, rtti):
         if rtti is not None:
             transformer = structdefnode.db.gctransformer
-            graph = transformer.static_deallocation_graph_for_type(structdefnode.STRUCT)
-            # XXX come up with a nicer interface in gctransformer
-            structdefnode.db.translator.rtyper.specialize_more_blocks()
-            FUNCTYPE = lltype.FuncType([llmemory.Address], lltype.Void)
-            fptr = lltype.functionptr(FUNCTYPE, graph.name, graph=graph)
+            fptr = transformer.static_deallocation_funcptr_for_type(
+                structdefnode.STRUCT)
             structdefnode.gcinfo = RefcountingInfo()
             structdefnode.gcinfo.static_deallocator = structdefnode.db.get(fptr)
 
@@ -153,11 +150,8 @@
 
     def setup_gcinfo(self, defnode):
         transformer = defnode.db.gctransformer
-        graph = transformer.finalizer_graph_for_type(defnode.LLTYPE)
-        if graph:
-            defnode.db.translator.rtyper.specialize_more_blocks()
-            FUNCTYPE = lltype.FuncType([llmemory.Address], lltype.Void)
-            fptr = lltype.functionptr(FUNCTYPE, graph.name, graph=graph)
+        fptr = transformer.finalizer_funcptr_for_type(defnode.LLTYPE)
+        if fptr:
             defnode.gcinfo = BoehmInfo()
             defnode.gcinfo.finalizer = defnode.db.get(fptr)
 

Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Tue Feb 14 13:49:23 2006
@@ -259,6 +259,8 @@
     for i, (a, b) in enumerate(stack):
         print ' '*i, a, repr(b)[:100-i-len(a)], id(b)
 
+ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
+
 class RefcountingGCTransformer(GCTransformer):
 
     gc_header_offset = gc.GCHeaderOffset(lltype.Struct("header", ("refcount", lltype.Signed)))
@@ -280,29 +282,31 @@
         def no_pointer_dealloc(adr):
             objectmodel.llop.gc_free(lltype.Void, adr)
         if self.translator is not None and self.translator.rtyper is not None:
-            self.increfgraph = self.annotate_helper(
+            increfgraph = self.annotate_helper(
                 incref, [annmodel.SomeAddress()])
             self.translator.rtyper.specialize_more_blocks()
-            self.increfptr = const_funcptr_fromgraph(self.increfgraph)
-            self.seen_graphs[self.increfgraph] = True
+            self.increfptr = const_funcptr_fromgraph(increfgraph)
+            self.seen_graphs[increfgraph] = True
             
-            self.decref_graph = self.annotate_helper(
-                decref, [annmodel.SomeAddress(), lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))])
+            decref_graph = self.annotate_helper(
+                decref, [annmodel.SomeAddress(), lltype.Ptr(ADDRESS_VOID_FUNC)])
             self.translator.rtyper.specialize_more_blocks()
-            self.decref_ptr = const_funcptr_fromgraph(self.decref_graph)
-            self.seen_graphs[self.decref_graph] = True
+            self.decref_ptr = const_funcptr_fromgraph(decref_graph)
+            self.seen_graphs[decref_graph] = True
 
-            self.no_pointer_dealloc_graph = self.annotate_helper(
+            no_pointer_dealloc_graph = self.annotate_helper(
                 no_pointer_dealloc, [annmodel.SomeAddress()])
             self.translator.rtyper.specialize_more_blocks()
-            self.no_pointer_dealloc_ptr = const_funcptr_fromgraph(self.no_pointer_dealloc_graph)
-            self.seen_graphs[self.no_pointer_dealloc_graph] = True
-        self.deallocators_needing_transforming = []
+            self.no_pointer_dealloc_ptr = lltype.functionptr(
+                ADDRESS_VOID_FUNC, no_pointer_dealloc_graph.name,
+                graph=no_pointer_dealloc_graph)
+            self.seen_graphs[no_pointer_dealloc_graph] = True
+        self.deallocator_graphs_needing_transforming = []
         # cache graphs:
-        self.decref_graphs = {}
-        self.static_deallocator_graphs = {}
-        self.dynamic_deallocator_graphs = {}
-        self.queryptr2dynamic_deallocator_graph = {}
+        self.decref_funcptrs = {}
+        self.static_deallocator_funcptrs = {}
+        self.dynamic_deallocator_funcptrs = {}
+        self.queryptr2dynamic_deallocator_funcptr = {}
         
 
     def push_alive_nopyobj(self, var):
@@ -317,13 +321,12 @@
         adr1 = varoftype(llmemory.Address)
         result = [SpaceOperation("cast_ptr_to_adr", [var], adr1)]
 
-        graph = self.dynamic_deallocation_graph_for_type(PTRTYPE.TO)
-
-        FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
-        dealloc_fptr = rmodel.inputconst(
-             lltype.Ptr(FUNC), lltype.functionptr(FUNC, graph.name, graph=graph))
-        
-        result.append(SpaceOperation("direct_call", [self.decref_ptr, adr1, dealloc_fptr],
+        dealloc_fptr = self.dynamic_deallocation_funcptr_for_type(PTRTYPE.TO)
+        cdealloc_fptr = rmodel.inputconst(
+            lltype.Ptr(ADDRESS_VOID_FUNC), dealloc_fptr)
+             
+        result.append(SpaceOperation("direct_call",
+                                     [self.decref_ptr, adr1, cdealloc_fptr],
                                      varoftype(lltype.Void)))
         return result
 
@@ -332,7 +335,8 @@
             return [op]
         oldval = Variable()
         oldval.concretetype = op.args[2].concretetype
-        getoldvalop = SpaceOperation("getfield", [op.args[0], op.args[1]], oldval)
+        getoldvalop = SpaceOperation("getfield",
+                                     [op.args[0], op.args[1]], oldval)
         result = [getoldvalop]
         result.extend(self.pop_alive(oldval))
         result.extend(self.push_alive(op.args[2]))
@@ -360,19 +364,19 @@
                 pass
         return None
 
-    def static_deallocation_graph_for_type(self, TYPE):
-        if TYPE in self.static_deallocator_graphs:
-            return self.static_deallocator_graphs[TYPE]
-        g = self._static_deallocation_graph_for_type(TYPE)
+    def static_deallocation_funcptr_for_type(self, TYPE):
+        if TYPE in self.static_deallocator_funcptrs:
+            return self.static_deallocator_funcptrs[TYPE]
+        fptr = self._static_deallocation_funcptr_for_type(TYPE)
         self.specialize_more_blocks()
-        for g in self.deallocators_needing_transforming:
+        for g in self.deallocator_graphs_needing_transforming:
             MinimalGCTransformer(self.translator).transform_graph(g)
-        self.deallocators_needing_transforming = []
-        return g
+        self.deallocator_graphs_needing_transforming = []
+        return fptr
 
-    def _static_deallocation_graph_for_type(self, TYPE):
-        if TYPE in self.static_deallocator_graphs:
-            return self.static_deallocator_graphs[TYPE]
+    def _static_deallocation_funcptr_for_type(self, TYPE):
+        if TYPE in self.static_deallocator_funcptrs:
+            return self.static_deallocator_funcptrs[TYPE]
         #print_call_chain(self)
         def compute_pop_alive_ll_ops(hop):
             hop.llops.extend(self.pop_alive(hop.args_v[1]))
@@ -392,9 +396,9 @@
 
         if destrptr is None and not find_gc_ptrs_in_type(TYPE):
             #print repr(TYPE)[:80], 'is dealloc easy'
-            g = self.no_pointer_dealloc_graph
-            self.static_deallocator_graphs[TYPE] = g
-            return g
+            p = self.no_pointer_dealloc_ptr
+            self.static_deallocator_funcptrs[TYPE] = p
+            return p
 
         if destrptr is not None:
             body = '\n'.join(_static_deallocator_body_for_type('v', TYPE, 2))
@@ -438,32 +442,27 @@
         if destrptr:
             # however, the direct_call to the destructor needs to get
             # .cleanup attached
-            self.deallocators_needing_transforming.append(g)
-        
-        opcount = 0
-        for block in g.iterblocks():
-            opcount += len(block.operations)
-        if opcount == 0:
-            result = None
-        else:
-            result = g
-        self.static_deallocator_graphs[TYPE] = result
-        return result
+            self.deallocator_graphs_needing_transforming.append(g)
 
-    def dynamic_deallocation_graph_for_type(self, TYPE):
-        if TYPE in self.dynamic_deallocator_graphs:
-            return self.dynamic_deallocator_graphs[TYPE]
+        fptr = lltype.functionptr(ADDRESS_VOID_FUNC, g.name, graph=g)
+             
+        self.static_deallocator_funcptrs[TYPE] = fptr
+        return fptr
+
+    def dynamic_deallocation_funcptr_for_type(self, TYPE):
+        if TYPE in self.dynamic_deallocator_funcptrs:
+            return self.dynamic_deallocator_funcptrs[TYPE]
         #print_call_chain(self)
 
         rtti = self.get_rtti(TYPE)
         if rtti is None:
-            g = self._static_deallocation_graph_for_type(TYPE)
-            self.dynamic_deallocator_graphs[TYPE] = g
-            return g
+            p = self._static_deallocation_funcptr_for_type(TYPE)
+            self.dynamic_deallocator_funcptrs[TYPE] = p
+            return p
             
         queryptr = rtti._obj.query_funcptr
-        if queryptr._obj in self.queryptr2dynamic_deallocator_graph:
-            return self.queryptr2dynamic_deallocator_graph[queryptr._obj]
+        if queryptr._obj in self.queryptr2dynamic_deallocator_funcptr:
+            return self.queryptr2dynamic_deallocator_funcptr[queryptr._obj]
         
         RTTI_PTR = lltype.Ptr(lltype.RuntimeTypeInfo)
         QUERY_ARG_TYPE = lltype.typeOf(queryptr).TO.ARGS[0]
@@ -476,10 +475,12 @@
             gcheader.signed[0] = 0
             objectmodel.llop.gc_call_rtti_destructor(lltype.Void, rtti, addr)
         g = self.annotate_helper(dealloc, [llmemory.Address])
-        self.dynamic_deallocator_graphs[TYPE] = g
-        self.queryptr2dynamic_deallocator_graph[queryptr._obj] = g
         self.seen_graphs[g] = True
-        return g
+        
+        fptr = lltype.functionptr(ADDRESS_VOID_FUNC, g.name, graph=g)
+        self.dynamic_deallocator_funcptrs[TYPE] = fptr
+        self.queryptr2dynamic_deallocator_funcptr[queryptr._obj] = fptr
+        return fptr
 
 def varoftype(concretetype):
     var = Variable()
@@ -525,7 +526,7 @@
 
     def __init__(self, translator):
         super(BoehmGCTransformer, self).__init__(translator)
-        self.finalizer_graphs = {}
+        self.finalizer_funcptrs = {}
 
     def push_alive_nopyobj(self, var):
         return []
@@ -541,9 +542,9 @@
                 pass
         return None
 
-    def finalizer_graph_for_type(self, TYPE):
-        if TYPE in self.finalizer_graphs:
-            return self.finalizer_graphs[TYPE]
+    def finalizer_funcptr_for_type(self, TYPE):
+        if TYPE in self.finalizer_funcptrs:
+            return self.finalizer_funcptrs[TYPE]
         
         def compute_pop_alive_ll_ops(hop):
             hop.llops.extend(self.pop_alive(hop.args_v[1]))
@@ -588,8 +589,13 @@
 
         if g:
             self.seen_graphs[g] = True
-        self.finalizer_graphs[TYPE] = g
-        return g
+
+            fptr = lltype.functionptr(ADDRESS_VOID_FUNC, g.name, graph=g)
+            self.finalizer_funcptrs[TYPE] = fptr
+            return fptr
+        else:
+            self.finalizer_funcptrs[TYPE] = None
+            return None
         
 # ___________________________________________________________________
 # calculate some statistics about the number of variables that need

Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py	Tue Feb 14 13:49:23 2006
@@ -329,7 +329,7 @@
 # test deallocators
 
 def make_deallocator(TYPE,
-                     attr="static_deallocation_graph_for_type",
+                     attr="static_deallocation_funcptr_for_type",
                      cls=gctransform.RefcountingGCTransformer):
     def f():
         pass
@@ -337,14 +337,17 @@
     t.buildannotator().build_types(f, [])
     t.buildrtyper().specialize(t)
     transformer = cls(t)
-    graph = getattr(transformer, attr)(TYPE)
+    fptr = getattr(transformer, attr)(TYPE)
     t.rtyper.specialize_more_blocks()
     if conftest.option.view:
         t.view()
-    return graph, t
+    if fptr:
+        return fptr._obj.graph, t
+    else:
+        return None, t
 
 def make_boehm_finalizer(TYPE):
-    return make_deallocator(TYPE, attr="finalizer_graph_for_type",
+    return make_deallocator(TYPE, attr="finalizer_funcptr_for_type",
                             cls=gctransform.BoehmGCTransformer)
 
 def test_deallocator_simple():
@@ -446,11 +449,11 @@
     t.buildannotator().build_types(f, [])
     t.buildrtyper().specialize(t)
     transformer = gctransform.RefcountingGCTransformer(t)
-    graph_S = transformer.dynamic_deallocation_graph_for_type(S)
-    graph_S1 = transformer.dynamic_deallocation_graph_for_type(S1)
-    graph_T = transformer.dynamic_deallocation_graph_for_type(T)
-    assert graph_S is not graph_T
-    assert graph_S is graph_S1
+    p_S = transformer.dynamic_deallocation_funcptr_for_type(S)
+    p_S1 = transformer.dynamic_deallocation_funcptr_for_type(S1)
+    p_T = transformer.dynamic_deallocation_funcptr_for_type(T)
+    assert p_S is not p_T
+    assert p_S is p_S1
 
 def test_dynamic_deallocator():
     class A(object):
@@ -468,10 +471,11 @@
         else:
             c = b
         return c.x
-    t, transformer = rtype_and_transform(f, [int], gctransform.RefcountingGCTransformer, check=False)
+    t, transformer = rtype_and_transform(
+        f, [int], gctransform.RefcountingGCTransformer, check=False)
     fgraph = graphof(t, f)
     TYPE = fgraph.startblock.operations[0].result.concretetype.TO
-    graph = transformer.dynamic_deallocation_graph_for_type(TYPE)
+    p = transformer.dynamic_deallocation_funcptr_for_type(TYPE)
     t.rtyper.specialize_more_blocks() 
 
 def test_recursive_structure():
@@ -482,7 +486,8 @@
         s1 = lltype.malloc(S)
         s2 = lltype.malloc(S)
         s1.x = s2
-    t, transformer = rtype_and_transform(f, [], gctransform.RefcountingGCTransformer, check=False)
+    t, transformer = rtype_and_transform(
+        f, [], gctransform.RefcountingGCTransformer, check=False)
 
 
 def test_boehm_finalizer_simple():



More information about the Pypy-commit mailing list