[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