[pypy-svn] r54450 - in pypy/branch/gc-tweak/pypy/rpython: lltypesystem memory memory/gc memory/gctransform

arigo at codespeak.net arigo at codespeak.net
Mon May 5 21:56:10 CEST 2008


Author: arigo
Date: Mon May  5 21:56:10 2008
New Revision: 54450

Modified:
   pypy/branch/gc-tweak/pypy/rpython/lltypesystem/opimpl.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gctypelayout.py
   pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py
Log:
Experimental.  Build on top of the GenerationGC's GCFLAG_NO_HEAP_PTRS
flag to make the HybridGC a full 3-generations collector.  Unsure if
the additional complexity is worth the trouble.


Modified: pypy/branch/gc-tweak/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/lltypesystem/opimpl.py	Mon May  5 21:56:10 2008
@@ -384,7 +384,8 @@
 
 def op_debug_print(*args):
     for arg in args:
-        print arg
+        print arg,
+    print
 
 # ____________________________________________________________
 

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/generation.py	Mon May  5 21:56:10 2008
@@ -16,8 +16,12 @@
 # pointer to a young object.
 GCFLAG_NO_YOUNG_PTRS = SemiSpaceGC.first_unused_gcflag << 0
 
-# The following flag is set for static roots which are not on the list
-# of static roots yet, but will appear with write barrier
+# The following flag is set on some last-generation objects (== prebuilt
+# objects for GenerationGC, but see also HybridGC).  The flag is set
+# unless the object is already listed in 'last_generation_root_objects'.
+# When a pointer is written inside an object with GCFLAG_NO_HEAP_PTRS
+# set, the write_barrier clears the flag and adds the object to
+# 'last_generation_root_objects'.
 GCFLAG_NO_HEAP_PTRS = SemiSpaceGC.first_unused_gcflag << 1
 
 class GenerationGC(SemiSpaceGC):
@@ -70,6 +74,7 @@
         self.lb_young_var_basesize = sz
 
     def setup(self):
+        self.last_generation_root_objects = self.AddressStack()
         SemiSpaceGC.setup(self)
         self.set_nursery_size(self.initial_nursery_size)
         # the GC is fully setup now.  The rest can make use of it.
@@ -281,6 +286,31 @@
             obj = self.young_objects_with_weakrefs.pop()
             self.objects_with_weakrefs.append(obj)
 
+    def collect_roots(self):
+        self.root_walker.walk_roots(
+            SemiSpaceGC._collect_root,  # stack roots
+            SemiSpaceGC._collect_root,  # static in prebuilt non-gc structures
+            None)   # we don't need the static in prebuilt gc objects
+        self.collect_last_generation_roots()
+
+    def collect_last_generation_roots(self):
+        stack = self.last_generation_root_objects
+        self.last_generation_root_objects = self.AddressStack()
+        while stack.non_empty():
+            obj = stack.pop()
+            self.header(obj).tid |= GCFLAG_NO_HEAP_PTRS
+            # ^^^ the flag we just added will be removed immediately if
+            # the object still contains pointers to younger objects
+            self.trace(obj, self._trace_external_obj, obj)
+        stack.delete()
+
+    def _trace_external_obj(self, pointer, obj):
+        addr = pointer.address[0]
+        if addr != NULL:
+            newaddr = self.copy(addr)
+            pointer.address[0] = newaddr
+            self.write_into_last_generation_obj(obj, newaddr)
+
     # ____________________________________________________________
     # Implementation of nursery-only collections
 
@@ -390,25 +420,28 @@
         if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
             self.remember_young_pointer(addr_struct, newvalue)
 
-    def append_to_static_roots(self, pointer, arg):
-        self.root_walker.append_static_root(pointer)
-
-    def move_to_static_roots(self, addr_struct):
-        objhdr = self.header(addr_struct)
-        objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
-        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),
                      "nursery object with GCFLAG_NO_YOUNG_PTRS")
-        oldhdr = self.header(addr_struct)
         if self.is_in_nursery(addr):
             self.old_objects_pointing_to_young.append(addr_struct)
