[pypy-svn] r32032 - in pypy/dist/pypy/jit: codegen/i386 hintannotator hintannotator/test timeshifter timeshifter/test
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 6 19:31:35 CEST 2006
Author: arigo
Date: Wed Sep 6 19:31:32 2006
New Revision: 32032
Added:
pypy/dist/pypy/jit/timeshifter/test/test_exception.py (contents, props changed)
Modified:
pypy/dist/pypy/jit/codegen/i386/ri386genop.py
pypy/dist/pypy/jit/hintannotator/model.py
pypy/dist/pypy/jit/hintannotator/test/test_annotator.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rtyper.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/test/test_vlist.py
pypy/dist/pypy/jit/timeshifter/timeshift.py
Log:
(pedronis, arigo)
Timeshift functions with exceptions. In more details:
- split JITState / VirtualFrame classes
- exc_value_box and exc_type_box on the jitstate
- more support for functions returning Void
- ptr_iszero/ptr_nonzero operation support (in the
hintannotator, in the timeshifter, in the i386
backend)
Modified: pypy/dist/pypy/jit/codegen/i386/ri386genop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/ri386genop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/ri386genop.py Wed Sep 6 19:31:32 2006
@@ -363,7 +363,7 @@
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_setarrayitem(self, (gv_ptr, gv_index, gv_value), gv_RESTYPE):
+ def op_setarrayitem(self, hello_world):
# XXX! only works for GcArray(Signed) for now!!
XXX-fixme
A = DUMMY_A
@@ -381,6 +381,9 @@
op = memSIB(edx, ecx, 0, startoffset)
self.mc.MOV(op, eax)
+ op_ptr_nonzero = op_int_is_true
+ op_ptr_iszero = op_bool_not # for now
+
DUMMY_A = lltype.GcArray(lltype.Signed)
SIZE2SHIFT = {1: 0,
Modified: pypy/dist/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/model.py (original)
+++ pypy/dist/pypy/jit/hintannotator/model.py Wed Sep 6 19:31:32 2006
@@ -12,7 +12,9 @@
cast_int_to_uint
cast_uint_to_int
cast_char_to_int
- cast_bool_to_int""".split()
+ cast_bool_to_int
+ ptr_nonzero
+ ptr_iszero""".split()
BINARY_OPERATIONS = """int_add int_sub int_mul int_mod int_and int_rshift int_floordiv
uint_add uint_sub uint_mul uint_mod uint_and uint_rshift uint_floordiv
@@ -302,6 +304,13 @@
res_vstruct =hs_s1.contentdef.cast(TO)
return SomeLLAbstractContainer(res_vstruct)
+ def ptr_nonzero(hs_s1):
+ return getbookkeeper().immutablevalue(True)
+
+ def ptr_iszero(hs_s1):
+ return getbookkeeper().immutablevalue(False)
+
+
# ____________________________________________________________
# binary
@@ -348,6 +357,12 @@
contentdef = hs_cont1.contentdef.union(hs_cont2.contentdef)
return SomeLLAbstractContainer(contentdef)
+ def ptr_eq((hs_cont1, hs_cont2)):
+ return SomeLLAbstractConstant(lltype.Bool, {})
+
+ def ptr_ne((hs_cont1, hs_cont2)):
+ return SomeLLAbstractConstant(lltype.Bool, {})
+
class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractValue)):
def union((hs_cont1, hs_val2)):
@@ -361,6 +376,14 @@
return pair(hs_cont2, hs_val1).union()
+class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractValue),
+ pairtype(SomeLLAbstractValue, SomeLLAbstractContainer)):
+
+ def ptr_eq(_):
+ return getbookkeeper().immutablevalue(False)
+
+ def ptr_ne(_):
+ return getbookkeeper().immutablevalue(True)
class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractConstant)):
@@ -369,20 +392,6 @@
hs_res = hs_a1.contentdef.read_item()
return reorigin(hs_res, hs_res, hs_index)
- def ptr_eq((hs_cont1, hs_ptr2)):
- return getbookkeeper().immutablevalue(False)
-
- def ptr_ne((hs_cont1, hs_ptr2)):
- return getbookkeeper().immutablevalue(True)
-
-class __extend__(pairtype(SomeLLAbstractConstant, SomeLLAbstractContainer)):
-
- def ptr_eq((hs_ptr1, hs_cont2)):
- return getbookkeeper().immutablevalue(False)
-
- def ptr_ne((hs_ptr1, hs_cont2)):
- return getbookkeeper().immutablevalue(True)
-
# ____________________________________________________________
def handle_highlevel_operation(bookkeeper, ll_func, *args_hs):
Modified: pypy/dist/pypy/jit/hintannotator/test/test_annotator.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/test/test_annotator.py (original)
+++ pypy/dist/pypy/jit/hintannotator/test/test_annotator.py Wed Sep 6 19:31:32 2006
@@ -507,8 +507,6 @@
return 0
hs = hannotate(g, [bool], policy=P_OOPSPEC_NOVIRTUAL)
- # xxx this has a green return but the function has side effects
- # we need to proper notice that for correct timeshifting
assert isinstance(hs, SomeLLAbstractConstant)
assert hs.concretetype == lltype.Signed
@@ -519,7 +517,5 @@
raise e
hs = hannotate(g, [bool], policy=P_OOPSPEC_NOVIRTUAL)
- # xxx this has a green return but the function has side effects
- # we need to proper notice that for correct timeshifting
assert isinstance(hs, SomeLLAbstractConstant)
assert hs.concretetype == lltype.Signed
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Wed Sep 6 19:31:32 2006
@@ -126,6 +126,7 @@
NamedFieldDesc.__init__(self, RGenOp, PTRTYPE, name)
self.fieldindex = index
self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl())
+ self.defaultbox = self.redboxcls(self.kind, self.gv_default)
class ArrayFieldDesc(FieldDesc):
def __init__(self, RGenOp, PTRTYPE):
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Wed Sep 6 19:31:32 2006
@@ -136,6 +136,22 @@
argbox.getgenvar(jitstate.curbuilder))
return rvalue.IntRedBox(fielddesc.indexkind, genvar)
+def ll_genptrnonzero(jitstate, argbox, reverse):
+ if argbox.is_constant():
+ addr = rvalue.ll_getvalue(argbox, llmemory.Address)
+ return rvalue.ll_fromvalue(jitstate, bool(addr) ^ reverse)
+ assert isinstance(argbox, rvalue.PtrRedBox)
+ builder = jitstate.curbuilder
+ if argbox.content is None:
+ gv_addr = argbox.getgenvar(builder)
+ if reverse:
+ gv_res = builder.genop1("ptr_iszero", gv_addr)
+ else:
+ gv_res = builder.genop1("ptr_nonzero", gv_addr)
+ else:
+ gv_res = builder.rgenop.genconst(True ^ reverse)
+ return rvalue.IntRedBox(builder.rgenop.kindToken(lltype.Bool), gv_res)
+
# ____________________________________________________________
# other jitstate/graph level operations
@@ -162,7 +178,7 @@
start_new_block._annspecialcase_ = "specialize:arglltype(2)"
def retrieve_jitstate_for_merge(states_dic, jitstate, key, redboxes):
- jitstate.local_boxes = redboxes
+ save_locals(jitstate, redboxes)
if key not in states_dic:
start_new_block(states_dic, jitstate, key)
return False # continue
@@ -203,47 +219,47 @@
else:
exitgvar = switchredbox.getgenvar(jitstate.curbuilder)
later_builder = jitstate.curbuilder.jump_if_false(exitgvar)
- memo = rvalue.copy_memo()
- jitstate.local_boxes = redboxes_false
- later_jitstate = jitstate.copy(memo)
- later_jitstate.curbuilder = later_builder
- later_jitstate.exitindex = exitindex
- jitstate.split_queue.append(later_jitstate)
- jitstate.local_boxes = redboxes_true
+ save_locals(jitstate, redboxes_false)
+ jitstate.split(later_builder, exitindex)
+ save_locals(jitstate, redboxes_true)
enter_block(jitstate)
return True
def dispatch_next(oldjitstate, return_cache):
- split_queue = oldjitstate.split_queue
+ split_queue = oldjitstate.frame.split_queue
if split_queue:
jitstate = split_queue.pop()
enter_block(jitstate)
return jitstate
else:
- return_queue = oldjitstate.return_queue
- for jitstate in return_queue[:-1]:
- res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
- jitstate.local_boxes)
- assert res is True # finished
- frozen, block = return_cache[()]
- jitstate = return_queue[-1]
- retbox = jitstate.local_boxes[0]
- backstate = jitstate.backstate
- backstate.curbuilder = jitstate.curbuilder
- backstate.local_boxes.append(retbox)
- backstate.exitindex = -1
- # XXX for now the return value box is put in the parent's local_boxes,
- # where a 'restore_local' operation will fetch it
- return backstate
+ return leave_graph(oldjitstate.frame.return_queue, return_cache)
def getexitindex(jitstate):
return jitstate.exitindex
+def save_locals(jitstate, redboxes):
+ jitstate.frame.local_boxes = redboxes
+
def getlocalbox(jitstate, i):
- return jitstate.local_boxes[i]
+ return jitstate.frame.local_boxes[i]
+
+def getreturnbox(jitstate):
+ return jitstate.returnbox
+
+def getexctypebox(jitstate):
+ return jitstate.exc_type_box
+
+def getexcvaluebox(jitstate):
+ return jitstate.exc_value_box
+
+def setexctypebox(jitstate, box):
+ jitstate.exc_type_box = box
+
+def setexcvaluebox(jitstate, box):
+ jitstate.exc_value_box = box
def save_return(jitstate):
- jitstate.return_queue.append(jitstate)
+ jitstate.frame.return_queue.append(jitstate)
def ll_gvar_from_redbox(jitstate, redbox):
return redbox.getgenvar(jitstate.curbuilder)
@@ -251,69 +267,85 @@
def ll_gvar_from_constant(jitstate, ll_value):
return jitstate.curbuilder.rgenop.genconst(ll_value)
-def save_locals(jitstate, redboxes):
- jitstate.local_boxes = redboxes
-
# ____________________________________________________________
-class FrozenJITState(object):
- fz_backstate = None
+class FrozenVirtualFrame(object):
+ fz_backframe = None
#fz_local_boxes = ... set by freeze()
- def exactmatch(self, jitstate, outgoingvarboxes, memo):
+ def exactmatch(self, vframe, outgoingvarboxes, memo):
self_boxes = self.fz_local_boxes
- live_boxes = jitstate.local_boxes
+ live_boxes = vframe.local_boxes
fullmatch = True
for i in range(len(self_boxes)):
if not self_boxes[i].exactmatch(live_boxes[i],
outgoingvarboxes,
memo):
fullmatch = False
- if self.fz_backstate is not None:
- assert jitstate.backstate is not None
- if not self.fz_backstate.exactmatch(jitstate.backstate,
+ if self.fz_backframe is not None:
+ assert vframe.backframe is not None
+ if not self.fz_backframe.exactmatch(vframe.backframe,
outgoingvarboxes,
memo):
fullmatch = False
else:
- assert jitstate.backstate is None
+ assert vframe.backframe is None
return fullmatch
-class JITState(object):
- exitindex = -1
+class FrozenJITState(object):
+ #fz_frame = ... set by freeze()
+ #fz_exc_type_box = ... set by freeze()
+ #fz_exc_value_box = ... set by freeze()
- def __init__(self, split_queue, return_queue, builder, backstate):
+ def exactmatch(self, jitstate, outgoingvarboxes, memo):
+ fullmatch = True
+ if not self.fz_frame.exactmatch(jitstate.frame,
+ outgoingvarboxes,
+ memo):
+ fullmatch = False
+ if not self.fz_exc_type_box.exactmatch(jitstate.exc_type_box,
+ outgoingvarboxes,
+ memo):
+ fullmatch = False
+ if not self.fz_exc_value_box.exactmatch(jitstate.exc_value_box,
+ outgoingvarboxes,
+ memo):
+ fullmatch = False
+ return fullmatch
+
+
+class VirtualFrame(object):
+
+ def __init__(self, backframe, split_queue, return_queue):
+ self.backframe = backframe
self.split_queue = split_queue
self.return_queue = return_queue
- self.curbuilder = builder
- self.backstate = backstate
#self.local_boxes = ... set by callers
def enter_block(self, incoming, memo):
for box in self.local_boxes:
box.enter_block(incoming, memo)
- if self.backstate is not None:
- self.backstate.enter_block(incoming, memo)
+ if self.backframe is not None:
+ self.backframe.enter_block(incoming, memo)
def freeze(self, memo):
- result = FrozenJITState()
+ result = FrozenVirtualFrame()
frozens = [box.freeze(memo) for box in self.local_boxes]
result.fz_local_boxes = frozens
- if self.backstate is not None:
- result.fz_backstate = self.backstate.freeze(memo)
+ if self.backframe is not None:
+ result.fz_backframe = self.backframe.freeze(memo)
return result
def copy(self, memo):
- if self.backstate is None:
- newbackstate = None
+ if self.backframe is None:
+ newbackframe = None
else:
- newbackstate = self.backstate.copy(memo)
- result = JITState(self.split_queue,
- self.return_queue,
- None,
- newbackstate)
+ newbackframe = self.backframe.copy(memo)
+ result = VirtualFrame(newbackframe,
+ self.split_queue,
+ self.return_queue)
result.local_boxes = [box.copy(memo) for box in self.local_boxes]
return result
@@ -321,14 +353,63 @@
local_boxes = self.local_boxes
for i in range(len(local_boxes)):
local_boxes[i] = local_boxes[i].replace(memo)
- if self.backstate is not None:
- self.backstate.replace(memo)
+ if self.backframe is not None:
+ self.backframe.replace(memo)
-def enter_graph(backstate):
- return JITState([], [], backstate.curbuilder, backstate)
+class JITState(object):
+ returnbox = None
+
+ def __init__(self, builder, frame, exc_type_box, exc_value_box,
+ exitindex=-1):
+ self.curbuilder = builder
+ self.frame = frame
+ self.exc_type_box = exc_type_box
+ self.exc_value_box = exc_value_box
+ self.exitindex = exitindex
-def fresh_jitstate(builder):
- jitstate = JITState([], [], builder, None)
- jitstate.local_boxes = []
+ def split(self, newbuilder, newexitindex):
+ memo = rvalue.copy_memo()
+ later_jitstate = JITState(newbuilder,
+ self.frame.copy(memo),
+ self.exc_type_box .copy(memo),
+ self.exc_value_box.copy(memo),
+ newexitindex)
+ self.frame.split_queue.append(later_jitstate)
+
+ def enter_block(self, incoming, memo):
+ self.frame.enter_block(incoming, memo)
+ self.exc_type_box .enter_block(incoming, memo)
+ self.exc_value_box.enter_block(incoming, memo)
+
+ def freeze(self, memo):
+ result = FrozenJITState()
+ result.fz_frame = self.frame.freeze(memo)
+ result.fz_exc_type_box = self.exc_type_box .freeze(memo)
+ result.fz_exc_value_box = self.exc_value_box.freeze(memo)
+ return result
+
+ def replace(self, memo):
+ self.frame.replace(memo)
+ self.exc_type_box = self.exc_type_box .replace(memo)
+ self.exc_value_box = self.exc_value_box.replace(memo)
+
+
+def enter_graph(jitstate):
+ jitstate.frame = VirtualFrame(jitstate.frame, [], [])
+
+def leave_graph(return_queue, return_cache):
+ for jitstate in return_queue[:-1]:
+ res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
+ # XXX strange next argument
+ jitstate.frame.local_boxes)
+ assert res is True # finished
+ frozen, block = return_cache[()]
+ jitstate = return_queue[-1]
+ myframe = jitstate.frame
+ if myframe.local_boxes: # else it's a green Void return
+ jitstate.returnbox = myframe.local_boxes[0]
+ # ^^^ fetched by an 'fetch_return' operation
+ jitstate.frame = myframe.backframe
+ jitstate.exitindex = -1
return jitstate
Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py Wed Sep 6 19:31:32 2006
@@ -120,6 +120,21 @@
def translate_op_getfield(self, hop):
if isinstance(hop.args_r[0], BlueRepr):
return hop.args_r[0].timeshift_getfield(hop)
+ ts = self.timeshifter
+ if hop.args_v[0] == ts.cexcdata:
+ # reading one of the exception boxes (exc_type or exc_value)
+ fieldname = hop.args_v[1].value
+ if fieldname.endswith('exc_type'):
+ reader = rtimeshift.getexctypebox
+ elif fieldname.endswith('exc_value'):
+ reader = rtimeshift.getexcvaluebox
+ else:
+ raise Exception("getfield(exc_data, %r)" % (fieldname,))
+ v_jitstate = hop.llops.getjitstate()
+ return hop.llops.genmixlevelhelpercall(reader,
+ [ts.s_JITState],
+ [v_jitstate ],
+ ts.s_RedBox)
# non virtual case
PTRTYPE = originalconcretetype(hop.args_s[0])
if PTRTYPE.TO._hints.get('immutable', False): # foldable if all green
@@ -127,7 +142,6 @@
if res is not None:
return res
- ts = self.timeshifter
v_argbox, c_fieldname = hop.inputargs(self.getredrepr(PTRTYPE),
green_void_repr)
structdesc = rcontainer.StructTypeDesc(self.RGenOp, PTRTYPE.TO)
@@ -183,10 +197,26 @@
def translate_op_setfield(self, hop):
if isinstance(hop.args_r[0], BlueRepr):
return hop.args_r[0].timeshift_setfield(hop)
- # non virtual case ...
ts = self.timeshifter
PTRTYPE = originalconcretetype(hop.args_s[0])
VALUETYPE = originalconcretetype(hop.args_s[2])
+ if hop.args_v[0] == ts.cexcdata:
+ # reading one of the exception boxes (exc_type or exc_value)
+ fieldname = hop.args_v[1].value
+ if fieldname.endswith('exc_type'):
+ writer = rtimeshift.setexctypebox
+ elif fieldname.endswith('exc_value'):
+ writer = rtimeshift.setexcvaluebox
+ else:
+ raise Exception("setfield(exc_data, %r)" % (fieldname,))
+ v_valuebox = hop.inputarg(self.getredrepr(VALUETYPE), arg=2)
+ v_jitstate = hop.llops.getjitstate()
+ hop.llops.genmixlevelhelpercall(writer,
+ [ts.s_JITState, ts.s_RedBox],
+ [v_jitstate, v_valuebox ],
+ annmodel.s_None)
+ return
+ # non virtual case ...
v_destbox, c_fieldname, v_valuebox = hop.inputargs(self.getredrepr(PTRTYPE),
green_void_repr,
self.getredrepr(VALUETYPE)
@@ -227,6 +257,21 @@
r_result = hop.r_result
return r_result.create(hop)
+ def translate_op_ptr_nonzero(self, hop, reverse=False):
+ ts = self.timeshifter
+ PTRTYPE = originalconcretetype(hop.args_s[0])
+ v_argbox, = hop.inputargs(self.getredrepr(PTRTYPE))
+ v_jitstate = hop.llops.getjitstate()
+ c_reverse = hop.inputconst(lltype.Bool, reverse)
+ return hop.llops.genmixlevelhelpercall(rtimeshift.ll_genptrnonzero,
+ [ts.s_JITState, ts.s_RedBox, annmodel.SomeBool()],
+ [v_jitstate, v_argbox, c_reverse ],
+ ts.s_RedBox)
+
+ def translate_op_ptr_iszero(self, hop):
+ return self.translate_op_ptr_nonzero(hop, reverse=True)
+
+
def guess_call_kind(self, spaceop):
assert spaceop.opname == 'direct_call'
c_func = spaceop.args[0]
@@ -262,6 +307,13 @@
v_jitstate = hop.llops.getjitstate()
return ts.read_out_box(hop.llops, v_jitstate, index)
+ def translate_op_fetch_return(self, hop):
+ ts = self.timeshifter
+ v_jitstate = hop.llops.getjitstate()
+ return hop.llops.genmixlevelhelpercall(rtimeshift.getreturnbox,
+ [ts.s_JITState],
+ [v_jitstate ],
+ ts.s_RedBox)
def handle_oopspec_call(self, hop):
# special-cased call, for things like list methods
Added: pypy/dist/pypy/jit/timeshifter/test/test_exception.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/timeshifter/test/test_exception.py Wed Sep 6 19:31:32 2006
@@ -0,0 +1,69 @@
+import py
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.llinterp import LLException
+from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
+from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL
+
+
+class TestException(TimeshiftingTests):
+
+ def test_exception_check_melts_away(self):
+ def ll_two(x):
+ if x == 0:
+ raise ValueError
+ return x-1
+ def ll_function(y):
+ return ll_two(y) + 40
+
+ res = self.timeshift(ll_function, [3], [0], policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns({})
+
+ def test_propagate_exception(self):
+ S = lltype.Struct('S', ('flag', lltype.Signed))
+ s = lltype.malloc(S, immortal=True)
+ def ll_two(x):
+ if x == 0:
+ raise ValueError
+ return x+7
+ def ll_function(y):
+ res = ll_two(y)
+ s.flag = 1
+ return res
+
+ s.flag = 0
+ res = self.timeshift(ll_function, [0], [], policy=P_NOVIRTUAL)
+ assert res == -1
+ assert s.flag == 0
+
+ s.flag = 0
+ res = self.timeshift(ll_function, [0], [0], policy=P_NOVIRTUAL)
+ assert res == -1
+ assert s.flag == 0
+
+ s.flag = 0
+ res = self.timeshift(ll_function, [17], [0], policy=P_NOVIRTUAL)
+ assert res == 24
+ assert s.flag == 1
+ self.check_insns({'setfield': 1})
+
+ def test_catch(self):
+ def ll_two(x):
+ if x == 0:
+ raise ValueError
+ return x+7
+ def ll_function(y):
+ try:
+ return ll_two(y)
+ except ValueError:
+ return 42
+
+ res = self.timeshift(ll_function, [0], [], policy=P_NOVIRTUAL)
+ assert res == 42
+
+ res = self.timeshift(ll_function, [0], [0], policy=P_NOVIRTUAL)
+ assert res == 42
+
+ res = self.timeshift(ll_function, [17], [0], policy=P_NOVIRTUAL)
+ assert res == 24
+ self.check_insns({})
Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Wed Sep 6 19:31:32 2006
@@ -21,8 +21,6 @@
P_NOVIRTUAL = AnnotatorPolicy()
P_NOVIRTUAL.novirtualcontainer = True
-P_NOVIRTUAL.exceptiontransform = False # XXX for now, needs to make ptr_ne/eq
- # not force things
def getargtypes(annotator, values):
return [annotation(annotator, x) for x in values]
@@ -91,6 +89,7 @@
# make the timeshifted graphs
htshift = HintTimeshift(ha, rtyper, self.RGenOp)
+ fresh_jitstate = htshift.ll_fresh_jitstate
RESTYPE = htshift.originalconcretetype(
ha.translator.graphs[0].getreturnvar())
htshift.timeshift()
@@ -172,10 +171,10 @@
i += 1
timeshifted_entrypoint_args += (box,)
- top_jitstate = rtimeshift.fresh_jitstate(builder)
+ top_jitstate = fresh_jitstate(builder)
top_jitstate = timeshifted_entrypoint(top_jitstate,
*timeshifted_entrypoint_args)
- returnbox = top_jitstate.local_boxes[0]
+ returnbox = rtimeshift.getreturnbox(top_jitstate)
gv_ret = returnbox.getgenvar(top_jitstate.curbuilder)
top_jitstate.curbuilder.finish_and_return(sigtoken, gv_ret)
@@ -796,3 +795,13 @@
assert res == 21
self.check_insns({'int_gt': 1, 'int_add': 1,
'int_sub': 1, 'int_mul': 1})
+
+ def test_void_call(self):
+ def ll_do_nothing(x):
+ pass
+ def ll_function(y):
+ ll_do_nothing(y)
+ return y
+
+ res = self.timeshift(ll_function, [3], [], policy=P_NOVIRTUAL)
+ assert res == 3
Modified: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_vlist.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_vlist.py Wed Sep 6 19:31:32 2006
@@ -4,8 +4,6 @@
P_OOPSPEC = AnnotatorPolicy()
P_OOPSPEC.novirtualcontainer = True
P_OOPSPEC.oopspec = True
-P_OOPSPEC.exceptiontransform = False # XXX for now, needs to make ptr_ne/eq
- # not force things
class TestVList(TimeshiftingTests):
Modified: pypy/dist/pypy/jit/timeshifter/timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/timeshift.py Wed Sep 6 19:31:32 2006
@@ -49,6 +49,21 @@
## self.r_box_accum = getrepr(self.s_box_accum)
## self.r_box_accum.setup()
+ self.cexcdata = hannotator.exceptiontransformer.cexcdata
+ gv_excdata = RGenOp.constPrebuiltGlobal(self.cexcdata.value)
+ LL_EXC_TYPE = rtyper.exceptiondata.lltype_of_exception_type
+ LL_EXC_VALUE = rtyper.exceptiondata.lltype_of_exception_value
+ null_exc_type_box = rvalue.redbox_from_prebuilt_value(RGenOp,
+ lltype.nullptr(LL_EXC_TYPE.TO))
+ null_exc_value_box = rvalue.redbox_from_prebuilt_value(RGenOp,
+ lltype.nullptr(LL_EXC_VALUE.TO))
+
+ def ll_fresh_jitstate(builder):
+ return JITState(builder, None,
+ null_exc_type_box,
+ null_exc_value_box)
+ self.ll_fresh_jitstate = ll_fresh_jitstate
+
def s_r_instanceof(self, cls, can_be_None=True):
# Return a SomeInstance / InstanceRepr pair correspnding to the specified class.
return self.annhelper.s_r_instanceof(cls, can_be_None=can_be_None)
@@ -199,14 +214,13 @@
newstartblock = self.insert_before_block(self.graph.startblock, None,
closeblock=True)
llops = HintLowLevelOpList(self)
- v_backstate = llops.getjitstate()
+ v_jitstate = llops.getjitstate()
llops.genop('direct_call', [self.c_ll_clearcaches_ptr])
- v_jitstate1 = llops.genmixlevelhelpercall(rtimeshift.enter_graph,
- [self.s_JITState],
- [v_backstate],
- self.s_JITState)
- llops.setjitstate(v_jitstate1)
+ llops.genmixlevelhelpercall(rtimeshift.enter_graph,
+ [self.s_JITState],
+ [v_jitstate ],
+ annmodel.s_None)
newstartblock.operations = list(llops)
def insert_before_block(self, block, block_entering_links,
@@ -313,7 +327,7 @@
orig_key_v = []
for newvar in newinputargs:
r = self.hrtyper.bindingrepr(newvar)
- if isinstance(r, GreenRepr):
+ if isinstance(r, GreenRepr) and r.lowleveltype is not lltype.Void:
r_from = getrepr(r.annotation())
s_erased = r.erased_annotation()
r_to = getrepr(s_erased)
@@ -585,10 +599,7 @@
block.operations.insert(i, extraop)
replacement = {}
- # XXX for now, the call appends the return value box to
- # the local_boxes of our jitstate, from where we can fish
- # it using a 'restore_local' ----------vvvvvvvvvvv
- for i, var in enumerate(vars_to_save + [op.result]):
+ for i, var in enumerate(vars_to_save):
newvar = copyvar(self.hannotator, var)
c_index = flowmodel.Constant(i, concretetype=lltype.Signed)
extraop = flowmodel.SpaceOperation('restore_local',
@@ -597,6 +608,15 @@
block.operations.append(extraop)
replacement[var] = newvar
+ if isinstance(hrtyper.bindingrepr(op.result), RedRepr):
+ var = op.result
+ newvar = copyvar(self.hannotator, var)
+ extraop = flowmodel.SpaceOperation('fetch_return',
+ [],
+ newvar)
+ block.operations.append(extraop)
+ replacement[var] = newvar
+
link.args = [replacement.get(var, var) for var in link.args]
block = link.target
entering_links[block] = [link]
More information about the Pypy-commit
mailing list