[pypy-svn] r54479 - in pypy/branch/gc-tweak/pypy/rpython/memory: . gc
arigo at codespeak.net
arigo at codespeak.net
Tue May 6 16:39:34 CEST 2008
Author: arigo
Date: Tue May 6 16:39:32 2008
New Revision: 54479
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/gctypelayout.py
pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py
Log:
Try to cover as many invariants as possible in the debug checks.
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 16:39:32 2008
@@ -150,7 +150,7 @@
trace._annspecialcase_ = 'specialize:arg(2)'
def debug_check_consistency(self):
- """To use around a collection. If self.DEBUG is set, this
+ """To use after 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.
@@ -176,11 +176,16 @@
if obj:
record(obj)
- self.root_walker.walk_roots(callback, callback, callback)
+ self.root_walker._walk_prebuilt_gc(record)
+ self.root_walker.walk_roots(callback, callback, None)
while pending:
obj = pending.pop()
+ self.debug_check_object(obj)
self.trace(obj, callback2, None)
+ def debug_check_object(self, obj):
+ pass
+
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 16:39:32 2008
@@ -321,7 +321,6 @@
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
@@ -444,6 +443,48 @@
# overridden by HybridGC
return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0
+ def debug_check_object(self, obj):
+ """Check the invariants about 'obj' that should be true
+ between collections."""
+ SemiSpaceGC.debug_check_object(self, obj)
+ tid = self.header(obj).tid
+ if tid & GCFLAG_NO_YOUNG_PTRS:
+ def _no_nursery_pointer(root, ignored):
+ assert not self.is_in_nursery(root.address[0])
+ assert not self.is_in_nursery(obj)
+ self.trace(obj, _no_nursery_pointer, None)
+ elif not self.is_in_nursery(obj):
+ assert self.header(obj)._obj in self._d_oopty
+ if tid & GCFLAG_NO_HEAP_PTRS:
+ def _no_gen1or2_pointer(root, ignored):
+ target = root.address[0]
+ assert not target or self.is_last_generation(target)
+ assert self.is_last_generation(obj)
+ self.trace(obj, _no_gen1or2_pointer, None)
+ elif self.is_last_generation(obj):
+ assert self.header(obj)._obj in self._d_lgro
+
+ def debug_check_consistency(self):
+ if self.DEBUG:
+ self._make_dict("old_objects_pointing_to_young", "_d_oopty")
+ self._make_dict("last_generation_root_objects", "_d_lgro")
+ SemiSpaceGC.debug_check_consistency(self)
+ def check1(obj, ignored):
+ assert not (self.header(obj).tid & GCFLAG_NO_YOUNG_PTRS)
+ def check2(obj, ignored):
+ assert not (self.header(obj).tid & GCFLAG_NO_HEAP_PTRS)
+ self.old_objects_pointing_to_young.foreach(check1, None)
+ self.last_generation_root_objects.foreach(check2, None)
+
+ def _make_dict(self, attr, shortattr):
+ result = {}
+ def _add_dict(obj, ignored):
+ hdrobj = self.header(obj)._obj
+ result[hdrobj] = True
+ lst = getattr(self, attr)
+ lst.foreach(_add_dict, None)
+ setattr(self, shortattr, result)
+
# ____________________________________________________________
import os
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 16:39:32 2008
@@ -264,12 +264,6 @@
# 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
@@ -469,3 +463,28 @@
"nonmoving freed: ",
dead_size, "bytes in",
dead_count, "objs")
+
+ def debug_check_object(self, obj):
+ """Check the invariants about 'obj' that should be true
+ between collections."""
+ GenerationGC.debug_check_object(self, obj)
+ tid = self.header(obj).tid
+ if tid & GCFLAG_UNVISITED:
+ assert self.header(obj)._obj in self._d_gen2ro
+
+ def debug_check_consistency(self):
+ if self.DEBUG:
+ self._make_dict("gen2_rawmalloced_objects", "_d_gen2ro")
+ GenerationGC.debug_check_consistency(self)
+ def check_gen2(obj, ignored):
+ tid = self.header(obj).tid
+ assert tid & GCFLAG_EXTERNAL
+ assert tid & GCFLAG_UNVISITED
+ assert (tid & GCFLAG_AGE_MASK) < GCFLAG_AGE_MAX
+ def check_gen3(obj, ignored):
+ tid = self.header(obj).tid
+ assert tid & GCFLAG_EXTERNAL
+ assert not (tid & GCFLAG_UNVISITED)
+ assert (tid & GCFLAG_AGE_MASK) == GCFLAG_AGE_MAX
+ self.gen2_rawmalloced_objects.foreach(check_gen2, None)
+ self.gen3_rawmalloced_objects.foreach(check_gen3, None)
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 16:39:32 2008
@@ -202,13 +202,13 @@
self.max_space_size = size
def collect(self):
+ self.debug_check_consistency()
self.semispace_collect()
# the indirection is required by the fact that collect() is referred
# to by the gc transformer, and the default argument would crash
# (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)
@@ -571,5 +571,14 @@
finally:
self.finalizer_lock_count -= 1
+ def debug_check_object(self, obj):
+ """Check the invariants about 'obj' that should be true
+ between collections."""
+ tid = self.header(obj).tid
+ if not (tid & GCFLAG_EXTERNAL):
+ assert not (tid & GCFLAG_FORWARDED)
+ assert (self.tospace <= obj < self.free) == (not (tid&GCFLAG_EXTERNAL))
+ assert not (tid & GCFLAG_FINALIZATION_ORDERING)
+
STATISTICS_NUMBERS = 0
Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gctypelayout.py (original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gctypelayout.py Tue May 6 16:39:32 2008
@@ -193,6 +193,9 @@
self.addresses_of_static_ptrs = []
# this lists contains pointers in raw Structs and Arrays
self.addresses_of_static_ptrs_in_nongc = []
+ # for debugging, the following list collects all the prebuilt
+ # GcStructs and GcArrays
+ self.all_prebuilt_gc = []
self.finalizer_funcptrs = {}
self.offsettable_cache = {}
self.next_typeid_cache = {}
@@ -280,6 +283,7 @@
hdr = gc.gcheaderbuilder.new_header(value)
adr = llmemory.cast_ptr_to_adr(hdr)
gc.init_gc_object_immortal(adr, typeid)
+ self.all_prebuilt_gc.append(value)
# The following collects the addresses of all the fields that have
# a GC Pointer type, inside the current prebuilt object. All such
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 16:39:32 2008
@@ -25,8 +25,9 @@
TYPE = lltype.typeOf(obj)
layoutbuilder.consider_constant(TYPE, obj, self.gc)
- self.constantroots = list(layoutbuilder.addresses_of_static_ptrs)
+ self.constantroots = layoutbuilder.addresses_of_static_ptrs
self.constantrootsnongc = layoutbuilder.addresses_of_static_ptrs_in_nongc
+ self._all_prebuilt_gc = layoutbuilder.all_prebuilt_gc
# ____________________________________________________________
#
@@ -133,6 +134,10 @@
if addrofaddr.address[0]:
collect_stack_root(gc, addrofaddr)
+ def _walk_prebuilt_gc(self, collect): # debugging only! not RPython
+ for obj in self.gcheap._all_prebuilt_gc:
+ collect(llmemory.cast_ptr_to_adr(obj._as_ptr()))
+
class DirectRunLayoutBuilder(gctypelayout.TypeLayoutBuilder):
More information about the pypy-svn
mailing list