Author: Devin Jeanpierre <[email protected]>
Branch: gc-forkfriendly
Changeset: r84849:11bee4605bdc
Date: 2016-05-31 13:58 -0700
http://bitbucket.org/pypy/pypy/changeset/11bee4605bdc/

Log:    Fix type unification problem mentioned in last commit.

        A remaining issue is a problem with test_newgc.py like so:

        data_rpython_memory_test.c:17655:4: error: 
&#8216;pypy_g_header_1433&#8217;
        undeclared here (not in a function) (&pypy_g_header_1433.h_tid), /*
        gcheader.remote_flags */

        Interesting! I'll try to fix separately (maybe hg bisect will help
        here.)

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -1760,9 +1760,9 @@
         # GcStruct is in the list self.old_objects_pointing_to_young.
         debug_start("gc-minor-walkroots")
         if self.gc_state == STATE_MARKING:
-            callback = IncrementalMiniMarkGC._trace_drag_out1_marking_phase
+            callback = IncrementalMiniMarkGCBase._trace_drag_out1_marking_phase
         else:
-            callback = IncrementalMiniMarkGC._trace_drag_out1
+            callback = IncrementalMiniMarkGCBase._trace_drag_out1
         #
         # Note a subtlety: if the nursery contains pinned objects "from
         # earlier", i.e. created earlier than the previous minor
@@ -2334,21 +2334,11 @@
         if self.get_flags(obj) & GCFLAG_VISITED:
             new_list.append(obj)
 
-    def _free_if_unvisited(self, hdr):
-        size_gc_header = self.gcheaderbuilder.size_gc_header
-        obj = hdr + size_gc_header
-        if self.get_flags(obj) & GCFLAG_VISITED:
-            self.remove_flags(obj, GCFLAG_VISITED)
-            return False     # survives
-        # dies
-        self.finalize_header(hdr)
-        return True
-
     def _reset_gcflag_visited(self, obj, ignored):
         self.remove_flags(obj, GCFLAG_VISITED)
 
     def free_unvisited_arena_objects_step(self, limit):
-        return self.ac.mass_free_incremental(self._free_if_unvisited, limit)
+        return self.ac.mass_free_incremental(_free_if_unvisited, self, limit)
 
     def free_rawmalloced_object_if_unvisited(self, obj, check_flag):
         if self.get_flags(obj) & check_flag:
@@ -2405,8 +2395,8 @@
         #
         # Add the roots from the other sources.
         self.root_walker.walk_roots(
-            IncrementalMiniMarkGC._collect_ref_stk, # stack roots
-            IncrementalMiniMarkGC._collect_ref_stk, # static in prebuilt 
non-gc structures
+            IncrementalMiniMarkGCBase._collect_ref_stk, # stack roots
+            IncrementalMiniMarkGCBase._collect_ref_stk, # static in prebuilt 
non-gc structures
             None)   # we don't need the static in all prebuilt gc objects
         #
         # If we are in an inner collection caused by a call to a finalizer,
@@ -3055,6 +3045,18 @@
     def remove_flags(self, obj, flags):
         self.header(obj).tid &= ~flags
 
+
+def _free_if_unvisited(hdr, gc):
+    size_gc_header = gc.gcheaderbuilder.size_gc_header
+    obj = hdr + size_gc_header
+    if gc.get_flags(obj) & GCFLAG_VISITED:
+        gc.remove_flags(obj, GCFLAG_VISITED)
+        return False     # survives
+    # dies
+    gc.finalize_header(hdr)
+    return True
+
+
 class IncrementalMiniMarkGC(IncrementalMiniMarkGCBase):
     HDR = lltype.Struct('header', ('tid', lltype.Signed))
     # During a minor collection, the objects in the nursery that are
