[pypy-svn] r37933 - in pypy/branch/jit-virtual-world/pypy: interpreter module/pypyjit module/pypyjit/test
arigo at codespeak.net
arigo at codespeak.net
Sun Feb 4 23:14:52 CET 2007
Author: arigo
Date: Sun Feb 4 23:14:50 2007
New Revision: 37933
Modified:
pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py
pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py
pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py
Log:
(pedronis, arigo)
Fixes in the colors in the bytecode dispatch loop. This now threads
next_instr as a green all around.
Freeze the table used by COMPARE_OP. Grab the fastlocals_w and make it
virtual. Add an assert in STORE_FAST to ensure that LOAD_FAST knows in
the common case that it won't fail with UnboundLocalError.
Modified: pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py (original)
+++ pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py Sun Feb 4 23:14:50 2007
@@ -10,7 +10,7 @@
from pypy.interpreter import gateway, function, eval
from pypy.interpreter import pyframe, pytraceback
from pypy.interpreter.argument import Arguments
-from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.pycode import PyCode, CO_VARARGS, CO_VARKEYWORDS
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib.objectmodel import we_are_translated, hint
from pypy.rlib.rarithmetic import r_uint, intmask
@@ -53,21 +53,51 @@
def dispatch(self, pycode, next_instr, ec):
if JITTING:
hint(None, global_merge_point=True)
-
+ pycode = hint(pycode, deepfreeze=True)
# *loads* of nonsense for now
- stuff = self.valuestackdepth
- if len(self.blockstack):
- stuff |= (-sys.maxint-1)
-
- stuff = hint(stuff, promote=True)
- if stuff >= 0:
- # blockdepth == 0, common case
+
+ fastlocals_w = [None] * pycode.co_nlocals
+
+ if next_instr == 0:
+ # first time we enter this function
+ depth = 0
self.blockstack = []
- depth = stuff & sys.maxint
- pycode = hint(pycode, deepfreeze=True)
+ numargs = pycode.co_argcount
+ if pycode.co_flags & CO_VARARGS: numargs += 1
+ if pycode.co_flags & CO_VARKEYWORDS: numargs += 1
+ while True:
+ numargs -= 1
+ if numargs < 0:
+ break
+ hint(numargs, concrete=True)
+ w_obj = self.fastlocals_w[numargs]
+ assert w_obj is not None
+ fastlocals_w[numargs] = w_obj
+
+ else:
+ stuff = self.valuestackdepth
+ if len(self.blockstack):
+ stuff |= (-sys.maxint-1)
+
+ stuff = hint(stuff, promote=True)
+ if stuff >= 0:
+ # blockdepth == 0, common case
+ self.blockstack = []
+ depth = stuff & sys.maxint
+
+ i = pycode.co_nlocals
+ while True:
+ i -= 1
+ if i < 0:
+ break
+ hint(i, concrete=True)
+ w_obj = self.fastlocals_w[i]
+ fastlocals_w[i] = w_obj
+
self.pycode = pycode
self.valuestackdepth = depth
+ self.fastlocals_w = fastlocals_w
virtualstack_w = [None] * pycode.co_stacksize
while depth > 0:
@@ -93,6 +123,12 @@
# returns=w_result)
except Return:
w_result = self.popvalue()
+ if JITTING:
+ self.blockstack = None
+ self.valuestack_w = None
+ return w_result
+ except Yield:
+ w_result = self.popvalue()
return w_result
except OperationError, operr:
next_instr = self.handle_operation_error(ec, operr)
@@ -116,7 +152,6 @@
next_instr = self.handle_asynchronous_error(ec,
self.space.w_RuntimeError,
self.space.wrap(msg))
- next_instr = hint(next_instr, promote=True)
def handle_asynchronous_error(self, ec, w_type, w_value=None):
# catch asynchronous exceptions and turn them
@@ -185,12 +220,11 @@
else:
unroller = SReturnValue(w_returnvalue)
next_instr = block.handle(self, unroller)
- #next_instr = hint(next_instr, promote=True)
return next_instr # now inside a 'finally' block
if opcode == opcodedesc.YIELD_VALUE.index:
#self.last_instr = intmask(next_instr - 1) XXX clean up!
- raise Return
+ raise Yield
if opcode == opcodedesc.END_FINALLY.index:
unroller = self.end_finally()
@@ -203,7 +237,6 @@
raise Return
else:
next_instr = block.handle(self, unroller)
- #next_instr = hint(next_instr, promote=True)
return next_instr
if we_are_translated():
@@ -225,7 +258,6 @@
# Instead, it's constant-folded to either True or False
if res is not None:
next_instr = res
- #next_instr = hint(next_instr, promote=True)
break
else:
self.MISSING_OPCODE(oparg, next_instr)
@@ -296,6 +328,7 @@
def STORE_FAST(f, varindex, *ignored):
w_newvalue = f.popvalue()
+ assert w_newvalue is not None
f.fastlocals_w[varindex] = w_newvalue
#except:
# print "exception: got index error"
@@ -719,8 +752,9 @@
def COMPARE_OP(f, testnum, *ignored):
w_2 = f.popvalue()
w_1 = f.popvalue()
+ table = hint(f.compare_dispatch_table, deepfreeze=True)
try:
- testfn = f.compare_dispatch_table[testnum]
+ testfn = table[testnum]
except IndexError:
raise BytecodeCorruption, "bad COMPARE_OP oparg"
w_result = testfn(f, w_1, w_2)
@@ -949,6 +983,8 @@
class Return(Exception):
"""Obscure."""
+class Yield(Exception):
+ """Obscure."""
class BytecodeCorruption(Exception):
"""Detected bytecode corruption. Never caught; it's an error."""
@@ -1068,13 +1104,17 @@
return space.newtuple([w(self._opname), w(self.handlerposition),
w(self.valuestackdepth)])
+ def handle(self, frame, unroller):
+ next_instr = self.really_handle(frame, unroller) # JIT hack
+ return hint(next_instr, promote=True)
+
class LoopBlock(FrameBlock):
"""A loop block. Stores the end-of-loop pointer in case of 'break'."""
_opname = 'SETUP_LOOP'
handling_mask = SBreakLoop.kind | SContinueLoop.kind
- def handle(self, frame, unroller):
+ def really_handle(self, frame, unroller):
if isinstance(unroller, SContinueLoop):
# re-push the loop block without cleaning up the value stack,
# and jump to the beginning of the loop, stored in the
@@ -1093,7 +1133,7 @@
_opname = 'SETUP_EXCEPT'
handling_mask = SApplicationException.kind
- def handle(self, frame, unroller):
+ def really_handle(self, frame, unroller):
# push the exception to the value stack for inspection by the
# exception handler (the code after the except:)
self.cleanupstack(frame)
@@ -1127,7 +1167,7 @@
frame.pushvalue(frame.space.w_None)
frame.pushvalue(frame.space.w_None)
- def handle(self, frame, unroller):
+ def really_handle(self, frame, unroller):
# any abnormal reason for unrolling a finally: triggers the end of
# the block unrolling and the entering the finally: handler.
# see comments in cleanup().
Modified: pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py (original)
+++ pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py Sun Feb 4 23:14:50 2007
@@ -43,6 +43,10 @@
else:
return super_dispatch(self, pycode, next_instr, ec)
+ def CALL_FUNCTION(f, oparg, *ignored):
+ # XXX disable the call_valuestack hacks which are bad for the JIT
+ return f.call_function(oparg)
+
setup()
PORTAL = PyFrame.dispatch_jit
Modified: pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py (original)
+++ pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py Sun Feb 4 23:14:50 2007
@@ -16,3 +16,13 @@
assert f(6, 7) == 43
pypyjit.enable(f.func_code)
assert f(6, 7) == 43
+
+ def gen(x):
+ i = 0
+ while i < x:
+ yield i*i
+ i += 1
+
+ assert list(gen(3)) == [0, 1, 4]
+ pypyjit.enable(gen.func_code)
+ assert list(gen(3)) == [0, 1, 4]
More information about the Pypy-commit
mailing list