[pypy-svn] r77784 - in pypy/trunk/pypy/rpython: lltypesystem test

arigo at codespeak.net arigo at codespeak.net
Mon Oct 11 14:34:40 CEST 2010


Author: arigo
Date: Mon Oct 11 14:34:35 2010
New Revision: 77784

Modified:
   pypy/trunk/pypy/rpython/lltypesystem/rclass.py
   pypy/trunk/pypy/rpython/test/test_rclass.py
Log:
Change the order of the instance attributes: order them by decreasing size.
It might help make some instances more compact by removing the padding that
the C compiler puts.


Modified: pypy/trunk/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/rclass.py	Mon Oct 11 14:34:35 2010
@@ -329,16 +329,33 @@
             fields['__class__'] = 'typeptr', get_type_repr(self.rtyper)
         else:
             # instance attributes
-            if llfields is None:
-                llfields = []
             attrs = self.classdef.attrs.items()
             attrs.sort()
+            myllfields = []
             for name, attrdef in attrs:
                 if not attrdef.readonly:
                     r = self.rtyper.getrepr(attrdef.s_value)
                     mangled_name = 'inst_' + name
                     fields[name] = mangled_name, r
-                    llfields.append((mangled_name, r.lowleveltype))
+                    myllfields.append((mangled_name, r.lowleveltype))
+
+            # Sort the instance attributes by decreasing "likely size",
+            # as reported by rffi.sizeof(), to minimize padding holes in C.
+            # Fields of the same size are sorted by name (by attrs.sort()
+            # above) just to minimize randomness.
+            def keysize((_, T)):
+                if T is lltype.Void:
+                    return None
+                from pypy.rpython.lltypesystem.rffi import sizeof
+                try:
+                    return -sizeof(T)
+                except StandardError:
+                    return None
+            myllfields.sort(key = keysize)
+            if llfields is None:
+                llfields = myllfields
+            else:
+                llfields = llfields + myllfields
 
             self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
                                          self.gcflavor)

Modified: pypy/trunk/pypy/rpython/test/test_rclass.py
==============================================================================
--- pypy/trunk/pypy/rpython/test/test_rclass.py	(original)
+++ pypy/trunk/pypy/rpython/test/test_rclass.py	Mon Oct 11 14:34:35 2010
@@ -3,7 +3,7 @@
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.rpython.lltypesystem.lltype import *
 from pypy.rpython.ootypesystem import ootype
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, r_longlong
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 from pypy.objspace.flow.model import summary
 
@@ -1001,6 +1001,40 @@
         res = self.interpret(f, [5])
         assert res == 0
 
+    def test_order_of_fields(self):
+        class A(object):
+            pass
+        def f(n):
+            a = A()
+            a.as_int = n
+            a.as_char = chr(n)
+            a.as_unichar = unichr(n)
+            a.as_double = n + 0.5
+            a.as_bool = bool(n)
+            a.as_void = None
+            a.as_longlong = r_longlong(n)
+            a.as_reference = A()
+            return a
+
+        res = self.interpret(f, [5])
+        names = list(typeOf(res).TO._names)
+        i = names.index('inst_as_int')
+        c = names.index('inst_as_char')
+        u = names.index('inst_as_unichar')
+        d = names.index('inst_as_double')
+        b = names.index('inst_as_bool')
+        v = names.index('inst_as_void')
+        l = names.index('inst_as_longlong')
+        r = names.index('inst_as_reference')
+        assert v == 1      # void fields are first
+        assert sorted([c, b]) == [7, 8]
+        if sys.maxint == 2147483647:
+            assert sorted([u, i, r]) == [4, 5, 6]        # 32-bit types
+            assert sorted([d, l]) == [2, 3]              # 64-bit types
+        else:
+            assert sorted([u]) == [6]                    # 32-bit types
+            assert sorted([i, r, d, l]) == [2, 3, 4, 5]  # 64-bit types
+
 
 class TestOOtype(BaseTestRclass, OORtypeMixin):
 



More information about the Pypy-commit mailing list