[pypy-commit] pypy gc-minimark-pinning: Attempt to rewrite the logic in maybe_collect_and_reserve()
arigo
noreply at buildbot.pypy.org
Sat May 12 18:12:03 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: gc-minimark-pinning
Changeset: r55058:03188efc3b60
Date: 2012-05-12 18:11 +0200
http://bitbucket.org/pypy/pypy/changeset/03188efc3b60/
Log: Attempt to rewrite the logic in maybe_collect_and_reserve() in order
to kill again the argument 'min_size' to minor_collection().
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -593,35 +593,44 @@
and finally reserve 'totalsize' bytes at the start of the
now-empty nursery.
"""
- while self.nursery_barriers.non_empty():
- # move over to the next contiguous block of memory
- size_gc_header = self.gcheaderbuilder.size_gc_header
- pinned_obj_size = size_gc_header + self.get_size(
- self.nursery_top + size_gc_header)
- self.nursery_free = self.nursery_top + pinned_obj_size
- self.nursery_top = self.nursery_barriers.popleft()
- # try again
+ count = 0
+ #
+ while True:
+ if self.nursery_barriers.non_empty():
+ # first thing we can try: if there are non-contiguous
+ # blocks from pinned objects, move to the next one
+ size_gc_header = self.gcheaderbuilder.size_gc_header
+ pinned_obj_size = size_gc_header + self.get_size(
+ self.nursery_top + size_gc_header)
+ self.nursery_free = self.nursery_top + pinned_obj_size
+ self.nursery_top = self.nursery_barriers.popleft()
+ #
+ else:
+ # do a minor collection
+ self.minor_collection()
+ # here, the nursery contains only pinned objects and
+ # allocation will succeed (maybe not in the first
+ # block). If we reach this point for the first time
+ # then check if we should do a major collection. If we
+ # do then afterward the nursery is again in a random
+ # state because of execute_finalizers(); so we might
+ # reach this point a second time, but not more.
+ count += 1
+ if count == 1:
+ if (self.get_total_memory_used() >
+ self.next_major_collection_threshold):
+ self.major_collection()
+ else:
+ ll_assert(count == 2,
+ "Seeing minor_collection() more than twice. "
+ "Too many pinned objects?")
+ #
+ # Attempt to get 'totalsize' out of the nursery now. This
+ # may fail again, and then we loop; but it's the uncommon case.
result = self.nursery_free
self.nursery_free = result + totalsize
if self.nursery_free <= self.nursery_top:
- return result
- #
- self.minor_collection(totalsize)
- # try allocating now, otherwise we do a major collect
- do_major_collect = False
- #
- if do_major_collect or (self.get_total_memory_used() > self.next_major_collection_threshold):
- self.major_collection()
- #
- # The nursery might not be empty now, because of
- # execute_finalizers(). If it is almost full again,
- # we need to fix it with another call to minor_collection().
- if self.nursery_free + totalsize > self.nursery_top:
- self.minor_collection(totalsize)
- #
- result = self.nursery_free
- self.nursery_free = result + totalsize
- ll_assert(self.nursery_free <= self.nursery_top, "nursery overflow")
+ break
#
if self.debug_tiny_nursery >= 0: # for debugging
ll_assert(not self.nursery_barriers.non_empty(), "no support for nursery debug and pinning")
@@ -1268,7 +1277,7 @@
# ----------
# Nursery collection
- def minor_collection(self, min_size=0):
+ def minor_collection(self):
"""Perform a minor collection: find the objects from the nursery
that remain alive and move them out."""
#
@@ -1361,13 +1370,6 @@
self.nursery_free = self.nursery
self.nursery_barriers.append(self.nursery + self.nursery_size)
self.nursery_top = self.nursery_barriers.popleft()
- while self.nursery_barriers.non_empty() and self.nursery_free + min_size > self.nursery_top:
- cur_obj_size = size_gc_header + self.get_size(self.nursery_top +
- size_gc_header)
- self.nursery_free = self.nursery_top + cur_obj_size
- self.nursery_top = self.nursery_barriers.popleft()
- if self.nursery_free + min_size > self.nursery_top:
- ll_assert(False, "too many pinned objects")
#
debug_print("minor collect, total memory used:",
self.get_total_memory_used())
More information about the pypy-commit
mailing list