[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