-            oldhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
-        if oldhdr.tid & GCFLAG_NO_HEAP_PTRS:
-            self.move_to_static_roots(addr_struct)
+            self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
+        elif addr == NULL:
+            return
+        self.write_into_last_generation_obj(addr_struct, addr)
     remember_young_pointer._dont_inline_ = True
 
+    def write_into_last_generation_obj(self, addr_struct, addr):
+        objhdr = self.header(addr_struct)
+        if objhdr.tid & GCFLAG_NO_HEAP_PTRS:
+            if not self.is_last_generation(addr):
+                objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+                self.last_generation_root_objects.append(addr_struct)
+
+    def is_last_generation(self, obj):
+        # overridden by HybridGC
+        return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0
+
 # ____________________________________________________________
 
 import os

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/hybrid.py	Mon May  5 21:56:10 2008
@@ -2,30 +2,72 @@
 from pypy.rpython.memory.gc.semispace import SemiSpaceGC
 from pypy.rpython.memory.gc.semispace import DEBUG_PRINT
 from pypy.rpython.memory.gc.generation import GenerationGC, GCFLAG_FORWARDED
+from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL
 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
 from pypy.rpython.lltypesystem.llmemory import raw_malloc_usage
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.debug import ll_assert
 from pypy.rlib.rarithmetic import ovfcheck
 
-# The "age" of an object is the number of times it is copied between the
-# two semispaces.  When an object would reach MAX_SEMISPACE_AGE, it is
-# instead copied to a nonmoving location.  For example, a value of 4
+#   _______in the semispaces_________      ______external (non-moving)_____
+#  /                                 \    /                                \
+#                                          ___raw_malloc'ed__    _prebuilt_
+#  +----------------------------------+   /                  \  /          \
+#  |    | | | | |    |                |
+#  |    | | | | |    |                |    age < max      age == max
+#  |nur-|o|o|o|o|    |                |      +---+      +---+      +---+
+#  |sery|b|b|b|b|free|     empty      |      |obj|      |obj|      |obj|  
+#  |    |j|j|j|j|    |                |      +---+      +---+      +---+  
+#  |    | | | | |    |                |       +---+      +---+      +---+
+#  +-----------------+----------------+       |obj|      |obj|      |obj|
+#        age <= max                           +---+      +---+      +---+
+#            
+#  |gen1|------------- generation 2 -----------------|-----generation 3-----|
+#
+# Object lists:
+#   * gen2_rawmalloced_objects
+#   * gen3_rawmalloced_objects
+#   * old_objects_pointing_to_young: gen2or3 objs that point to gen1 objs
+#   * last_generation_root_objects: gen3 objs that point to gen1or2 objs
+#
+# How to tell the objects apart:
+#   * external:      tid & GCFLAG_EXTERNAL
+#   * gen1:          is_in_nursery(obj)
+#   * gen3:          (tid & (GCFLAG_EXTERNAL|GCFLAG_AGE_MASK)) ==
+#                           (GCFLAG_EXTERNAL|GCFLAG_AGE_MAX)
+#
+# Some invariants:
+#   * gen3 are either GCFLAG_NO_HEAP_PTRS or in 'last_generation_root_objects'
+#   * between collections, GCFLAG_UNVISITED set exactly for gen2_rawmalloced
+#
+# A malloc_varsize() of large objects returns objects that are external
+# but initially of generation 2.  Old objects from the semispaces are
+# moved to external objects directly as generation 3.
+
+# The "age" of an object is the number of times it survived a full
+# collections, without counting the step that moved it out of the nursery.
+# When a semispace-based object would grow older than MAX_SEMISPACE_AGE,
+# it is instead copied to a nonmoving location.  For example, a value of 3
 # ensures that an object is copied at most 5 times in total: from the
 # nursery to the semispace, then three times between the two spaces,
 # then one last time to a nonmoving location.
-MAX_SEMISPACE_AGE = 4
+MAX_SEMISPACE_AGE = 3
 
 GCFLAG_UNVISITED = GenerationGC.first_unused_gcflag << 0
 _gcflag_next_bit = GenerationGC.first_unused_gcflag << 1
 GCFLAG_AGE_ONE   = _gcflag_next_bit
