[pypy-svn] r77336 - in pypy/trunk/pypy: jit/backend/x86 rlib rpython/lltypesystem rpython/lltypesystem/test

arigo at codespeak.net arigo at codespeak.net
Fri Sep 24 13:29:52 CEST 2010


Author: arigo
Date: Fri Sep 24 13:29:49 2010
New Revision: 77336

Modified:
   pypy/trunk/pypy/jit/backend/x86/codebuf.py
   pypy/trunk/pypy/rlib/rmmap.py
   pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
Log:
Add a way to force (manually) ll2ctypes to allocate objects "far apart"
from each other.  To be used to detect some class of issues with the
64-bit JIT.


Modified: pypy/trunk/pypy/jit/backend/x86/codebuf.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/codebuf.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/codebuf.py	Fri Sep 24 13:29:49 2010
@@ -152,7 +152,7 @@
             # Hack to make sure that mcs are not within 32-bits of one
             # another for testing purposes
             from pypy.rlib.rmmap import hint
-            hint.pos += 0xFFFFFFFF
+            hint.pos += 0x80000000 - map_size
             
         self._init(data, map_size)
 

Modified: pypy/trunk/pypy/rlib/rmmap.py
==============================================================================
--- pypy/trunk/pypy/rlib/rmmap.py	(original)
+++ pypy/trunk/pypy/rlib/rmmap.py	Fri Sep 24 13:29:49 2010
@@ -292,7 +292,8 @@
                 c_munmap(self.getptr(0), self.size)
                 self.setdata(NODATA, 0)
 
-    __del__ = close
+    def __del__(self):
+        self.close()
 
     def unmapview(self):
         UnmapViewOfFile(self.getptr(0))

Modified: pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py	Fri Sep 24 13:29:49 2010
@@ -26,6 +26,60 @@
 from pypy.translator.platform import platform
 from array import array
 
+# ____________________________________________________________
+
+far_regions = None
+
+def allocate_ctypes(ctype):
+    if far_regions:
+        import random
+        pieces = far_regions._ll2ctypes_pieces
+        num = random.randrange(len(pieces))
+        i1, stop = pieces[num]
+        i2 = i1 + (ctypes.sizeof(ctype) + 7) & ~7
+        if i2 > stop:
+            raise MemoryError("out of memory in far_regions")
+        pieces[num] = i2, stop
+        p = lltype2ctypes(far_regions.getptr(i1))
+        return ctypes.cast(p, ctypes.POINTER(ctype)).contents
+    else:
+        return ctype()
+
+def do_allocation_in_far_regions():
+    """On 32 bits: this reserves 1.25GB of address space, or 2.5GB on Linux,
+       which helps test this module for address values that are signed or
+       unsigned.
+
+       On 64-bits: reserves 10 times 2GB of address space.  This should help
+       to find 32-vs-64-bit issues in the JIT.  It is likely that objects
+       are further apart than 32 bits can represent; it is also possible
+       to hit the corner case of being precisely e.g. 2GB - 8 bytes apart.
+
+       Avoid this function if your OS reserves actual RAM from mmap() eagerly.
+    """
+    global far_regions
+    if not far_regions:
+        from pypy.rlib import rmmap
+        if sys.maxint > 0x7FFFFFFF:
+            PIECESIZE = 0x80000000
+        else:
+            if sys.platform == 'linux':
+                PIECESIZE = 0x10000000
+            else:
+                PIECESIZE = 0x08000000
+        PIECES = 10
+        m = rmmap.mmap(-1, PIECES * PIECESIZE,
+                       rmmap.MAP_PRIVATE|rmmap.MAP_ANONYMOUS,
+                       rmmap.PROT_READ|rmmap.PROT_WRITE)
+        m.close = lambda : None    # leak instead of giving a spurious
+                                   # error at CPython's shutdown
+        m._ll2ctypes_pieces = []
+        for i in range(PIECES):
+            m._ll2ctypes_pieces.append((i * PIECESIZE, (i+1) * PIECESIZE))
+        far_regions = m
+
+# ____________________________________________________________
+
 _ctypes_cache = {}
 _eci_cache = {}
 
@@ -87,13 +141,13 @@
             if S._arrayfld is None:
                 if n is not None:
                     raise TypeError("%r is not variable-sized" % (S,))
-                storage = cls()
+                storage = allocate_ctypes(cls)
                 return storage
             else:
                 if n is None:
                     raise TypeError("%r is variable-sized" % (S,))
                 biggercls = build_ctypes_struct(S, None, n)
-                bigstruct = biggercls()
+                bigstruct = allocate_ctypes(biggercls)
                 array = getattr(bigstruct, S._arrayfld)
                 if hasattr(array, 'length'):
                     array.length = n
@@ -135,7 +189,7 @@
             if not isinstance(n, int):
                 raise TypeError, "array length must be an int"
             biggercls = get_ctypes_array_of_size(A, n)
-            bigarray = biggercls()
+            bigarray = allocate_ctypes(biggercls)
             if hasattr(bigarray, 'length'):
                 bigarray.length = n
             return bigarray

Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	Fri Sep 24 13:29:49 2010
@@ -16,6 +16,12 @@
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.rpython.rtyper import RPythonTyper
 
+
+if False:    # for now, please keep it False by default
+    from pypy.rpython.lltypesystem import ll2ctypes
+    ll2ctypes.do_allocation_in_far_regions()
+
+
 class TestLL2Ctypes(object):
 
     def setup_method(self, meth):



More information about the Pypy-commit mailing list