[pypy-svn] r58427 - pypy/branch/gc-experiments/pypy/rpython/memory/gc
fijal at codespeak.net
fijal at codespeak.net
Thu Sep 25 12:58:17 CEST 2008
Author: fijal
Date: Thu Sep 25 12:58:16 2008
New Revision: 58427
Modified:
pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py
pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py
Log:
* add a comment "how I would like this to be"
* shuffle code a bit around, doesn't really matter.
Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py (original)
+++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/base.py Thu Sep 25 12:58:16 2008
@@ -4,6 +4,7 @@
from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE
from pypy.rpython.memory.support import get_address_stack, get_address_deque
from pypy.rpython.memory.support import AddressDict
+from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage
class GCBase(object):
_alloc_flavor_ = "raw"
@@ -252,6 +253,7 @@
return size
+
def deal_with_objects_with_finalizers(self, scan):
# walk over list of objects with finalizers
# if it is not copied, add it to the list of to-be-called finalizers
@@ -304,7 +306,6 @@
self.objects_with_finalizers = new_with_finalizer
return scan
-
def _append_if_nonnull(pointer, stack):
if pointer.address[0] != NULL:
stack.append(pointer.address[0])
Modified: pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py
==============================================================================
--- pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py (original)
+++ pypy/branch/gc-experiments/pypy/rpython/memory/gc/markcompact.py Thu Sep 25 12:58:16 2008
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, llarena
-from pypy.rpython.memory.gc.base import MovingGCBase, GCFLAG_FORWARDED,\
- TYPEID_MASK
+from pypy.rpython.memory.gc.base import MovingGCBase, \
+ TYPEID_MASK, GCFLAG_FINALIZATION_ORDERING
from pypy.rlib.debug import ll_assert
from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE
from pypy.rpython.memory.support import get_address_stack, get_address_deque
@@ -14,6 +14,25 @@
memoryError = MemoryError()
+# Mark'n'compact garbage collector
+#
+# main point of this GC is to save as much memory as possible
+# (not to be worse than semispace), but avoid having peaks of
+# memory during collection. Inspired, at least partly by squeak's
+# garbage collector
+
+# so, the idea as now is:
+
+# we allocate space (full of zeroes) which is big enough to handle
+# all possible cases. Because it's full of zeroes, we never allocate
+# it really, unless we start using it
+
+# for each collection we mark objects which are alive, also marking all
+# for which we want to run finalizers. we mark them by storing forward
+# pointer, which will be a place to copy them. After that, we copy all
+# using memmove to another view of the same space, hence compacting
+# everything
+
class MarkCompactGC(MovingGCBase):
HDR = lltype.Struct('header', ('tid', lltype.Signed),
('forward_ptr', llmemory.Address))
@@ -87,36 +106,16 @@
if self.run_finalizers.non_empty():
self.update_run_finalizers()
if self.objects_with_finalizers.non_empty():
- self.deal_with_objects_with_finalizers(self.space)
+ self.deal_with_objects_with_finalizers(None)
if self.objects_with_weakrefs.non_empty():
self.invalidate_weakrefs()
self.debug_check_consistency()
toaddr = llarena.arena_new_view(self.space)
- self.create_forward_pointers(toaddr)
self.debug_check_consistency()
- self.update_forward_refs()
self.compact(toaddr)
self.space = toaddr
self.debug_check_consistency()
- def create_forward_pointers(self, toaddr):
- fromaddr = self.space
- size_gc_header = self.gcheaderbuilder.size_gc_header
- while fromaddr < self.spaceptr:
- hdr = llmemory.cast_adr_to_ptr(fromaddr, lltype.Ptr(self.HDR))
- obj = fromaddr + size_gc_header
- objsize = self.get_size(obj)
- totalsize = size_gc_header + objsize
- if hdr.tid & GCFLAG_MARKBIT:
- # this objects survives, clear MARKBIT
- if fromaddr.offset != toaddr.offset:
- # this object is forwarded, set forward bit and address
- hdr.tid |= GCFLAG_FORWARDED
- llarena.arena_reserve(toaddr, totalsize)
- hdr.forward_ptr = toaddr + size_gc_header
- toaddr += size_gc_header + objsize
- fromaddr += size_gc_header + objsize
-
def get_type_id(self, addr):
return self.header(addr).tid & TYPEID_MASK
@@ -178,8 +177,7 @@
if addr != NULL:
hdr = llmemory.cast_adr_to_ptr(addr - size_gc_header,
lltype.Ptr(self.HDR))
- if hdr.tid & GCFLAG_FORWARDED:
- pointer.address[0] = hdr.forward_ptr
+ pointer.address[0] = hdr.forward_ptr
def mark(self):
self.root_walker.walk_roots(
@@ -193,6 +191,44 @@
self.header(obj).tid |= GCFLAG_MARKBIT
self.trace(obj, self._mark_object, None)
+ def deal_with_objects_with_finalizers(self, ignored):
+ new_with_finalizer = self.AddressDeque()
+ while self.objects_with_finalizers.non_empty():
+ obj = self.objects_with_finalizers.popleft()
+ if self.surviving(obj):
+ new_with_finalizer.append(obj)
+ break
+ finalizers_to_run.append(obj)
+ xxxx
+
def debug_check_object(self, obj):
# XXX write it down
pass
+
+ def surviving(self, obj):
+ hdr = self.header(obj)
+ return hdr.tid & GCFLAG_MARKBIT
+
+ def _finalization_state(self, obj):
+ hdr = self.header(obj)
+ if self.surviving(obj):
+ if hdr.tid & GCFLAG_FINALIZATION_ORDERING:
+ return 2
+ else:
+ return 3
+ else:
+ if hdr.tid & GCFLAG_FINALIZATION_ORDERING:
+ return 1
+ else:
+ return 0
+
+ def _recursively_bump_finalization_state_from_1_to_2(self, obj, scan):
+ # it's enough to leave mark bit here
+ hdr = self.header(obj)
+ if hdr.tid & GCFLAG_MARKBIT:
+ return # cycle
+ self.header(obj).tid |= GCFLAG_MARKBIT
+ self.trace(obj, self._mark_object, None)
+
+ def get_forwarding_address(self, obj):
+ return obj
More information about the Pypy-commit
mailing list