[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