[pypy-svn] r49780 - in pypy/branch/lazy-write-barrier/pypy/rpython/memory: . gc gctransform test

fijal at codespeak.net fijal at codespeak.net
Fri Dec 14 13:55:46 CET 2007


Author: fijal
Date: Fri Dec 14 13:55:46 2007
New Revision: 49780

Modified:
   pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/generation.py
   pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/marksweep.py
   pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctypelayout.py
   pypy/branch/lazy-write-barrier/pypy/rpython/memory/test/test_transformed_gc.py
Log:
inprogress checkin of lazy write barrier approach


Modified: pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/generation.py	Fri Dec 14 13:55:46 2007
@@ -13,6 +13,10 @@
 # pointer to a young object.
 GCFLAG_NO_YOUNG_PTRS = 2 << GCFLAGSHIFT
 
+# The following flag is set for static roots which are not on the list
+# of static roots yet, but will appear with write barrier
+GCFLAG_NEVER_SET = 3 << GCFLAGSHIFT
+
 DEBUG_PRINT = False
 
 class GenerationGC(SemiSpaceGC):
@@ -287,6 +291,15 @@
     def write_barrier(self, oldvalue, newvalue, addr_struct):
         if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
             self.remember_young_pointer(addr_struct, newvalue)
+        if self.header(addr_struct).tid & GCFLAG_NEVER_SET:
+            self.move_to_static_roots(addr_struct)
+
+    def append_to_static_roots(self, pointer, arg):
+        self.get_roots.append_static_root(pointer)
+
+    def move_to_static_roots(self, addr_struct):
+        self.header(addr_struct).tid &= ~GCFLAG_NEVER_SET
+        self.trace(addr_struct, self.append_to_static_roots, None)
 
     def remember_young_pointer(self, addr_struct, addr):
         ll_assert(not self.is_in_nursery(addr_struct),

Modified: pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/marksweep.py
==============================================================================
--- pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/marksweep.py	(original)
+++ pypy/branch/lazy-write-barrier/pypy/rpython/memory/gc/marksweep.py	Fri Dec 14 13:55:46 2007
@@ -483,8 +483,9 @@
         hdr = llmemory.cast_adr_to_ptr(addr, self.HDRPTR)
         hdr.typeid = typeid << 1
 
-    def init_gc_object_immortal(self, addr, typeid):
+    def init_gc_object_immortal(self, addr, typeid, flags=0):
         # prebuilt gc structures always have the mark bit set
+        # ignore flags
         hdr = llmemory.cast_adr_to_ptr(addr, self.HDRPTR)
         hdr.typeid = (typeid << 1) | 1
 

Modified: pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctransform/framework.py	Fri Dec 14 13:55:46 2007
@@ -403,6 +403,7 @@
         gcdata = self.gcdata
         sizeofaddr = llmemory.sizeof(llmemory.Address)
         rootstacksize = sizeofaddr * self.root_stack_depth
+        TP = lltype.Ptr(lltype.Array(llmemory.Address))
 
         class StackRootIterator:
             _alloc_flavor_ = 'raw'
@@ -421,6 +422,11 @@
                 gcdata.root_stack_top = top + n*sizeofaddr
                 return top
             incr_stack = staticmethod(incr_stack)
+
+            def append_static_root(adr):
+                gcdata.static_root_end.address[0] = adr
+                gcdata.static_root_end += sizeofaddr
+            append_static_root = staticmethod(append_static_root)
             
             def decr_stack(n):
                 top = gcdata.root_stack_top - n*sizeofaddr
@@ -509,8 +515,11 @@
             self.layoutbuilder.addresses_of_static_ptrs +
             self.layoutbuilder.addresses_of_static_ptrs_in_nongc)
         log.info("found %s static roots" % (len(addresses_of_static_ptrs), ))
+        additional_ptrs = self.layoutbuilder.additional_roots_sources
+        log.info("additional %d potential static roots" % additional_ptrs)
         ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address),
-                                               len(addresses_of_static_ptrs),
+                                               len(addresses_of_static_ptrs) +
+                                               additional_ptrs,
                                                immortal=True)
         for i in range(len(addresses_of_static_ptrs)):
             ll_static_roots_inside[i] = addresses_of_static_ptrs[i]

