[pypy-svn] r49851 - pypy/dist/pypy/interpreter

arigo at codespeak.net arigo at codespeak.net
Sun Dec 16 17:46:13 CET 2007


Author: arigo
Date: Sun Dec 16 17:46:11 2007
New Revision: 49851

Modified:
   pypy/dist/pypy/interpreter/executioncontext.py
   pypy/dist/pypy/interpreter/pyopcode.py
Log:
Tweak inlining in the main interpreter loop.  Gives good speed-ups.


Modified: pypy/dist/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/dist/pypy/interpreter/executioncontext.py	(original)
+++ pypy/dist/pypy/interpreter/executioncontext.py	Sun Dec 16 17:46:11 2007
@@ -99,24 +99,22 @@
 
     def bytecode_trace(self, frame):
         "Trace function called before each bytecode."
-        # XXX there should be some flag here which checks whether
-        #     this should be really invoked. We spend roughly 0.5% time
-        #     here when not doing anything
-        # First, call yield_thread() before each Nth bytecode,
-        #     as selected by sys.setcheckinterval()
-        ticker = self.ticker
-        if ticker <= 0:
+        # this is split into a fast path and a slower path that is
+        # not invoked every time bytecode_trace() is.
+        ticker = self.ticker - 1
+        self.ticker = ticker
+        if ticker < 0 or frame.w_f_trace is not None:
+            self._do_bytecode_trace(frame)
+    bytecode_trace.always_inline = True
+
+    def _do_bytecode_trace(self, frame):
+        if self.ticker < 0:
             Action.perform_actions(self.space.pending_actions)
             Action.perform_actions(self.pending_actions)
-            ticker = self.space.sys.checkinterval
-        self.ticker = ticker - 1
+            self.ticker = self.space.sys.checkinterval
         if frame.w_f_trace is None or self.is_tracing:
             return
-        self._do_bytecode_trace(frame)
-
-
-    def _do_bytecode_trace(self, frame):
-        code = getattr(frame, 'pycode')
+        code = frame.pycode
         if frame.instr_lb <= frame.last_instr < frame.instr_ub:
             if frame.last_instr <= frame.instr_prev:
                 # We jumped backwards in the same line.

Modified: pypy/dist/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyopcode.py	(original)
+++ pypy/dist/pypy/interpreter/pyopcode.py	Sun Dec 16 17:46:11 2007
@@ -283,11 +283,15 @@
         # access a local variable directly
         w_value = f.fastlocals_w[varindex]
         if w_value is None:
-            varname = f.getlocalvarname(varindex)
-            message = "local variable '%s' referenced before assignment" % varname
-            raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message))
+            f._load_fast_failed(varindex)
         f.pushvalue(w_value)
 
+    def _load_fast_failed(f, varindex):
+        varname = f.getlocalvarname(varindex)
+        message = "local variable '%s' referenced before assignment" % varname
+        raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message))
+    _load_fast_failed.dont_inline = True
+
     def LOAD_CONST(f, constindex, *ignored):
         w_const = f.getconstant_w(constindex)
         f.pushvalue(w_const)
@@ -639,14 +643,20 @@
             # not in the globals, now look in the built-ins
             w_value = f.get_builtin().getdictvalue(f.space, w_varname)
             if w_value is None:
-                varname = f.space.str_w(w_varname)
-                message = "global name '%s' is not defined" % varname
-                raise OperationError(f.space.w_NameError,
-                                     f.space.wrap(message))
+                f._load_global_failed(w_varname)
         return w_value
+    _load_global.always_inline = True
+
+    def _load_global_failed(f, w_varname):
+        varname = f.space.str_w(w_varname)
+        message = "global name '%s' is not defined" % varname
+        raise OperationError(f.space.w_NameError,
+                             f.space.wrap(message))
+    _load_global_failed.dont_inline = True
 
     def LOAD_GLOBAL(f, nameindex, *ignored):
         f.pushvalue(f._load_global(f.getname_w(nameindex)))
+    LOAD_GLOBAL.always_inline = True
 
     def DELETE_FAST(f, varindex, *ignored):
         if f.fastlocals_w[varindex] is None:
@@ -678,6 +688,7 @@
         w_obj = f.popvalue()
         w_value = f.space.getattr(w_obj, w_attributename)
         f.pushvalue(w_value)
+    LOAD_ATTR.always_inline = True
 
     def cmp_lt(f, w_1, w_2):  return f.space.lt(w_1, w_2)
     def cmp_le(f, w_1, w_2):  return f.space.le(w_1, w_2)



More information about the Pypy-commit mailing list