[pypy-svn] r70916 - in pypy/branch/gc-huge-list/pypy/rpython: lltypesystem lltypesystem/test memory
arigo at codespeak.net
arigo at codespeak.net
Wed Jan 27 14:44:57 CET 2010
Author: arigo
Date: Wed Jan 27 14:44:56 2010
New Revision: 70916
Modified:
pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/llarena.py
pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/test/test_llarena.py
pypy/branch/gc-huge-list/pypy/rpython/memory/lltypelayout.py
Log:
(arigo, fijal)
Add limited support for negative offsets in llarena,
to be used for card marking for large arrays.
Modified: pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/llarena.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/llarena.py (original)
+++ pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/llarena.py Wed Jan 27 14:44:56 2010
@@ -63,6 +63,22 @@
raise ArenaError("Address offset is outside the arena")
return fakearenaaddress(self, offset)
+ def allocate_bytes_array(self, offset, size):
+ self.check()
+ if offset + size > self.nbytes:
+ raise ArenaError("object overflows beyond the end of the arena")
+ for c in self.usagemap[offset:offset+size]:
+ if c == '0':
+ pass
+ else:
+ raise ArenaError("overlap or uninitialized memory")
+ pattern = 'b' * size
+ self.usagemap[offset:offset+size] = array.array('c', pattern)
+ bytesize = llmemory.sizeof(lltype.Char)
+ for i in range(offset, offset+size):
+ addr2 = bytesize._raw_malloc([], zero=True)
+ self.setobject(addr2, i, 1)
+
def allocate_object(self, offset, size):
self.check()
bytes = llmemory.raw_malloc_usage(size)
@@ -277,6 +293,26 @@
def raw_memcopy(self, srcadr, dstadr):
self.basesize.raw_memcopy(srcadr, dstadr)
+class NegativeByteIndex(llmemory.AddressOffset):
+ """Used to access an array of bytes just before an object.
+ For bit arrays used by the GC.
+ """
+ def __init__(self, index):
+ assert index >= 0
+ self.index = index
+
+ def __repr__(self):
+ return '< NegativeByteIndex %s >' % self.index
+
+ def ref(self, ptr):
+ addr = llmemory.cast_ptr_to_adr(ptr)
+ arena_addr = _getfakearenaaddress(addr)
+ newofs = arena_addr.offset + ~self.index
+ arena = arena_addr.arena
+ assert newofs >= 0
+ assert arena.usagemap[newofs] == 'b'
+ return arena.objectptrs[newofs]
+
# ____________________________________________________________
#
# Public interface: arena_malloc(), arena_free(), arena_reset()
@@ -321,6 +357,12 @@
% (addr.offset,))
addr.arena.allocate_object(addr.offset, size)
+def arena_reserve_array_of_bytes(addr, size):
+ """Mark some bytes in an arena as reserved for bytes array
+ """
+ addr = _getfakearenaaddress(addr)
+ addr.arena.allocate_bytes_array(addr.offset, size)
+
def arena_shrink_obj(addr, newsize):
""" Mark object as shorter than it was
"""
Modified: pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/test/test_llarena.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/test/test_llarena.py (original)
+++ pypy/branch/gc-huge-list/pypy/rpython/lltypesystem/test/test_llarena.py Wed Jan 27 14:44:56 2010
@@ -1,11 +1,10 @@
import py
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.lltypesystem.llmemory import cast_adr_to_ptr
-from pypy.rpython.lltypesystem.llarena import arena_malloc, arena_reset
-from pypy.rpython.lltypesystem.llarena import arena_reserve, arena_free
-from pypy.rpython.lltypesystem.llarena import round_up_for_allocation
-from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view
-from pypy.rpython.lltypesystem.llarena import arena_shrink_obj
+from pypy.rpython.lltypesystem.llarena import (arena_malloc, arena_reset,
+ arena_reserve, arena_free, round_up_for_allocation, ArenaError,
+ arena_new_view, arena_shrink_obj, NegativeByteIndex,
+ arena_reserve_array_of_bytes)
def test_arena():
S = lltype.Struct('S', ('x',lltype.Signed))
@@ -282,3 +281,19 @@
arena_reserve(a, size_gc_header + llmemory.sizeof(S, 10))
arena_shrink_obj(a, size_gc_header + llmemory.sizeof(S, 5))
arena_reset(a, size_gc_header + llmemory.sizeof(S, 5), False)
+
+def test_negative_byte_index():
+ S = lltype.Struct('S', ('x',lltype.Signed))
+ a = arena_malloc(200, True)
+ arena_reserve_array_of_bytes(a, 20) # array of (up to) 20 bytes
+ b = a + 20
+ arena_reserve(b, llmemory.sizeof(S))
+ s1 = cast_adr_to_ptr(b, lltype.Ptr(S))
+ s1.x = 123
+ (b + NegativeByteIndex(0)).char[0] = 'X'
+ (b + NegativeByteIndex(1)).char[0] = 'Y'
+ (b + NegativeByteIndex(19)).char[0] = 'Z'
+ assert (b + NegativeByteIndex(0)).char[0] == 'X'
+ assert (b + NegativeByteIndex(1)).char[0] == 'Y'
+ assert (b + NegativeByteIndex(19)).char[0] == 'Z'
+ py.test.raises(AssertionError, "b + NegativeByteIndex(20)")
Modified: pypy/branch/gc-huge-list/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/memory/lltypelayout.py (original)
+++ pypy/branch/gc-huge-list/pypy/rpython/memory/lltypelayout.py Wed Jan 27 14:44:56 2010
@@ -124,5 +124,7 @@
basesize = minsize
mask = memory_alignment - 1
return (basesize + mask) & ~ mask
+ elif isinstance(offset, llarena.NegativeByteIndex):
+ return ~offset.index
else:
raise Exception("unknown offset type %r"%offset)
More information about the Pypy-commit
mailing list