[pypy-svn] r47353 - in pypy/dist/pypy: rpython/lltypesystem rpython/lltypesystem/test rpython/memory rpython/memory/test translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Tue Oct 9 16:40:40 CEST 2007
Author: arigo
Date: Tue Oct 9 16:40:40 2007
New Revision: 47353
Modified:
pypy/dist/pypy/rpython/lltypesystem/llarena.py
pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py
pypy/dist/pypy/rpython/memory/gc.py
pypy/dist/pypy/rpython/memory/gctypelayout.py
pypy/dist/pypy/rpython/memory/lltypelayout.py
pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
pypy/dist/pypy/translator/c/test/test_boehm.py
pypy/dist/pypy/translator/c/test/test_newgc.py
Log:
Alignment support for the GCs. Fix the SemiSpaceGC to always allocate
objects properly aligned.
Modified: pypy/dist/pypy/rpython/lltypesystem/llarena.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llarena.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/llarena.py Tue Oct 9 16:40:40 2007
@@ -216,12 +216,16 @@
assert myarenasize == arena_addr.arena.nbytes
arena_addr.arena.reset(zero)
-def arena_reserve(addr, size):
+def arena_reserve(addr, size, check_alignment=True):
"""Mark some bytes in an arena as reserved, and returns addr.
For debugging this can check that reserved ranges of bytes don't
overlap. The size must be symbolic; in non-translated version
this is used to know what type of lltype object to allocate."""
+ from pypy.rpython.memory.lltypelayout import memory_alignment
assert isinstance(addr, fakearenaaddress)
+ if check_alignment and (addr.offset & (memory_alignment-1)) != 0:
+ raise ArenaError("object at offset %d would not be correctly aligned"
+ % (addr.offset,))
addr.arena.allocate_object(addr.offset, size)
def round_up_for_allocation(size):
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_llarena.py Tue Oct 9 16:40:40 2007
@@ -22,7 +22,9 @@
assert s1_ptr2.x == 1
assert s1_ptr1 == s1_ptr2
- arena_reserve(a + ssize + 1, llmemory.sizeof(S))
+ py.test.raises(ArenaError, arena_reserve, a + ssize + 1, # misaligned
+ llmemory.sizeof(S))
+ arena_reserve(a + ssize + 1, llmemory.sizeof(S), check_alignment=False)
s2_ptr1 = cast_adr_to_ptr(a + ssize + 1, SPTR)
py.test.raises(lltype.UninitializedMemoryAccess, 's2_ptr1.x')
s2_ptr1.x = 2
@@ -40,10 +42,14 @@
py.test.raises(ArenaError, cast_adr_to_ptr, a+ssize, SPTR)
py.test.raises(ArenaError, cast_adr_to_ptr, a+2*ssize, SPTR)
py.test.raises(ArenaError, cast_adr_to_ptr, a+2*ssize+1, SPTR)
- py.test.raises(ArenaError, arena_reserve, a+1, llmemory.sizeof(S))
- py.test.raises(ArenaError, arena_reserve, a+ssize, llmemory.sizeof(S))
- py.test.raises(ArenaError, arena_reserve, a+2*ssize, llmemory.sizeof(S))
- py.test.raises(ArenaError, arena_reserve, a+2*ssize+1, llmemory.sizeof(S))
+ py.test.raises(ArenaError, arena_reserve, a+1, llmemory.sizeof(S),
+ False)
+ py.test.raises(ArenaError, arena_reserve, a+ssize, llmemory.sizeof(S),
+ False)
+ py.test.raises(ArenaError, arena_reserve, a+2*ssize, llmemory.sizeof(S),
+ False)
+ py.test.raises(ArenaError, arena_reserve, a+2*ssize+1, llmemory.sizeof(S),
+ False)
arena_reset(a, myarenasize, True)
py.test.raises(ArenaError, cast_adr_to_ptr, a, SPTR)
@@ -52,7 +58,7 @@
assert s1_ptr1.x == 0
s1_ptr1.x = 5
- arena_reserve(a + ssize, llmemory.sizeof(S2))
+ arena_reserve(a + ssize, llmemory.sizeof(S2), check_alignment=False)
s2_ptr1 = cast_adr_to_ptr(a + ssize, S2PTR)
assert s2_ptr1.y == '\x00'
s2_ptr1.y = 'X'
@@ -114,7 +120,7 @@
SPTR = lltype.Ptr(SX)
myarenasize = 50
a = arena_malloc(myarenasize, False)
- b = a + 4
+ b = a + round_up_for_allocation(llmemory.sizeof(lltype.Char))
arena_reserve(b, precomputed_size)
(b + llmemory.offsetof(SX, 'x')).signed[0] = 123
assert llmemory.cast_adr_to_ptr(b, SPTR).x == 123
Modified: pypy/dist/pypy/rpython/memory/gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc.py (original)
+++ pypy/dist/pypy/rpython/memory/gc.py Tue Oct 9 16:40:40 2007
@@ -1012,7 +1012,7 @@
llarena.arena_reserve(result, totalsize)
self.init_gc_object(result, typeid)
(result + size_gc_header + offset_to_length).signed[0] = length
- self.free += totalsize
+ self.free += llarena.round_up_for_allocation(totalsize)
if has_finalizer:
self.objects_with_finalizers.append(result + size_gc_header)
return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
@@ -1129,6 +1129,7 @@
lenaddr = obj + self.varsize_offset_to_length(typeid)
length = lenaddr.signed[0]
size += length * self.varsize_item_sizes(typeid)
+ size = llarena.round_up_for_allocation(size)
return size
def header(self, addr):
Modified: pypy/dist/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctypelayout.py (original)
+++ pypy/dist/pypy/rpython/memory/gctypelayout.py Tue Oct 9 16:40:40 2007
@@ -1,4 +1,4 @@
-from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory, llarena
from pypy.rpython.memory.gctransform.support import find_gc_ptrs_in_type
@@ -33,8 +33,13 @@
info["weakptrofs"] = weakpointer_offset(TYPE)
if not TYPE._is_varsize():
info["isvarsize"] = False
- info["fixedsize"] = llmemory.sizeof(TYPE)
+ info["fixedsize"] = llarena.round_up_for_allocation(
+ llmemory.sizeof(TYPE))
info["ofstolength"] = -1
+ # note about round_up_for_allocation(): in the 'info' table
+ # we put a rounded-up size only for fixed-size objects. For
+ # varsize ones, the GC must anyway compute the size at run-time
+ # and round up that result.
else:
info["isvarsize"] = True
info["fixedsize"] = llmemory.sizeof(TYPE, 0)
Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lltypelayout.py (original)
+++ pypy/dist/pypy/rpython/memory/lltypelayout.py Tue Oct 9 16:40:40 2007
@@ -2,6 +2,8 @@
import struct
+memory_alignment = 4
+
primitive_to_fmt = {lltype.Signed: "l",
lltype.Unsigned: "L",
lltype.Char: "c",
@@ -108,6 +110,7 @@
return 0
elif isinstance(offset, llarena.RoundedUpForAllocation):
basesize = convert_offset_to_int(offset.basesize)
- return (basesize + 7) & ~ 7
+ mask = memory_alignment - 1
+ return (basesize + mask) & ~ mask
else:
raise Exception("unknown offset type %r"%offset)
Modified: pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py Tue Oct 9 16:40:40 2007
@@ -83,15 +83,17 @@
class gcpolicy(gc.FrameworkGcPolicy):
class transformerclass(framework.FrameworkGCTransformer):
- from pypy.rpython.memory.gc import MarkSweepGC as GCClass
GC_PARAMS = {'start_heap_size': 4096 }
root_stack_depth = 200
gcname = "framework"
def heap_usage(self, statistics):
- if hasattr(self.gcpolicy.transformerclass.GCClass, 'STAT_HEAP_USAGE'):
- return statistics(
- self.gcpolicy.transformerclass.GCClass.STAT_HEAP_USAGE)
+ try:
+ GCClass = self.gcpolicy.transformerclass.GCClass
+ except AttributeError:
+ from pypy.rpython.memory.gc import MarkSweepGC as GCClass
+ if hasattr(GCClass, 'STAT_HEAP_USAGE'):
+ return statistics(GCClass.STAT_HEAP_USAGE)
else:
return -1 # xxx
Modified: pypy/dist/pypy/translator/c/test/test_boehm.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_boehm.py (original)
+++ pypy/dist/pypy/translator/c/test/test_boehm.py Tue Oct 9 16:40:40 2007
@@ -27,6 +27,8 @@
config = get_pypy_config(translating=True)
config.translation.gc = self.gcpolicy
config.translation.stacklessgc = self.stacklessgc
+ if self.gcpolicy == "framework":
+ config.translation.frameworkgc = self.frameworkgc
config.translation.simplifying = True
t = TranslationContext(config=config)
self.t = t
Modified: pypy/dist/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_newgc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_newgc.py Tue Oct 9 16:40:40 2007
@@ -278,6 +278,7 @@
class TestUsingFramework(AbstractGCTestClass):
gcpolicy = "framework"
+ frameworkgc = "marksweep"
def test_empty_collect(self):
def f():
@@ -774,6 +775,27 @@
res = fn()
assert res == 42
+ def test_object_alignment(self):
+ # all objects returned by the GC should be aligned on a 8-bytes
+ # boundary, or whatever sizeof(double) is on this platform
+ mylist = ['a', 'bc', '84139871', 'ajkdh', '876']
+ def f():
+ result = 0
+ buffer = ""
+ for j in range(100):
+ for s in mylist:
+ buffer += s
+ result |= id(buffer)
+ return result
+
+ fn = self.getcompiled(f)
+ res = fn()
+ import struct
+ expected_alignment = struct.calcsize("d")
+ assert (expected_alignment & (expected_alignment-1)) == 0, (
+ "sizeof(double) not a power of two")
+ assert (res & (expected_alignment-1)) == 0
+
class TestUsingStacklessFramework(TestUsingFramework):
def getcompiled(self, f):
@@ -799,3 +821,9 @@
def test_weakref(self):
py.test.skip("fails for some reason I couldn't figure out yet :-(")
+
+class TestSemiSpaceGC(TestUsingFramework):
+ frameworkgc = "semispace"
+
+ def setup_class(cls):
+ py.test.skip("in-progress")
More information about the Pypy-commit
mailing list