[pypy-svn] r68247 - in pypy/branch/gc-compress/pypy: rpython/lltypesystem rpython/lltypesystem/test translator/c translator/c/src translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 8 15:48:22 CEST 2009
Author: arigo
Date: Thu Oct 8 15:48:20 2009
New Revision: 68247
Modified:
pypy/branch/gc-compress/pypy/rpython/lltypesystem/llgroup.py
pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llgroup.py
pypy/branch/gc-compress/pypy/translator/c/node.py
pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h
pypy/branch/gc-compress/pypy/translator/c/test/test_lltyped.py
Log:
Detect at compile-time when the size of a group is greater
than the maximum permitted, i.e. 2**16 * sizeof(long).
Uses a really obscure C hack.
Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/llgroup.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/llgroup.py (original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/llgroup.py Thu Oct 8 15:48:20 2009
@@ -28,8 +28,10 @@
struct = structptr._as_obj()
assert struct not in _membership,"cannot be a member of several groups"
assert struct._parentstructure() is None
+ index = len(self.members)
self.members.append(struct)
_membership[struct] = self
+ return GroupMemberOffset(self, index)
def member_of_group(structptr):
return _membership.get(structptr._as_obj(), None)
@@ -48,11 +50,11 @@
def lltype(self):
return rffi.USHORT
- def __init__(self, grp, member):
+ def __init__(self, grp, memberindex):
assert lltype.typeOf(grp) == Group
self.grpptr = grp._as_ptr()
- self.member = member._as_ptr()
- self.index = grp.members.index(member._as_obj())
+ self.index = memberindex
+ self.member = grp.members[memberindex]._as_ptr()
def _get_group_member(self, grpptr):
assert grpptr == self.grpptr, "get_group_member: wrong group!"
Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llgroup.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llgroup.py (original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/test/test_llgroup.py Thu Oct 8 15:48:20 2009
@@ -20,14 +20,10 @@
p1b.x = 456
p2a.y = 789
p2b.z = -12
- grp.add_member(p1a)
- grp.add_member(p2a)
- grp.add_member(p2b)
- grp.add_member(p1b)
- self.g1a = GroupMemberOffset(grp, p1a)
- self.g1b = GroupMemberOffset(grp, p1b)
- self.g2a = GroupMemberOffset(grp, p2a)
- self.g2b = GroupMemberOffset(grp, p2b)
+ self.g1a = grp.add_member(p1a)
+ self.g2a = grp.add_member(p2a)
+ self.g2b = grp.add_member(p2b)
+ self.g1b = grp.add_member(p1b)
self.p1a = p1a
self.p1b = p1b
self.p2a = p2a
Modified: pypy/branch/gc-compress/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/gc-compress/pypy/translator/c/node.py (original)
+++ pypy/branch/gc-compress/pypy/translator/c/node.py Thu Oct 8 15:48:20 2009
@@ -926,6 +926,7 @@
def forward_declaration(self):
self._fix_members()
+ yield ''
ctype = ['%s {' % cdecl(self.implementationtypename, '')]
for i, member in enumerate(self.obj.members):
structtypename = self.db.gettype(typeOf(member))
@@ -935,10 +936,13 @@
yield '%s;' % (
forward_cdecl(ctype, self.name, self.db.standalone,
self.is_thread_local()))
+ yield '#include "src/llgroup.h"'
+ yield 'PYPY_GROUP_CHECK_SIZE(%s);' % self.name
for i, member in enumerate(self.obj.members):
structnode = self.db.getcontainernode(member)
yield '#define %s %s.member%d' % (structnode.name,
self.name, i)
+ yield ''
def initializationexpr(self):
self._fix_members()
Modified: pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h
==============================================================================
--- pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h (original)
+++ pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h Thu Oct 8 15:48:20 2009
@@ -1,3 +1,5 @@
+#ifndef _PYPY_LL_GROUP_H_
+#define _PYPY_LL_GROUP_H_
#define GROUP_MEMBER_OFFSET(group, membername) \
@@ -8,3 +10,12 @@
#define OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset, r) \
r = ((char*)groupptr) + ((long)compactoffset)*sizeof(long) + skipoffset
+
+/* A macro to crash at compile-time if sizeof(group) is too large.
+ Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */
+#define PYPY_GROUP_CHECK_SIZE(groupname) \
+ typedef char group_##groupname##_is_too_large[2*(sizeof(groupname) \
+ <= 65536 * sizeof(long))-1]
+
+
+#endif /* _PYPY_LL_GROUP_H_ */
Modified: pypy/branch/gc-compress/pypy/translator/c/test/test_lltyped.py
==============================================================================
--- pypy/branch/gc-compress/pypy/translator/c/test/test_lltyped.py (original)
+++ pypy/branch/gc-compress/pypy/translator/c/test/test_lltyped.py Thu Oct 8 15:48:20 2009
@@ -707,3 +707,37 @@
fn = self.getcompiled(f)
res = fn()
assert res == 42
+
+ def test_llgroup_size_limit(self):
+ yield self._test_size_limit, True
+ yield self._test_size_limit, False
+
+ def _test_size_limit(self, toobig):
+ from pypy.rpython.lltypesystem import llgroup
+ from pypy.rpython.lltypesystem.lloperation import llop
+ from pypy.translator.platform import CompilationError
+ grp = llgroup.group("big")
+ S1 = Struct('S1', ('x', Signed), ('y', Signed),
+ ('z', Signed), ('u', Signed),
+ ('x2', Signed), ('y2', Signed),
+ ('z2', Signed), ('u2', Signed),
+ ('x3', Signed), ('y3', Signed),
+ ('z3', Signed), ('u3', Signed),
+ ('x4', Signed), ('y4', Signed),
+ ('z4', Signed), ('u4', Signed))
+ goffsets = []
+ for i in range(4096 + toobig):
+ goffsets.append(grp.add_member(malloc(S1, immortal=True)))
+ grpptr = grp._as_ptr()
+ def f(n):
+ p = llop.get_group_member(Ptr(S1), grpptr, goffsets[n])
+ q = llop.get_group_member(Ptr(S1), grpptr, goffsets[0])
+ p.x = 5
+ q.x = 666
+ return p.x
+ if toobig:
+ py.test.raises(CompilationError, self.getcompiled, f, [int])
+ else:
+ fn = self.getcompiled(f, [int])
+ res = fn(-1)
+ assert res == 5
More information about the Pypy-commit
mailing list