[pypy-commit] pypy gc-minimark-pinning: pass more of a test and write insert for support. crap ugly
fijal
noreply at buildbot.pypy.org
Thu Apr 12 23:32:10 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: gc-minimark-pinning
Changeset: r54317:aa6c3180899c
Date: 2012-04-12 23:31 +0200
http://bitbucket.org/pypy/pypy/changeset/aa6c3180899c/
Log: pass more of a test and write insert for support. crap ugly
diff --git a/pypy/rpython/lltypesystem/llarena.py b/pypy/rpython/lltypesystem/llarena.py
--- a/pypy/rpython/lltypesystem/llarena.py
+++ b/pypy/rpython/lltypesystem/llarena.py
@@ -394,7 +394,7 @@
arena_addr = getfakearenaaddress(arena_addr)
assert arena_addr.offset == 0
assert size == arena_addr.arena.nbytes
- arena_addr.arena.set_protect(inaccessible)
+ arena_addr.arena.set_protect(inaccessible)
# ____________________________________________________________
#
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -247,6 +247,8 @@
self.nursery_top = NULL
self.debug_tiny_nursery = -1
self.debug_rotating_nurseries = None
+ self.surviving_pinned_objects = NULL
+ self.nursery_barriers = NULL
#
# The ArenaCollection() handles the nonmovable objects allocation.
if ArenaCollectionClass is None:
@@ -306,7 +308,7 @@
# minor collection.
self.nursery_objects_shadows = self.AddressDict()
# all pinned objects that were in the nursery *before* last
- # minor collect. This is a sorted stack that should be consulted when
+ # minor collect. This is a sorted deque that should be consulted when
# considering next nursery ceiling
self.nursery_barriers = self.AddressDeque()
@@ -1257,6 +1259,8 @@
#
# Before everything else, remove from 'old_objects_pointing_to_young'
# the young arrays.
+ self.nursery_barriers.delete()
+ self.surviving_pinned_objects = self.AddressStack()
if self.young_rawmalloced_objects:
self.remove_young_arrays_from_old_objects_pointing_to_young()
#
@@ -1308,22 +1312,24 @@
# All live nursery objects are out, and the rest dies. Fill
# the whole nursery with zero and reset the current nursery pointer.
# self.nursery_barriers are *not* freed
- # XXX sort the nursery_barriers
- new_barriers = self.AddressDeque()
+ nursery_barriers = self.AddressDeque()
prev = self.nursery
size_gc_header = self.gcheaderbuilder.size_gc_header
- while self.nursery_barriers.non_empty():
- next = self.nursery_barriers.popleft()
- llarena.arena_reset(prev, next - prev, 2)
+ while self.surviving_pinned_objects.non_empty():
+ next = self.surviving_pinned_objects.pop()
+ assert next >= prev
+ size = llarena.getfakearenaaddress(next) - prev
+ llarena.arena_reset(prev, size, 2)
# clean the visited flag
obj = next + size_gc_header
self.header(obj).tid &= ~GCFLAG_VISITED
- prev = prev + (next - prev) + (size_gc_header +
+ prev = prev + size + (size_gc_header +
self.get_size(obj))
- new_barriers.append(next)
+ nursery_barriers.append(next)
llarena.arena_reset(prev, self.nursery_top - prev, 2)
- self.nursery_barriers.delete()
- self.nursery_barriers = new_barriers
+ self.surviving_pinned_objects.delete()
+ self.surviving_pinned_objects = NULL
+ self.nursery_barriers = nursery_barriers
self.debug_rotate_nursery()
self.nursery_free = self.nursery
self.nursery_barriers.append(self.nursery + self.nursery_size)
@@ -1478,7 +1484,8 @@
hdr.tid |= GCFLAG_VISITED
ll_assert(not self.header(obj).tid & GCFLAG_HAS_SHADOW, "support shadow with pinning")
ll_assert(not self.header(obj).tid & GCFLAG_HAS_CARDS, "support cards with pinning")
- self.nursery_barriers.append(obj - size_gc_header)
+ self.surviving_pinned_objects.insert(
+ llarena.getfakearenaaddress(obj - size_gc_header))
return
elif self.header(obj).tid & GCFLAG_HAS_SHADOW == 0:
#
diff --git a/pypy/rpython/memory/support.py b/pypy/rpython/memory/support.py
--- a/pypy/rpython/memory/support.py
+++ b/pypy/rpython/memory/support.py
@@ -173,6 +173,47 @@
chunk.items[count] = got
got = next
+ def insert(self, addr):
+ """ Insert addr in the already sorted stack to make sure
+ the smallest one is on top
+ """
+ if self.used_in_last_chunk == 0:
+ self.append(addr)
+ return
+ got = self.pop()
+ read = self.used_in_last_chunk - 1
+ if read == -1 and got <= addr:
+ self.append(addr)
+ self.append(got)
+ return
+ read_chunk = self.chunk
+ self.append(got)
+ if got > addr:
+ self.append(addr)
+ return
+ write = self.used_in_last_chunk
+ if self.used_in_last_chunk == chunk_size:
+ self.enlarge()
+ write = 0
+ self.used_in_last_chunk += 1
+ write_chunk = self.chunk
+ while got < addr and not read_chunk is null_chunk:
+ write_chunk.items[write] = got
+ write -= 1
+ if write < 0:
+ write_chunk = write_chunk.next
+ write = chunk_size - 1
+ got = read_chunk.items[read]
+ read -= 1
+ if read < 0:
+ read_chunk = read_chunk.next
+ read = chunk_size - 1
+ if got < addr:
+ write_chunk.items[write] = got
+ write_chunk.items[0] = addr
+ else:
+ write_chunk.items[write] = addr
+
cache[chunk_size] = AddressStack
return AddressStack
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -966,5 +966,35 @@
res = self.interpret(f, [10])
assert res == 2
+ def test_pinning_collect_2(self):
+ from pypy.rpython.lltypesystem import llmemory
+
+ TP = lltype.GcStruct('x', ('x', lltype.Signed), ('y', lltype.Signed))
+
+ def f(i):
+ e = lltype.malloc(TP)
+ e.x = 3
+ lltype.malloc(TP)
+ e2 = lltype.malloc(TP)
+ e2.x = 5
+ rgc.pin(e2)
+ rgc.pin(e)
+ prev = llmemory.cast_ptr_to_adr(e)
+ prev2 = llmemory.cast_ptr_to_adr(e2)
+ for k in range(i):
+ lltype.malloc(TP)
+ res = int(llmemory.cast_ptr_to_adr(e) == prev)
+ res += int(llmemory.cast_ptr_to_adr(e2) == prev2)
+ rgc.unpin(e)
+ for k in range(i):
+ lltype.malloc(TP)
+ rgc.unpin(e2)
+ assert e.x == 3 # noone overwrote it
+ assert e2.x == 5 # noone overwrote it
+ return res
+
+ res = self.interpret(f, [10])
+ assert res == 2
+
class TestMiniMarkGCCardMarking(TestMiniMarkGC):
GC_PARAMS = {'card_page_indices': 4}
diff --git a/pypy/rpython/memory/test/test_support.py b/pypy/rpython/memory/test/test_support.py
--- a/pypy/rpython/memory/test/test_support.py
+++ b/pypy/rpython/memory/test/test_support.py
@@ -3,7 +3,7 @@
from pypy.rpython.memory.support import get_address_deque
from pypy.rpython.test.test_llinterp import interpret
-from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory, llarena
from pypy.rpython.lltypesystem.llmemory import raw_malloc, raw_free, NULL
class TestAddressStack(object):
@@ -94,6 +94,26 @@
assert a == addrs[i]
assert not ll.non_empty()
+ def test_insert(self):
+ AddressStack = get_address_stack(chunk_size=5)
+ ll = AddressStack()
+ lla = llarena.arena_malloc(10, 2)
+ addrs = [lla + i for i in range(10)]
+ ll.insert(addrs[2])
+ ll.insert(addrs[1])
+ ll.insert(addrs[5])
+ ll.insert(addrs[4])
+ ll.insert(addrs[6])
+ ll.insert(addrs[9])
+ ll.insert(addrs[0])
+ ll.insert(addrs[8])
+ ll.insert(addrs[7])
+ ll.insert(addrs[3])
+ expected = range(10)
+ for i in expected:
+ a = ll.pop()
+ assert a == addrs[i]
+
class TestAddressDeque:
def test_big_access(self):
More information about the pypy-commit
mailing list