[pypy-svn] r57275 - in pypy/dist/pypy/rlib: . test

fijal at codespeak.net fijal at codespeak.net
Fri Aug 15 14:32:51 CEST 2008


Author: fijal
Date: Fri Aug 15 14:32:50 2008
New Revision: 57275

Modified:
   pypy/dist/pypy/rlib/rmmap.py
   pypy/dist/pypy/rlib/test/test_rmmap.py
Log:
Add alloc/free pair to interface of rmmap, copied from codebuf_* in jit.


Modified: pypy/dist/pypy/rlib/rmmap.py
==============================================================================
--- pypy/dist/pypy/rlib/rmmap.py	(original)
+++ pypy/dist/pypy/rlib/rmmap.py	Fri Aug 15 14:32:50 2008
@@ -64,7 +64,8 @@
 elif _MS_WINDOWS:
     constant_names = ['PAGE_READONLY', 'PAGE_READWRITE', 'PAGE_WRITECOPY',
                       'FILE_MAP_READ', 'FILE_MAP_WRITE', 'FILE_MAP_COPY',
-                      'DUPLICATE_SAME_ACCESS']
+                      'DUPLICATE_SAME_ACCESS', 'MEM_COMMIT', 'MEM_RESERVE',
+                      'MEM_RELEASE', 'PAGE_EXECUTE_READWRITE']
     for name in constant_names:
         setattr(CConfig, name, rffi_platform.ConstantInteger(name))
 
@@ -176,7 +177,14 @@
     # but it should not be so!
     _get_osfhandle = winexternal('_get_osfhandle', [INT], HANDLE)
     GetLastError = winexternal('GetLastError', [], DWORD)
-    
+    VirtualAlloc = winexternal('VirtualAlloc',
+                               [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORD],
+                               rffi.VOIDP)
+    VirtualProtect = winexternal('VirtualProtect',
+                                 [rffi.VOIDP, rffi.SIZE_T, DWORD, DWORDP], BOOL)
+    VirtualFree = winexternal('VirtualFree',
+                              [rffi.VOIDP, rffi.SIZE_T, DWORD], BOOL)
+
     
     def _get_page_size():
         try:
@@ -610,6 +618,24 @@
         
         m.setdata(res, map_size)
         return m
+
+    # XXX is this really necessary?
+    class Hint:
+        pos = -0x4fff0000   # for reproducible results
+    hint = Hint()
+
+    def alloc(map_size):
+        flags = MAP_PRIVATE | MAP_ANONYMOUS
+        prot = PROT_EXEC | PROT_READ | PROT_WRITE
+        hintp = rffi.cast(PTR, hint.pos)
+        res = c_mmap(hintp, map_size, prot, flags, -1, 0)
+        if res == rffi.cast(PTR, -1):
+            raise MemoryError
+        hint.pos += map_size
+        return res
+
+    free = c_munmap
+    
 elif _MS_WINDOWS:
     def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT):
         # check size boundaries
@@ -708,5 +734,20 @@
         err = rffi.cast(lltype.Signed, dwErr)
         raise OSError(err, os.strerror(err))
 
+    
+    def alloc(map_size):
+        null = lltype.nullptr(rffi.VOIDP.TO)
+        res = VirtualAlloc(null, map_size, MEM_COMMIT|MEM_RESERVE,
+                           PAGE_EXECUTE_READWRITE)
+        if not res:
+            raise MemoryError
+        arg = lltype.malloc(DWORDP.TO, 1, zero=True, flavor='raw')
+        VirtualProtect(res, map_size, PAGE_EXECUTE_READWRITE, arg)
+        lltype.free(arg, flavor='raw')
+        # ignore errors, just try
+        return res
+
+    def free(ptr, map_size):
+        VirtualFree(ptr, 0, MEM_RELEASE)
         
 # register_external here?

Modified: pypy/dist/pypy/rlib/test/test_rmmap.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_rmmap.py	(original)
+++ pypy/dist/pypy/rlib/test/test_rmmap.py	Fri Aug 15 14:32:50 2008
@@ -2,7 +2,7 @@
 import os
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.rlib import rmmap as mmap
-from pypy.rlib.rmmap import RTypeError, RValueError
+from pypy.rlib.rmmap import RTypeError, RValueError, alloc, free
 import sys
 
 class TestMMap:
@@ -382,3 +382,18 @@
             return r
 
         compile(func, [int])
+
+def test_alloc_free():
+    map_size = 65536
+    data = alloc(map_size)
+    for i in range(0, map_size, 171):
+        data[i] = chr(i & 0xff)
+    for i in range(0, map_size, 171):
+        assert data[i] == chr(i & 0xff)
+    free(data, map_size)
+
+def test_compile_alloc_free():
+    from pypy.translator.c.test.test_genc import compile
+
+    fn = compile(test_alloc_free, [])
+    fn()



More information about the Pypy-commit mailing list