-GCFLAG_AGE_MAX   = _gcflag_next_bit * (MAX_SEMISPACE_AGE-1)
+GCFLAG_AGE_MAX   = _gcflag_next_bit * MAX_SEMISPACE_AGE
 GCFLAG_AGE_MASK  = 0
 while GCFLAG_AGE_MASK < GCFLAG_AGE_MAX:
     GCFLAG_AGE_MASK |= _gcflag_next_bit
     _gcflag_next_bit <<= 1
 
+# The 3rd generation objects are only collected after the following
+# number of calls to semispace_collect():
+GENERATION3_COLLECT_THRESHOLD = 20
+
 
 class HybridGC(GenerationGC):
     """A two-generations semi-space GC like the GenerationGC,
@@ -33,6 +75,7 @@
     they are allocated via raw_malloc/raw_free in a mark-n-sweep fashion.
     """
     first_unused_gcflag = _gcflag_next_bit
+    prebuilt_gc_objects_are_static_roots = True
 
     # the following values override the default arguments of __init__ when
     # translating to a real backend.
@@ -66,10 +109,12 @@
         self.large_objects_collect_trigger = self.space_size
         if DEBUG_PRINT:
             self._initial_trigger = self.large_objects_collect_trigger
-        self.pending_external_object_list = self.AddressDeque()
+        self.rawmalloced_objects_to_trace = self.AddressStack()
+        self.count_semispaceonly_collects = 0
 
     def setup(self):
-        self.large_objects_list = self.AddressDeque()
+        self.gen2_rawmalloced_objects = self.AddressStack()
+        self.gen3_rawmalloced_objects = self.AddressStack()
         GenerationGC.setup(self)
 
     def set_max_heap_size(self, size):
@@ -184,7 +229,7 @@
         # need to follow suit.
         llmemory.raw_memclear(result, totalsize)
         size_gc_header = self.gcheaderbuilder.size_gc_header
-        self.large_objects_list.append(result + size_gc_header)
+        self.gen2_rawmalloced_objects.append(result + size_gc_header)
         return result
 
     def allocate_external_object(self, totalsize):
@@ -192,19 +237,62 @@
         # If so, we'd also use arena_reset() in malloc_varsize_marknsweep().
         return llmemory.raw_malloc(totalsize)
 
+    def init_gc_object_immortal(self, addr, typeid,
+                                flags=(GCFLAG_NO_YOUNG_PTRS |
+                                       GCFLAG_NO_HEAP_PTRS |
+                                       GCFLAG_AGE_MAX)):
+        GenerationGC.init_gc_object_immortal(self, addr, typeid, flags)
+
+    # ___________________________________________________________________
+    # collect() and semispace_collect() are not synonyms in this GC: the
+    # former is a complete collect, while the latter is only collecting
+    # the semispaces and not always doing the mark-n-sweep pass over the
+    # external objects of 3rd generation.
+
+    def collect(self):
+        self.count_semispaceonly_collects = GENERATION3_COLLECT_THRESHOLD
+        GenerationGC.collect(self)
+
+    def is_collecting_gen3(self):
+        count = self.count_semispaceonly_collects
+        return count >= GENERATION3_COLLECT_THRESHOLD
+
     # ___________________________________________________________________
     # the following methods are hook into SemiSpaceGC.semispace_collect()
 
     def starting_full_collect(self):
-        # At the start of a collection, all raw_malloc'ed objects should
-        # have the GCFLAG_UNVISITED bit set.  No other object ever has
-        # this bit set.
-        ll_assert(not self.pending_external_object_list.non_empty(),
-                  "pending_external_object_list should be empty at start")
+        # At the start of a collection, the GCFLAG_UNVISITED bit is set
+        # exactly on the objects in gen2_rawmalloced_objects.  Only
+        # raw_malloc'ed objects can ever have this bit set.
+        self.count_semispaceonly_collects += 1
+        if self.is_collecting_gen3():
+            # set the GCFLAG_UNVISITED on all rawmalloced generation-3 objects
+            # as well, to let them be recorded by visit_external_object()
+            self.gen3_rawmalloced_objects.foreach(self._set_gcflag_unvisited,
+                                                  None)
+        ll_assert(not self.rawmalloced_objects_to_trace.non_empty(),
+                  "rawmalloced_objects_to_trace should be empty at start")
         if DEBUG_PRINT:
             self._nonmoving_copy_count = 0
             self._nonmoving_copy_size = 0
 
