[pypy-svn] r47616 - in pypy/dist/pypy/rpython/memory: . gc gctransform

cfbolz at codespeak.net cfbolz at codespeak.net
Sat Oct 20 01:40:49 CEST 2007


Author: cfbolz
Date: Sat Oct 20 01:40:48 2007
New Revision: 47616

Modified:
   pypy/dist/pypy/rpython/memory/gc/generation.py
   pypy/dist/pypy/rpython/memory/gc/semispace.py
   pypy/dist/pypy/rpython/memory/gctransform/framework.py
   pypy/dist/pypy/rpython/memory/gcwrapper.py
Log:
check in an idea that will likely not work as easily to not have it get lost (I
will revert it afterwards): don't walk the full list of static roots at every
minor collection, instead keep a list of static structures that had young
pointers stored into them since the last collection.

This does not work, because it ignores the static roots that are part of a
nongc-struct/arrays.


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	Sat Oct 20 01:40:48 2007
@@ -1,5 +1,5 @@
 import sys
-from pypy.rpython.memory.gc.semispace import SemiSpaceGC
+from pypy.rpython.memory.gc.semispace import SemiSpaceGC, GCFLAG_IMMORTAL
 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
@@ -7,6 +7,7 @@
 nonnull_endmarker = llmemory.raw_malloc(llmemory.sizeof(lltype.Char))
 llmemory.raw_memclear(nonnull_endmarker, llmemory.sizeof(lltype.Char))
 
+GCFLAG_REMEMBERED = 2
 
 class GenerationGC(SemiSpaceGC):
     """A basic generational GC: it's a SemiSpaceGC with an additional
@@ -35,6 +36,7 @@
         self.old_objects_pointing_to_young = nonnull_endmarker
         # ^^^ the head of a linked list inside the old objects space
         self.young_objects_with_weakrefs = self.AddressLinkedList()
+        self.static_to_young_pointer = self.AddressLinkedList()
 
     def reset_nursery(self):
         self.nursery      = llmemory.NULL
@@ -90,6 +92,7 @@
 
     def semispace_collect(self, size_changing=False):
         self.reset_forwarding() # we are doing a full collection anyway
+        self.reset_static()
         self.weakrefs_grow_older()
         self.reset_nursery()
         SemiSpaceGC.semispace_collect(self, size_changing)
@@ -102,6 +105,12 @@
             hdr.forw = llmemory.NULL
         self.old_objects_pointing_to_young = nonnull_endmarker
 
+    def reset_static(self):
+        while self.static_to_young_pointer.non_empty():
+            obj = self.static_to_young_pointer.pop()
+            hdr = self.header(obj)
+            hdr.typeid &= ~GCFLAG_REMEMBERED
+
     def weakrefs_grow_older(self):
         while self.young_objects_with_weakrefs.non_empty():
             obj = self.young_objects_with_weakrefs.pop()
@@ -116,6 +125,7 @@
         if self.nursery:
             # a nursery-only collection
             scan = self.free
+            self.collect_static_to_nursery()
             self.collect_oldrefs_to_nursery()
             self.collect_roots_in_nursery()
             self.scan_objects_just_copied_out_of_nursery(scan)
@@ -150,7 +160,7 @@
         self.old_objects_pointing_to_young = nonnull_endmarker
 
     def collect_roots_in_nursery(self):
-        roots = self.get_roots()
+        roots = self.get_roots(with_static=False)
         while 1:
             root = roots.pop()
             if root == NULL:
@@ -160,6 +170,13 @@
                 root.address[0] = self.copy(obj)
         free_non_gc_object(roots)
 
+    def collect_static_to_nursery(self):
+        while self.static_to_young_pointer.non_empty():
+            obj = self.static_to_young_pointer.pop()
+            hdr = self.header(obj)
+            hdr.typeid &= ~GCFLAG_REMEMBERED
+            self.trace_and_drag_out_of_nursery(obj)
+
     def scan_objects_just_copied_out_of_nursery(self, scan):
         while scan < self.free:
             curr = scan + self.size_gc_header()
@@ -217,8 +234,17 @@
 
     def write_barrier(self, addr, addr_to, addr_struct):
         if not self.is_in_nursery(addr_struct) and self.is_in_nursery(addr):
-            oldhdr = self.header(addr_struct)
-            if oldhdr.forw == NULL:
-                oldhdr.forw = self.old_objects_pointing_to_young
-                self.old_objects_pointing_to_young = addr_struct
+            self.remember_young_pointer(addr_struct, addr)
         addr_to.address[0] = addr
+
+
+    def remember_young_pointer(self, addr_struct, addr):
+        oldhdr = self.header(addr_struct)
+        if oldhdr.forw == NULL:
+            oldhdr.forw = self.old_objects_pointing_to_young
+            self.old_objects_pointing_to_young = addr_struct
+        elif (oldhdr.typeid >> 16) & (GCFLAG_IMMORTAL | GCFLAG_REMEMBERED) == (
+                 GCFLAG_IMMORTAL):
+            self.static_to_young_pointer.append(addr_struct)
+            oldhdr.typeid |= GCFLAG_REMEMBERED
+    remember_young_pointer.dont_inline = True

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	Sat Oct 20 01:40:48 2007
@@ -14,6 +14,8 @@
 
 memoryError = MemoryError()
 
+GCFLAG_IMMORTAL = 1
+
 class SemiSpaceGC(MovingGCBase):
     _alloc_flavor_ = "raw"
     inline_simple_malloc = True
@@ -277,7 +279,7 @@
         return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
 
     def get_type_id(self, addr):
-        return self.header(addr).typeid
+        return self.header(addr).typeid & 0xff
 
     def init_gc_object(self, addr, typeid):
         hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
@@ -288,7 +290,7 @@
         # immortal objects always have forward to themselves
         hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
         hdr.forw = addr + self.gcheaderbuilder.size_gc_header
-        hdr.typeid = typeid
+        hdr.typeid = typeid | (GCFLAG_IMMORTAL << 16)
 
     def deal_with_objects_with_finalizers(self):
         # walk over list of objects with finalizers

Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform/framework.py	Sat Oct 20 01:40:48 2007
@@ -339,9 +339,12 @@
                 return top.address[0]
             pop_root = staticmethod(pop_root)
 
-            def __init__(self):
+            def __init__(self, with_static=True):
                 self.stack_current = gcdata.root_stack_top
-                self.static_current = gcdata.static_root_start
+                if with_static:
+                    self.static_current = gcdata.static_root_start
+                else:
+                    self.static_current = gcdata.static_root_end
 
             def pop(self):
                 while self.static_current != gcdata.static_root_end:

Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gcwrapper.py	(original)
+++ pypy/dist/pypy/rpython/memory/gcwrapper.py	Sat Oct 20 01:40:48 2007
@@ -27,12 +27,13 @@
 
         self.constantroots = layoutbuilder.addresses_of_static_ptrs
 
-    def get_roots_from_llinterp(self):
+    def get_roots_from_llinterp(self, with_static=True):
         sizeofaddr = llmemory.sizeof(llmemory.Address)
         ll = [llmemory.NULL]     # end marker
-        for addrofaddr in self.constantroots:
-            if addrofaddr.address[0]:
-                ll.append(addrofaddr)
+        if with_static:
+            for addrofaddr in self.constantroots:
+                if addrofaddr.address[0]:
+                    ll.append(addrofaddr)
         for addrofaddr in self.llinterp.find_roots():
             if addrofaddr.address[0]:
                 ll.append(addrofaddr)



More information about the Pypy-commit mailing list