[pypy-svn] r68839 - pypy/branch/logging/pypy/rpython/memory/gc
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 29 11:33:04 CET 2009
Author: arigo
Date: Thu Oct 29 11:33:04 2009
New Revision: 68839
Modified:
pypy/branch/logging/pypy/rpython/memory/gc/generation.py
pypy/branch/logging/pypy/rpython/memory/gc/hybrid.py
pypy/branch/logging/pypy/rpython/memory/gc/semispace.py
Log:
Check against using a helper (like rlog.debug_log()) in the GC that
would end up mallocating more objects using the GC. Done with a
flag to detect recursion.
Modified: pypy/branch/logging/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/logging/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/branch/logging/pypy/rpython/memory/gc/generation.py Thu Oct 29 11:33:04 2009
@@ -328,10 +328,16 @@
def collect_nursery(self):
if self.nursery_size > self.top_of_space - self.free:
# the semispace is running out, do a full collect
+ # (also handles the case of a recursive collect done by mistake)
self.obtain_free_space(self.nursery_size)
ll_assert(self.nursery_size <= self.top_of_space - self.free,
"obtain_free_space failed to do its job")
if self.nursery:
+ ll_assert(not self.collection_in_progress,
+ "should not reach this point")
+ self.collection_in_progress = True
+ old_top_of_space = self.top_of_space
+ self.top_of_space = self.free # temp., to detect recursion
rlog.debug_log("gc-minor-{", ".--- minor collect ---")
# a nursery-only collection
scan = beginning = self.free
@@ -351,6 +357,8 @@
"`------ survived (fraction of the size): %(survived)f",
oldobj = oldobj_count,
survived = float(scan - beginning) / self.nursery_size)
+ self.top_of_space = old_top_of_space
+ self.collection_in_progress = False
#self.debug_check_consistency() # -- quite expensive
else:
# no nursery - this occurs after a full collect, triggered either
Modified: pypy/branch/logging/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/logging/pypy/rpython/memory/gc/hybrid.py (original)
+++ pypy/branch/logging/pypy/rpython/memory/gc/hybrid.py Thu Oct 29 11:33:04 2009
@@ -182,6 +182,8 @@
# In order to keep malloc_varsize_clear() as compact as possible,
# we recompute what we need in this slow path instead of passing
# it all as function arguments.
+ ll_assert(not self.collection_in_progress,
+ "malloc_varsize_slowpath() while a collection is in progress")
size_gc_header = self.gcheaderbuilder.size_gc_header
nonvarsize = size_gc_header + self.fixed_size(typeid)
itemsize = self.varsize_item_sizes(typeid)
@@ -222,6 +224,8 @@
return llmemory.cast_ptr_to_adr(gcref)
def realloc(self, ptr, newlength, fixedsize, itemsize, lengthofs, grow):
+ ll_assert(not self.collection_in_progress,
+ "realloc() while a collection is in progress")
size_gc_header = self.size_gc_header()
addr = llmemory.cast_ptr_to_adr(ptr)
ll_assert(self.header(addr).tid & GCFLAG_EXTERNAL,
Modified: pypy/branch/logging/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/logging/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/branch/logging/pypy/rpython/memory/gc/semispace.py Thu Oct 29 11:33:04 2009
@@ -61,6 +61,7 @@
self.space_size = self.param_space_size
self.max_space_size = self.param_max_space_size
self.red_zone = 0
+ self.collection_in_progress = False
self.program_start_time = time.time()
self.tospace = llarena.arena_malloc(self.space_size, True)
@@ -213,6 +214,18 @@
# (this is also a hook for the HybridGC)
def semispace_collect(self, size_changing=False):
+ ll_assert(not self.collection_in_progress,
+ "allocating memory while the GC is collecting!")
+ self.collection_in_progress = True
+ # temporarily set 'top_of_space' to a value that will prevent
+ # all mallocs from succeeding and cause semispace_collect()
+ # to be called again -- and hitting the ll_assert() above.
+ tospace = self.fromspace
+ fromspace = self.tospace
+ self.fromspace = fromspace
+ self.tospace = tospace
+ self.top_of_space = tospace
+
if rlog.has_log():
start_usage = self.free - self.tospace
start_time = time.time()
@@ -225,17 +238,11 @@
else:
start_time = 0 # Help the flow space
start_usage = 0 # Help the flow space
- #llop.debug_print(lltype.Void, 'semispace_collect', int(size_changing))
# Switch the spaces. We copy everything over to the empty space
# (self.fromspace at the beginning of the collection), and clear the old
# one (self.tospace at the beginning). Their purposes will be reversed
# for the next collection.
- tospace = self.fromspace
- fromspace = self.tospace
- self.fromspace = fromspace
- self.tospace = tospace
- self.top_of_space = tospace + self.space_size
scan = self.free = tospace
self.starting_full_collect()
self.collect_roots()
@@ -248,6 +255,9 @@
self.invalidate_weakrefs()
self.update_objects_with_id()
self.finished_full_collect()
+ self.top_of_space = self.tospace + self.space_size
+ ll_assert(self.free <= self.top_of_space, "space overflowed")
+ self.collection_in_progress = False
self.debug_check_consistency()
if not size_changing:
llarena.arena_reset(fromspace, self.space_size, True)
@@ -601,6 +611,8 @@
def identityhash(self, gcobj):
# The following code should run at most twice.
while 1:
+ ll_assert(not self.collection_in_progress,
+ "identityhash() while the GC is collecting!")
obj = llmemory.cast_ptr_to_adr(gcobj)
hdr = self.header(obj)
#
More information about the Pypy-commit
mailing list