[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