[pypy-svn] r47805 - pypy/dist/pypy/rpython/memory/gc
arigo at codespeak.net
arigo at codespeak.net
Wed Oct 24 11:38:36 CEST 2007
Author: arigo
Date: Wed Oct 24 11:38:36 2007
New Revision: 47805
Modified:
pypy/dist/pypy/rpython/memory/gc/base.py
pypy/dist/pypy/rpython/memory/gc/generation.py
pypy/dist/pypy/rpython/memory/gc/semispace.py
Log:
Implement a "red zone" mechanism in the semispace GC to double the
space size before it is completely full.
Modified: pypy/dist/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/base.py (original)
+++ pypy/dist/pypy/rpython/memory/gc/base.py Wed Oct 24 11:38:36 2007
@@ -5,6 +5,7 @@
_alloc_flavor_ = "raw"
moving_gc = False
needs_write_barrier = False
+ needs_zero_gc_pointers = True
def set_query_functions(self, is_varsize, getfinalizer,
offsets_to_gc_pointers,
Modified: pypy/dist/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/dist/pypy/rpython/memory/gc/generation.py Wed Oct 24 11:38:36 2007
@@ -4,6 +4,7 @@
from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage
from pypy.rpython.lltypesystem import lltype, llmemory, llarena
from pypy.rlib.objectmodel import free_non_gc_object, debug_assert
+from pypy.rpython.lltypesystem.lloperation import llop
# The following flag is never set on young objects, i.e. the ones living
# in the nursery. It is initially set on all prebuilt and old objects,
@@ -148,6 +149,7 @@
debug_assert(self.nursery_size <= self.top_of_space - self.free,
"obtain_free_space failed to do its job")
if self.nursery:
+ #llop.debug_print(lltype.Void, "minor collect")
# a nursery-only collection
scan = self.free
self.collect_oldrefs_to_nursery()
Modified: pypy/dist/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/dist/pypy/rpython/memory/gc/semispace.py Wed Oct 24 11:38:36 2007
@@ -20,6 +20,7 @@
class SemiSpaceGC(MovingGCBase):
_alloc_flavor_ = "raw"
inline_simple_malloc = True
+ needs_zero_gc_pointers = False
HDR = lltype.Struct('header', ('forw', llmemory.Address),
('tid', lltype.Signed))
@@ -45,6 +46,7 @@
self.run_finalizers = self.AddressLinkedList()
self.objects_with_weakrefs = self.AddressLinkedList()
self.finalizer_lock_count = 0
+ self.red_zone = 0
def disable_finalizers(self):
self.finalizer_lock_count += 1
@@ -109,7 +111,11 @@
def try_obtain_free_space(self, needed):
# XXX for bonus points do big objects differently
needed = raw_malloc_usage(needed)
- self.semispace_collect()
+ if (self.red_zone >= 2 and self.space_size < self.max_space_size and
+ self.double_space_size()):
+ pass # collect was done during double_space_size()
+ else:
+ self.semispace_collect()
missing = needed - (self.top_of_space - self.free)
if missing <= 0:
return True # success
@@ -133,6 +139,7 @@
return True
def double_space_size(self):
+ self.red_zone = 0
old_fromspace = self.fromspace
newsize = self.space_size * 2
newspace = llarena.arena_malloc(newsize, True)
@@ -192,7 +199,24 @@
self.notify_objects_just_moved()
if not size_changing:
llarena.arena_reset(fromspace, self.space_size, True)
+ self.record_red_zone()
self.execute_finalizers()
+ #llop.debug_print(lltype.Void, 'collected', self.space_size, size_changing, self.top_of_space - self.free)
+
+ def record_red_zone(self):
+ # red zone: if the space is more than 80% full, the next collection
+ # should double its size. If it is more than 66% full twice in a row,
+ # then it should double its size too. (XXX adjust)
+ # The goal is to avoid many repeated collection that don't free a lot
+ # of memory each, if the size of the live object set is just below the
+ # size of the space.
+ free_after_collection = self.top_of_space - self.free
+ if free_after_collection > self.space_size // 3:
+ self.red_zone = 0
+ else:
+ self.red_zone += 1
+ if free_after_collection < self.space_size // 5:
+ self.red_zone += 1
def scan_copied(self, scan):
while scan < self.free:
More information about the Pypy-commit
mailing list