diff --git a/rpython/memory/gc/incminimark_remoteheader.py 
b/rpython/memory/gc/incminimark_remoteheader.py
--- a/rpython/memory/gc/incminimark_remoteheader.py
+++ b/rpython/memory/gc/incminimark_remoteheader.py
@@ -68,15 +68,10 @@
             # __free_flags_if_finalized.
             hdr.remote_flags[0] |= incminimark.GCFLAG_DEAD
 
-    def __free_flags_if_finalized(self, adr):
-        flag_ptr = llmemory.cast_adr_to_ptr(adr, SIGNEDP)
-        # If -42, it was set in finalize_header and the object was freed.
-        return flag_ptr[0] & incminimark.GCFLAG_DEAD
-
     def free_unvisited_arena_objects_step(self, limit):
         done = 
incminimark.IncrementalMiniMarkGCBase.free_unvisited_arena_objects_step(self, 
limit)
         self.__ac_for_flags.mass_free_incremental(
-            self.__free_flags_if_finalized, done)
+            _free_flags_if_finalized, None, done)
         return done
 
     def start_free(self):
@@ -96,3 +91,9 @@
 
     def remove_flags(self, obj, flags):
         self.header(obj).remote_flags[0] &= ~flags
+
+
+def _free_flags_if_finalized(adr, unused_arg):
+    flag_ptr = llmemory.cast_adr_to_ptr(adr, SIGNEDP)
+    # If -42, it was set in finalize_header and the object was freed.
+    return bool(flag_ptr[0] & incminimark.GCFLAG_DEAD)
diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py
--- a/rpython/memory/gc/minimark.py
+++ b/rpython/memory/gc/minimark.py
@@ -1632,7 +1632,7 @@
         # Ask the ArenaCollection to visit all objects.  Free the ones
         # that have not been visited above, and reset GCFLAG_VISITED on
         # the others.
-        self.ac.mass_free(self._free_if_unvisited)
+        self.ac.mass_free(_free_if_unvisited, self)
         #
         # We also need to reset the GCFLAG_VISITED on prebuilt GC objects.
         self.prebuilt_root_objects.foreach(self._reset_gcflag_visited, None)
@@ -1682,15 +1682,6 @@
         # more allocations.
         self.execute_finalizers()
 
-
-    def _free_if_unvisited(self, hdr):
-        size_gc_header = self.gcheaderbuilder.size_gc_header
-        obj = hdr + size_gc_header
-        if self.header(obj).tid & GCFLAG_VISITED:
-            self.header(obj).tid &= ~GCFLAG_VISITED
-            return False     # survives
-        return True      # dies
-
     def _reset_gcflag_visited(self, obj, ignored):
         self.header(obj).tid &= ~GCFLAG_VISITED
 
@@ -2077,3 +2068,12 @@
                 (obj + offset).address[0] = llmemory.NULL
         self.old_objects_with_weakrefs.delete()
         self.old_objects_with_weakrefs = new_with_weakref
+
+
+def _free_if_unvisited(hdr, gc):
+    size_gc_header = gc.gcheaderbuilder.size_gc_header
+    obj = hdr + size_gc_header
+    if gc.header(obj).tid & GCFLAG_VISITED:
+        gc.header(obj).tid &= ~GCFLAG_VISITED
+        return False     # survives
+    return True      # dies
diff --git a/rpython/memory/gc/minimarkpage.py 
b/rpython/memory/gc/minimarkpage.py
--- a/rpython/memory/gc/minimarkpage.py
+++ b/rpython/memory/gc/minimarkpage.py
@@ -3,6 +3,7 @@
 from rpython.rlib.rarithmetic import LONG_BIT, r_uint
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.debug import ll_assert, fatalerror
+from rpython.rlib.objectmodel import specialize
 
 WORD = LONG_BIT // 8
 NULL = llmemory.NULL
@@ -334,9 +335,10 @@
             size_class -= 1
 
 