+    def _set_gcflag_unvisited(self, obj, ignored):
+        ll_assert(not (self.header(obj).tid & GCFLAG_UNVISITED),
+                  "bogus GCFLAG_UNVISITED on gen3 obj")
+        self.header(obj).tid |= GCFLAG_UNVISITED
+
+    def collect_roots(self):
+        if not self.is_collecting_gen3():
+            GenerationGC.collect_roots(self)
+        else:
+            # as we don't record which prebuilt gc objects point to
+            # rawmalloced generation 3 objects, we have to trace all
+            # the prebuilt gc objects.
+            self.root_walker.walk_roots(
+                SemiSpaceGC._collect_root,  # stack roots
+                SemiSpaceGC._collect_root,  # static in prebuilt non-gc structs
+                SemiSpaceGC._collect_root)  # static in prebuilt gc objects
+
     def surviving(self, obj):
         # To use during a collection.  The objects that survive are the
         # ones with GCFLAG_FORWARDED set and GCFLAG_UNVISITED not set.
@@ -213,12 +301,16 @@
         flags = self.header(obj).tid & (GCFLAG_FORWARDED|GCFLAG_UNVISITED)
         return flags == GCFLAG_FORWARDED
 
+    def is_last_generation(self, obj):
+        return ((self.header(obj).tid & (GCFLAG_EXTERNAL|GCFLAG_AGE_MASK)) ==
+                (GCFLAG_EXTERNAL|GCFLAG_AGE_MAX))
+
     def visit_external_object(self, obj):
         hdr = self.header(obj)
         if hdr.tid & GCFLAG_UNVISITED:
             # This is a not-visited-yet raw_malloced object.
             hdr.tid -= GCFLAG_UNVISITED
-            self.pending_external_object_list.append(obj)
+            self.rawmalloced_objects_to_trace.append(obj)
 
     def make_a_copy(self, obj, objsize):
         # During a full collect, all copied objects might implicitly come
@@ -258,8 +350,14 @@
         hdr = self.header(newobj)
         hdr.tid |= self.GCFLAGS_FOR_NEW_EXTERNAL_OBJECTS
         # GCFLAG_UNVISITED is not set
-        self.large_objects_list.append(newobj)
-        self.pending_external_object_list.append(newobj)
+        # GCFLAG_NO_HEAP_PTRS is not set either, conservatively.  It may be
+        # set by the next collection's collect_last_generation_roots().
+        # This old object is immediately put at generation 3.
+        ll_assert(self.is_last_generation(newobj),
+                  "make_a_nonmoving_copy: object too young")
+        self.gen3_rawmalloced_objects.append(newobj)
+        self.last_generation_root_objects.append(newobj)
+        self.rawmalloced_objects_to_trace.append(newobj)   # visit me
         return newobj
 
     def scan_copied(self, scan):
@@ -270,23 +368,62 @@
             newscan = GenerationGC.scan_copied(self, scan)
             progress = newscan != scan
             scan = newscan
-            while self.pending_external_object_list.non_empty():
-                obj = self.pending_external_object_list.popleft()
+            while self.rawmalloced_objects_to_trace.non_empty():
+                obj = self.rawmalloced_objects_to_trace.pop()
                 self.trace_and_copy(obj)
                 progress = True
         return scan
 
     def finished_full_collect(self):
