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

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Oct 9 11:45:11 CEST 2007


Author: cfbolz
Date: Tue Oct  9 11:45:11 2007
New Revision: 47328

Modified:
   pypy/dist/pypy/rpython/memory/gcwrapper.py
   pypy/dist/pypy/rpython/memory/test/test_gc.py
Log:
enable finalizer test and fix gcwrapper to make it pass


Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gcwrapper.py	(original)
+++ pypy/dist/pypy/rpython/memory/gcwrapper.py	Tue Oct  9 11:45:11 2007
@@ -1,4 +1,5 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython import llinterp
 from pypy.rpython.memory.support import get_address_linked_list
 from pypy.rpython.memory import gctypelayout
 from pypy.objspace.flow.model import Constant
@@ -16,7 +17,7 @@
         self.gc.setup()
 
     def prepare_graphs(self, flowgraphs):
-        layoutbuilder = DirectRunLayoutBuilder()
+        layoutbuilder = DirectRunLayoutBuilder(self.llinterp)
         self.get_type_id = layoutbuilder.get_type_id
         self.gc.set_query_functions(*layoutbuilder.get_query_functions())
 
@@ -71,8 +72,29 @@
 
 class DirectRunLayoutBuilder(gctypelayout.TypeLayoutBuilder):
 
+    def __init__(self, llinterp):
+        self.llinterp = llinterp
+        super(DirectRunLayoutBuilder, self).__init__()
+
     def make_finalizer_funcptr_for_type(self, TYPE):
-        return None     # XXX
+        from pypy.rpython.memory.gctransform.support import get_rtti, \
+                type_contains_pyobjs
+        rtti = get_rtti(TYPE)
+        if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'):
+            destrptr = rtti._obj.destructor_funcptr
+            DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0]
+            destrgraph = destrptr._obj.graph
+        else:
+            return None
+
+        assert not type_contains_pyobjs(TYPE), "not implemented"
+        def ll_finalizer(addr):
+            try:
+                v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG)
+                self.llinterp.eval_graph(destrgraph, [v])
+            except llinterp.LLException:
+                print "a destructor raised an exception, ignoring it"
+        return ll_finalizer
 
 
 def collect_constants(graphs):

Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gc.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_gc.py	Tue Oct  9 11:45:11 2007
@@ -101,6 +101,29 @@
         assert res == concat(100)
         #assert simulator.current_size - curr < 16000 * INT_SIZE / 4
 
+    def test_finalizer(self):
+        class B(object):
+            pass
+        b = B()
+        b.nextid = 0
+        b.num_deleted = 0
+        class A(object):
+            def __init__(self):
+                self.id = b.nextid
+                b.nextid += 1
+            def __del__(self):
+                b.num_deleted += 1
+        def f(x):
+            a = A()
+            i = 0
+            while i < x:
+                i += 1
+                a = A()
+            llop.gc__collect(lltype.Void)
+            llop.gc__collect(lltype.Void)
+            return b.num_deleted
+        res = self.interpret(f, [5])
+        assert res == 6
 
 
 class TestMarkSweepGC(GCTest):
@@ -108,6 +131,8 @@
 
 class TestSemiSpaceGC(GCTest):
     from pypy.rpython.memory.gc import SemiSpaceGC as GCClass
+    def test_finalizer(self):
+        py.test.skip("implement me")
 
 class TestDeferredRefcountingGC(GCTest):
     from pypy.rpython.memory.gc import DeferredRefcountingGC as GCClass



More information about the Pypy-commit mailing list