[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