[pypy-svn] r51248 - in pypy/branch/jit-refactoring/pypy/jit/rainbow: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Mon Feb 4 13:18:51 CET 2008
Author: cfbolz
Date: Mon Feb 4 13:18:51 2008
New Revision: 51248
Added:
pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
- copied, changed from r51237, pypy/branch/jit-refactoring/pypy/jit/rainbow/bytecode.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py (contents, props changed)
Removed:
pypy/branch/jit-refactoring/pypy/jit/rainbow/bytecode.py
Modified:
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py
Log:
split the codewriter into its own file
Added: pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py Mon Feb 4 13:18:51 2008
@@ -0,0 +1,327 @@
+from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.unroll import unrolling_iterable
+from pypy.jit.timeshifter import rtimeshift
+from pypy.jit.timeshifter.greenkey import empty_key, GreenKey
+from pypy.rpython.lltypesystem import lltype
+
+class JitCode(object):
+ """
+ normal operations have the following format:
+ 2 byte - operation
+ n * 2 byte - arguments
+
+ for nonvoid results the result is appended to the varlist
+
+ red vars are just indexes
+ green vars are positive indexes
+ green consts are negative indexes
+ """
+
+ def __init__(self, name, code, constants, typekinds, redboxclasses,
+ keydescs, called_bytecodes, num_mergepoints, graph_color,
+ nonrainbow_functions, is_portal):
+ self.name = name
+ self.code = code
+ self.constants = constants
+ self.typekinds = typekinds
+ self.redboxclasses = redboxclasses
+ self.keydescs = keydescs
+ self.called_bytecodes = called_bytecodes
+ self.num_mergepoints = num_mergepoints
+ self.graph_color = graph_color
+ self.nonrainbow_functions = nonrainbow_functions
+ self.is_portal = is_portal
+
+ def _freeze_(self):
+ return True
+
+SIGN_EXTEND2 = 1 << 15
+
+class STOP(object):
+ pass
+STOP = STOP()
+
+class JitInterpreter(object):
+ def __init__(self):
+ self.opcode_implementations = []
+ self.opcode_descs = []
+ self.opname_to_index = {}
+ self.jitstate = None
+ self.queue = None
+ self._add_implemented_opcodes()
+
+ def run(self, jitstate, bytecode, greenargs, redargs,
+ start_bytecode_loop=True):
+ self.jitstate = jitstate
+ self.queue = rtimeshift.DispatchQueue(bytecode.num_mergepoints)
+ rtimeshift.enter_frame(self.jitstate, self.queue)
+ self.frame = self.jitstate.frame
+ self.frame.pc = 0
+ self.frame.bytecode = bytecode
+ self.frame.local_boxes = redargs
+ self.frame.local_green = greenargs
+ if start_bytecode_loop:
+ self.bytecode_loop()
+ return self.jitstate
+
+ def bytecode_loop(self):
+ while 1:
+ bytecode = self.load_2byte()
+ assert bytecode >= 0
+ result = self.opcode_implementations[bytecode](self)
+ if result is STOP:
+ return
+ else:
+ assert result is None
+
+ def dispatch(self):
+ is_portal = self.frame.bytecode.is_portal
+ graph_color = self.frame.bytecode.graph_color
+ queue = self.queue
+ newjitstate = rtimeshift.dispatch_next(queue)
+ resumepoint = rtimeshift.getresumepoint(newjitstate)
+ self.newjitstate(newjitstate)
+ if resumepoint == -1:
+ if graph_color == "red":
+ newjitstate = rtimeshift.leave_graph_red(
+ queue, is_portal)
+ elif graph_color == "yellow":
+ newjitstate = rtimeshift.leave_graph_yellow(queue)
+ elif graph_color == "green":
+ assert 0, "green graphs shouldn't be seen by the rainbow interp"
+ elif graph_color == "gray":
+ assert not is_portal
+ newjitstate = rtimeshift.leave_graph_gray(queue)
+ else:
+ assert 0, "unknown graph color %s" % (graph_color, )
+
+ self.newjitstate(newjitstate)
+ if self.frame is None:
+ return STOP
+ else:
+ self.frame.pc = resumepoint
+
+ # operation helper functions
+
+ def load_2byte(self):
+ pc = self.frame.pc
+ assert pc >= 0
+ result = ((ord(self.frame.bytecode.code[pc]) << 8) |
+ ord(self.frame.bytecode.code[pc + 1]))
+ self.frame.pc = pc + 2
+ return intmask((result ^ SIGN_EXTEND2) - SIGN_EXTEND2)
+
+ def load_4byte(self):
+ pc = self.frame.pc
+ assert pc >= 0
+ result = ((ord(self.frame.bytecode.code[pc + 0]) << 24) |
+ (ord(self.frame.bytecode.code[pc + 1]) << 16) |
+ (ord(self.frame.bytecode.code[pc + 2]) << 8) |
+ (ord(self.frame.bytecode.code[pc + 3]) << 0))
+ self.frame.pc = pc + 4
+ return intmask(result)
+
+ def get_greenarg(self):
+ i = self.load_2byte()
+ if i < 0:
+ return self.frame.bytecode.constants[~i]
+ return self.frame.local_green[i]
+
+ def get_green_varargs(self):
+ greenargs = []
+ num = self.load_2byte()
+ for i in range(num):
+ greenargs.append(self.get_greenarg())
+ return greenargs
+
+ def get_red_varargs(self):
+ redargs = []
+ num = self.load_2byte()
+ for i in range(num):
+ redargs.append(self.get_redarg())
+ return redargs
+
+ def get_redarg(self):
+ return self.frame.local_boxes[self.load_2byte()]
+
+ def red_result(self, box):
+ self.frame.local_boxes.append(box)
+
+ def green_result(self, gv):
+ self.frame.local_green.append(gv)
+
+ def newjitstate(self, newjitstate):
+ self.jitstate = newjitstate
+ self.queue = None
+ if newjitstate is not None:
+ frame = newjitstate.frame
+ self.frame = frame
+ if frame is not None:
+ self.queue = frame.dispatchqueue
+ else:
+ self.frame = None
+
+ # operation implementations
+ def opimpl_make_redbox(self):
+ genconst = self.get_greenarg()
+ typeindex = self.load_2byte()
+ kind = self.frame.bytecode.typekinds[typeindex]
+ redboxcls = self.frame.bytecode.redboxclasses[typeindex]
+ self.red_result(redboxcls(kind, genconst))
+
+ def opimpl_goto(self):
+ target = self.load_4byte()
+ self.frame.pc = target
+
+ def opimpl_green_goto_iftrue(self):
+ genconst = self.get_greenarg()
+ target = self.load_4byte()
+ arg = genconst.revealconst(lltype.Bool)
+ if arg:
+ self.frame.pc = target
+
+ def opimpl_red_goto_iftrue(self):
+ switchbox = self.get_redarg()
+ target = self.load_4byte()
+ # XXX not sure about passing no green vars
+ descision = rtimeshift.split(self.jitstate, switchbox, self.frame.pc)
+ if descision:
+ self.frame.pc = target
+
+ def opimpl_red_return(self):
+ rtimeshift.save_return(self.jitstate)
+ return self.dispatch()
+
+ def opimpl_gray_return(self):
+ rtimeshift.save_return(self.jitstate)
+ return self.dispatch()
+
+ def opimpl_yellow_return(self):
+ # save the greens to make the return value findable by collect_split
+ rtimeshift.save_greens(self.jitstate, self.frame.local_green)
+ rtimeshift.save_return(self.jitstate)
+ return self.dispatch()
+
+ def opimpl_make_new_redvars(self):
+ self.frame.local_boxes = self.get_red_varargs()
+
+ def opimpl_make_new_greenvars(self):
+ # an opcode with a variable number of args
+ # num_args arg_old_1 arg_new_1 ...
+ num = self.load_2byte()
+ if num == 0 and len(self.frame.local_green) == 0:
+ # fast (very common) case
+ return
+ newgreens = []
+ for i in range(num):
+ newgreens.append(self.get_greenarg())
+ self.frame.local_green = newgreens
+
+ def opimpl_merge(self):
+ mergepointnum = self.load_2byte()
+ keydescnum = self.load_2byte()
+ if keydescnum == -1:
+ key = empty_key
+ else:
+ keydesc = self.frame.bytecode.keydescs[keydescnum]
+ key = GreenKey(self.frame.local_green[:keydesc.nb_vals], keydesc)
+ states_dic = self.queue.local_caches[mergepointnum]
+ done = rtimeshift.retrieve_jitstate_for_merge(states_dic, self.jitstate,
+ key, None)
+ if done:
+ return self.dispatch()
+
+ def opimpl_red_direct_call(self):
+ greenargs = self.get_green_varargs()
+ redargs = self.get_red_varargs()
+ bytecodenum = self.load_2byte()
+ targetbytecode = self.frame.bytecode.called_bytecodes[bytecodenum]
+ self.run(self.jitstate, targetbytecode, greenargs, redargs,
+ start_bytecode_loop=False)
+ # this frame will be resumed later in the next bytecode, which is
+ # red_after_direct_call
+
+ def opimpl_red_after_direct_call(self):
+ newjitstate = rtimeshift.collect_split(
+ self.jitstate, self.frame.pc,
+ self.frame.local_green)
+ assert newjitstate is self.jitstate
+
+ def opimpl_green_direct_call(self):
+ greenargs = self.get_green_varargs()
+ redargs = self.get_red_varargs()
+ index = self.load_2byte()
+ function = self.frame.bytecode.nonrainbow_functions[index]
+ function(self, greenargs, redargs)
+
+ def opimpl_yellow_direct_call(self):
+ greenargs = self.get_green_varargs()
+ redargs = self.get_red_varargs()
+ bytecodenum = self.load_2byte()
+ targetbytecode = self.frame.bytecode.called_bytecodes[bytecodenum]
+ self.run(self.jitstate, targetbytecode, greenargs, redargs,
+ start_bytecode_loop=False)
+ # this frame will be resumed later in the next bytecode, which is
+ # yellow_after_direct_call
+
+ def opimpl_yellow_after_direct_call(self):
+ newjitstate = rtimeshift.collect_split(
+ self.jitstate, self.frame.pc,
+ self.frame.local_green)
+ assert newjitstate is self.jitstate
+
+ def opimpl_yellow_retrieve_result(self):
+ # XXX all this jitstate.greens business is a bit messy
+ self.green_result(self.jitstate.greens[0])
+
+
+ # ____________________________________________________________
+ # construction-time interface
+
+ def _add_implemented_opcodes(self):
+ for name in dir(self):
+ if not name.startswith("opimpl_"):
+ continue
+ opname = name[len("opimpl_"):]
+ self.opname_to_index[opname] = len(self.opcode_implementations)
+ self.opcode_implementations.append(getattr(self, name).im_func)
+ self.opcode_descs.append(None)
+
+ def find_opcode(self, name):
+ return self.opname_to_index.get(name, -1)
+
+ def make_opcode_implementation(self, color, opdesc):
+ numargs = unrolling_iterable(range(opdesc.nb_args))
+ if color == "green":
+ def implementation(self):
+ args = (opdesc.RESULT, )
+ for i in numargs:
+ genconst = self.get_greenarg()
+ arg = genconst.revealconst(opdesc.ARGS[i])
+ args += (arg, )
+ rgenop = self.jitstate.curbuilder.rgenop
+ result = rgenop.genconst(opdesc.llop(*args))
+ self.green_result(result)
+ elif color == "red":
+ if opdesc.nb_args == 1:
+ impl = rtimeshift.ll_gen1
+ elif opdesc.nb_args == 2:
+ impl = rtimeshift.ll_gen2
+ else:
+ XXX
+ def implementation(self):
+ args = (opdesc, self.jitstate, )
+ for i in numargs:
+ args += (self.get_redarg(), )
+ result = impl(*args)
+ self.red_result(result)
+ else:
+ assert 0, "unknown color"
+ implementation.func_name = "opimpl_%s_%s" % (color, opdesc.opname)
+ opname = "%s_%s" % (color, opdesc.opname)
+ index = self.opname_to_index[opname] = len(self.opcode_implementations)
+ self.opcode_implementations.append(implementation)
+ self.opcode_descs.append(opdesc)
+ return index
+
+
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py Mon Feb 4 13:18:51 2008
@@ -4,7 +4,7 @@
from pypy.jit.hintannotator.policy import StopAtXPolicy, HintAnnotatorPolicy
from pypy.jit.hintannotator.model import SomeLLAbstractConstant, OriginFlags
from pypy.jit.hintannotator.model import originalconcretetype
-from pypy.jit.rainbow.bytecode import BytecodeWriter, label, tlabel, assemble
+from pypy.jit.rainbow.codewriter import BytecodeWriter, label, tlabel, assemble
from pypy.jit.codegen.llgraph.rgenop import RGenOp as LLRGenOp
from pypy.jit.rainbow.test.test_serializegraph import AbstractSerializationTest
from pypy.jit.rainbow import bytecode
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py Mon Feb 4 13:18:51 2008
@@ -2,8 +2,8 @@
from pypy.jit.hintannotator.annotator import HintAnnotator
from pypy.jit.hintannotator.policy import StopAtXPolicy, HintAnnotatorPolicy
from pypy.jit.hintannotator.model import SomeLLAbstractConstant, OriginFlags
-from pypy.jit.rainbow.bytecode import BytecodeWriter, label, tlabel, assemble
from pypy.jit.codegen.llgraph.rgenop import RGenOp
+from pypy.jit.rainbow.codewriter import BytecodeWriter, label, tlabel, assemble
from pypy.rlib.jit import hint
from pypy import conftest
More information about the Pypy-commit
mailing list