[pypy-commit] pypy continulet-jit-3: (fijal, arigo)
arigo
noreply at buildbot.pypy.org
Sat Oct 13 18:44:31 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: continulet-jit-3
Changeset: r58105:716a9d2d6183
Date: 2012-10-13 18:44 +0200
http://bitbucket.org/pypy/pypy/changeset/716a9d2d6183/
Log: (fijal, arigo)
Start serious fixing and refactoring in the frontend.
diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -18,7 +18,6 @@
from pypy.jit.metainterp import resoperation
from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.metainterp.jitframe import JITFRAMEPTR
from pypy.jit.backend.llgraph import symbolic
from pypy.jit.codewriter import longlong
from pypy.jit.codewriter.effectinfo import EffectInfo
@@ -481,7 +480,6 @@
class Frame(object):
OPHANDLERS = [None] * (rop._LAST+1)
- _TYPE = JITFRAMEPTR.TO
def __init__(self, cpu):
self.verbose = False
@@ -517,6 +515,7 @@
"""Execute all operations in a loop,
possibly following to other loops as well.
"""
+ assert self._may_force == -1
assert self._last_exception is None, "exception left behind"
verbose = True
self.opindex = 0
@@ -578,7 +577,11 @@
if self.verbose:
log.trace('finished: %s' % (
', '.join(map(str, args)),))
- self.fail_args = args
+ assert len(op.args) <= 1, "FINISH with more than 1 arg"
+ self.finish_args = op.args
+ self.fail_args = op.fail_args
+ self.fail_index = op.fail_index
+ self._may_force = self.opindex
return
else:
@@ -1066,16 +1069,15 @@
#
# Emulate the fast path
failindex = frame_descr_index(subframe)
- realsubframe = lltype.cast_opaque_ptr(JITFRAMEPTR, subframe)
if failindex == self.cpu.done_with_this_frame_int_v:
reset_vable(jd, vable)
- return self.cpu.get_latest_value_int(realsubframe, 0)
+ return self.cpu.get_latest_value_int(subframe, 0)
if failindex == self.cpu.done_with_this_frame_ref_v:
reset_vable(jd, vable)
- return self.cpu.get_latest_value_ref(realsubframe, 0)
+ return self.cpu.get_latest_value_ref(subframe, 0)
if failindex == self.cpu.done_with_this_frame_float_v:
reset_vable(jd, vable)
- return self.cpu.get_latest_value_float(realsubframe, 0)
+ return self.cpu.get_latest_value_float(subframe, 0)
if failindex == self.cpu.done_with_this_frame_void_v:
reset_vable(jd, vable)
return None
@@ -1083,7 +1085,7 @@
assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish
assembler_helper = assembler_helper_ptr._obj._callable
try:
- return assembler_helper(realsubframe, vable)
+ return assembler_helper(subframe, vable)
except LLException, lle:
assert self._last_exception is None, "exception left behind"
self._last_exception = lle
@@ -1320,7 +1322,6 @@
import sys, pdb
pdb.post_mortem(sys.exc_info()[2])
raise
- del frame.env
return result
def frame_descr_index(frame):
@@ -1392,10 +1393,13 @@
frame._forced = True
assert frame._may_force >= 0
call_op = frame.loop.operations[frame._may_force]
- guard_op = frame.loop.operations[frame._may_force+1]
opnum = call_op.opnum
- assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER
- frame._populate_fail_args(guard_op, skip=call_op.result)
+ if opnum != rop.FINISH:
+ assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER
+ guard_op = frame.loop.operations[frame._may_force+1]
+ frame._populate_fail_args(guard_op, skip=call_op.result)
+ else:
+ frame._populate_fail_args(call_op)
return frame.fail_index
##def cast_adr_to_int(memocast, adr):
@@ -1863,12 +1867,12 @@
COMPILEDLOOP = lltype.Ptr(lltype.OpaqueType("CompiledLoop"))
-FRAME = JITFRAMEPTR
-#OOFRAME = lltype.Ptr(lltype.OpaqueType("OOFrame"))
+FRAME = lltype.Ptr(lltype.OpaqueType("Frame"))
+OOFRAME = lltype.Ptr(lltype.OpaqueType("OOFrame"))
_TO_OPAQUE[CompiledLoop] = COMPILEDLOOP.TO
-#_TO_OPAQUE[Frame] = FRAME.TO
-#_TO_OPAQUE[OOFrame] = OOFRAME.TO
+_TO_OPAQUE[Frame] = FRAME.TO
+_TO_OPAQUE[OOFrame] = OOFRAME.TO
s_CompiledLoop = annmodel.SomePtr(COMPILEDLOOP)
s_Frame = annmodel.SomePtr(FRAME)
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -12,7 +12,6 @@
from pypy.jit.metainterp.history import REF, INT, FLOAT, STRUCT
from pypy.jit.metainterp.warmstate import unwrap
from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.metainterp.jitframe import JITFRAMEPTR
from pypy.jit.backend import model
from pypy.jit.backend.llgraph import llimpl, symbolic
from pypy.jit.metainterp.typesystem import llhelper, oohelper
@@ -216,7 +215,7 @@
else:
raise Exception("'%s' args contain: %r" % (op.getopname(),
x))
- if op.is_guard():
+ if op.is_guard() or op.getopnum() == rop.FINISH:
faildescr = op.getdescr()
assert isinstance(faildescr, history.AbstractFailDescr)
faildescr._fail_args_types = []
@@ -252,9 +251,7 @@
targettoken = op.getdescr()
llimpl.compile_add_jump_target(c, targettoken, clt)
elif op.getopnum() == rop.FINISH:
- faildescr = op.getdescr()
- index = self.get_fail_descr_number(faildescr)
- llimpl.compile_add_fail(c, index)
+ pass
else:
assert False, "unknown operation"
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -153,11 +153,19 @@
necessarily correct after a FINISH."""
return len(jitframe.jf_gcvalues)
- def grab_exc_value(self, jitframe):
- """Return and clear the exception set by the latest execute_token(),
- when it exits due to a failure of a GUARD_EXCEPTION or
- GUARD_NO_EXCEPTION. (Returns a GCREF)""" # XXX remove me
- return jitframe.jf_excvalue
+ def get_finish_value_int(self, jitframe):
+ """Return the result passed to FINISH, which was an int."""
+ return jitframe.jf_finish_int
+
+ def get_finish_value_float(self, jitframe):
+ """Return the result passed to FINISH, which was a FLOATSTORAGE."""
+ return jitframe.jf_finish_float
+
+ def get_finish_value_ref(self, jitframe):
+ """Return and clear the result passed to FINISH, which was a GCREF.
+ Also used when it exits due to a failure of a GUARD_EXCEPTION or
+ GUARD_NO_EXCEPTION, to return the exception."""
+ return jitframe.jf_finish_ref
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
"""Redirect oldlooptoken to newlooptoken. More precisely, it is
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -1549,7 +1549,6 @@
def resume_in_blackhole(metainterp_sd, jitdriver_sd, jitframe, resumedescr,
all_virtuals=None):
from pypy.jit.metainterp.resume import blackhole_from_resumedata
- #debug_start('jit-blackhole')
blackholeinterp = blackhole_from_resumedata(
metainterp_sd.blackholeinterpbuilder,
jitdriver_sd,
@@ -1564,15 +1563,11 @@
current_exc = blackholeinterp._prepare_resume_from_failure(
resumedescr.guard_opnum, jitframe, dont_change_position)
- #try:
_run_forever(blackholeinterp, current_exc)
- #finally:
- #debug_stop('jit-blackhole')
def convert_and_run_from_pyjitpl(metainterp, raising_exception=False):
# Get a chain of blackhole interpreters and fill them by copying
# 'metainterp.framestack'.
- #debug_start('jit-blackhole')
metainterp_sd = metainterp.staticdata
nextbh = None
for frame in metainterp.framestack:
@@ -1590,7 +1585,4 @@
firstbh.exception_last_value = current_exc
current_exc = lltype.nullptr(rclass.OBJECTPTR.TO)
#
- #try:
_run_forever(firstbh, current_exc)
- #finally:
- #debug_stop('jit-blackhole')
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -411,71 +411,6 @@
# ____________________________________________________________
-class _DoneWithThisFrameDescr(AbstractFailDescr):
- pass
-
-class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
- assert jitdriver_sd.result_type == history.VOID
- raise metainterp_sd.DoneWithThisFrameVoid()
-
-class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
- assert jitdriver_sd.result_type == history.INT
- result = metainterp_sd.cpu.get_latest_value_int(jitframe, 0)
- raise metainterp_sd.DoneWithThisFrameInt(result)
-
-class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
- assert jitdriver_sd.result_type == history.REF
- cpu = metainterp_sd.cpu
- result = cpu.get_latest_value_ref(jitframe, 0)
- raise metainterp_sd.DoneWithThisFrameRef(cpu, result)
-
-class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
- assert jitdriver_sd.result_type == history.FLOAT
- result = metainterp_sd.cpu.get_latest_value_float(jitframe, 0)
- raise metainterp_sd.DoneWithThisFrameFloat(result)
-
-class ExitFrameWithExceptionDescrRef(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
- cpu = metainterp_sd.cpu
- value = cpu.get_latest_value_ref(jitframe, 0)
- raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value)
-
-
-class TerminatingLoopToken(JitCellToken): # FIXME: kill?
- terminating = True
-
- def __init__(self, nargs, finishdescr):
- self.finishdescr = finishdescr
-
-def make_done_loop_tokens():
- done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid()
- done_with_this_frame_descr_int = DoneWithThisFrameDescrInt()
- done_with_this_frame_descr_ref = DoneWithThisFrameDescrRef()
- done_with_this_frame_descr_float = DoneWithThisFrameDescrFloat()
- exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef()
-
- # pseudo loop tokens to make the life of optimize.py easier
- return {'loop_tokens_done_with_this_frame_int': [
- TerminatingLoopToken(1, done_with_this_frame_descr_int)
- ],
- 'loop_tokens_done_with_this_frame_ref': [
- TerminatingLoopToken(1, done_with_this_frame_descr_ref)
- ],
- 'loop_tokens_done_with_this_frame_float': [
- TerminatingLoopToken(1, done_with_this_frame_descr_float)
- ],
- 'loop_tokens_done_with_this_frame_void': [
- TerminatingLoopToken(0, done_with_this_frame_descr_void)
- ],
- 'loop_tokens_exit_frame_with_exception_ref': [
- TerminatingLoopToken(1, exit_frame_with_exception_descr_ref)
- ],
- }
-
class ResumeDescr(AbstractFailDescr):
pass
@@ -698,7 +633,8 @@
# future failure of the GUARD_NOT_FORCED
self.save_data(jitframe, all_virtuals)
- def save_data(self, key, value):
+ def save_data(self, jitframe, value):
+ return # XXXXX
globaldata = self.metainterp_sd.globaldata
if we_are_translated():
assert key not in globaldata.resume_virtuals
@@ -710,6 +646,7 @@
rv.append((key, value))
def fetch_data(self, key):
+ XXXXX
globaldata = self.metainterp_sd.globaldata
if we_are_translated():
assert key in globaldata.resume_virtuals
@@ -727,8 +664,7 @@
return data
def _clone_if_mutable(self):
- res = ResumeGuardForcedDescr(self.metainterp_sd,
- self.jitdriver_sd)
+ res = self.__class__(self.metainterp_sd, self.jitdriver_sd)
self.copy_all_attributes_into(res)
return res
@@ -815,6 +751,46 @@
metainterp_sd.stats.add_jitcell_token(jitcell_token)
+_DoneWithThisFrameDescr = ResumeGuardForcedDescr # XXX replace me
+
+class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr):
+ def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
+ assert jitdriver_sd is self.jitdriver_sd
+ assert jitdriver_sd.result_type == history.VOID
+ raise metainterp_sd.DoneWithThisFrameVoid()
+
+class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr):
+ def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
+ assert jitdriver_sd is self.jitdriver_sd
+ assert jitdriver_sd.result_type == history.INT
+ result = metainterp_sd.cpu.get_finish_value_int(jitframe)
+ raise metainterp_sd.DoneWithThisFrameInt(result)
+
+class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr):
+ def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
+ assert jitdriver_sd is self.jitdriver_sd
+ assert jitdriver_sd.result_type == history.REF
+ cpu = metainterp_sd.cpu
+ result = cpu.get_finish_value_ref(jitframe)
+ raise metainterp_sd.DoneWithThisFrameRef(cpu, result)
+
+class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr):
+ def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
+ assert jitdriver_sd is self.jitdriver_sd
+ assert jitdriver_sd.result_type == history.FLOAT
+ result = metainterp_sd.cpu.get_finish_value_float(jitframe)
+ raise metainterp_sd.DoneWithThisFrameFloat(result)
+
+class ExitFrameWithExceptionDescrRef(_DoneWithThisFrameDescr):
+ def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
+ assert jitdriver_sd is self.jitdriver_sd
+ cpu = metainterp_sd.cpu
+ value = cpu.get_finish_value_ref(jitframe)
+ raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value)
+
+# ____________________________________________________________
+
+
def compile_trace(metainterp, resumekey, resume_at_jump_descr=None):
"""Try to compile a new bridge leading from the beginning of the history
to some existing place.
@@ -874,6 +850,7 @@
calls back the interpreter. Used temporarily: a fully compiled
version of the code may end up replacing it.
"""
+ XXXX # fix me
jitcell_token = make_jitcell_token(jitdriver_sd)
nb_red_args = jitdriver_sd.num_red_args
assert len(redargtypes) == nb_red_args
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -654,7 +654,6 @@
target_tokens = None
failed_states = None
retraced_count = 0
- terminating = False # see TerminatingLoopToken in compile.py
invalidated = False
outermost_jitdriver_sd = None
# and more data specified by the backend when the loop is compiled
@@ -784,7 +783,7 @@
box = op.getarg(i)
if isinstance(box, Box):
assert box in seen
- if op.is_guard():
+ if op.is_guard() or op.getopnum() == rop.FINISH:
assert op.getdescr() is not None
if hasattr(op.getdescr(), '_debug_suboperations'):
ops = op.getdescr()._debug_suboperations
diff --git a/pypy/jit/metainterp/jitdriver.py b/pypy/jit/metainterp/jitdriver.py
--- a/pypy/jit/metainterp/jitdriver.py
+++ b/pypy/jit/metainterp/jitdriver.py
@@ -18,7 +18,6 @@
# self.warmstate ... pypy.jit.metainterp.warmspot
# self.handle_jitexc_from_bh pypy.jit.metainterp.warmspot
# self.no_loop_header ... pypy.jit.metainterp.warmspot
- # self.portal_finishtoken... pypy.jit.metainterp.pyjitpl
# self.index ... pypy.jit.codewriter.call
# self.mainjitcode ... pypy.jit.codewriter.call
diff --git a/pypy/jit/metainterp/jitframe.py b/pypy/jit/metainterp/jitframe.py
--- a/pypy/jit/metainterp/jitframe.py
+++ b/pypy/jit/metainterp/jitframe.py
@@ -1,16 +1,6 @@
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi
-from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.lltypesystem import lltype, llmemory
-_LONGLONGARRAY = lltype.GcArray(lltype.SignedLongLong)
-
-JITFRAME = lltype.GcStruct('JITFRAME',
- ('jf_descr', llmemory.GCREF),
- ('jf_excvalue', llmemory.GCREF),
- ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)),
- ('jf_gcvalues', lltype.Array(llmemory.GCREF)))
-JITFRAMEPTR = lltype.Ptr(JITFRAME)
-
# Constants used for the 'jit_frame' field of virtualizables/virtualrefs:
#
# 1. TOKEN_NONE means not in the JIT at all, except as described below.
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -546,6 +546,8 @@
op = self.store_final_boxes_in_guard(op)
elif op.can_raise():
self.exception_might_have_happened = True
+ elif op.getopnum() == rop.FINISH:
+ op = self.store_final_boxes_in_guard(op)
if op.result:
if op.result in self.seen_results:
raise ValueError, "invalid optimization"
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1459,8 +1459,6 @@
self._addr2name_keys = []
self._addr2name_values = []
- self.__dict__.update(compile.make_done_loop_tokens())
-
def _freeze_(self):
return True
@@ -1500,18 +1498,6 @@
self.callinfocollection = codewriter.callcontrol.callinfocollection
self.has_libffi_call = codewriter.callcontrol.has_libffi_call
#
- # store this information for fastpath of call_assembler
- # (only the paths that can actually be taken)
- for jd in self.jitdrivers_sd:
- name = {history.INT: 'int',
- history.REF: 'ref',
- history.FLOAT: 'float',
- history.VOID: 'void'}[jd.result_type]
- tokens = getattr(self, 'loop_tokens_done_with_this_frame_%s' % name)
- jd.portal_finishtoken = tokens[0].finishdescr
- num = self.cpu.get_fail_descr_number(tokens[0].finishdescr)
- setattr(self.cpu, 'done_with_this_frame_%s_v' % name, num)
- #
exc_descr = compile.PropagateExceptionDescr()
num = self.cpu.get_fail_descr_number(exc_descr)
self.cpu.propagate_exception_v = num
@@ -1598,8 +1584,6 @@
self.indirectcall_dict = None
self.addr2name = None
self.loopnumbering = 0
- self.resume_virtuals = {}
- self.resume_virtuals_not_translated = []
# ____________________________________________________________
@@ -2204,40 +2188,34 @@
self.raise_continue_running_normally(live_arg_boxes, jitcell_token)
def compile_done_with_this_frame(self, exitbox):
- self.gen_store_back_in_virtualizable()
- # temporarily put a JUMP to a pseudo-loop
- sd = self.staticdata
result_type = self.jitdriver_sd.result_type
if result_type == history.VOID:
assert exitbox is None
- exits = []
- loop_tokens = sd.loop_tokens_done_with_this_frame_void
+ self.compile_done([], compile.DoneWithThisFrameDescrVoid)
elif result_type == history.INT:
- exits = [exitbox]
- loop_tokens = sd.loop_tokens_done_with_this_frame_int
+ self.compile_done([exitbox], compile.DoneWithThisFrameDescrInt)
elif result_type == history.REF:
- exits = [exitbox]
- loop_tokens = sd.loop_tokens_done_with_this_frame_ref
+ self.compile_done([exitbox], compile.DoneWithThisFrameDescrRef)
elif result_type == history.FLOAT:
- exits = [exitbox]
- loop_tokens = sd.loop_tokens_done_with_this_frame_float
+ self.compile_done([exitbox], compile.DoneWithThisFrameDescrFloat)
else:
assert False
- # FIXME: kill TerminatingLoopToken?
- # FIXME: can we call compile_trace?
- token = loop_tokens[0].finishdescr
+
+ def compile_exit_frame_with_exception(self, valuebox):
+ self.compile_done([valuebox], compile.ExitFrameWithExceptionDescrRef)
+
+ def compile_done(self, exits, DoneCls):
+ self.record_set_jit_frame()
+ virtualizable_boxes = None
+ if (self.jitdriver_sd.virtualizable_info is not None or
+ self.jitdriver_sd.greenfield_info is not None):
+ virtualizable_boxes = self.virtualizable_boxes
+ assert len(self.virtualref_boxes) == 0
+ token = DoneCls(self.staticdata, self.jitdriver_sd)
+ resume.capture_resumedata([], virtualizable_boxes, [], token)
self.history.record(rop.FINISH, exits, None, descr=token)
target_token = compile.compile_trace(self, self.resumekey)
- if target_token is not token:
- compile.giveup()
-
- def compile_exit_frame_with_exception(self, valuebox):
- self.gen_store_back_in_virtualizable()
- sd = self.staticdata
- token = sd.loop_tokens_exit_frame_with_exception_ref[0].finishdescr
- self.history.record(rop.FINISH, [valuebox], None, descr=token)
- target_token = compile.compile_trace(self, self.resumekey)
- if target_token is not token:
+ if target_token is None:
compile.giveup()
@specialize.arg(1)
@@ -2325,7 +2303,12 @@
virtualizable_box = self.virtualizable_boxes[-1]
virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
vinfo.tracing_before_residual_call(virtualizable)
- #
+ self.record_set_jit_frame()
+
+ def record_set_jit_frame(self):
+ vinfo = self.jitdriver_sd.virtualizable_info
+ if vinfo is not None:
+ virtualizable_box = self.virtualizable_boxes[-1]
jit_frame_box = history.BoxPtr()
self.history.record(rop.JIT_FRAME, [], jit_frame_box)
self.history.record(rop.SETFIELD_GC, [virtualizable_box,
@@ -2423,7 +2406,9 @@
# warmstate.py.
virtualizable_box = self.virtualizable_boxes[-1]
virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
- assert not vinfo.is_token_nonnull_gcref(virtualizable)
+ # clear the jit_frame, forgetting whatever stale value it has
+ # so far, and store the content of the boxes into the virtualizable
+ vinfo.reset_jit_frame(virtualizable)
# fill the virtualizable with the local boxes
self.synchronize_virtualizable()
#
@@ -2459,28 +2444,6 @@
virtualizable)
self.virtualizable_boxes.append(virtualizable_box)
- def gen_store_back_in_virtualizable(self):
- vinfo = self.jitdriver_sd.virtualizable_info
- if vinfo is not None:
- # xxx only write back the fields really modified
- vbox = self.virtualizable_boxes[-1]
- for i in range(vinfo.num_static_extra_boxes):
- fieldbox = self.virtualizable_boxes[i]
- descr = vinfo.static_field_descrs[i]
- self.execute_and_record(rop.SETFIELD_GC, descr, vbox, fieldbox)
- i = vinfo.num_static_extra_boxes
- virtualizable = vinfo.unwrap_virtualizable_box(vbox)
- for k in range(vinfo.num_arrays):
- descr = vinfo.array_field_descrs[k]
- abox = self.execute_and_record(rop.GETFIELD_GC, descr, vbox)
- descr = vinfo.array_descrs[k]
- for j in range(vinfo.get_array_length(virtualizable, k)):
- itembox = self.virtualizable_boxes[i]
- i += 1
- self.execute_and_record(rop.SETARRAYITEM_GC, descr,
- abox, ConstInt(j), itembox)
- assert i + 1 == len(self.virtualizable_boxes)
-
def replace_box(self, oldbox, newbox):
assert isinstance(oldbox, Box)
for frame in self.framestack:
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -593,7 +593,7 @@
}
is_guard = name.startswith('GUARD')
- if is_guard:
+ if is_guard or name == 'FINISH':
assert withdescr
baseclass = GuardResOp
elif withdescr:
diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py
--- a/pypy/jit/metainterp/resume.py
+++ b/pypy/jit/metainterp/resume.py
@@ -55,13 +55,17 @@
def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes,
storage):
n = len(framestack)-1
- top = framestack[n]
- _ensure_parent_resumedata(framestack, n)
- frame_info_list = FrameInfo(top.parent_resumedata_frame_info_list,
- top.jitcode, top.pc)
+ if n >= 0:
+ top = framestack[n]
+ _ensure_parent_resumedata(framestack, n)
+ frame_info_list = FrameInfo(top.parent_resumedata_frame_info_list,
+ top.jitcode, top.pc)
+ snapshot = Snapshot(top.parent_resumedata_snapshot,
+ top.get_list_of_active_boxes(False))
+ else:
+ frame_info_list = None
+ snapshot = None
storage.rd_frame_info_list = frame_info_list
- snapshot = Snapshot(top.parent_resumedata_snapshot,
- top.get_list_of_active_boxes(False))
if virtualizable_boxes is not None:
boxes = virtualref_boxes + virtualizable_boxes
else:
@@ -1103,11 +1107,9 @@
assert vinfo.is_token_nonnull_gcref(virtualizable)
vinfo.reset_token_gcref(virtualizable)
else:
- # just jumped away from assembler (case 4 in the comment in
- # virtualizable.py) into tracing (case 2); check that vable_token
- # is and stays 0. Note the call to reset_vable_token() in
- # warmstate.py.
- assert not vinfo.is_token_nonnull_gcref(virtualizable)
+ # here, virtualizable.jit_frame may contain a leftover from
+ # earlier. We have to clean it here.
+ vinfo.reset_jit_frame(virtualizable)
return vinfo.write_from_resume_data_partial(virtualizable, self, numb)
def load_value_of_type(self, TYPE, tagged):
diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py
--- a/pypy/jit/metainterp/test/test_virtualizable.py
+++ b/pypy/jit/metainterp/test/test_virtualizable.py
@@ -12,7 +12,6 @@
from pypy.jit.metainterp.warmspot import get_stats, get_translator
from pypy.jit.metainterp import history
from pypy.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
-from pypy.jit.metainterp.jitframe import JITFRAMEPTR
def promote_virtualizable(*args):
pass
@@ -145,11 +144,41 @@
while m > 0:
g(xy, n)
m -= 1
+ promote_virtualizable(xy, 'inst_x')
return xy.inst_x
res = self.meta_interp(f, [18])
assert res == 10180
self.check_resops(setfield_gc=0, getfield_gc=2)
+ def test_synchronize_in_return_with_rescall(self):
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'],
+ virtualizables = ['xy'])
+ @dont_look_inside
+ def rescall(xy, n):
+ if n > 9999999:
+ promote_virtualizable(xy, 'inst_x')
+ def g(xy, n):
+ while n > 0:
+ myjitdriver.can_enter_jit(xy=xy, n=n)
+ myjitdriver.jit_merge_point(xy=xy, n=n)
+ promote_virtualizable(xy, 'inst_x')
+ xy.inst_x += 1
+ rescall(xy, n)
+ n -= 1
+ def f(n):
+ xy = self.setup()
+ xy.inst_x = 10000
+ m = 10
+ while m > 0:
+ g(xy, n)
+ m -= 1
+ promote_virtualizable(xy, 'inst_x')
+ return xy.inst_x
+ res = self.meta_interp(f, [18])
+ assert res == 10180
+ # two setfield_gc(virtualizable, jit_frame)
+ self.check_resops(setfield_gc=2, getfield_gc=2)
+
def test_virtualizable_and_greens(self):
myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'xy'],
virtualizables = ['xy'])
diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py
--- a/pypy/jit/metainterp/virtualizable.py
+++ b/pypy/jit/metainterp/virtualizable.py
@@ -216,6 +216,7 @@
self.cast_gcref_to_vtype = cast_gcref_to_vtype
def reset_jit_frame(virtualizable):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
virtualizable.jit_frame = jitframe.TOKEN_NONE
self.reset_jit_frame = reset_jit_frame
diff --git a/pypy/jit/metainterp/virtualref.py b/pypy/jit/metainterp/virtualref.py
--- a/pypy/jit/metainterp/virtualref.py
+++ b/pypy/jit/metainterp/virtualref.py
@@ -12,7 +12,7 @@
# we make the low-level type of an RPython class directly
self.JIT_VIRTUAL_REF = lltype.GcStruct('JitVirtualRef',
('super', rclass.OBJECT),
- ('jit_frame', jitframe.JITFRAMEPTR),
+ ('jit_frame', llmemory.GCREF),
('forced', rclass.OBJECTPTR))
self.jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE,
zero=True, flavor='raw',
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -549,9 +549,8 @@
ASMRESTYPE = lltype.Float
else:
assert False
- from pypy.jit.metainterp.jitframe import JITFRAMEPTR
(_, jd._PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType(
- [JITFRAMEPTR, llmemory.GCREF], ASMRESTYPE)
+ [llmemory.GCREF], ASMRESTYPE)
def rewrite_can_enter_jits(self):
sublists = {}
@@ -804,12 +803,8 @@
vinfo = jd.virtualizable_info
- def assembler_call_helper(jitframe, virtualizableref):
+ def assembler_call_helper(jitframe):
fail_descr = self.cpu.get_latest_descr(jitframe)
- if vinfo is not None:
- virtualizable = lltype.cast_opaque_ptr(
- vinfo.VTYPEPTR, virtualizableref)
- vinfo.reset_jit_frame(virtualizable)
try:
fail_descr.handle_fail(self.metainterp_sd, jd, jitframe)
except JitException, e:
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -301,23 +301,22 @@
func_execute_token = self.cpu.make_execute_token(*ARGS)
def execute_assembler(loop_token, *args):
+ # XXX temporary: we need to force the virtualizable, in case
+ # it contains a jit_frame. Do better later.
+ if vinfo is not None:
+ virtualizable = args[index_of_virtualizable]
+ vinfo.clear_jit_frame(virtualizable)
+ #
# Call the backend to run the 'looptoken' with the given
# input args.
frame = func_execute_token(loop_token, *args)
- fail_descr = self.cpu.get_latest_descr(frame)
- #
- # If we have a virtualizable, we have to reset its
- # 'jit_frame' field afterwards
- if vinfo is not None:
- virtualizable = args[index_of_virtualizable]
- virtualizable = vinfo.cast_gcref_to_vtype(virtualizable)
- vinfo.reset_jit_frame(virtualizable)
#
# Record in the memmgr that we just ran this loop,
# so that it will keep it alive for a longer time
warmrunnerdesc.memory_manager.keep_loop_alive(loop_token)
#
# Handle the failure
+ fail_descr = self.cpu.get_latest_descr(frame)
fail_descr.handle_fail(metainterp_sd, jitdriver_sd, frame)
#
assert 0, "should have raised"
More information about the pypy-commit
mailing list