[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