Modified: pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctypelayout.py	(original)
+++ pypy/branch/lazy-write-barrier/pypy/rpython/memory/gctypelayout.py	Fri Dec 14 13:55:46 2007
@@ -17,6 +17,8 @@
         self.addresses_of_static_ptrs = []
         # this lists contains pointers in raw Structs and Arrays
         self.addresses_of_static_ptrs_in_nongc = []
+        # dictionary address -> list of addresses
+        self.additional_roots_sources = 0
         self.finalizer_funcptrs = {}
 
     def get_type_id(self, TYPE):
@@ -149,11 +151,22 @@
             return
         self.seen_roots[id(value)] = True
 
+        # XXX hack, a lot of gengc details here
+        from pypy.rpython.memory.gc.generation import GenerationGC
+        from pypy.rpython.memory.gc.generation import GCFLAG_NEVER_SET
+        if isinstance(gc, GenerationGC):
+            gen_gc = True
+        else:
+            gen_gc = False
+
         if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
             typeid = self.get_type_id(TYPE)
             hdr = gc.gcheaderbuilder.new_header(value)
             adr = llmemory.cast_ptr_to_adr(hdr)
-            gc.init_gc_object_immortal(adr, typeid)
+            flags = 0
+            if gen_gc:
+                flags = GCFLAG_NEVER_SET
+            gc.init_gc_object_immortal(adr, typeid, flags=flags)
 
         # The following collects the addresses of all the fields that have
         # a GC Pointer type, inside the current prebuilt object.  All such
@@ -161,7 +174,17 @@
         # they could be changed later to point to GC heap objects.
         adr = llmemory.cast_ptr_to_adr(value._as_ptr())
         if TYPE._gckind == "gc":
-            appendto = self.addresses_of_static_ptrs
+            if gen_gc:
+                # check if have any
+                gen = mutable_gc_pointers_inside(value, adr)
+                try:
+                    gen.next()
+                except StopIteration:
+                    return
+                self.additional_roots_sources += 1
+                return
+            else:
+                appendto = self.addresses_of_static_ptrs
         else:
             appendto = self.addresses_of_static_ptrs_in_nongc
         for a in mutable_gc_pointers_inside(value, adr):

Modified: pypy/branch/lazy-write-barrier/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/branch/lazy-write-barrier/pypy/rpython/memory/test/test_transformed_gc.py	(original)
+++ pypy/branch/lazy-write-barrier/pypy/rpython/memory/test/test_transformed_gc.py	Fri Dec 14 13:55:46 2007
@@ -37,7 +37,8 @@
     gcpolicy = None
     stacklessgc = False
 
-    def runner(self, f, nbargs=0, statistics=False, **extraconfigopts):
+    def runner(self, f, nbargs=0, statistics=False, transformer=False,
+               **extraconfigopts):
         if nbargs == 2:
             def entrypoint(args):
                 x = args[0]
@@ -84,6 +85,8 @@
             def statistics(index):
                 return llinterp.eval_graph(statisticsgraph, [ll_gc, index])
             return run, statistics
+        elif transformer:
+            return run, db.gctransformer
         else:
             return run
         
@@ -862,6 +865,32 @@
         run = self.runner(f, nbargs=0)
         run([])
 
+    def test_immutable_to_old_promotion(self):
+        T_CHILD = lltype.Ptr(lltype.GcStruct('Child', ('field', lltype.Signed)))
+        T_PARENT = lltype.Ptr(lltype.GcStruct('Parent', ('sub', T_CHILD)))
+        child = lltype.malloc(T_CHILD.TO)
+        child2 = lltype.malloc(T_CHILD.TO)
+        parent = lltype.malloc(T_PARENT.TO)
+        parent2 = lltype.malloc(T_PARENT.TO)
+        parent.sub = child
+        child.field = 3
+        parent2.sub = child2
+        child2.field = 8
+
+        T_ALL = lltype.Ptr(lltype.GcArray(T_PARENT))
+        all = lltype.malloc(T_ALL.TO, 2)
+        all[0] = parent
+        all[1] = parent2
+
+        def f(x, y):
+            res = all[x]
+            #all[x] = lltype.nullptr(T_PARENT.TO)
+            return res.sub.field
+
+        run, transformer = self.runner(f, nbargs=2, transformer=True)
+        run([1, 4])
+        assert len(transformer.layoutbuilder.addresses_of_static_ptrs) == 0
+        assert transformer.layoutbuilder.additional_roots_sources == 5
 
 class TestGenerationalNoFullCollectGC(GCTest):
     # test that nursery is doing its job and that no full collection



More information about the Pypy-commit mailing list