[pypy-commit] pypy ffi-backend: Move calls to llmemory.raw_memcopy to JIT-aware helpers.

arigo noreply at buildbot.pypy.org
Sun Jul 29 18:29:49 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r56503:8ef6c686949b
Date: 2012-07-29 18:29 +0200
http://bitbucket.org/pypy/pypy/changeset/8ef6c686949b/

Log:	Move calls to llmemory.raw_memcopy to JIT-aware helpers.

diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -98,12 +98,7 @@
     def write_error_return_value(self, ll_res):
         fresult = self.getfunctype().ctitem
         if fresult.size > 0:
-            # push push push at the llmemory interface (with hacks that
-            # are all removed after translation)
-            zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
-            llmemory.raw_memcopy(llmemory.cast_ptr_to_adr(self.ll_error) +zero,
-                                 llmemory.cast_ptr_to_adr(ll_res) + zero,
-                                 fresult.size * llmemory.sizeof(lltype.Char))
+            misc._raw_memcopy(self.ll_error, ll_res, fresult.size)
             keepalive_until_here(self)
 
 
@@ -145,9 +140,7 @@
         else:
             # zero extension: fill the '*result' with zeros, and (on big-
             # endian machines) correct the 'result' pointer to write to
-            zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
-            llmemory.raw_memclear(llmemory.cast_ptr_to_adr(ll_res) + zero,
-                                SIZE_OF_FFI_ARG * llmemory.sizeof(lltype.Char))
+            misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
             if BIG_ENDIAN:
                 diff = SIZE_OF_FFI_ARG - fresult.size
                 ll_res = rffi.ptradd(ll_res, diff)
@@ -180,9 +173,7 @@
             pass
         # In this case, we don't even know how big ll_res is.  Let's assume
         # it is just a 'ffi_arg', and store 0 there.
-        zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
-        llmemory.raw_memclear(llmemory.cast_ptr_to_adr(ll_res) + zero,
-                              SIZE_OF_FFI_ARG * llmemory.sizeof(lltype.Char))
+        misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
         return
     #
     ec = None
diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -3,7 +3,7 @@
 """
 
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+from pypy.rpython.lltypesystem import rffi
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.rlib.objectmodel import keepalive_until_here
@@ -56,13 +56,8 @@
         space = self.space
         self.check_complete()
         ob = cdataobj.W_CDataNewOwning(space, self.size, self)
-        # push push push at the llmemory interface (with hacks that
-        # are all removed after translation)
-        zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
-        llmemory.raw_memcopy(
-            llmemory.cast_ptr_to_adr(cdata) + zero,
-            llmemory.cast_ptr_to_adr(ob._cdata) + zero,
-            self.size * llmemory.sizeof(lltype.Char))
+        misc._raw_memcopy(cdata, ob._cdata, self.size)
+        keepalive_until_here(ob)
         return ob
 
     def offsetof(self, fieldname):
@@ -79,13 +74,7 @@
         ob = space.interpclass_w(w_ob)
         if isinstance(ob, cdataobj.W_CData):
             if ob.ctype is self and self.size >= 0:
-                # push push push at the llmemory interface (with hacks that
-                # are all removed after translation)
-                zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
-                llmemory.raw_memcopy(
-                    llmemory.cast_ptr_to_adr(ob._cdata) + zero,
-                    llmemory.cast_ptr_to_adr(cdata) + zero,
-                    self.size * llmemory.sizeof(lltype.Char))
+                misc._raw_memcopy(ob._cdata, cdata, self.size)
                 keepalive_until_here(ob)
                 return True
         return False
diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -1,7 +1,8 @@
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rlib.rarithmetic import r_ulonglong
 from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib import jit
 
 # ____________________________________________________________
 
@@ -135,3 +136,33 @@
 
 neg_msg = "can't convert negative number to unsigned"
 ovf_msg = "long too big to convert"
+
+# ____________________________________________________________
+
+def _raw_memcopy(source, dest, size):
+    if jit.isconstant(size):
+        # for the JIT: first handle the case where 'size' is known to be
+        # a constant equal to 1, 2, 4, 8
+        for TP, TPP in _prim_unsigned_types:
+            if size == rffi.sizeof(TP):
+                rffi.cast(TPP, dest)[0] = rffi.cast(TPP, source)[0]
+                return
+    _raw_memcopy_opaque(source, dest, size)
+
+ at jit.dont_look_inside
+def _raw_memcopy_opaque(source, dest, size):
+    # push push push at the llmemory interface (with hacks that are all
+    # removed after translation)
+    zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
+    llmemory.raw_memcopy(
+        llmemory.cast_ptr_to_adr(source) + zero,
+        llmemory.cast_ptr_to_adr(dest) + zero,
+        size * llmemory.sizeof(lltype.Char))
+
+def _raw_memclear(dest, size):
+    # for now, only supports the cases of size = 1, 2, 4, 8
+    for TP, TPP in _prim_unsigned_types:
+        if size == rffi.sizeof(TP):
+            rffi.cast(TPP, dest)[0] = rffi.cast(TP, 0)
+            return
+    raise NotImplementedError("bad clear size")


More information about the pypy-commit mailing list