Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r92388:0d880d3a1b92
Date: 2017-09-14 11:06 +0200
http://bitbucket.org/pypy/pypy/changeset/0d880d3a1b92/

Log:    Redo 90a0d3659179; the problem was 9bd6fef43680.

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -335,6 +335,7 @@
         callback2, attrname = _convert_callback_formats(callback)    # :-/
         setattr(self, attrname, arg)
         self.root_walker.walk_roots(callback2, callback2, callback2)
+        self.enum_live_with_finalizers(callback, arg)
         self.enum_pending_finalizers(callback, arg)
     enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
 
@@ -347,6 +348,12 @@
             i += 1
     enum_pending_finalizers._annspecialcase_ = 'specialize:arg(1)'
 
+    def enum_live_with_finalizers(self, callback, arg):
+        # as far as possible, enumerates the live objects with finalizers,
+        # even if they have not been detected as unreachable yet (but may be)
+        pass
+    enum_live_with_finalizers._annspecialcase_ = 'specialize:arg(1)'
+
     def _copy_pending_finalizers_deque(self, deque, copy_fn):
         tmp = self.AddressDeque()
         while deque.non_empty():
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
@@ -2522,6 +2522,11 @@
         MovingGCBase.enumerate_all_roots(self, callback, arg)
     enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
 
+    def enum_live_with_finalizers(self, callback, arg):
+        self.probably_young_objects_with_finalizers.foreach(callback, arg, 2)
+        self.old_objects_with_finalizers.foreach(callback, arg, 2)
+    enum_live_with_finalizers._annspecialcase_ = 'specialize:arg(1)'
+
     def _collect_obj(self, obj, ignored):
         # Ignore pinned objects, which are the ones still in the nursery here.
         # Cache effects: don't read any flag out of 'obj' at this point.
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
@@ -1787,6 +1787,11 @@
         MovingGCBase.enumerate_all_roots(self, callback, arg)
     enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
 
+    def enum_live_with_finalizers(self, callback, arg):
+        self.probably_young_objects_with_finalizers.foreach(callback, arg, 2)
+        self.old_objects_with_finalizers.foreach(callback, arg, 2)
+    enum_live_with_finalizers._annspecialcase_ = 'specialize:arg(1)'
+
     @staticmethod
     def _collect_obj(obj, objects_to_trace):
         objects_to_trace.append(obj)
diff --git a/rpython/memory/support.py b/rpython/memory/support.py
--- a/rpython/memory/support.py
+++ b/rpython/memory/support.py
@@ -269,22 +269,23 @@
             self.index_in_oldest = index + 1
             return result
 
-        def foreach(self, callback, arg):
+        def foreach(self, callback, arg, step=1):
             """Invoke 'callback(address, arg)' for all addresses in the deque.
             Typically, 'callback' is a bound method and 'arg' can be None.
+            If step > 1, only calls it for addresses multiple of 'step'.
             """
             chunk = self.oldest_chunk
             index = self.index_in_oldest
             while chunk is not self.newest_chunk:
                 while index < chunk_size:
                     callback(chunk.items[index], arg)
-                    index += 1
+                    index += step
                 chunk = chunk.next
-                index = 0
+                index -= chunk_size
             limit = self.index_in_newest
             while index < limit:
                 callback(chunk.items[index], arg)
-                index += 1
+                index += step
         foreach._annspecialcase_ = 'specialize:arg(1)'
 
         def delete(self):
diff --git a/rpython/memory/test/test_support.py 
b/rpython/memory/test/test_support.py
--- a/rpython/memory/test/test_support.py
+++ b/rpython/memory/test/test_support.py
@@ -160,6 +160,10 @@
 
             ll.foreach(callback, 42)
             assert seen == addrs
+            seen = []
+            ll.foreach(callback, 42, step=2)
+            assert seen == addrs[::2]
+
             for a in addrs:
                 b = ll.popleft()
                 assert a == b
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to