[pypy-svn] r51846 - in pypy/branch/jit-refactoring/pypy/jit: rainbow rainbow/test timeshifter
cfbolz at codespeak.net
cfbolz at codespeak.net
Mon Feb 25 13:36:08 CET 2008
Author: cfbolz
Date: Mon Feb 25 13:36:07 2008
New Revision: 51846
Modified:
pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py
pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py
pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py
Log:
implement residual red calls
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py Mon Feb 25 13:36:07 2008
@@ -1,6 +1,7 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.objectmodel import we_are_translated
from pypy.objspace.flow import model as flowmodel
+from pypy.rpython.annlowlevel import cachedtype
from pypy.rpython.lltypesystem import lltype
from pypy.jit.hintannotator.model import originalconcretetype
from pypy.jit.hintannotator import model as hintmodel
@@ -11,6 +12,49 @@
from pypy.translator.backendopt.removenoops import remove_same_as
+class CallDesc:
+ __metaclass__ = cachedtype
+
+ def __init__(self, RGenOp, FUNCTYPE, voidargs=()):
+ self.sigtoken = RGenOp.sigToken(FUNCTYPE.TO)
+ self.result_kind = RGenOp.kindToken(FUNCTYPE.TO.RESULT)
+ # xxx what if the result is virtualizable?
+ self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.TO.RESULT)
+ whatever_return_value = FUNCTYPE.TO.RESULT._defl()
+ numargs = len(FUNCTYPE.TO.ARGS)
+ argiter = unrolling_iterable(FUNCTYPE.TO.ARGS)
+ def green_call(interpreter, fnptr_gv, greenargs):
+ fnptr = fnptr_gv.revealconst(FUNCTYPE)
+ assert len(greenargs) + len(voidargs) == numargs
+ args = ()
+ j = 0
+ k = 0
+ for ARG in argiter:
+ if ARG == lltype.Void:
+ arg = voidargs[k]
+ # XXX terrible hack
+ if not we_are_translated():
+ arg._TYPE = lltype.Void
+ args += (arg, )
+ k += 1
+ else:
+ genconst = greenargs[j]
+ arg = genconst.revealconst(ARG)
+ args += (arg, )
+ j += 1
+ rgenop = interpreter.jitstate.curbuilder.rgenop
+ try:
+ result = rgenop.genconst(fnptr(*args))
+ except Exception, e:
+ XXX # set exception
+ return rgenop.genconst(whatever_return_value)
+ interpreter.green_result(result)
+ self.green_call = green_call
+
+ def _freeze_(self):
+ return True
+
+
class BytecodeWriter(object):
def __init__(self, t, hannotator, RGenOp):
self.translator = t
@@ -50,7 +94,7 @@
self.called_bytecodes = []
self.num_local_mergepoints = 0
self.graph_color = self.graph_calling_color(graph)
- self.nonrainbow_functions = []
+ self.calldescs = []
self.is_portal = is_portal
# mapping constant -> index in constants
self.const_positions = {}
@@ -81,7 +125,7 @@
# mapping graphs to index
self.graph_positions = {}
# mapping fnobjs to index
- self.nonrainbow_positions = {}
+ self.calldesc_positions = {}
self.graph = graph
self.mergepoint_set = {}
@@ -105,7 +149,7 @@
self.called_bytecodes,
self.num_local_mergepoints,
self.graph_color,
- self.nonrainbow_functions,
+ self.calldescs,
self.is_portal)
if is_portal:
self.finish_all_graphs()
@@ -347,8 +391,8 @@
def redvar_position(self, arg):
return self.redvar_positions[arg]
- def register_greenvar(self, arg, where=None):
- assert isinstance(arg, flowmodel.Variable)
+ def register_greenvar(self, arg, where=None, check=True):
+ assert isinstance(arg, flowmodel.Variable) or not check
if where is None:
where = self.free_green[self.current_block]
self.free_green[self.current_block] += 1
@@ -444,41 +488,14 @@
self.graph_positions[graph] = index
return index
- def nonrainbow_position(self, fnptr, *voidargs):
- fn = fnptr._obj
- key = fn, voidargs
- if key in self.nonrainbow_positions:
- return self.nonrainbow_positions[key]
- FUNCTYPE = lltype.typeOf(fn)
- argiter = unrolling_iterable(FUNCTYPE.ARGS)
- numargs = len(FUNCTYPE.ARGS)
- def call_normal_function(interpreter, greenargs):
- assert len(greenargs) + len(voidargs) == numargs
- args = ()
- j = 0
- k = 0
- for ARG in argiter:
- if ARG == lltype.Void:
- arg = voidargs[k]
- # XXX terrible hack
- if not we_are_translated():
- arg._TYPE = lltype.Void
- args += (arg, )
- k += 1
- else:
- genconst = greenargs[j]
- arg = genconst.revealconst(ARG)
- args += (arg, )
- j += 1
- rgenop = interpreter.jitstate.curbuilder.rgenop
- try:
- result = rgenop.genconst(fnptr(*args))
- except Exception, e:
- XXX # need to create a default result and set exception
- interpreter.green_result(result)
- result = len(self.nonrainbow_functions)
- self.nonrainbow_functions.append(call_normal_function)
- self.nonrainbow_positions[key] = result
+ def calldesc_position(self, FUNCTYPE, *voidargs):
+ key = FUNCTYPE, voidargs
+ if key in self.calldesc_positions:
+ return self.calldesc_positions[key]
+ result = len(self.calldescs)
+ self.calldescs.append(
+ CallDesc(self.RGenOp, FUNCTYPE, voidargs))
+ self.calldesc_positions[key] = result
return result
def interiordesc(self, op, PTRTYPE, nb_offsets):
@@ -584,12 +601,12 @@
pass
def serialize_op_direct_call(self, op):
- kind, exc = self.guess_call_kind(op)
- print op, kind, exc
+ kind, withexc = self.guess_call_kind(op)
+ print op, kind, withexc
if kind == "oopspec":
from pypy.jit.timeshifter.oop import Index
fnobj = op.args[0].value._obj
- oopspecdescindex = self.oopspecdesc_position(fnobj, exc)
+ oopspecdescindex = self.oopspecdesc_position(fnobj, withexc)
oopspecdesc = self.oopspecdescs[oopspecdescindex]
opargs = op.args[1:]
args_v = []
@@ -627,19 +644,42 @@
elif kind == "green":
voidargs = [const.value for const in op.args[1:]
if const.concretetype == lltype.Void]
- pos = self.nonrainbow_position(op.args[0].value, *voidargs)
+ fnptr = op.args[0]
+ pos = self.calldesc_position(lltype.typeOf(fnptr.value), *voidargs)
+ func = self.serialize_oparg("green", fnptr)
emitted_args = []
for v in op.args[1:]:
if v.concretetype != lltype.Void:
emitted_args.append(self.serialize_oparg("green", v))
self.emit("green_direct_call")
+ self.emit(func, pos)
self.emit(len(emitted_args))
self.emit(*emitted_args)
- self.emit(pos)
self.register_greenvar(op.result)
return
elif kind == "residual":
- XXX
+ fnptr = op.args[0]
+ pos = self.calldesc_position(lltype.typeOf(fnptr.value))
+ func = self.serialize_oparg("red", fnptr)
+ emitted_args = []
+ for v in op.args[1:]:
+ emitted_args.append(self.serialize_oparg("red", v))
+ self.emit("red_residual_direct_call")
+ self.emit(func, pos, withexc, len(emitted_args), *emitted_args)
+ self.register_redvar(op.result)
+ pos = self.register_redvar(("residual_flags_red", op.args[0]))
+ self.emit("promote")
+ self.emit(pos)
+ self.emit(self.promotiondesc_position(lltype.Signed))
+ self.register_greenvar(("residual_flags_green", op.args[0]), check=False)
+ self.emit("residual_fetch", True, pos)
+ return
+ elif kind == "rpyexc_raise":
+ emitted_args = []
+ for v in op.args[1:]:
+ emitted_args.append(self.serialize_oparg("red", v))
+ self.emit("setexception", *emitted_args)
+ return
targets = dict(self.graphs_from(op))
assert len(targets) == 1
targetgraph, = targets.values()
@@ -703,7 +743,7 @@
pass
def serialize_op_getfield(self, op):
- assert self.opcolor(op) == "red"
+ color = self.opcolor(op)
args = op.args
if args[0] == self.exceptiondesc.cexcdata:
# reading one of the exception boxes (exc_type or exc_value)
@@ -731,9 +771,11 @@
fielddescindex = self.fielddesc_position(PTRTYPE.TO, fieldname)
if fielddescindex == -1: # Void field
return
- self.emit("red_getfield", index, fielddescindex, deepfrozen)
- self.register_redvar(op.result)
-
+ self.emit("%s_getfield" % (color, ), index, fielddescindex, deepfrozen)
+ if color == "red":
+ self.register_redvar(op.result)
+ else:
+ self.register_greenvar(op.result)
def serialize_op_setfield(self, op):
args = op.args
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py Mon Feb 25 13:36:07 2008
@@ -21,7 +21,7 @@
keydescs, structtypedescs, fielddescs, arrayfielddescs,
interiordescs, oopspecdescs, promotiondescs,
called_bytecodes, num_mergepoints,
- graph_color, nonrainbow_functions, is_portal):
+ graph_color, calldescs, is_portal):
self.name = name
self.code = code
self.constants = constants
@@ -37,7 +37,7 @@
self.called_bytecodes = called_bytecodes
self.num_mergepoints = num_mergepoints
self.graph_color = graph_color
- self.nonrainbow_functions = nonrainbow_functions
+ self.calldescs = calldescs
self.is_portal = is_portal
def _freeze_(self):
@@ -71,7 +71,6 @@
if finaljitstate is not None:
interpreter.finish_jitstate(interpreter.portalstate.sigtoken)
-
def arguments(*argtypes, **kwargs):
result = kwargs.pop("returns", None)
assert not kwargs
@@ -107,9 +106,9 @@
elif argspec == "bytecode":
bytecodenum = self.load_2byte()
args += (self.frame.bytecode.called_bytecodes[bytecodenum], )
- elif argspec == "nonrainbow_function":
+ elif argspec == "calldesc":
index = self.load_2byte()
- function = self.frame.bytecode.nonrainbow_functions[index]
+ function = self.frame.bytecode.calldescs[index]
args += (function, )
elif argspec == "oopspec":
oopspecindex = self.load_2byte()
@@ -455,9 +454,9 @@
self.frame.local_green)
assert newjitstate is self.jitstate
- @arguments("green_varargs", "nonrainbow_function")
- def opimpl_green_direct_call(self, greenargs, function):
- function(self, greenargs)
+ @arguments("green", "calldesc", "green_varargs")
+ def opimpl_green_direct_call(self, fnptr_gv, calldesc, greenargs):
+ calldesc.green_call(self, fnptr_gv, greenargs)
@arguments("green_varargs", "red_varargs", "bytecode")
def opimpl_yellow_direct_call(self, greenargs, redargs, targetbytecode):
@@ -493,6 +492,24 @@
def opimpl_red_oopspec_call_3(self, oopspec, deepfrozen, arg1, arg2, arg3):
return oopspec.ll_handler(self.jitstate, oopspec, deepfrozen, arg1, arg2, arg3)
+ @arguments("red", "calldesc", "bool", "red_varargs")
+ def opimpl_red_residual_direct_call(self, funcbox, calldesc, withexc, redargs):
+ result = rtimeshift.gen_residual_call(self.jitstate, calldesc,
+ funcbox, redargs)
+ self.red_result(result)
+ if withexc:
+ exceptiondesc = self.exceptiondesc
+ else:
+ exceptiondesc = None
+ flagbox = rtimeshift.after_residual_call(self.jitstate,
+ exceptiondesc, True)
+ self.red_result(flagbox)
+
+ @arguments("bool", "red")
+ def opimpl_residual_fetch(self, check_forced, flagbox):
+ rtimeshift.residual_fetch(self.jitstate, self.exceptiondesc,
+ check_forced, flagbox)
+
# exceptions
@@ -513,6 +530,10 @@
def opimpl_write_excvalue(self, valuebox):
rtimeshift.setexcvaluebox(self.jitstate, valuebox)
+ @arguments("red", "red")
+ def opimpl_setexception(self, typebox, valuebox):
+ rtimeshift.setexception(self.jitstate, typebox, valuebox)
+
# structs and arrays
@arguments("structtypedesc", returns="red")
@@ -536,6 +557,11 @@
return rtimeshift.gengetfield(self.jitstate, deepfrozen, fielddesc,
structbox)
+ @arguments("red", "fielddesc", "bool", returns="green_from_red")
+ def opimpl_green_getfield(self, structbox, fielddesc, deepfrozen):
+ return rtimeshift.gengetfield(self.jitstate, deepfrozen, fielddesc,
+ structbox)
+
@arguments("red", "fielddesc", "red")
def opimpl_red_setfield(self, destbox, fielddesc, valuebox):
rtimeshift.gensetfield(self.jitstate, fielddesc, destbox,
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 25 13:36:07 2008
@@ -198,7 +198,8 @@
self.residual_graph = graph
if conftest.option.view:
graph.show()
- llinterp = LLInterpreter(self.rtyper)
+ llinterp = LLInterpreter(
+ self.rtyper, exc_data_ptr=writer.exceptiondesc.exc_data_ptr)
res = llinterp.eval_graph(graph, residualargs)
return res
@@ -236,6 +237,8 @@
assert count == expected_count
class SimpleTests(InterpretationTest):
+ small = True
+
def test_simple_fixed(self):
py.test.skip("green return")
def ll_function(x, y):
@@ -991,7 +994,6 @@
self.check_insns({})
def test_residual_red_call(self):
- py.test.skip("needs promote")
def g(x):
return x+1
@@ -1003,7 +1005,6 @@
self.check_insns(int_add=0)
def test_residual_red_call_with_exc(self):
- py.test.skip("needs promote")
def h(x):
if x > 0:
return x+1
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 25 13:36:07 2008
@@ -246,14 +246,15 @@
writer, jitcode = self.serialize(ll_function, [int])
assert jitcode.code == assemble(writer.interpreter,
- "green_direct_call", 1, 0, 0,
+ "green_direct_call", -1, 0, 1, 0,
"make_redbox", 1, 0,
"make_new_redvars", 1, 0,
"make_new_greenvars", 0,
"red_return")
assert jitcode.is_portal
assert len(jitcode.called_bytecodes) == 0
- assert len(jitcode.nonrainbow_functions) == 1
+ assert len(jitcode.calldescs) == 1
+ assert len(jitcode.constants) == 1
def test_yellow_call(self):
def ll_two(x):
Modified: pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py Mon Feb 25 13:36:07 2008
@@ -19,15 +19,17 @@
self.hash = lambda self: 0
self.compare = lambda self, other: True
- TARGETTYPES = []
- for TYPE in TYPES:
+ index_TYPE = []
+ for i, TYPE in enumerate(TYPES):
# XXX more cases?
TARGET = lltype.Signed
- if TYPE == lltype.Float:
+ if TYPE == lltype.Void:
+ continue
+ elif TYPE == lltype.Float:
TARGET = TYPE
- TARGETTYPES.append(TARGET)
+ index_TYPE.append((i, TARGET))
- iterator = unrolling_iterable(enumerate(TARGETTYPES))
+ iterator = unrolling_iterable(index_TYPE)
length = len(TYPES)
def greenhash(self):
retval = 0x345678
Modified: pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py Mon Feb 25 13:36:07 2008
@@ -566,37 +566,16 @@
##def ll_gvar_from_constant(jitstate, ll_value):
## return jitstate.curbuilder.rgenop.genconst(ll_value)
-class CallDesc:
- __metaclass__ = cachedtype
-
- def __init__(self, RGenOp, FUNCTYPE):
- self.sigtoken = RGenOp.sigToken(FUNCTYPE)
- self.result_kind = RGenOp.kindToken(FUNCTYPE.RESULT)
- # xxx what if the result is virtualizable?
- self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT)
- whatever_return_value = FUNCTYPE.RESULT._defl()
- def green_call(jitstate, fnptr, *args):
- try:
- result = fnptr(*args)
- except Exception, e:
- jitstate.residual_exception(e)
- result = whatever_return_value
- return result
- self.green_call = green_call
-
- def _freeze_(self):
- return True
-def gen_residual_call(jitstate, calldesc, funcbox):
+def gen_residual_call(jitstate, calldesc, funcbox, argboxes):
builder = jitstate.curbuilder
gv_funcbox = funcbox.getgenvar(jitstate)
- argboxes = jitstate.frame.local_boxes
args_gv = [argbox.getgenvar(jitstate) for argbox in argboxes]
jitstate.prepare_for_residual_call()
gv_result = builder.genop_call(calldesc.sigtoken, gv_funcbox, args_gv)
return calldesc.redboxbuilder(calldesc.result_kind, gv_result)
-def ll_after_residual_call(jitstate, exceptiondesc, check_forced):
+def after_residual_call(jitstate, exceptiondesc, check_forced):
builder = jitstate.curbuilder
if check_forced:
gv_flags = jitstate.check_forced_after_residual_call()
More information about the Pypy-commit
mailing list