[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