-    def mass_free_incremental(self, ok_to_free_func, max_pages):
-        """For each object, if ok_to_free_func(obj) returns True, then free
-        the object.  This returns True if complete, or False if the limit
+    @specialize.arg(1)
+    def mass_free_incremental(self, ok_to_free_func, func_arg, max_pages):
+        """For each object, if ok_to_free_func(obj, func_arg) returns True, 
then
+        free the object.  This returns True if complete, or False if the limit
         'max_pages' is reached.
         """
         size_class = self.size_class_with_old_pages
@@ -350,7 +352,7 @@
             # not completely freed are re-chained either in
             # 'full_page_for_size[]' or 'page_for_size[]'.
             max_pages = self.mass_free_in_pages(size_class, ok_to_free_func,
-                                                max_pages)
+                                                func_arg, max_pages)
             if max_pages <= 0:
                 self.size_class_with_old_pages = size_class
                 return False
@@ -364,13 +366,14 @@
         return True
 
 
-    def mass_free(self, ok_to_free_func):
-        """For each object, if ok_to_free_func(obj) returns True, then free
-        the object.
+    @specialize.arg(1)
+    def mass_free(self, ok_to_free_func, func_arg):
+        """For each object, if ok_to_free_func(obj, func_arg) returns True, 
then
+        free the object.
         """
         self.mass_free_prepare()
         #
-        res = self.mass_free_incremental(ok_to_free_func, sys.maxint)
+        res = self.mass_free_incremental(ok_to_free_func, func_arg, sys.maxint)
         ll_assert(res, "non-incremental mass_free_in_pages() returned False")
 
 
@@ -412,7 +415,9 @@
         self.min_empty_nfreepages = 1
 
 
-    def mass_free_in_pages(self, size_class, ok_to_free_func, max_pages):
+    @specialize.arg(2)
+    def mass_free_in_pages(self, size_class, ok_to_free_func, func_arg,
+                           max_pages):
         nblocks = self.nblocks_for_size[size_class]
         block_size = size_class * WORD
         remaining_partial_pages = self.page_for_size[size_class]
@@ -430,7 +435,8 @@
             while page != PAGE_NULL:
                 #
                 # Collect the page.
-                surviving = self.walk_page(page, block_size, ok_to_free_func)
+                surviving = self.walk_page(
+                    page, block_size, ok_to_free_func, func_arg)
                 nextpage = page.nextpage
                 #
                 if surviving == nblocks:
@@ -491,7 +497,8 @@
         arena.freepages = pageaddr
 
 
-    def walk_page(self, page, block_size, ok_to_free_func):
+    @specialize.arg(3)
+    def walk_page(self, page, block_size, ok_to_free_func, func_arg):
         """Walk over all objects in a page, and ask ok_to_free_func()."""
         #
         # 'freeblock' is the next free block
@@ -528,7 +535,7 @@
                 ll_assert(freeblock > obj,
                           "freeblocks are linked out of order")
                 #
-                if ok_to_free_func(obj):
+                if ok_to_free_func(obj, func_arg):
                     #
                     # The object should die.
                     llarena.arena_reset(obj, _dummy_size(block_size), 0)
diff --git a/rpython/memory/gc/minimarktest.py 
b/rpython/memory/gc/minimarktest.py
--- a/rpython/memory/gc/minimarktest.py
+++ b/rpython/memory/gc/minimarktest.py
@@ -38,11 +38,11 @@
         self.all_objects = []
         self.total_memory_used = 0
 
-    def mass_free_incremental(self, ok_to_free_func, max_pages):
+    def mass_free_incremental(self, ok_to_free_func, func_arg, max_pages):
         old = self.old_all_objects
         while old:
             rawobj, nsize = old.pop()
-            if ok_to_free_func(rawobj):
+            if ok_to_free_func(rawobj, func_arg):
                 llarena.arena_free(rawobj)
             else:
                 self.all_objects.append((rawobj, nsize))
@@ -52,7 +52,7 @@
                 return False
         return True
 
-    def mass_free(self, ok_to_free_func):
+    def mass_free(self, ok_to_free_func, func_arg):
         self.mass_free_prepare()
