[pypy-svn] r68432 - pypy/branch/gc-hash/pypy/rpython/memory/gc
arigo at codespeak.net
arigo at codespeak.net
Wed Oct 14 12:48:31 CEST 2009
Author: arigo
Date: Wed Oct 14 12:48:30 2009
New Revision: 68432
Modified:
pypy/branch/gc-hash/pypy/rpython/memory/gc/generation.py
pypy/branch/gc-hash/pypy/rpython/memory/gc/hybrid.py
pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py
Log:
Some progress. TestHybridGC is now happy,
but TestHybridGCRemoveTypePtr not.
Modified: pypy/branch/gc-hash/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gc/generation.py Wed Oct 14 12:48:30 2009
@@ -241,11 +241,11 @@
llop.debug_print(lltype.Void, "percent survived", float(self.free - self.tospace) / self.space_size)
def make_a_copy(self, obj, objsize):
- newobj = SemiSpaceGC.make_a_copy(self, obj, objsize)
+ tid = self.header(obj).tid
# During a full collect, all copied objects might implicitly come
# from the nursery. In case they do, we must add this flag:
- self.header(newobj).tid |= GCFLAG_NO_YOUNG_PTRS
- return newobj
+ tid |= GCFLAG_NO_YOUNG_PTRS
+ return self._make_a_copy_with_tid(obj, objsize, tid)
# history: this was missing and caused an object to become old but without the
# flag set. Such an object is bogus in the sense that the write_barrier doesn't
# work on it. So it can eventually contain a ptr to a young object but we didn't
@@ -384,8 +384,7 @@
while scan < self.free:
curr = scan + self.size_gc_header()
self.trace_and_drag_out_of_nursery(curr)
- scan += (self.size_gc_header() + self.get_size(curr)
- + self.extra_hash_space(curr))
+ scan += self.size_gc_header() + self.get_size_incl_hash(curr)
return scan
def trace_and_drag_out_of_nursery(self, obj):
Modified: pypy/branch/gc-hash/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gc/hybrid.py (original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gc/hybrid.py Wed Oct 14 12:48:30 2009
@@ -2,6 +2,7 @@
from pypy.rpython.memory.gc.semispace import SemiSpaceGC
from pypy.rpython.memory.gc.generation import GenerationGC
from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED
+from pypy.rpython.memory.gc.semispace import GCFLAG_HASHTAKEN, GCFLAG_HASHFIELD
from pypy.rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS
from pypy.rpython.memory.gc.generation import GCFLAG_NO_HEAP_PTRS
from pypy.rpython.lltypesystem import lltype, llmemory, llarena
@@ -401,15 +402,18 @@
tid &= ~GCFLAG_AGE_MASK
# skip GenerationGC.make_a_copy() as we already did the right
# thing about GCFLAG_NO_YOUNG_PTRS
- newobj = SemiSpaceGC.make_a_copy(self, obj, objsize)
- self.header(newobj).tid = tid
- return newobj
+ return self._make_a_copy_with_tid(obj, objsize, tid)
def make_a_nonmoving_copy(self, obj, objsize):
# NB. the object can have a finalizer or be a weakref, but
# it's not an issue.
totalsize = self.size_gc_header() + objsize
- newaddr = self.allocate_external_object(totalsize)
+ oldhdr = self.header(obj)
+ if oldhdr.tid & (GCFLAG_HASHTAKEN|GCFLAG_HASHFIELD):
+ totalsize_incl_hash = totalsize + llmemory.sizeof(lltype.Signed)
+ else:
+ totalsize_incl_hash = totalsize
+ newaddr = self.allocate_external_object(totalsize_incl_hash)
if not newaddr:
return llmemory.NULL # can't raise MemoryError during a collect()
if self.config.gcconfig.debugprint:
@@ -423,6 +427,16 @@
# GCFLAG_UNVISITED is not set
# GCFLAG_NO_HEAP_PTRS is not set either, conservatively. It may be
# set by the next collection's collect_last_generation_roots().
+ #
+ # check if we need to write a hash value at the end of the new obj
+ if hdr.tid & (GCFLAG_HASHTAKEN|GCFLAG_HASHFIELD):
+ if hdr.tid & GCFLAG_HASHFIELD:
+ hash = (obj + objsize).signed[0]
+ else:
+ hash = llmemory.cast_adr_to_int(obj)
+ hdr.tid |= GCFLAG_HASHFIELD
+ (newaddr + totalsize).signed[0] = hash
+ #
# This old object is immediately put at generation 3.
ll_assert(self.is_last_generation(newobj),
"make_a_nonmoving_copy: object too young")
@@ -503,13 +517,13 @@
if tid & GCFLAG_UNVISITED:
if self.config.gcconfig.debugprint:
dead_count+=1
- dead_size+=raw_malloc_usage(self.get_size(obj))
+ dead_size+=raw_malloc_usage(self.get_size_incl_hash(obj))
addr = obj - self.gcheaderbuilder.size_gc_header
llmemory.raw_free(addr)
else:
if self.config.gcconfig.debugprint:
alive_count+=1
- alive_size+=raw_malloc_usage(self.get_size(obj))
+ alive_size+=raw_malloc_usage(self.get_size_incl_hash(obj))
if generation == 3:
surviving_objects.append(obj)
elif generation == 2:
Modified: pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gc/semispace.py Wed Oct 14 12:48:30 2009
@@ -302,19 +302,18 @@
if free_after_collection < self.space_size // 5:
self.red_zone += 1
- def extra_hash_space(self, obj):
+ def get_size_incl_hash(self, obj):
+ size = self.get_size(obj)
hdr = self.header(obj)
if hdr.tid & GCFLAG_HASHFIELD:
- return llmemory.sizeof(lltype.Signed)
- else:
- return 0
+ size += llmemory.sizeof(lltype.Signed)
+ return size
def scan_copied(self, scan):
while scan < self.free:
curr = scan + self.size_gc_header()
self.trace_and_copy(curr)
- scan += (self.size_gc_header() + self.get_size(curr)
- + self.extra_hash_space(curr))
+ scan += self.size_gc_header() + self.get_size_incl_hash(curr)
return scan
def collect_roots(self):
@@ -341,27 +340,32 @@
self.set_forwarding_address(obj, newobj, objsize)
return newobj
- def make_a_copy(self, obj, objsize):
+ def _make_a_copy_with_tid(self, obj, objsize, tid):
totalsize = self.size_gc_header() + objsize
newaddr = self.free
llarena.arena_reserve(newaddr, totalsize)
raw_memcopy(obj - self.size_gc_header(), newaddr, totalsize)
#
# check if we need to write a hash value at the end of the new obj
- newhdr = llmemory.cast_adr_to_ptr(newaddr, lltype.Ptr(self.HDR))
- if newhdr.tid & (GCFLAG_HASHTAKEN|GCFLAG_HASHFIELD):
- if newhdr.tid & GCFLAG_HASHFIELD:
- hash = (obj + self.get_size(obj)).signed[0]
+ if tid & (GCFLAG_HASHTAKEN|GCFLAG_HASHFIELD):
+ if tid & GCFLAG_HASHFIELD:
+ hash = (obj + objsize).signed[0]
else:
hash = llmemory.cast_adr_to_int(obj)
- newhdr.tid |= GCFLAG_HASHFIELD
+ tid |= GCFLAG_HASHFIELD
(newaddr + totalsize).signed[0] = hash
totalsize += llmemory.sizeof(lltype.Signed)
#
self.free += totalsize
+ newhdr = llmemory.cast_adr_to_ptr(newaddr, lltype.Ptr(self.HDR))
+ newhdr.tid = tid
newobj = newaddr + self.size_gc_header()
return newobj
+ def make_a_copy(self, obj, objsize):
+ tid = self.header(obj).tid
+ return self._make_a_copy_with_tid(obj, objsize, tid)
+
def trace_and_copy(self, obj):
self.trace(obj, self._trace_copy, None)
More information about the Pypy-commit
mailing list