[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