-        res = self.mass_free_incremental(ok_to_free_func, sys.maxint)
+        res = self.mass_free_incremental(ok_to_free_func, func_arg, sys.maxint)
         assert res
diff --git a/rpython/memory/gc/test/test_minimarkpage.py 
b/rpython/memory/gc/test/test_minimarkpage.py
--- a/rpython/memory/gc/test/test_minimarkpage.py
+++ b/rpython/memory/gc/test/test_minimarkpage.py
@@ -260,7 +260,7 @@
         self.lastnum = 0.0
         self.seen = {}
 
-    def __call__(self, addr):
+    def __call__(self, addr, arg):
         if callable(self.answer):
             ok_to_free = self.answer(addr)
         else:
@@ -280,7 +280,7 @@
     pagesize = hdrsize + 7*WORD
     ac = arena_collection_for_test(pagesize, "2", fill_with_objects=2)
     ok_to_free = OkToFree(ac, False)
-    ac.mass_free(ok_to_free)
+    ac.mass_free(ok_to_free, None)
     assert ok_to_free.seen == {hdrsize + 0*WORD: False,
                                hdrsize + 2*WORD: False}
     page = getpage(ac, 0)
@@ -295,7 +295,7 @@
     pagesize = hdrsize + 7*WORD
     ac = arena_collection_for_test(pagesize, "2", fill_with_objects=2)
     ok_to_free = OkToFree(ac, True)
-    ac.mass_free(ok_to_free)
+    ac.mass_free(ok_to_free, None)
     assert ok_to_free.seen == {hdrsize + 0*WORD: True,
                                hdrsize + 2*WORD: True}
     pageaddr = pagenum(ac, 0)
@@ -307,7 +307,7 @@
     pagesize = hdrsize + 7*WORD
     ac = arena_collection_for_test(pagesize, "#", fill_with_objects=2)
     ok_to_free = OkToFree(ac, False)
-    ac.mass_free(ok_to_free)
+    ac.mass_free(ok_to_free, None)
     assert ok_to_free.seen == {hdrsize + 0*WORD: False,
                                hdrsize + 2*WORD: False,
                                hdrsize + 4*WORD: False}
@@ -323,7 +323,7 @@
     pagesize = hdrsize + 9*WORD
     ac = arena_collection_for_test(pagesize, "#", fill_with_objects=2)
     ok_to_free = OkToFree(ac, 0.5)
-    ac.mass_free(ok_to_free)
+    ac.mass_free(ok_to_free, None)
     assert ok_to_free.seen == {hdrsize + 0*WORD: False,
                                hdrsize + 2*WORD: True,
                                hdrsize + 4*WORD: False,
@@ -348,7 +348,7 @@
     assert page.nfree == 4
     #
     ok_to_free = OkToFree(ac, False)
-    ac.mass_free(ok_to_free)
+    ac.mass_free(ok_to_free, None)
     assert ok_to_free.seen == {hdrsize +  0*WORD: False,
                                hdrsize +  4*WORD: False,
                                hdrsize +  8*WORD: False,
@@ -376,7 +376,7 @@
     assert page.nfree == 4
     #
     ok_to_free = OkToFree(ac, 0.5)
-    ac.mass_free(ok_to_free)
+    ac.mass_free(ok_to_free, None)
     assert ok_to_free.seen == {hdrsize +  0*WORD: False,
                                hdrsize +  4*WORD: True,
                                hdrsize +  8*WORD: False,
@@ -449,10 +449,10 @@
             live_objects_extra = {}
             fresh_extra = 0
             if not incremental:
-                ac.mass_free(ok_to_free)
+                ac.mass_free(ok_to_free, None)
             else:
                 ac.mass_free_prepare()
-                while not ac.mass_free_incremental(ok_to_free,
+                while not ac.mass_free_incremental(ok_to_free, None,
                                                    random.randrange(1, 3)):
                     print '[]'
                     prev = ac.total_memory_used
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to