[pypy-svn] r53554 - in pypy/branch/ctypes-stable/pypy/rlib: . test

pedronis at codespeak.net pedronis at codespeak.net
Tue Apr 8 00:03:59 CEST 2008


Author: pedronis
Date: Tue Apr  8 00:03:58 2008
New Revision: 53554

Modified:
   pypy/branch/ctypes-stable/pypy/rlib/libffi.py
   pypy/branch/ctypes-stable/pypy/rlib/test/test_libffi.py
Log:
try to allocate closure memory through codebuf, libffi and _rawffi tests still pass but needs more testing and translation
checking



Modified: pypy/branch/ctypes-stable/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/ctypes-stable/pypy/rlib/libffi.py	(original)
+++ pypy/branch/ctypes-stable/pypy/rlib/libffi.py	Tue Apr  8 00:03:58 2008
@@ -49,6 +49,8 @@
                                                  ('type', rffi.USHORT),
                                                  ('elements', FFI_TYPE_PP)])
 
+    ffi_closure = rffi_platform.Struct('ffi_closure', [])
+
 def add_simple_type(type_name):
     for name in ['size', 'alignment', 'type']:
         setattr(CConfig, type_name + '_' + name,
@@ -119,8 +121,7 @@
 FFI_CIFP = rffi.COpaquePtr('ffi_cif', compilation_info=CConfig.
                            _compilation_info_)
 
-FFI_CLOSUREP = rffi.COpaquePtr('ffi_closure', compilation_info=CConfig.
-                               _compilation_info_)
+FFI_CLOSUREP = lltype.Ptr(cConfig.ffi_closure)
 
 VOIDPP = rffi.CArrayPtr(rffi.VOIDP)
 
@@ -209,6 +210,39 @@
     userdata = rffi.cast(USERDATA_P, ll_userdata)
     userdata.callback(ll_args, ll_res, userdata)
 
+# heap for closures
+from pypy.jit.codegen.i386 import codebuf_posix
+
+CHUNK = 4096
+CLOSURES = rffi.CArrayPtr(FFI_CLOSUREP.TO)
+
+class ClosureHeap(object):
+
+    def __init__(self):
+        self.free_list = lltype.nullptr(rffi.VOIDP.TO)
+
+    def _more(self):
+        chunk = rffi.cast(CLOSURES, codebuf_posix.alloc(CHUNK))
+        count = CHUNK//rffi.sizeof(FFI_CLOSUREP.TO)
+        for i in range(count):
+            rffi.cast(rffi.VOIDPP, chunk)[0] = self.free_list
+            self.free_list = rffi.cast(rffi.VOIDP, chunk)
+            chunk = rffi.ptradd(chunk, 1)
+
+    def alloc(self):
+        if not self.free_list:
+            self._more()
+        p = self.free_list
+        self.free_list = rffi.cast(rffi.VOIDPP, p)[0]
+        return rffi.cast(FFI_CLOSUREP, p)
+
+    def free(self, p):
+        rffi.cast(rffi.VOIDPP, p)[0] = self.free_list
+        self.free_list = rffi.cast(rffi.VOIDP, p)
+
+closureHeap = ClosureHeap()
+    
+
 class AbstractFuncPtr(object):
     ll_cif = lltype.nullptr(FFI_CIFP.TO)
     ll_argtypes = lltype.nullptr(FFI_TYPE_PP.TO)
@@ -246,7 +280,7 @@
     # it cannot be any kind of movable gc reference
     def __init__(self, argtypes, restype, func, additional_arg=0):
         AbstractFuncPtr.__init__(self, "callback", argtypes, restype)
-        self.ll_closure = lltype.malloc(FFI_CLOSUREP.TO, flavor='raw')
+        self.ll_closure = closureHeap.alloc()
         self.ll_userdata = lltype.malloc(USERDATA_P.TO, flavor='raw')
         self.ll_userdata.callback = rffi.llhelper(CALLBACK_TP, func)
         self.ll_userdata.addarg = additional_arg
@@ -259,7 +293,7 @@
     def __del__(self):
         AbstractFuncPtr.__del__(self)
         if self.ll_closure:
-            lltype.free(self.ll_closure, flavor='raw')
+            closureHeap.free(self.ll_closure)
             self.ll_closure = lltype.nullptr(FFI_CLOSUREP.TO)
         if self.ll_userdata:
             lltype.free(self.ll_userdata, flavor='raw')

Modified: pypy/branch/ctypes-stable/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/branch/ctypes-stable/pypy/rlib/test/test_libffi.py	(original)
+++ pypy/branch/ctypes-stable/pypy/rlib/test/test_libffi.py	Tue Apr  8 00:03:58 2008
@@ -109,6 +109,36 @@
         del libc
         assert not ALLOCATED
 
+    def test_closure_heap(self):
+        ch = ClosureHeap()
+
+        assert not ch.free_list
+        a = ch.alloc()
+        assert ch.free_list        
+        b = ch.alloc()
+        
+        chunks = [a, b]
+        p = ch.free_list
+        while p:
+            chunks.append(p)
+            p = rffi.cast(rffi.VOIDPP, p)[0]
+        closure_size = rffi.sizeof(FFI_CLOSUREP.TO)
+        assert len(chunks) == CHUNK//closure_size
+        for i in range(len(chunks) -1 ):
+            s = rffi.cast(rffi.UINT, chunks[i+1])
+            e = rffi.cast(rffi.UINT, chunks[i])
+            assert (e-s) >= rffi.sizeof(FFI_CLOSUREP.TO)
+
+        ch.free(a)
+        assert ch.free_list == rffi.cast(rffi.VOIDP, a)
+        snd = rffi.cast(rffi.VOIDPP, a)[0]
+        assert snd == chunks[2]
+
+        ch.free(b)
+        assert ch.free_list == rffi.cast(rffi.VOIDP, b)
+        snd = rffi.cast(rffi.VOIDPP, b)[0]
+        assert snd == rffi.cast(rffi.VOIDP, a)
+        
     def test_callback(self):
         libc = CDLL('libc.so.6')
         qsort = libc.getpointer('qsort', [ffi_type_pointer, ffi_type_slong,



More information about the Pypy-commit mailing list