[pypy-svn] r17086 - in pypy/dist/pypy: interpreter objspace
arigo at codespeak.net
arigo at codespeak.net
Tue Aug 30 17:08:58 CEST 2005
Author: arigo
Date: Tue Aug 30 17:08:54 2005
New Revision: 17086
Modified:
pypy/dist/pypy/interpreter/eval.py
pypy/dist/pypy/interpreter/gateway.py
pypy/dist/pypy/objspace/descroperation.py
Log:
Enormous speed increase following discussion with Samuele about how incredibly
indirect something like a space.add() between two integers actually is.
This introduces a rather isolated shortcut, which even makes sense when
reading the source of descroperation.py, where the non-shortcut case of
space.get_and_call_function() can be seen as a fall-back for the uncommon
general case.
Modified: pypy/dist/pypy/interpreter/eval.py
==============================================================================
--- pypy/dist/pypy/interpreter/eval.py (original)
+++ pypy/dist/pypy/interpreter/eval.py Tue Aug 30 17:08:54 2005
@@ -50,6 +50,10 @@
def getdocstring(self):
return None
+ fastcall_1 = None
+ fastcall_2 = None
+ fastcall_3 = None
+
class Frame(Wrappable):
"""A frame is an environment supporting the execution of a code object.
Abstract base class."""
Modified: pypy/dist/pypy/interpreter/gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/gateway.py (original)
+++ pypy/dist/pypy/interpreter/gateway.py Tue Aug 30 17:08:54 2005
@@ -396,6 +396,17 @@
self.framecls = make_builtin_frame_class(func, orig_sig, unwrap_spec)
+ # speed hack
+ if unwrap_spec == [ObjSpace, W_Root]:
+ self.__class__ = BuiltinCode1
+ self.fastfunc_1 = func
+ elif unwrap_spec == [ObjSpace, W_Root, W_Root]:
+ self.__class__ = BuiltinCode2
+ self.fastfunc_2 = func
+ elif unwrap_spec == [ObjSpace, W_Root, W_Root, W_Root]:
+ self.__class__ = BuiltinCode3
+ self.fastfunc_3 = func
+
def create_frame(self, space, w_globals, closure=None):
return self.framecls(space, self, w_globals)
@@ -405,6 +416,18 @@
def getdocstring(self):
return self.docstring
+class BuiltinCode1(BuiltinCode):
+ def fastcall_1(self, space, w1):
+ return self.fastfunc_1(space, w1)
+
+class BuiltinCode2(BuiltinCode):
+ def fastcall_2(self, space, w1, w2):
+ return self.fastfunc_2(space, w1, w2)
+
+class BuiltinCode3(BuiltinCode):
+ def fastcall_3(self, space, w1, w2, w3):
+ return self.fastfunc_3(space, w1, w2, w3)
+
class interp2app(Wrappable):
"""Build a gateway that calls 'f' at interp-level."""
Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py (original)
+++ pypy/dist/pypy/objspace/descroperation.py Tue Aug 30 17:08:54 2005
@@ -80,8 +80,29 @@
return space.call_args(w_impl, args)
def get_and_call_function(space, w_descr, w_obj, *args_w):
- args = Arguments(space, list(args_w))
- return space.get_and_call_args(w_descr, w_obj, args)
+ descr = space.interpclass_w(w_descr)
+ # a special case for performance and to avoid infinite recursion
+ if type(descr) is Function:
+ # the fastcall paths are purely for performance, but the resulting
+ # increase of speed is huge
+ if len(args_w) == 0:
+ fastcall_1 = descr.code.fastcall_1
+ if fastcall_1:
+ return fastcall_1(space, w_obj)
+ elif len(args_w) == 1:
+ fastcall_2 = descr.code.fastcall_2
+ if fastcall_2:
+ return fastcall_2(space, w_obj, args_w[0])
+ elif len(args_w) == 2:
+ fastcall_3 = descr.code.fastcall_3
+ if fastcall_3:
+ return fastcall_3(space, w_obj, args_w[0], args_w[1])
+ args = Arguments(space, list(args_w))
+ return descr.call_args(args.prepend(w_obj))
+ else:
+ args = Arguments(space, list(args_w))
+ w_impl = space.get(w_descr, w_obj)
+ return space.call_args(w_impl, args)
def call_args(space, w_obj, args):
# a special case for performance
More information about the Pypy-commit
mailing list