[pypy-svn] r54477 - in pypy/branch/gc-tweak/pypy/rpython/memory: . gc

arigo at codespeak.net arigo at codespeak.net
Tue May 6 15:24:58 CEST 2008


Author: arigo
Date: Tue May  6 15:24:58 2008
New Revision: 54477

Modified:
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/base.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py
Log:
While running test_gc, add an explicit check before and after minor and
major collections which verifies the global consistency of the objects.



Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/base.py	Tue May  6 15:24:58 2008
@@ -7,6 +7,7 @@
     needs_write_barrier = False
     malloc_zero_filled = False
     prebuilt_gc_objects_are_static_roots = True
+    DEBUG = False      # set to True for test_gc.py
 
     def set_query_functions(self, is_varsize, has_gcptr_in_varsize,
                             is_gcarrayofgcptr,
@@ -148,6 +149,38 @@
                 length -= 1
     trace._annspecialcase_ = 'specialize:arg(2)'
 
+    def debug_check_consistency(self):
+        """To use around a collection.  If self.DEBUG is set, this
+        enumerates all roots and trace all objects to check if we didn't
+        accidentally free a reachable object or forgot to update a pointer
+        to an object that moved.
+        """
+        if self.DEBUG:
+            # this part is not rpython
+            seen = {}
+            pending = []
+
+            def record(obj):
+                hdrobj = self.header(obj)._obj
+                if hdrobj not in seen:
+                    seen[hdrobj] = True
+                    pending.append(obj)
+
+            def callback(self, root):
+                obj = root.address[0]
+                assert obj
+                record(obj)
+
+            def callback2(pointer, ignored):
+                obj = pointer.address[0]
+                if obj:
+                    record(obj)
+
+            self.root_walker.walk_roots(callback, callback, callback)
+            while pending:
+                obj = pending.pop()
+                self.trace(obj, callback2, None)
+
 
 class MovingGCBase(GCBase):
     moving_gc = True

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py	Tue May  6 15:24:58 2008
@@ -321,6 +321,7 @@
             ll_assert(self.nursery_size <= self.top_of_space - self.free,
                          "obtain_free_space failed to do its job")
         if self.nursery:
+            self.debug_check_consistency()
             if DEBUG_PRINT:
                 llop.debug_print(lltype.Void, "minor collect")
             # a nursery-only collection
@@ -337,6 +338,7 @@
             llarena.arena_reset(self.nursery, self.nursery_size, True)
             if DEBUG_PRINT:
                 llop.debug_print(lltype.Void, "percent survived:", float(scan - beginning) / self.nursery_size)
+            self.debug_check_consistency()
         else:
             # no nursery - this occurs after a full collect, triggered either
             # just above or by some previous non-nursery-based allocation.

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py	Tue May  6 15:24:58 2008
@@ -264,6 +264,12 @@
         # At the start of a collection, the GCFLAG_UNVISITED bit is set
         # exactly on the objects in gen2_rawmalloced_objects.  Only
         # raw_malloc'ed objects can ever have this bit set.
+        if self.DEBUG:
+            def check_bit(obj, expected):
+                assert self.header(obj).tid & GCFLAG_UNVISITED == expected
+            self.gen2_rawmalloced_objects.foreach(check_bit, GCFLAG_UNVISITED)
+            self.gen3_rawmalloced_objects.foreach(check_bit, 0)
+
         self.count_semispaceonly_collects += 1
         if self.is_collecting_gen3():
             # set the GCFLAG_UNVISITED on all rawmalloced generation-3 objects

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py	Tue May  6 15:24:58 2008
@@ -208,6 +208,7 @@
         # (this is also a hook for the HybridGC)
 
     def semispace_collect(self, size_changing=False):
+        self.debug_check_consistency()
         if DEBUG_PRINT:
             import time
             llop.debug_print(lltype.Void)
@@ -235,6 +236,7 @@
         if self.objects_with_weakrefs.non_empty():
             self.invalidate_weakrefs()
         self.finished_full_collect()
+        self.debug_check_consistency()
         self.notify_objects_just_moved()
         if not size_changing:
             llarena.arena_reset(fromspace, self.space_size, True)

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py	Tue May  6 15:24:58 2008
@@ -10,6 +10,7 @@
     def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}):
         self.gc = gc_class(chunk_size = 10, **GC_PARAMS)
         self.gc.set_root_walker(LLInterpRootWalker(self))
+        self.gc.DEBUG = True
         self.llinterp = llinterp
         self.prepare_graphs(flowgraphs)
         self.gc.setup()



More information about the Pypy-commit mailing list