-        ll_assert(not self.pending_external_object_list.non_empty(),
-                  "pending_external_object_list should be empty at end")
-        # free all mark-n-sweep-managed objects that have not been marked
-        large_objects = self.large_objects_list
-        remaining_large_objects = self.AddressDeque()
+        ll_assert(not self.rawmalloced_objects_to_trace.non_empty(),
+                  "rawmalloced_objects_to_trace should be empty at end")
+        if DEBUG_PRINT:
+            llop.debug_print(lltype.Void,
+                             "| [hybrid] made nonmoving:         ",
+                             self._nonmoving_copy_size, "bytes in",
+                             self._nonmoving_copy_count, "objs")
+        # sweep the nonmarked rawmalloced objects
+        if self.is_collecting_gen3():
+            self.sweep_rawmalloced_objects(generation=3)
+        self.sweep_rawmalloced_objects(generation=2)
+        # As we just collected, it's fine to raw_malloc'ate up to space_size
+        # bytes again before we should force another collect.
+        self.large_objects_collect_trigger = self.space_size
+        if self.is_collecting_gen3():
+            self.count_semispaceonly_collects = 0
+        if DEBUG_PRINT:
+            self._initial_trigger = self.large_objects_collect_trigger
+
+    def sweep_rawmalloced_objects(self, generation):
+        # free all the rawmalloced objects of the specified generation
+        # that have not been marked
+        if generation == 2:
+            objects = self.gen2_rawmalloced_objects
+            # generation 2 sweep: if A points to an object object B that
+            # moves from gen2 to gen3, it's possible that A no longer points
+            # to any gen2 object.  In this case, A remains a bit too long in
+            # last_generation_root_objects, but this will be fixed by the
+            # next collect_last_generation_roots().
+        else:
+            objects = self.gen3_rawmalloced_objects
+            # generation 3 sweep: remove from last_generation_root_objects
+            # all the objects that we are about to free
+            gen3roots = self.last_generation_root_objects
+            newgen3roots = self.AddressStack()
+            while gen3roots.non_empty():
+                obj = gen3roots.pop()
+                if not (self.header(obj).tid & GCFLAG_UNVISITED):
+                    newgen3roots.append(obj)
+            gen3roots.delete()
+            self.last_generation_root_objects = newgen3roots
+
+        surviving_objects = self.AddressStack()
         if DEBUG_PRINT: alive_count = alive_size = 0
         if DEBUG_PRINT: dead_count = dead_size = 0
-        while large_objects.non_empty():
-            obj = large_objects.popleft()
-            if self.header(obj).tid & GCFLAG_UNVISITED:
+        while objects.non_empty():
+            obj = objects.pop()
+            tid = self.header(obj).tid
+            if tid & GCFLAG_UNVISITED:
                 if DEBUG_PRINT:dead_count+=1
                 if DEBUG_PRINT:dead_size+=raw_malloc_usage(self.get_size(obj))
                 addr = obj - self.gcheaderbuilder.size_gc_header
@@ -294,25 +431,35 @@
             else:
                 if DEBUG_PRINT:alive_count+=1
                 if DEBUG_PRINT:alive_size+=raw_malloc_usage(self.get_size(obj))
-                self.header(obj).tid |= GCFLAG_UNVISITED
-                remaining_large_objects.append(obj)
-        large_objects.delete()
-        self.large_objects_list = remaining_large_objects
-        # As we just collected, it's fine to raw_malloc'ate up to space_size
-        # bytes again before we should force another collect.
-        self.large_objects_collect_trigger = self.space_size
-
+                if generation == 3:
+                    surviving_objects.append(obj)
+                else:
+                    ll_assert((tid & GCFLAG_AGE_MASK) < GCFLAG_AGE_MAX,
+                              "wrong age for generation 2 object")
+                    tid += GCFLAG_AGE_ONE
+                    if (tid & GCFLAG_AGE_MASK) == GCFLAG_AGE_MAX:
+                        # the object becomes part of generation 3
+                        self.gen3_rawmalloced_objects.append(obj)
+                        # GCFLAG_NO_HEAP_PTRS not set yet, conservatively
+                        self.last_generation_root_objects.append(obj)
+                    else:
+                        # the object stays in generation 2
+                        tid |= GCFLAG_UNVISITED
+                        surviving_objects.append(obj)
+                    self.header(obj).tid = tid
+        objects.delete()
+        if generation == 2:
+            self.gen2_rawmalloced_objects = surviving_objects
+        else:
+            self.gen3_rawmalloced_objects = surviving_objects
         if DEBUG_PRINT:
