[pypy-svn] r54554 - pypy/branch/gc-tweak/pypy/rpython/memory/gc/test

arigo at codespeak.net arigo at codespeak.net
Thu May 8 13:26:22 CEST 2008


Author: arigo
Date: Thu May  8 13:26:22 2008
New Revision: 54554

Added:
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/test/test_direct.py   (contents, props changed)
Log:
Starting some direct GC tests that can run
without the llinterpreter at all.


Added: pypy/branch/gc-tweak/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- (empty file)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/test/test_direct.py	Thu May  8 13:26:22 2008
@@ -0,0 +1,120 @@
+""" The tests below don't use translation at all.  They run the GCs by
+instantiating them and asking them to allocate memory by calling their
+methods directly.  The tests need to maintain by hand what the GC should
+see as the list of roots (stack and prebuilt objects).
+"""
+
+import py
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.memory.gctypelayout import TypeLayoutBuilder
+
+ADDR_ARRAY = lltype.Array(llmemory.Address)
+S = lltype.GcForwardReference()
+S.become(lltype.GcStruct('S',
+                         ('x', lltype.Signed),
+                         ('next', lltype.Ptr(S))))
+
+
+class DirectRootWalker(object):
+
+    def __init__(self, tester):
+        self.tester = tester
+
+    def walk_roots(self, collect_stack_root,
+                   collect_static_in_prebuilt_nongc,
+                   collect_static_in_prebuilt_gc):
+        gc = self.tester.gc
+        layoutbuilder = self.tester.layoutbuilder
+        if collect_static_in_prebuilt_gc:
+            for addrofaddr in layoutbuilder.addresses_of_static_ptrs:
+                if addrofaddr.address[0]:
+                    collect_static_in_prebuilt_gc(gc, addrofaddr)
+        if collect_static_in_prebuilt_nongc:
+            for addrofaddr in layoutbuilder.addresses_of_static_ptrs_in_nongc:
+                if addrofaddr.address[0]:
+                    collect_static_in_prebuilt_nongc(gc, addrofaddr)
+        if collect_stack_root:
+            stackroots = self.tester.stackroots
+            a = lltype.malloc(ADDR_ARRAY, len(stackroots), flavor='raw')
+            for i in range(len(a)):
+                a[i] = llmemory.cast_ptr_to_adr(stackroots[i])
+            a_base = lltype.direct_arrayitems(a)
+            for i in range(len(a)):
+                ai = lltype.direct_ptradd(a_base, i)
+                collect_stack_root(gc, llmemory.cast_ptr_to_adr(ai))
+            for i in range(len(a)):
+                PTRTYPE = lltype.typeOf(stackroots[i])
+                stackroots[i] = llmemory.cast_adr_to_ptr(a[i], PTRTYPE)
+            lltype.free(a, flavor='raw')
+
+    def _walk_prebuilt_gc(self, callback):
+        pass
+
+
+class DirectGCTest(object):
+    GC_PARAMS = {}
+
+    def setup_method(self, meth):
+        self.stackroots = []
+        self.gc = self.GCClass(**self.GC_PARAMS)
+        self.gc.DEBUG = True
+        self.rootwalker = DirectRootWalker(self)
+        self.gc.set_root_walker(self.rootwalker)
+        self.layoutbuilder = TypeLayoutBuilder()
+        self.get_type_id = self.layoutbuilder.get_type_id
+        self.layoutbuilder.initialize_gc_query_function(self.gc)
+        self.gc.setup()
+
+    def consider_constant(self, p):
+        obj = p._obj
+        TYPE = lltype.typeOf(obj)
+        self.layoutbuilder.consider_constant(TYPE, obj, self.gc)
+
+    def write(self, p, fieldname, newvalue):
+        if self.gc.needs_write_barrier:
+            oldaddr = llmemory.cast_ptr_to_adr(getattr(p, fieldname))
+            newaddr = llmemory.cast_ptr_to_adr(newvalue)
+            addr_struct = llmemory.cast_ptr_to_adr(p)
+            self.gc.write_barrier(oldaddr, newaddr, addr_struct)
+        setattr(p, fieldname, newvalue)
+
+    def malloc(self, TYPE):
+        addr = self.gc.malloc(self.get_type_id(TYPE))
+        return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(TYPE))
+
+    def test_simple(self):
+        p = self.malloc(S)
+        p.x = 5
+        self.stackroots.append(p)
+        self.gc.collect()
+        p = self.stackroots[0]
+        assert p.x == 5
+
+    def test_missing_stack_root(self):
+        p = self.malloc(S)
+        p.x = 5
+        self.gc.collect()    # 'p' should go away
+        py.test.raises(RuntimeError, 'p.x')
+
+    def test_prebuilt_gc(self):
+        k = lltype.malloc(S, immortal=True)
+        k.x = 42
+        self.consider_constant(k)
+        self.write(k, 'next', self.malloc(S))
+        k.next.x = 43
+        self.write(k.next, 'next', self.malloc(S))
+        k.next.next.x = 44
+        self.gc.collect()
+        assert k.x == 42
+        assert k.next.x == 43
+        assert k.next.next.x == 44
+
+
+class TestSemiSpaceGC(DirectGCTest):
+    from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass
+
+class TestGenerationGC(TestSemiSpaceGC):
+    from pypy.rpython.memory.gc.generation import GenerationGC as GCClass
+
+class TestHybridGC(TestGenerationGC):
+    from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass



More information about the Pypy-commit mailing list