[pypy-svn] r47359 - in pypy/dist/pypy/rpython: lltypesystem memory memory/test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Oct 9 19:14:14 CEST 2007


Author: cfbolz
Date: Tue Oct  9 19:14:12 2007
New Revision: 47359

Modified:
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/rpython/lltypesystem/opimpl.py
   pypy/dist/pypy/rpython/memory/gc.py
   pypy/dist/pypy/rpython/memory/test/test_gc.py
Log:
make the semispace GC safe against recursive collects


Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Tue Oct  9 19:14:12 2007
@@ -436,7 +436,7 @@
 
     # __________ debugging __________
     'debug_view':           LLOp(),
-    'debug_print':          LLOp(),
+    'debug_print':          LLOp(canrun=True),
     'debug_pdb':            LLOp(),
     'debug_assert':         LLOp(tryfold=True),
     'debug_fatalerror':     LLOp(),

Modified: pypy/dist/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/opimpl.py	Tue Oct  9 19:14:12 2007
@@ -386,6 +386,10 @@
         raise TypeError("cannot fold getfield on mutable array")
     return p[index]
 
+def op_debug_print(*args):
+    for arg in args:
+        print arg
+
 # ____________________________________________________________
 
 def get_op_impl(opname):

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 19:14:12 2007
@@ -1044,7 +1044,8 @@
         free_non_gc_object(roots)
         scan = self.scan_copied(scan)
         # walk over list of objects that contain weakrefs
-        # if the object it references survives and invalidate it otherwise
+        # if the object it references survives then update the weakref
+        # otherwise invalidate the weakref
         new_with_weakref = self.AddressLinkedList()
         while self.objects_with_weakrefs.non_empty():
             obj = self.objects_with_weakrefs.pop()
@@ -1059,9 +1060,20 @@
                         pointing_to)
                 else:
                     (obj + offset).address[0] = NULL
+            # XXX the next line can be indented? only do after weakref
+            # tests pass
             new_with_weakref.append(obj)
         self.objects_with_weakrefs.delete()
         self.objects_with_weakrefs = new_with_weakref
+        if self.run_finalizers.non_empty():
+            # we are in an inner collection, caused by a finalizer
+            # the run_finalizers objects need to be copied
+            new_run_finalizer = self.AddressLinkedList()
+            while self.run_finalizers.non_empty():
+                obj = self.run_finalizers.pop()
+                new_run_finalizer.append(self.copy(obj))
+            self.run_finalizers.delete()
+            self.run_finalizers = new_run_finalizer
         # 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

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 19:14:12 2007
@@ -153,6 +153,31 @@
         res = self.interpret(f, [5])
         assert res == 12
 
+    def test_finalizer_calls_collect(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
+                llop.gc__collect(lltype.Void)
+        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
+
     def test_finalizer_resurrects(self):
         class B(object):
             pass
@@ -224,6 +249,7 @@
         res = self.interpret(f, [])
         assert res
 
+
 class TestMarkSweepGC(GCTest):
     from pypy.rpython.memory.gc import MarkSweepGC as GCClass
 



More information about the Pypy-commit mailing list