[pypy-svn] r51621 - in pypy/dist/pypy: rpython/memory rpython/tool rpython/tool/test translator/c/src translator/c/test translator/llvm

arigo at codespeak.net arigo at codespeak.net
Tue Feb 19 10:11:24 CET 2008


Author: arigo
Date: Tue Feb 19 10:11:22 2008
New Revision: 51621

Modified:
   pypy/dist/pypy/rpython/memory/lltypelayout.py
   pypy/dist/pypy/rpython/tool/rffi_platform.py
   pypy/dist/pypy/rpython/tool/test/test_rffi_platform.py
   pypy/dist/pypy/translator/c/src/mem.h
   pypy/dist/pypy/translator/c/test/test_newgc.py
   pypy/dist/pypy/translator/llvm/database.py
Log:
Figured out that 8-bytes alignment is not really necessary; gcc uses
4-bytes alignment even for 'double'.  This checkin adds logic for
detecting the alignment.


Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lltypelayout.py	(original)
+++ pypy/dist/pypy/rpython/memory/lltypelayout.py	Tue Feb 19 10:11:22 2008
@@ -2,7 +2,7 @@
 
 import struct
 
-memory_alignment = 4
+memory_alignment = struct.calcsize("P")
 
 primitive_to_fmt = {lltype.Signed:          "l",
                     lltype.Unsigned:        "L",

Modified: pypy/dist/pypy/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/rffi_platform.py	(original)
+++ pypy/dist/pypy/rpython/tool/rffi_platform.py	Tue Feb 19 10:11:22 2008
@@ -63,6 +63,24 @@
         setattr(CConfig, k, v)
     return configure(CConfig)['SIZE']
 
+def memory_alignment():
+    """Return the alignment (in bytes) of memory allocations.
+    This is enough to make sure a structure with pointers and 'double'
+    fields is properly aligned."""
+    global _memory_alignment
+    if _memory_alignment is None:
+        S = getstruct('struct memory_alignment_test', """
+           struct memory_alignment_test {
+               double d;
+               void* p;
+           };
+        """, [])
+        result = S._hints['align']
+        assert result & (result-1) == 0, "not a power of two??"
+        _memory_alignment = result
+    return _memory_alignment
+_memory_alignment = None
+
 # ____________________________________________________________
 #
 # General interface

Modified: pypy/dist/pypy/rpython/tool/test/test_rffi_platform.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/test/test_rffi_platform.py	(original)
+++ pypy/dist/pypy/rpython/tool/test/test_rffi_platform.py	Tue Feb 19 10:11:22 2008
@@ -203,3 +203,8 @@
 
 def test_sizeof():
     assert rffi_platform.sizeof("char", ExternalCompilationInfo()) == 1
+
+def test_memory_alignment():
+    a = rffi_platform.memory_alignment()
+    print a
+    assert a % struct.calcsize("P") == 0

Modified: pypy/dist/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/mem.h	(original)
+++ pypy/dist/pypy/translator/c/src/mem.h	Tue Feb 19 10:11:22 2008
@@ -3,8 +3,17 @@
  /***  C header subsection: operations on LowLevelTypes    ***/
 
 /* alignment for arena-based garbage collectors: the following line
-   enforces an alignment of sizeof(double). */
-#define MEMORY_ALIGNMENT		sizeof(double)
+   enforces an alignment that should be enough for any structure
+   containing pointers and 'double' fields. */
+struct rpy_memory_alignment_test1 {
+  double d;
+  void* p;
+};
+struct rpy_memory_alignment_test2 {
+  char c;
+  struct rpy_memory_alignment_test1 s;
+};
+#define MEMORY_ALIGNMENT	offsetof(struct rpy_memory_alignment_test2, s)
 #define ROUND_UP_FOR_ALLOCATION(x)	\
 		(((x) + (MEMORY_ALIGNMENT-1)) & ~(MEMORY_ALIGNMENT-1))
 

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 Feb 19 10:11:22 2008
@@ -784,9 +784,9 @@
         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
+        # all objects returned by the GC should be properly aligned.
         from pypy.rpython.lltypesystem import rffi
+        from pypy.rpython.tool import rffi_platform
         mylist = ['a', 'bc', '84139871', 'ajkdh', '876']
         def f():
             result = 0
@@ -800,10 +800,7 @@
 
         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")
+        expected_alignment = rffi_platform.memory_alignment()
         assert (res & (expected_alignment-1)) == 0
 
     def test_void_list(self):

Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py	(original)
+++ pypy/dist/pypy/translator/llvm/database.py	Tue Feb 19 10:11:22 2008
@@ -576,10 +576,13 @@
     def repr_offset(self, value):
         if isinstance(value, llarena.RoundedUpForAllocation):
             # XXX not supported when used in a CompositeOffset
+            from pypy.rpython.tool import rffi_platform
+            align = rffi_platform.memory_alignment()
             r_basesize = self.repr_offset(value.basesize)
             # Note that the following expression is known to crash 'llc';
             # you may need to upgrade llvm.
-            return "and(i32 add(i32 %s, i32 7), i32 -8)" % r_basesize
+            return "and(i32 add(i32 %s, i32 %d), i32 %d)" % (
+                r_basesize, align-1, ~(align-1))
 
         from_, indices, to = self.get_offset(value, [])
 



More information about the Pypy-commit mailing list