[pypy-svn] r68259 - in pypy/branch/gc-compress/pypy/rpython/lltypesystem: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 8 22:59:35 CEST 2009
Author: arigo
Date: Thu Oct 8 22:59:31 2009
New Revision: 68259
Modified:
pypy/branch/gc-compress/pypy/rpython/lltypesystem/llarena.py
pypy/branch/gc-compress/pypy/rpython/lltypesystem/llmemory.py
pypy/branch/gc-compress/pypy/rpython/lltypesystem/lltype.py
pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llarena.py
Log:
Kill the llarena feature of replacing an object with a stub.
Instead, add the feature of swapping the header of an object
for a completely different header.
Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/llarena.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/llarena.py (original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/llarena.py Thu Oct 8 22:59:31 2009
@@ -103,6 +103,48 @@
Arena.object_arena_location[container] = self, offset
Arena.old_object_arena_location[container] = self, offset
+ def get_header_ofs(self, obj, oldheadersize):
+ headers = []
+ for offset, ptr in self.objectptrs.items():
+ size = self.objectsizes[offset]
+ if offset >= obj: # object is at or after 'obj'
+ continue
+ if offset + size < obj: # object is before the header
+ continue
+ headers.append(offset)
+ assert len(headers) >= 1, "header not found"
+ assert len(headers) == 1, "uh? multiple headers?"
+ offset = headers[0]
+ size = self.objectsizes[offset]
+ assert offset + size == obj + self.objectsizes[obj], "not a header?"
+ assert obj - offset == llmemory.raw_malloc_usage(oldheadersize)
+ return offset
+
+ def swap_header(self, startobj, oldheadersize, newheadersize):
+ prev_end = [0]
+ for offset, ptr in self.objectptrs.items():
+ size = self.objectsizes[offset]
+ if offset + size < startobj:
+ prev_end.append((offset + size))
+ prev_end = max(prev_end)
+ new_bytes = llmemory.raw_malloc_usage(newheadersize)
+ assert prev_end <= startobj - new_bytes, "new header too big"
+ old_offset = self.get_header_ofs(startobj, oldheadersize)
+ assert isinstance(newheadersize, llmemory.GCHeaderOffset)
+ obj = self.objectptrs[startobj]
+ oldheaderptr = self.objectptrs.pop(old_offset)
+ oldheadersize.gcheaderbuilder.detach_header(obj, oldheaderptr)
+ newheader = newheadersize.gcheaderbuilder.new_header(obj)
+ newheader = llmemory.cast_ptr_to_adr(newheader)
+ #
+ del self.objectsizes[old_offset]
+ self.setobject(newheader, startobj - new_bytes,
+ new_bytes + self.objectsizes[startobj])
+ oldheaderobj = oldheaderptr._as_obj()
+ del Arena.object_arena_location[oldheaderobj]
+ oldheaderobj._free()
+
+
class fakearenaaddress(llmemory.fakeaddress):
def __init__(self, arena, offset):
@@ -309,6 +351,13 @@
"""
return Arena(ptr.arena.nbytes, False).getaddr(0)
+def arena_swap_header(obj, oldheadersize, newheadersize):
+ """Free the old header attached to 'obj', and attach one
+ of the size 'newheadersize' instead."""
+ arena_addr = _getfakearenaaddress(obj)
+ arena_addr.arena.swap_header(arena_addr.offset, oldheadersize,
+ newheadersize)
+
# ____________________________________________________________
#
# Translation support: the functions above turn into the code below.
Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/llmemory.py Thu Oct 8 22:59:31 2009
@@ -376,9 +376,7 @@
# NOTE: the 'ptr' in the addresses must be normalized.
# Use cast_ptr_to_adr() instead of directly fakeaddress() if unsure.
def __init__(self, ptr):
- if ptr is not None and ptr._obj0 is None:
- ptr = None # null ptr => None
- self.ptr = ptr
+ self.ptr = ptr or None # null ptr => None
def __repr__(self):
if self.ptr is None:
@@ -417,8 +415,8 @@
def __eq__(self, other):
if isinstance(other, fakeaddress):
try:
- obj1 = self._fixup().ptr
- obj2 = other._fixup().ptr
+ obj1 = self.ptr
+ obj2 = other.ptr
if obj1 is not None: obj1 = obj1._obj
if obj2 is not None: obj2 = obj2._obj
return obj1 == obj2
@@ -457,9 +455,8 @@
return self.ptr
def _cast_to_ptr(self, EXPECTED_TYPE):
- addr = self._fixup()
- if addr:
- return cast_any_ptr(EXPECTED_TYPE, addr.ptr)
+ if self:
+ return cast_any_ptr(EXPECTED_TYPE, self.ptr)
else:
return lltype.nullptr(EXPECTED_TYPE.TO)
@@ -469,14 +466,6 @@
else:
return 0
- def _fixup(self):
- if self.ptr is not None and self.ptr._was_freed():
- # hack to support llarena.test_replace_object_with_stub()
- from pypy.rpython.lltypesystem import llarena
- return llarena._getfakearenaaddress(self)
- else:
- return self
-
# ____________________________________________________________
class NullAddressError(Exception):
Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/lltype.py Thu Oct 8 22:59:31 2009
@@ -1194,10 +1194,6 @@
from pypy.rpython.lltypesystem import llmemory
if isinstance(self._T, FuncType):
return llmemory.fakeaddress(self)
- elif self._was_freed():
- # hack to support llarena.test_replace_object_with_stub()
- from pypy.rpython.lltypesystem import llarena
- return llarena._oldobj_to_address(self._getobj(check=False))
elif isinstance(self._obj, _subarray):
return llmemory.fakeaddress(self)
## # return an address built as an offset in the whole array
Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llarena.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llarena.py (original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llarena.py Thu Oct 8 22:59:31 2009
@@ -5,6 +5,7 @@
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_swap_header
def test_arena():
S = lltype.Struct('S', ('x',lltype.Signed))
@@ -217,13 +218,15 @@
assert llmemory.cast_adr_to_int(a) == llmemory.cast_adr_to_int(a1)
assert llmemory.cast_adr_to_int(a+1) == llmemory.cast_adr_to_int(a1) + 1
-def test_replace_object_with_stub():
+def test_replace_object_header():
from pypy.rpython.memory.gcheader import GCHeaderBuilder
HDR = lltype.Struct('HDR', ('x', lltype.Signed))
+ STUB = lltype.Struct('STUB', ('t', lltype.Char))
S = lltype.GcStruct('S', ('y', lltype.Signed), ('z', lltype.Signed))
- STUB = lltype.GcStruct('STUB', ('t', lltype.Char))
gcheaderbuilder = GCHeaderBuilder(HDR)
size_gc_header = gcheaderbuilder.size_gc_header
+ gcstubbuilder = GCHeaderBuilder(STUB)
+ size_stub = gcstubbuilder.size_gc_header
ssize = llmemory.raw_malloc_usage(llmemory.sizeof(S))
a = arena_malloc(13*ssize, True)
@@ -231,31 +234,28 @@
arena_reserve(hdraddr, size_gc_header + llmemory.sizeof(S))
hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(HDR))
hdr.x = 42
- obj = llmemory.cast_adr_to_ptr(hdraddr + size_gc_header, lltype.Ptr(S))
+ objaddr = hdraddr + size_gc_header
+ obj = llmemory.cast_adr_to_ptr(objaddr, lltype.Ptr(S))
obj.y = -5
obj.z = -6
- hdraddr = llmemory.cast_ptr_to_adr(obj) - size_gc_header
- arena_reset(hdraddr, size_gc_header + llmemory.sizeof(S), False)
- arena_reserve(hdraddr, size_gc_header + llmemory.sizeof(STUB))
-
- # check that it possible to reach the newly reserved HDR+STUB
- # via the header of the old 'obj' pointer, both via the existing
- # 'hdraddr':
- hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(HDR))
- hdr.x = 46
- stub = llmemory.cast_adr_to_ptr(hdraddr + size_gc_header, lltype.Ptr(STUB))
- stub.t = '!'
-
- # and via a (now-invalid) pointer to the old 'obj': (this is needed
- # because during a garbage collection there are still pointers to
- # the old 'obj' around to be fixed)
- hdraddr = llmemory.cast_ptr_to_adr(obj) - size_gc_header
- hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(HDR))
- assert hdr.x == 46
- stub = llmemory.cast_adr_to_ptr(hdraddr + size_gc_header,
- lltype.Ptr(STUB))
- assert stub.t == '!'
+ arena_swap_header(objaddr, size_gc_header, size_stub)
+ assert obj.y == -5
+ assert obj.z == -6
+ stubaddr = objaddr - size_stub
+ stub = llmemory.cast_adr_to_ptr(stubaddr, lltype.Ptr(STUB))
+ stub.t = 'A'
+ py.test.raises(RuntimeError, "hdr.x")
+ py.test.raises(KeyError, "objaddr - size_gc_header")
+
+ arena_swap_header(objaddr, size_stub, size_gc_header)
+ hdr2addr = objaddr - size_gc_header
+ hdr2 = llmemory.cast_adr_to_ptr(hdr2addr, lltype.Ptr(HDR))
+ hdr2.x = 42
+ assert obj.y == -5
+ assert obj.z == -6
+ py.test.raises(RuntimeError, "stub.t")
+ py.test.raises(KeyError, "objaddr - size_stub")
def test_llinterpreted():
More information about the Pypy-commit
mailing list