[pypy-svn] r75966 - pypy/branch/fast-ctypes/pypy/rlib

getxsick at codespeak.net getxsick at codespeak.net
Wed Jul 7 13:29:30 CEST 2010


Author: getxsick
Date: Wed Jul  7 13:29:28 2010
New Revision: 75966

Modified:
   pypy/branch/fast-ctypes/pypy/rlib/rjitffi.py
Log:
add cache for compiled loops to prevent recompiling the same type of function
it needs some refactor though


Modified: pypy/branch/fast-ctypes/pypy/rlib/rjitffi.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/rlib/rjitffi.py	(original)
+++ pypy/branch/fast-ctypes/pypy/rlib/rjitffi.py	Wed Jul  7 13:29:28 2010
@@ -6,6 +6,8 @@
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.metainterp.typesystem import deref
 
+cache = [] # XXX global!
+
 class CDLL(object):
     def __init__(self, name, load=True):
         if load:
@@ -37,56 +39,75 @@
         self.cpu = cpu
         self.lib = lib.handler
         self.setup_stack()
-
-        if self.res_type == 'i':
-            self.bres = BoxInt()
-            res = lltype.Signed
-        elif self.res_type == 'f':
-            self.bres = BoxFloat()
-            res = lltype.Float
-        elif self.res_type == 'p':
-            self.bres = BoxPtr()
-            res = lltype.Signed
-        elif self.res_type == 'v':
-            self.bres = NULLBOX
-            res = lltype.Void
-        else:
-            raise ValueError(self.res_type)
+        self.looptoken = None
 
         try:
-            addr = rffi.cast(lltype.Signed, rdynload.dlsym(self.lib, func))
+            self.funcaddr = rffi.cast(lltype.Signed, rdynload.dlsym(self.lib,
+                                                                    func))
         except KeyError:
             raise ValueError("Cannot find symbol %s", func)
-        self.bfuncaddr = BoxInt(addr)
+        self.bargs.append(BoxInt())
 
-        args = []
-        for arg in self.args_type:
-            if arg == 'i':
-                args.append(lltype.Signed)
-            elif arg == 'f':
-                args.append(lltype.Float)
-            elif arg == 'p':
-                args.append(lltype.Signed)
+        # check if it's not already compiled
+        for func in cache:
+            if self.args_type == func.args_type and \
+               self.res_type == func.res_type:
+                self.looptoken = func.looptoken
+                self.oplist = func.oplist
+                break
+
+        if self.looptoken is None:
+            args = []
+            for arg in self.args_type:
+                if arg == 'i':
+                    self.bargs.append(BoxInt())
+                    args.append(lltype.Signed)
+                elif arg == 'f':
+                    self.bargs.append(BoxFloat())
+                    args.append(lltype.Float)
+                elif arg == 'p':
+                    self.bargs.append(BoxPtr())
+                    args.append(lltype.Signed)
+                else:
+                    raise ValueError(arg)
+
+            if self.res_type == 'i':
+                self.bres = BoxInt()
+                res = lltype.Signed
+            elif self.res_type == 'f':
+                self.bres = BoxFloat()
+                res = lltype.Float
+            elif self.res_type == 'p':
+                self.bres = BoxPtr()
+                res = lltype.Signed
+            elif self.res_type == 'v':
+                self.bres = NULLBOX
+                res = lltype.Void
             else:
-                raise ValueError(arg)
+                raise ValueError(self.res_type)
 
-        FPTR = lltype.Ptr(lltype.FuncType(args, res))
-        FUNC = deref(FPTR)
-        self.calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+            FPTR = lltype.Ptr(lltype.FuncType(args, res))
+            FUNC = deref(FPTR)
+            self.calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+
+            self.looptoken = LoopToken()
+            inputargs = self.bargs # [ self.bfuncaddr ] + self.bargs
+
+            self.oplist = [ResOperation(rop.CALL, inputargs, self.bres,
+                                        descr=self.calldescr),
+                           ResOperation(rop.FINISH, [self.bres], None,
+                                        descr=BasicFailDescr(0))]
+            self.cpu.compile_loop(inputargs, self.oplist, self.looptoken)
+
+            # add to the cache
+            cache.append(_Func(self.args_type, self.res_type, self.looptoken,
+                               self.oplist))
 
     def call(self):
-        inputargs = [self.bfuncaddr] + self.bargs
-
-        oplist = [ResOperation(rop.CALL, inputargs, self.bres,
-                               descr=self.calldescr),
-                  ResOperation(rop.FINISH, [self.bres], None,
-                               descr=BasicFailDescr(0))]
-        looptoken = LoopToken()
-        self.cpu.compile_loop(inputargs, oplist, looptoken)
-        self.cpu.set_future_value_int(0, self.bfuncaddr.getint())
+        self.push_funcaddr(self.funcaddr)
 
-        res = self.cpu.execute_token(looptoken)
-        if res is oplist[-1].descr:
+        res = self.cpu.execute_token(self.looptoken)
+        if res is self.oplist[-1].descr:
             self.guard_failed = False
         else:
             self.guard_failed = True
@@ -107,19 +128,27 @@
 
     def setup_stack(self):
         self.bargs = []
-        self.esp = 1 # 0 is a func addr
+        self.esp = 1 # 0 is funcaddr
+
+    def push_funcaddr(self, value):
+        self.cpu.set_future_value_int(0, value)
+        self.esp += 1
 
     def push_int(self, value):
         self.cpu.set_future_value_int(self.esp, value)
-        self.bargs.append(BoxInt(value))
         self.esp += 1
 
     def push_float(self, value):
         self.cpu.set_future_value_float(self.esp, value)
-        self.bargs.append(BoxFloat(value))
         self.esp += 1
 
     def push_ref(self, value):
         self.cpu.set_future_value_ref(self.esp, value)
-        self.bargs.append(BoxPtr(value))
         self.esp += 1
+
+class _Func(object):
+    def __init__(self, args_type, res_type, looptoken, oplist):
+        self.args_type = args_type
+        self.res_type = res_type
+        self.looptoken = looptoken
+        self.oplist = oplist



More information about the Pypy-commit mailing list