-            self._initial_trigger = self.large_objects_collect_trigger
-            llop.debug_print(lltype.Void,
-                             "| [hybrid] made nonmoving:         ",
-                             self._nonmoving_copy_size, "bytes in",
-                             self._nonmoving_copy_count, "objs")
             llop.debug_print(lltype.Void,
-                             "| [hybrid] nonmoving now alive:    ",
+                             "| [hyb] gen", generation,
+                             "nonmoving now alive: ",
                              alive_size, "bytes in",
                              alive_count, "objs")
             llop.debug_print(lltype.Void,
-                             "| [hybrid] nonmoving freed:        ",
+                             "| [hyb] gen", generation,
+                             "nonmoving freed:     ",
                              dead_size, "bytes in",
                              dead_count, "objs")

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gc/semispace.py	Mon May  5 21:56:10 2008
@@ -21,7 +21,7 @@
 GCFLAG_EXTERNAL = first_gcflag << 1
 GCFLAG_FINALIZATION_ORDERING = first_gcflag << 2
 
-DEBUG_PRINT = False
+DEBUG_PRINT = True
 memoryError = MemoryError()
 
 class SemiSpaceGC(MovingGCBase):
@@ -205,6 +205,7 @@
         self.semispace_collect()
         # the indirection is required by the fact that collect() is referred
         # to by the gc transformer, and the default argument would crash
+        # (this is also a hook for the HybridGC)
 
     def semispace_collect(self, size_changing=False):
         if DEBUG_PRINT:

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gctransform/framework.py	Mon May  5 21:56:10 2008
@@ -391,11 +391,8 @@
             self.layoutbuilder.addresses_of_static_ptrs_in_nongc +
             self.layoutbuilder.addresses_of_static_ptrs)
         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) +
-                                               additional_ptrs,
+                                               len(addresses_of_static_ptrs),
                                                immortal=True)
         for i in range(len(addresses_of_static_ptrs)):
             ll_static_roots_inside[i] = addresses_of_static_ptrs[i]
@@ -788,10 +785,6 @@
     def setup_root_walker(self):
         pass
 
-    def append_static_root(self, adr):
-        self.gcdata.static_root_end.address[0] = adr
-        self.gcdata.static_root_end += sizeofaddr
-
     def walk_roots(self, collect_stack_root,
                    collect_static_in_prebuilt_nongc,
                    collect_static_in_prebuilt_gc):

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gctypelayout.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gctypelayout.py	Mon May  5 21:56:10 2008
@@ -193,10 +193,6 @@
         self.addresses_of_static_ptrs = []
         # this lists contains pointers in raw Structs and Arrays
         self.addresses_of_static_ptrs_in_nongc = []
-        # if not gc.prebuilt_gc_objects_are_static_roots, then
-        # additional_roots_sources counts the number of locations
-        # within prebuilt GC objects that are of type Ptr(Gc)
-        self.additional_roots_sources = 0
         self.finalizer_funcptrs = {}
         self.offsettable_cache = {}
         self.next_typeid_cache = {}
@@ -292,8 +288,6 @@
         adr = llmemory.cast_ptr_to_adr(value._as_ptr())
         if TYPE._gckind == "gc":
             if not gc.prebuilt_gc_objects_are_static_roots:
-                for a in gc_pointers_inside(value, adr):
-                    self.additional_roots_sources += 1
                 return
             else:
                 appendto = self.addresses_of_static_ptrs

Modified: pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py	(original)
+++ pypy/branch/gc-tweak/pypy/rpython/memory/gcwrapper.py	Mon May  5 21:56:10 2008
@@ -114,9 +114,6 @@
     def __init__(self, gcheap):
         self.gcheap = gcheap
 
-    def append_static_root(self, pointer):
-        self.gcheap.constantroots.append(pointer)
-
     def walk_roots(self, collect_stack_root,
                    collect_static_in_prebuilt_nongc,
                    collect_static_in_prebuilt_gc):



More information about the Pypy-commit mailing list