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