[pypy-svn] r52786 - in pypy/branch/jit-hotpath/pypy/jit/rainbow: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Mar 20 18:36:03 CET 2008
Author: arigo
Date: Thu Mar 20 18:36:02 2008
New Revision: 52786
Modified:
pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/rhotpath.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_interpreter.py
Log:
(cfbolz a bit, arigo)
Support for exception-raising operations (mostly arithmetic ovf)
in the rainbow and fallback interpreters.
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py Thu Mar 20 18:36:02 2008
@@ -571,9 +571,14 @@
self.register_redvar(op.result)
if (opdesc is not None and
opdesc.tryfold and not opdesc.canfold and opdesc.canraise):
+ # XXX len(canraise) should be 1, except in
+ # kind-of-deprecated cases
exc_class = opdesc.llop.canraise[0]
- self.emit("split_raisingop",
- self.exceptioninstance_position(exc_class))
+ if self.hannotator.policy.hotpath:
+ self.emit("hp_split_raisingop")
+ else:
+ self.emit("split_raisingop")
+ self.emit(self.exceptioninstance_position(exc_class))
def serialize_opcode(self, color, op):
opname = op.opname
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py Thu Mar 20 18:36:02 2008
@@ -90,6 +90,11 @@
else:
Xxx("capture_exception")
+ def residual_ll_exception(self, ll_evalue):
+ ll_etype = self.hotrunnerdesc.ts.get_typeptr(ll_evalue)
+ self.gv_exc_type = self.rgenop.genconst(ll_etype)
+ self.gv_exc_value = self.rgenop.genconst(ll_evalue)
+
def run_directly(self, greenargs, redargs, targetbytecode):
return self.perform_call_mixed(greenargs, redargs,
targetbytecode.gv_ownfnptr,
@@ -539,6 +544,12 @@
if has_result:
self.red_result(gv_res)
+ @arguments("exception")
+ def opimpl_hp_split_raisingop(self, ll_evalue):
+ gv_raised = self.local_green.pop()
+ if gv_raised.revealconst(lltype.Bool):
+ self.residual_ll_exception(ll_evalue)
+
def hp_return(self):
frame = self.current_source_jitframe.backframe
if frame is None:
@@ -591,17 +602,33 @@
def get_opcode_implementation(self, func_name, argspec, opdesc):
numargs = unrolling_iterable(range(opdesc.nb_args))
- def implementation(self, *args_gv):
- args = (opdesc.RESULT, )
- for i in numargs:
- arg = args_gv[i].revealconst(opdesc.ARGS[i])
- args += (arg, )
- if not we_are_translated():
- if opdesc.opname == "int_is_true":
- # special case for tests, as in llinterp.py
- if type(args[1]) is CDefinedIntSymbolic:
- args = (args[0], args[1].default)
- return self.rgenop.genconst(opdesc.llop(*args))
+ if not opdesc.canraise:
+ def implementation(self, *args_gv):
+ args = (opdesc.RESULT, )
+ for i in numargs:
+ arg = args_gv[i].revealconst(opdesc.ARGS[i])
+ args += (arg, )
+ if not we_are_translated():
+ if opdesc.opname == "int_is_true":
+ # special case for tests, as in llinterp.py
+ if type(args[1]) is CDefinedIntSymbolic:
+ args = (args[0], args[1].default)
+ return self.rgenop.genconst(opdesc.llop(*args))
+ else:
+ exceptions_tuple = opdesc.llop.canraise
+ def implementation(self, *args_gv):
+ args = (opdesc.RESULT, )
+ for i in numargs:
+ arg = args_gv[i].revealconst(opdesc.ARGS[i])
+ args += (arg, )
+ try:
+ result = opdesc.llop(*args)
+ gv_raised = opdesc.gv_False
+ except exceptions_tuple:
+ result = opdesc.whatever_result
+ gv_raised = opdesc.gv_True
+ self.local_green.append(gv_raised)
+ return self.rgenop.genconst(result)
implementation.func_name = func_name
# the argspec may unwrap *args_gv from local_red or local_green
# and put the result back into local_red or local_green
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py Thu Mar 20 18:36:02 2008
@@ -27,6 +27,7 @@
self.RGenOp = RGenOp
self.exceptiondesc = codewriter.exceptiondesc
self.interpreter = codewriter.interpreter
+ self.ts = self.interpreter.ts
self.codewriter = codewriter
self.threshold = threshold
self.translate_support_code = translate_support_code
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py Thu Mar 20 18:36:02 2008
@@ -932,6 +932,11 @@
rhotpath.hp_after_residual_call(self.jitstate, self.hotrunnerdesc,
withexc, True)
+ @arguments("exception")
+ def opimpl_hp_split_raisingop(self, ll_evalue):
+ rhotpath.hp_after_raisingop(self.jitstate, self.hotrunnerdesc,
+ ll_evalue)
+
def hp_return(self):
frame = self.frame.backframe
if frame is None:
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/rhotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/rhotpath.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/rhotpath.py Thu Mar 20 18:36:02 2008
@@ -420,3 +420,53 @@
generate_fallback_code(fbp, hotpromotiondesc, flagbox,
check_exceptions=withexc)
assert 0, "unreachable"
+
+# ____________________________________________________________
+
+# support for turning the 'gv_raised' left behind by primitive raising
+# operations directly into a virtualized exception on the JITState,
+# splitting the machine code in two paths.
+
+class AfterRaisingOpFallbackPoint(PromoteFallbackPoint):
+
+ def __init__(self, jitstate, hotrunnerdesc, promotebox, hotpromotiondesc,
+ ll_evalue):
+ PromoteFallbackPoint.__init__(self, jitstate, hotrunnerdesc,
+ promotebox, hotpromotiondesc)
+ self.ll_evalue = ll_evalue
+
+ @specialize.arglltype(2)
+ def prepare_fallbackinterp(self, fallbackinterp, value):
+ value = bool(value)
+ fallbackinterp.local_red.pop() # remove the temporary raisedbox
+ if value:
+ # got an exception, register it on the fallbackinterp
+ fallbackinterp.residual_ll_exception(self.ll_evalue)
+
+ def prepare_compiler(self, interpreter, gv_value):
+ # remove the temporary raisedbox
+ interpreter.frame.local_boxes.pop()
+ if gv_value.revealconst(lltype.Bool):
+ # got an exception, register it on the interpreter
+ interpreter.jitstate.residual_ll_exception(self.ll_evalue)
+
+
+def hp_after_raisingop(jitstate, hotrunnerdesc, ll_evalue):
+ gv_raised = jitstate.greens.pop() # XXX hackish interface,
+ # pushed here by ll_gen1 or ll_gen2
+ # XXX slightly hackish as well, we actually need gv_raised to be
+ # in local_boxes to be passed along to the new block
+ assert not gv_raised.is_const
+ tok_bool = hotrunnerdesc.RGenOp.kindToken(lltype.Bool)
+ raisedbox = rvalue.IntRedBox(tok_bool, gv_raised)
+ jitstate.frame.local_boxes.append(raisedbox)
+
+ hotpromotiondesc = hotrunnerdesc.bool_hotpromotiondesc
+ fbp = AfterRaisingOpFallbackPoint(jitstate, hotrunnerdesc,
+ raisedbox, hotpromotiondesc,
+ ll_evalue)
+ generate_fallback_code(fbp, hotpromotiondesc, raisedbox,
+ check_exceptions=False)
+ # NB. check_exceptions is False because no exception should set
+ # set now (the RGenOp's genraisingop cannot set an exception itself)
+ assert 0, "unreachable"
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_interpreter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_interpreter.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_interpreter.py Thu Mar 20 18:36:02 2008
@@ -5,6 +5,7 @@
from pypy.rlib.objectmodel import keepalive_until_here
from pypy.jit.hintannotator.policy import HintAnnotatorPolicy, StopAtXPolicy
from pypy.jit.rainbow.test import test_hotpath
+from pypy.rlib.rarithmetic import ovfcheck
import sys
@@ -1753,26 +1754,28 @@
def test_red_int_add_ovf(self):
+ class MyJitDriver(JitDriver):
+ greens = []
+ reds = ['n', 'm', 'i', 'result']
def f(n, m):
- try:
- result = ovfcheck(n + m)
- except OverflowError:
- return -42 + m
+ i = 1024
+ while i > 0:
+ i >>= 1
+ try:
+ result = ovfcheck(n + m)
+ except OverflowError:
+ result = -42 + m
+ MyJitDriver.jit_merge_point(n=n, m=m, i=i, result=result)
+ MyJitDriver.can_enter_jit(n=n, m=m, i=i, result=result)
return result + 1
- res = self.interpret(f, [100, 20])
+ res = self.run(f, [100, 20], threshold=2)
assert res == 121
- self.check_insns(int_add_ovf=1)
- #res = self.interpret(f, [100, 20], [0, 1])
- #assert res == 121
- #self.check_insns()
+ self.check_insns_in_loops(int_add_ovf=1)
- res = self.interpret(f, [sys.maxint, 1])
- assert res == -41
- self.check_insns(int_add_ovf=1)
- res = self.interpret(f, [sys.maxint, 5], [0, 1])
- assert res == -42 + 5
- self.check_insns()
+ res = self.run(f, [sys.maxint, 1], threshold=2)
+ assert res == -40
+ self.check_insns_in_loops(int_add_ovf=1)
def test_green_int_add_ovf(self):
py.test.skip("not working yet")
More information about the Pypy-commit
mailing list