[pypy-svn] r23226 - in pypy/dist/pypy/rpython/memory: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sat Feb 11 02:41:04 CET 2006


Author: cfbolz
Date: Sat Feb 11 02:40:58 2006
New Revision: 23226

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
cache dynamic deallocators not only by their type but also according to the
query function


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Sat Feb 11 02:40:58 2006
@@ -289,6 +289,7 @@
         self.decref_graphs = {}
         self.static_deallocator_graphs = {}
         self.dynamic_deallocator_graphs = {}
+        self.queryptr2dynamic_deallocator_graph = {}
 
     def push_alive_nopyobj(self, var):
         adr1 = varoftype(llmemory.Address)
@@ -428,16 +429,10 @@
         rtti = self.get_rtti(TYPE)
         assert rtti is not None
         queryptr = rtti._obj.query_funcptr
+        if queryptr._obj in self.queryptr2dynamic_deallocator_graph:
+            return self.queryptr2dynamic_deallocator_graph[queryptr._obj]
         RTTI_PTR = lltype.Ptr(lltype.RuntimeTypeInfo)
         QUERY_ARG_TYPE = lltype.typeOf(queryptr).TO.ARGS[0]
-        def call_destructor_for_rtti(v, rtti):
-            pass
-        def call_destructor_for_rtti_compute_ops(hop):
-            _, v_addr, v_rtti = hop.inputargs(lltype.Void, llmemory.Address, hop.args_r[2])
-            return hop.genop("gc_call_rtti_destructor", [v_rtti, v_addr],
-                             resulttype = lltype.Void) 
-        call_destructor_for_rtti.llresult = lltype.Void
-        call_destructor_for_rtti.compute_ll_ops = call_destructor_for_rtti_compute_ops
         def dealloc(addr):
             # bump refcount to 1
             gcheader = addr - RefcountingGCTransformer.gc_header_offset
@@ -445,9 +440,10 @@
             v = objectmodel.cast_adr_to_ptr(addr, QUERY_ARG_TYPE)
             rtti = queryptr(v)
             gcheader.signed[0] = 0
-            call_destructor_for_rtti(addr, rtti)
+            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
 

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	Sat Feb 11 02:40:58 2006
@@ -419,6 +419,55 @@
     pinf = lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp)
     graph, t = make_deallocator(S)
 
+def test_caching_dynamic_deallocator():
+    S = lltype.GcStruct("S", ('x', lltype.Signed))
+    S1 = lltype.GcStruct("S1", ('s', S), ('y', lltype.Signed))
+    T = lltype.GcStruct("T", ('x', lltype.Signed))
+    def f_S(s):
+        s.x = 1
+    def f_S1(s1):
+        s1.s.x = 1
+        s1.y = 2
+    def f_T(s):
+        s.x = 1
+    def type_info_S(p):
+        return lltype.getRuntimeTypeInfo(S)
+    def type_info_T(p):
+        return lltype.getRuntimeTypeInfo(T)
+    qp = lltype.functionptr(lltype.FuncType([lltype.Ptr(S)],
+                                            lltype.Ptr(lltype.RuntimeTypeInfo)),
+                            "type_info_S", 
+                            _callable=type_info_S)
+    dp = lltype.functionptr(lltype.FuncType([lltype.Ptr(S)],
+                                            lltype.Void), 
+                            "destructor_funcptr", 
+                            _callable=f_S)
+    pinf = lltype.attachRuntimeTypeInfo(S, qp, destrptr=dp)
+    dp = lltype.functionptr(lltype.FuncType([lltype.Ptr(S)],
+                                            lltype.Void), 
+                            "destructor_funcptr", 
+                            _callable=f_S1)
+    pinf = lltype.attachRuntimeTypeInfo(S1, qp, destrptr=dp)
+    qp = lltype.functionptr(lltype.FuncType([lltype.Ptr(T)],
+                                            lltype.Ptr(lltype.RuntimeTypeInfo)),
+                            "type_info_S", 
+                            _callable=type_info_T)
+    dp = lltype.functionptr(lltype.FuncType([lltype.Ptr(T)],
+                                            lltype.Void), 
+                            "destructor_funcptr", 
+                            _callable=f_T)
+    pinf = lltype.attachRuntimeTypeInfo(T, qp, destrptr=dp)
+    def f():
+        pass
+    t = TranslationContext()
+    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
 
 def test_dynamic_deallocator():
     class A(object):



More information about the Pypy-commit mailing list