[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