Author: Armin Rigo <[email protected]>
Branch: gc-del-2
Changeset: r66070:62c37017e2a6
Date: 2013-08-11 12:32 +0200
http://bitbucket.org/pypy/pypy/changeset/62c37017e2a6/
Log: Introduce and use filter() on AddressStack.
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
@@ -1602,17 +1602,11 @@
self.free_rawmalloced_object_if_unvisited(obj)
def remove_young_arrays_from_old_objects_pointing_to_young(self):
- old = self.old_objects_pointing_to_young
- new = self.AddressStack()
- while old.non_empty():
- obj = old.pop()
- if not self.young_rawmalloced_objects.contains(obj):
- new.append(obj)
- # an extra copy, to avoid assignments to
- # 'self.old_objects_pointing_to_young'
- while new.non_empty():
- old.append(new.pop())
- new.delete()
+ self.old_objects_pointing_to_young.filter(self._filter_young_array,
+ None)
+
+ def _filter_young_array(self, obj, ignored):
+ return not self.young_rawmalloced_objects.contains(obj)
# ----------
# Full collection
diff --git a/rpython/memory/support.py b/rpython/memory/support.py
--- a/rpython/memory/support.py
+++ b/rpython/memory/support.py
@@ -143,6 +143,30 @@
count = chunk_size
foreach._annspecialcase_ = 'specialize:arg(1)'
+ def filter(self, callback, arg):
+ """Invoke 'callback(address, arg)' for all addresses in the stack.
+ When it returns False, remove the item from the stack (by
+ replacing it with self.pop(), so the order is destroyed).
+ Typically, 'callback' is a bound method and 'arg' can be None.
+ """
+ chunk = self.chunk
+ count = self.used_in_last_chunk
+ while chunk:
+ nextchunk = chunk.next
+ while count > 0:
+ count -= 1
+ if not callback(chunk.items[count], arg):
+ # a version of pop-and-put-back-at-chunk.items[count]
+ used = self.used_in_last_chunk - 1
+ ll_assert(used >= 0, "pop on empty AddressStack [2]")
+ chunk.items[count] = self.chunk.items[used]
+ self.used_in_last_chunk = used
+ if used == 0 and self.chunk.next:
+ self.shrink()
+ chunk = nextchunk
+ count = chunk_size
+ filter._annspecialcase_ = 'specialize:arg(1)'
+
def stack2dict(self):
result = AddressDict(self._length_estimate())
self.foreach(_add_in_dict, result)
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
@@ -78,6 +78,32 @@
ll.foreach(callback, 42)
assert seen == addrs or seen[::-1] == addrs # order not guaranteed
+ def test_filter(self):
+ import random
+ AddressStack = get_address_stack()
+ addrs = [raw_malloc(llmemory.sizeof(lltype.Signed))
+ for i in range(1500)]
+ addrset = set(addrs)
+
+ for kept in [0.0, 0.5, 1.0]:
+ ll = AddressStack()
+ for i in range(1500):
+ ll.append(addrs[i])
+
+ keep = set([a for a in addrs if random.random() < kept])
+
+ def filter(addr, fortytwo):
+ assert fortytwo == 42
+ assert addr in addrset
+ return addr in keep
+
+ ll.filter(filter, 42)
+
+ seen = set()
+ while ll.non_empty():
+ seen.add(ll.pop())
+ assert seen == keep
+
def test_remove(self):
AddressStack = get_address_stack()
addrs = [raw_malloc(llmemory.sizeof(lltype.Signed))
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit