[pypy-svn] r21009 - in pypy/dist/pypy: interpreter objspace

ac at codespeak.net ac at codespeak.net
Sat Dec 10 17:40:29 CET 2005


Author: ac
Date: Sat Dec 10 17:40:28 2005
New Revision: 21009

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/eval.py
   pypy/dist/pypy/interpreter/gateway.py
   pypy/dist/pypy/interpreter/pycode.py
   pypy/dist/pypy/objspace/descroperation.py
Log:
(arre, eric) Fully implement fastcall for applevel functions.


Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Sat Dec 10 17:40:28 2005
@@ -464,19 +464,29 @@
         # XXX start of hack for performance
         from pypy.interpreter.function import Function
         if isinstance(w_func, Function):
-            if len(args_w) == 1:
+            if len(args_w) == 0:
+                w_res = w_func.code.fastcall_0(self, w_func)
+                if w_res is not None:
+                    return w_res
+            elif len(args_w) == 1:
                 w_res = w_func.code.fastcall_1(self, w_func, args_w[0])
                 if w_res is not None:
                     return w_res
             elif len(args_w) == 2:
-                w_res = w_func.code.fastcall_2(self, args_w[0], args_w[1])
+                w_res = w_func.code.fastcall_2(self, w_func, args_w[0],
+                                               args_w[1])
                 if w_res is not None:
                     return w_res
             elif len(args_w) == 3:
-                w_res = w_func.code.fastcall_3(self, args_w[0],
+                w_res = w_func.code.fastcall_3(self, w_func, args_w[0],
                                                args_w[1], args_w[2])
                 if w_res is not None:
                     return w_res
+            elif len(args_w) == 4:
+                w_res = w_func.code.fastcall_4(self, w_func, args_w[0],
+                                               args_w[1], args_w[2], args_w[3])
+                if w_res is not None:
+                    return w_res
             args = Arguments(self, list(args_w))
             return w_func.call_args(args)
         # XXX end of hack for performance

Modified: pypy/dist/pypy/interpreter/eval.py
==============================================================================
--- pypy/dist/pypy/interpreter/eval.py	(original)
+++ pypy/dist/pypy/interpreter/eval.py	Sat Dec 10 17:40:28 2005
@@ -50,12 +50,16 @@
     def getdocstring(self):
         return None
 
-    # a performance hack (see gateway.BuiltinCode1/2/3)
+    # a performance hack (see gateway.BuiltinCode1/2/3 and pycode.PyCode)
+    def fastcall_0(self, space, func):
+        return None
     def fastcall_1(self, space, func, w1):
         return None
-    def fastcall_2(self, space, w1, w2):
+    def fastcall_2(self, space, func, w1, w2):
+        return None
+    def fastcall_3(self, space, func, w1, w2, w3):
         return None
-    def fastcall_3(self, space, w1, w2, w3):
+    def fastcall_4(self, space, func, w1, w2, w3, w4):
         return None
 
 class Frame(Wrappable):

Modified: pypy/dist/pypy/interpreter/gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/gateway.py	(original)
+++ pypy/dist/pypy/interpreter/gateway.py	Sat Dec 10 17:40:28 2005
@@ -415,6 +415,9 @@
         self.framefactory = make_builtin_frame_factory(func, orig_sig, unwrap_spec)
 
         # speed hack
+        if unwrap_spec == [ObjSpace]:
+            self.__class__ = BuiltinCode0
+            self.fastfunc_0 = func
         if unwrap_spec == [ObjSpace, W_Root]:
             self.__class__ = BuiltinCode1
             self.fastfunc_1 = func
@@ -424,6 +427,9 @@
         elif unwrap_spec == [ObjSpace, W_Root, W_Root, W_Root]:
             self.__class__ = BuiltinCode3
             self.fastfunc_3 = func
+        elif unwrap_spec == [ObjSpace, W_Root, W_Root, W_Root, W_Root]:
+            self.__class__ = BuiltinCode4
+            self.fastfunc_4 = func
 
     def create_frame(self, space, w_globals, closure=None):
         return self.framefactory.create(space, self, w_globals)
@@ -437,6 +443,21 @@
 
 # (verbose) performance hack below
 
+class BuiltinCode0(BuiltinCode):
+    def fastcall_0(self, space, w_func):
+        try:
+            w_result = self.fastfunc_0(space)
+        except KeyboardInterrupt: 
+            raise OperationError(space.w_KeyboardInterrupt, space.w_None) 
+        except MemoryError: 
+            raise OperationError(space.w_MemoryError, space.w_None) 
+        except RuntimeError, e: 
+            raise OperationError(space.w_RuntimeError, 
+                                 space.wrap("internal error: " + str(e))) 
+        if w_result is None:
+            w_result = space.w_None
+        return w_result
+
 class BuiltinCode1(BuiltinCode):
     def fastcall_1(self, space, w_func, w1):
         try:
@@ -453,7 +474,7 @@
         return w_result
 
 class BuiltinCode2(BuiltinCode):
-    def fastcall_2(self, space, w1, w2):
+    def fastcall_2(self, space, w_func, w1, w2):
         try:
             w_result = self.fastfunc_2(space, w1, w2)
         except KeyboardInterrupt: 
@@ -468,7 +489,7 @@
         return w_result
 
 class BuiltinCode3(BuiltinCode):
-    def fastcall_3(self, space, w1, w2, w3):
+    def fastcall_3(self, space, func, w1, w2, w3):
         try:
             w_result = self.fastfunc_3(space, w1, w2, w3)
         except KeyboardInterrupt: 
@@ -482,6 +503,21 @@
             w_result = space.w_None
         return w_result
 
+class BuiltinCode4(BuiltinCode):
+    def fastcall_4(self, space, func, w1, w2, w3, w4):
+        try:
+            w_result = self.fastfunc_4(space, w1, w2, w3, w4)
+        except KeyboardInterrupt: 
+            raise OperationError(space.w_KeyboardInterrupt, space.w_None) 
+        except MemoryError: 
+            raise OperationError(space.w_MemoryError, space.w_None) 
+        except RuntimeError, e: 
+            raise OperationError(space.w_RuntimeError, 
+                                 space.wrap("internal error: " + str(e))) 
+        if w_result is None:
+            w_result = space.w_None
+        return w_result
+
 
 class interp2app(Wrappable):
     """Build a gateway that calls 'f' at interp-level."""

Modified: pypy/dist/pypy/interpreter/pycode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycode.py	(original)
+++ pypy/dist/pypy/interpreter/pycode.py	Sat Dec 10 17:40:28 2005
@@ -158,12 +158,6 @@
         self._compute_fastcall()
         return self
 
-    def _compute_fastcall(self):
-        # Speed hack!
-        self.do_fastcall = -1
-        if self.co_flags & (CO_VARARGS | CO_VARKEYWORDS) == 0:
-            if self.co_argcount == 1:
-                self.do_fastcall = 1
         
     def _from_code(self, code, hidden_applevel=False, from_cpython=True):
         """ Initialize the code object from a real (CPython) one.
@@ -223,13 +217,65 @@
         self._compute_fastcall()
         return self
 
+    def _compute_fastcall(self):
+        # Speed hack!
+        self.do_fastcall = -1
+        if not (0 <= self.co_argcount <= 4):
+            return
+        if self.co_flags & (CO_VARARGS | CO_VARKEYWORDS):
+            return
+        if self.co_cellvars:
+            first_cellvar = self.co_cellvars[0]
+            for i in range(self.co_argcount):
+                if first_cellvar == self.co_varnames[i]:
+                    return
+
+        self.do_fastcall = self.co_argcount
+
+    def fastcall_0(self, space, w_func):
+        if self.do_fastcall == 0:
+            frame = self.create_frame(space, w_func.w_func_globals,
+                                      w_func.closure)
+            return frame.run()
+        return None
+
     def fastcall_1(self, space, w_func, w_arg):
-        if self.do_fastcall != 1:
-            return None
-        frame = self.create_frame(space, w_func.w_func_globals,
-                                       w_func.closure)
-        frame.setfastscope([w_arg])
-        return frame.run()
+        if self.do_fastcall == 1:
+            frame = self.create_frame(space, w_func.w_func_globals,
+                                      w_func.closure)
+            frame.fastlocals_w[0] = w_arg # frame.setfastscope([w_arg])
+            return frame.run()
+        return None
+
+    def fastcall_2(self, space, w_func, w_arg1, w_arg2):
+        if self.do_fastcall == 2:
+            frame = self.create_frame(space, w_func.w_func_globals,
+                                      w_func.closure)
+            frame.fastlocals_w[0] = w_arg1 # frame.setfastscope([w_arg])
+            frame.fastlocals_w[1] = w_arg2
+            return frame.run()
+        return None
+
+    def fastcall_3(self, space, w_func, w_arg1, w_arg2, w_arg3):
+        if self.do_fastcall == 3:
+            frame = self.create_frame(space, w_func.w_func_globals,
+                                      w_func.closure)
+            frame.fastlocals_w[0] = w_arg1 # frame.setfastscope([w_arg])
+            frame.fastlocals_w[1] = w_arg2 
+            frame.fastlocals_w[2] = w_arg3 
+            return frame.run()
+        return None
+
+    def fastcall_4(self, space, w_func, w_arg1, w_arg2, w_arg3, w_arg4):
+        if self.do_fastcall == 4:
+            frame = self.create_frame(space, w_func.w_func_globals,
+                                      w_func.closure)
+            frame.fastlocals_w[0] = w_arg1 # frame.setfastscope([w_arg])
+            frame.fastlocals_w[1] = w_arg2 
+            frame.fastlocals_w[2] = w_arg3 
+            frame.fastlocals_w[3] = w_arg4 
+            return frame.run()
+        return None
 
     def create_frame(self, space, w_globals, closure=None):
         "Create an empty PyFrame suitable for this code object."

Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py	(original)
+++ pypy/dist/pypy/objspace/descroperation.py	Sat Dec 10 17:40:28 2005
@@ -89,14 +89,19 @@
                 if w_res is not None:
                     return w_res
             elif len(args_w) == 1:
-                w_res = descr.code.fastcall_2(space, w_obj, args_w[0])
+                w_res = descr.code.fastcall_2(space, descr, w_obj, args_w[0])
                 if w_res is not None:
                     return w_res
             elif len(args_w) == 2:
-                w_res = descr.code.fastcall_3(space, w_obj, args_w[0],
+                w_res = descr.code.fastcall_3(space, descr, w_obj, args_w[0],
                                                             args_w[1])
                 if w_res is not None:
                     return w_res
+            elif len(args_w) == 3:
+                w_res = descr.code.fastcall_4(space, descr, w_obj, args_w[0],
+                                              args_w[1], args_w[2])
+                if w_res is not None:
+                    return w_res
             args = Arguments(space, list(args_w))
             return descr.call_args(args.prepend(w_obj))
         else:



More information about the Pypy-commit mailing list