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

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


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

Modified:
   pypy/dist/pypy/rpython/memory/gc.py
   pypy/dist/pypy/rpython/memory/test/test_gc.py
Log:
implement finalizers in the semispace GC


Modified: pypy/dist/pypy/rpython/memory/gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc.py	Tue Oct  9 11:54:45 2007
@@ -957,6 +957,9 @@
         self.free = NULL
         self.get_roots = get_roots
         self.gcheaderbuilder = GCHeaderBuilder(self.HDR)
+        self.AddressLinkedList = AddressLinkedList
+        self.objects_with_finalizers = AddressLinkedList()
+        self.run_finalizers = AddressLinkedList()
 
     def setup(self):
         self.tospace = llarena.arena_malloc(self.space_size, True)
@@ -968,8 +971,6 @@
 
     def malloc_fixedsize(self, typeid, size, can_collect, has_finalizer=False,
                          contains_weakptr=False):
-        if has_finalizer:
-            raise NotImplementedError("finalizers in SemiSpaceGC")
         if contains_weakptr:
             raise NotImplementedError("weakptr in SemiSpaceGC")
         size_gc_header = self.gcheaderbuilder.size_gc_header
@@ -986,6 +987,8 @@
         llarena.arena_reserve(result, totalsize)
         self.init_gc_object(result, typeid)
         self.free += totalsize
+        if has_finalizer:
+            self.objects_with_finalizers.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
 
     def malloc_varsize(self, typeid, length, size, itemsize, offset_to_length,
@@ -1012,6 +1015,8 @@
         self.init_gc_object(result, typeid)
         (result + size_gc_header + offset_to_length).signed[0] = length
         self.free += totalsize
+        if has_finalizer:
+            self.objects_with_finalizers.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
 
     # for now, the spaces are filled with zeroes in advance
@@ -1031,14 +1036,31 @@
             root = roots.pop()
             if root == NULL:
                 break
-##             print "root", root, root.address[0]
             root.address[0] = self.copy(root.address[0])
         free_non_gc_object(roots)
+        scan = self.scan_copied(scan)
+        # walk over list of objects with finalizers
+        # if it is not copied, add it to the list of to-be-called finalizers
+        # and copy it, to me make the finalizer runnable
+        new_with_finalizer = self.AddressLinkedList()
+        while self.objects_with_finalizers.non_empty():
+            obj = self.objects_with_finalizers.pop()
+            if self.is_forwarded(obj):
+                new_with_finalizer.append(self.get_forwarding_address(obj))
+            else:
+                self.run_finalizers.append(self.copy(obj))
+        scan = self.scan_copied(scan)
+        self.objects_with_finalizers.delete()
+        self.objects_with_finalizers = new_with_finalizer
+        llarena.arena_reset(fromspace, self.space_size, True)
+        self.execute_finalizers()
+
+    def scan_copied(self, scan):
         while scan < self.free:
             curr = scan + self.size_gc_header()
             self.trace_and_copy(curr)
             scan += self.get_size(curr) + self.size_gc_header()
-        llarena.arena_reset(fromspace, self.space_size, True)
+        return scan
 
     def copy(self, obj):
         if not self.fromspace <= obj < self.fromspace + self.space_size:
@@ -1125,6 +1147,13 @@
         hdr.forw = NULL
         hdr.typeid = typeid
 
+    def execute_finalizers(self):
+        while self.run_finalizers.non_empty():
+            obj = self.run_finalizers.pop()
+            hdr = self.header(obj)
+            finalizer = self.getfinalizer(hdr.typeid)
+            finalizer(obj)
+
 class DeferredRefcountingGC(GCBase):
     _alloc_flavor_ = "raw"
 

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:54:45 2007
@@ -131,8 +131,6 @@
 
 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