[pypy-svn] r79897 - in pypy/branch/gc-debug/pypy/rpython/lltypesystem: . test

arigo at codespeak.net arigo at codespeak.net
Wed Dec 8 16:13:21 CET 2010


Author: arigo
Date: Wed Dec  8 16:13:19 2010
New Revision: 79897

Modified:
   pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py
   pypy/branch/gc-debug/pypy/rpython/lltypesystem/lltype.py
   pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py
Log:
Add arena_protect(), for now only untranslated.


Modified: pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py
==============================================================================
--- pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py	(original)
+++ pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py	Wed Dec  8 16:13:19 2010
@@ -26,6 +26,7 @@
         self.objectptrs = {}        # {offset: ptr-to-container}
         self.objectsizes = {}       # {offset: size}
         self.freed = False
+        self.protect_inaccessible = None
         self.reset(zero)
 
     def __repr__(self):
@@ -59,6 +60,8 @@
     def check(self):
         if self.freed:
             raise ArenaError("arena was already freed")
+        if self.protect_inaccessible is not None:
+            raise ArenaError("arena is currently arena_protect()ed")
 
     def _getid(self):
         address, length = self.usagemap.buffer_info()
@@ -127,6 +130,21 @@
     def mark_freed(self):
         self.freed = True    # this method is a hook for tests
 
+    def set_protect(self, accessible):
+        if not accessible:
+            assert self.protect_inaccessible is None
+            saved = []
+            for ptr in self.objectptrs.values():
+                obj = ptr._obj
+                saved.append((obj, obj._protect()))
+            self.protect_inaccessible = saved
+        else:
+            assert self.protect_inaccessible is not None
+            saved = self.protect_inaccessible
+            for obj, storage in saved:
+                obj._unprotect(storage)
+            self.protect_inaccessible = None
+
 class fakearenaaddress(llmemory.fakeaddress):
 
     def __init__(self, arena, offset):
@@ -365,6 +383,16 @@
     """
     return Arena(ptr.arena.nbytes, False).getaddr(0)
 
+def arena_protect(arena_addr, size, accessible):
+    """For debugging, set or reset memory protection on an arena.
+    For now, the starting point and size should reference the whole arena.
+    The value of 'accessible' is a boolean.
+    """
+    arena_addr = getfakearenaaddress(arena_addr)
+    assert arena_addr.offset == 0
+    assert size == arena_addr.arena.nbytes
+    arena_addr.arena.set_protect(accessible)
+
 # ____________________________________________________________
 #
 # Translation support: the functions above turn into the code below.

Modified: pypy/branch/gc-debug/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/gc-debug/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/branch/gc-debug/pypy/rpython/lltypesystem/lltype.py	Wed Dec  8 16:13:19 2010
@@ -1381,6 +1381,15 @@
         self._check()   # no double-frees
         self._storage = None
 
+    def _protect(self):
+        result = self._storage
+        self._free()   # no double-frees or double-protects
+        return result
+
+    def _unprotect(self, saved_storage):
+        assert self._storage is None
+        self._storage = saved_storage
+
     def _was_freed(self):
         if self._storage is None:
             return True

Modified: pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py
==============================================================================
--- pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py	(original)
+++ pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py	Wed Dec  8 16:13:19 2010
@@ -6,6 +6,7 @@
 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_protect
 
 def test_arena():
     S = lltype.Struct('S', ('x',lltype.Signed))
@@ -282,3 +283,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_arena_protect():
+    a = arena_malloc(100, False)
+    S = lltype.Struct('S', ('x', lltype.Signed))
+    arena_reserve(a, llmemory.sizeof(S))
+    p = llmemory.cast_adr_to_ptr(a, lltype.Ptr(S))
+    p.x = 123
+    assert p.x == 123
+    arena_protect(a, 100, accessible=False)
+    py.test.raises(ArenaError, arena_reserve, a + 48, llmemory.sizeof(S))
+    py.test.raises(RuntimeError, "p.x")
+    py.test.raises(RuntimeError, "p.x = 124")
+    arena_protect(a, 100, accessible=True)
+    assert p.x == 123
+    p.x = 125
+    assert p.x == 125



More information about the Pypy-commit mailing list