[pypy-svn] r63826 - in pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Apr 8 14:23:03 CEST 2009
Author: arigo
Date: Wed Apr 8 14:23:00 2009
New Revision: 63826
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/dump.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
Log:
Fix test_recursive by splitting the class OOMetaInterp in three:
MetaInterpStaticData: frozen global
MetaInterpGlobalData: non-frozen global
MetaInterp: local to a trace
Once this is done, we only have to worry about changing Boxes,
which can be taken care of by saving and restoring their content
across recursive calls (done lazily).
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py Wed Apr 8 14:23:00 2009
@@ -75,15 +75,15 @@
class CodeWriter(object):
portal_graph = None
- def __init__(self, metainterp, policy):
+ def __init__(self, metainterp_sd, policy):
self.all_prebuilt_values = {}
self.all_graphs = {}
self.all_indirectcallsets = {}
self.all_listdescs = {}
self.unfinished_graphs = []
- self.metainterp = metainterp
- self.rtyper = metainterp.cpu.rtyper
- self.cpu = metainterp.cpu
+ self.metainterp_sd = metainterp_sd
+ self.rtyper = metainterp_sd.cpu.rtyper
+ self.cpu = metainterp_sd.cpu
self.policy = policy
def make_portal_bytecode(self, graph):
@@ -209,7 +209,7 @@
def __init__(self, codewriter, graph, portal):
self.codewriter = codewriter
- self.cpu = codewriter.metainterp.cpu
+ self.cpu = codewriter.metainterp_sd.cpu
self.portal = portal
self.bytecode = self.codewriter.get_jitcode(graph)
if not codewriter.policy.look_inside_graph(graph):
@@ -231,12 +231,13 @@
self.make_exception_handler(self.pending_exception_handlers.pop())
labelpos = {}
- code = assemble(labelpos, self.codewriter.metainterp, self.assembler)
+ code = assemble(labelpos, self.codewriter.metainterp_sd,
+ self.assembler)
self.resolve_switch_targets(labelpos)
self.bytecode.setup(code, self.constants)
self.bytecode._source = self.assembler
- self.bytecode._metainterp = self.codewriter.metainterp
+ self.bytecode._metainterp_sd = self.codewriter.metainterp_sd
self.bytecode._labelpos = labelpos
if self.debug:
self.bytecode.dump()
@@ -749,7 +750,7 @@
c_func, TP = support.builtin_func_for_spec(self.codewriter.rtyper,
oopspec_name, argtypes,
resulttype)
- if self.codewriter.metainterp.options.listops:
+ if self.codewriter.metainterp_sd.options.listops:
if self.handle_list_call(op, oopspec_name, args, TP):
return
## if oopspec_name.startswith('list.getitem'):
@@ -903,16 +904,17 @@
FIELDTYPE = getattr(STRUCTTYPE, argname)
if FIELDTYPE != lltype.Void:
TOPSTRUCT = heaptracker.cast_vable_type(STRUCTTYPE)
- metainterp = self.codewriter.metainterp
+ metainterp_sd = self.codewriter.metainterp_sd
+ vdescs = metainterp_sd._virtualizabledescs
try:
- virtualizabledesc = metainterp._virtualizabledescs[TOPSTRUCT]
+ virtualizabledesc = vdescs[TOPSTRUCT]
except KeyError:
from pypy.jit.metainterp import virtualizable
virtualizabledesc = virtualizable.VirtualizableDesc(
self.cpu, TOPSTRUCT, STRUCTTYPE)
- virtualizabledesc.hash = len(metainterp._virtualizabledescs)
- metainterp._virtualizabledescs[TOPSTRUCT] = virtualizabledesc
- metainterp._can_have_virtualizables = virtualizabledesc
+ virtualizabledesc.hash = len(metainterp_sd._virtualizabledescs)
+ vdescs[TOPSTRUCT] = virtualizabledesc
+ metainterp_sd._can_have_virtualizables = virtualizabledesc
# ^^^ stays None if this code is never seen
guard_field = self.cpu.fielddescrof(STRUCTTYPE, argname)
self.emit('guard_nonvirtualized')
@@ -1000,7 +1002,7 @@
break
return result
-def assemble(labelpos, metainterp, assembler):
+def assemble(labelpos, metainterp_sd, assembler):
result = []
for arg in assembler:
if isinstance(arg, str):
@@ -1008,7 +1010,7 @@
continue
#if arg == 'green':
# XXX should be removed and transformed into a list constant
- opcode = metainterp.find_opcode(arg)
+ opcode = metainterp_sd.find_opcode(arg)
result.append(chr(opcode))
elif isinstance(arg, bool):
result.append(chr(int(arg)))
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py Wed Apr 8 14:23:00 2009
@@ -74,13 +74,13 @@
extraloops = []
else:
extraloops = [loop]
- metainterp.stats.view(errmsg=errmsg, extraloops=extraloops)
+ metainterp.staticdata.stats.view(errmsg=errmsg, extraloops=extraloops)
def create_empty_loop(metainterp):
if we_are_translated():
name = 'Loop'
else:
- name = 'Loop #%d' % len(metainterp.stats.loops)
+ name = 'Loop #%d' % len(metainterp.staticdata.stats.loops)
return TreeLoop(name)
# ____________________________________________________________
@@ -92,13 +92,14 @@
loop.inputargs = history.inputargs
loop.operations = history.operations
loop.operations[-1].jump_target = loop
- old_loop = metainterp.optimize_loop(metainterp.options, old_loops,
- loop, metainterp.cpu)
+ metainterp_sd = metainterp.staticdata
+ old_loop = metainterp_sd.optimize_loop(metainterp_sd.options, old_loops,
+ loop, metainterp.cpu)
if old_loop is not None:
return old_loop
history.source_link = loop
send_loop_to_backend(metainterp, loop, "loop")
- metainterp.stats.loops.append(loop)
+ metainterp.staticdata.stats.loops.append(loop)
old_loops.append(loop)
return loop
@@ -106,7 +107,7 @@
metainterp.cpu.compile_operations(loop)
if not we_are_translated():
if type != "entry bridge":
- metainterp.stats.compiled_count += 1
+ metainterp.staticdata.stats.compiled_count += 1
else:
loop._ignore_during_counting = True
log.info("compiled new " + type)
@@ -114,19 +115,19 @@
# ____________________________________________________________
class DoneWithThisFrameDescr0(AbstractDescr):
- def handle_fail_op(self, metainterp, fail_op):
- raise metainterp.DoneWithThisFrame(None)
+ def handle_fail_op(self, metainterp_sd, fail_op):
+ raise metainterp_sd.DoneWithThisFrame(None)
class DoneWithThisFrameDescr1(AbstractDescr):
- def handle_fail_op(self, metainterp, fail_op):
+ def handle_fail_op(self, metainterp_sd, fail_op):
resultbox = fail_op.args[0]
- raise metainterp.DoneWithThisFrame(resultbox)
+ raise metainterp_sd.DoneWithThisFrame(resultbox)
class ExitFrameWithExceptionDescr(AbstractDescr):
- def handle_fail_op(self, metainterp, fail_op):
- typebox = fail_op.args[0]
- valuebox = fail_op.args[1]
- raise metainterp.ExitFrameWithException(typebox, valuebox)
+ def handle_fail_op(self, metainterp_sd, fail_op):
+ assert len(fail_op.args) == 1
+ valuebox = fail_op.args[0]
+ raise metainterp_sd.ExitFrameWithException(valuebox)
done_with_this_frame_descr_0 = DoneWithThisFrameDescr0()
done_with_this_frame_descr_1 = DoneWithThisFrameDescr1()
@@ -153,27 +154,29 @@
map_loop2descr[_loop] = done_with_this_frame_descr_0
_loop = TreeLoop('exit_frame_with_exception')
-_loop.specnodes = [NotSpecNode(), NotSpecNode()]
-_loop.inputargs = [BoxInt(), BoxPtr()]
+_loop.specnodes = [NotSpecNode()]
+_loop.inputargs = [BoxPtr()]
loops_exit_frame_with_exception = [_loop]
map_loop2descr[_loop] = exit_frame_with_exception_descr
del _loop
class ResumeGuardDescr(AbstractDescr):
- def __init__(self, guard_op, resume_info, history, history_guard_index):
+ def __init__(self, resume_info, history, history_guard_index):
self.resume_info = resume_info
- self.guard_op = guard_op
self.counter = 0
self.history = history
assert history_guard_index >= 0
self.history_guard_index = history_guard_index
- def handle_fail_op(self, metainterp, fail_op):
+ def handle_fail_op(self, metainterp_sd, fail_op):
+ from pypy.jit.metainterp.pyjitpl import MetaInterp
+ metainterp = MetaInterp(metainterp_sd)
return metainterp.handle_guard_failure(fail_op, self)
def get_guard_op(self):
- guard_op = self.guard_op
+ guard_op = self.history.operations[self.history_guard_index]
+ assert guard_op.is_guard()
if guard_op.optimized is not None: # should always be the case,
return guard_op.optimized # except if not optimizing at all
else:
@@ -216,7 +219,8 @@
# to previously-compiled code. We keep 'new_loop', which is not
# a loop at all but ends in a jump to the target loop. It starts
# with completely unoptimized arguments, as in the interpreter.
- num_green_args = metainterp.num_green_args
+ metainterp_sd = metainterp.staticdata
+ num_green_args = metainterp_sd.num_green_args
greenkey = self.original_boxes[:num_green_args]
redkey = self.original_boxes[num_green_args:]
metainterp.history.source_link = new_loop
@@ -224,10 +228,10 @@
new_loop.greenkey = greenkey
new_loop.inputargs = redkey
send_loop_to_backend(metainterp, new_loop, "entry bridge")
- metainterp.stats.loops.append(new_loop)
+ metainterp_sd.stats.loops.append(new_loop)
# send the new_loop to warmspot.py, to be called directly the next time
- metainterp.state.attach_unoptimized_bridge_from_interp(greenkey,
- new_loop)
+ metainterp_sd.state.attach_unoptimized_bridge_from_interp(greenkey,
+ new_loop)
def compile_fresh_bridge(metainterp, old_loops, resumekey):
@@ -238,8 +242,10 @@
# it does not work -- i.e. none of the existing old_loops match.
new_loop = create_empty_loop(metainterp)
new_loop.operations = metainterp.history.operations
- target_loop = metainterp.optimize_bridge(metainterp.options, old_loops,
- new_loop, metainterp.cpu)
+ metainterp_sd = metainterp.staticdata
+ target_loop = metainterp_sd.optimize_bridge(metainterp_sd.options,
+ old_loops, new_loop,
+ metainterp.cpu)
# Did it work? If not, prepare_loop_from_bridge() will probably be used.
if target_loop is not None:
# Yes, we managed to create a bridge. Dispatch to resumekey to
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/dump.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/dump.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/dump.py Wed Apr 8 14:23:00 2009
@@ -89,7 +89,7 @@
# XXX this is not really a disassembler, but just a pretty-printer
# for the '_source' attribute that codewriter.py attaches
source = jitcode._source
- interpreter = jitcode._metainterp
+ interpreter = jitcode._metainterp_sd
labelpos = jitcode._labelpos
print >> file, 'JITCODE %r' % (jitcode.name,)
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py Wed Apr 8 14:23:00 2009
@@ -544,8 +544,8 @@
def generate_merge_point(self, pc, varargs):
if isinstance(self.metainterp.history, history.BlackHole):
- raise self.metainterp.ContinueRunningNormally(varargs)
- num_green_args = self.metainterp.num_green_args
+ raise self.metainterp.staticdata.ContinueRunningNormally(varargs)
+ num_green_args = self.metainterp.staticdata.num_green_args
for i in range(num_green_args):
varargs[i] = self.implement_guard_value(pc, varargs[i])
@@ -632,7 +632,8 @@
op = ord(self.bytecode[pc])
#print self.metainterp.opcode_names[op]
self.pc = pc + 1
- stop = self.metainterp.opcode_implementations[op](self, pc)
+ staticdata = self.metainterp.staticdata
+ stop = staticdata.opcode_implementations[op](self, pc)
#self.metainterp.most_recent_mp = None
if stop:
break
@@ -663,7 +664,7 @@
else:
moreargs = list(extraargs)
guard_op = self.metainterp.history.record(opnum, moreargs, None)
- resumedescr = compile.ResumeGuardDescr(guard_op, resume_info,
+ resumedescr = compile.ResumeGuardDescr(resume_info,
self.metainterp.history, len(self.metainterp.history.operations)-1)
op = history.ResOperation(rop.FAIL, liveboxes, None, descr=resumedescr)
guard_op.suboperations = [op]
@@ -699,10 +700,7 @@
# ____________________________________________________________
-class Optimizer(object):
- pass
-
-class OOMetaInterp(object):
+class MetaInterpStaticData(object):
num_green_args = 0
def __init__(self, portal_graph, graphs, cpu, stats, options,
@@ -711,8 +709,7 @@
self.cpu = cpu
self.stats = stats
self.options = options
- self.compiled_merge_points = r_dict(history.mp_eq, history.mp_hash)
- # { greenkey: list-of-MergePoints }
+ self.globaldata = MetaInterpGlobalData()
self.opcode_implementations = []
self.opcode_names = []
@@ -723,7 +720,6 @@
else:
self.cpu.class_sizes = None
self._virtualizabledescs = {}
- self._debug_history = []
if optimizer is not None:
self.optimize_loop = optimizer.optimize_loop
self.optimize_bridge = optimizer.optimize_bridge
@@ -732,6 +728,9 @@
self.optimize_loop = optimize.optimize_loop
self.optimize_bridge = optimize.optimize_bridge
+ def _freeze_(self):
+ return True
+
def _recompute_class_sizes(self):
if self.cpu.class_sizes is None:
cs = {}
@@ -743,7 +742,58 @@
self._codewriter = codewriter.CodeWriter(self, policy)
self.portal_code = self._codewriter.make_portal_bytecode(
self.portal_graph)
- self.delete_history()
+
+ # ---------- construction-time interface ----------
+
+ def _register_opcode(self, opname):
+ assert len(self.opcode_implementations) < 256, \
+ "too many implementations of opcodes!"
+ name = "opimpl_" + opname
+ self.opname_to_index[opname] = len(self.opcode_implementations)
+ self.opcode_names.append(opname)
+ self.opcode_implementations.append(getattr(MIFrame, name).im_func)
+
+ def find_opcode(self, name):
+ try:
+ return self.opname_to_index[name]
+ except KeyError:
+ self._register_opcode(name)
+ return self.opname_to_index[name]
+
+# ____________________________________________________________
+
+class MetaInterpGlobalData(object):
+ def __init__(self):
+ self.metainterp_doing_call = None
+ self._debug_history = []
+ self.compiled_merge_points = r_dict(history.mp_eq, history.mp_hash)
+ # { greenkey: list-of-MergePoints }
+
+ def set_metainterp_doing_call(self, metainterp):
+ self.save_recursive_call()
+ self.metainterp_doing_call = metainterp
+
+ def unset_metainterp_doing_call(self, metainterp):
+ if self.metainterp_doing_call != metainterp:
+ metainterp._restore_recursive_call()
+ self.metainterp_doing_call = None
+
+ def save_recursive_call(self):
+ if self.metainterp_doing_call is not None:
+ self.metainterp_doing_call._save_recursive_call()
+ self.metainterp_doing_call = None
+
+ def assert_empty(self):
+ assert self.metainterp_doing_call is None
+
+# ____________________________________________________________
+
+class MetaInterp(object):
+ def __init__(self, staticdata):
+ self.staticdata = staticdata
+ self.cpu = staticdata.cpu
+ if not we_are_translated():
+ self._debug_history = staticdata.globaldata._debug_history
def newframe(self, jitcode):
if not we_are_translated():
@@ -763,7 +813,7 @@
else:
if not isinstance(self.history, history.BlackHole):
self.compile_done_with_this_frame(resultbox)
- raise self.DoneWithThisFrame(resultbox)
+ raise self.staticdata.DoneWithThisFrame(resultbox)
def finishframe_exception(self, exceptionbox, excvaluebox):
while self.framestack:
@@ -778,22 +828,13 @@
self._debug_history.append(['leave_exc', frame.jitcode, None])
self.framestack.pop()
if not isinstance(self.history, history.BlackHole):
- self.compile_exit_frame_with_exception(exceptionbox, excvaluebox)
- raise self.ExitFrameWithException(exceptionbox, excvaluebox)
+ self.compile_exit_frame_with_exception(excvaluebox)
+ raise self.staticdata.ExitFrameWithException(excvaluebox)
def create_empty_history(self):
self.history = history.History(self.cpu)
- if self.stats is not None:
- self.stats.history = self.history
-
- def delete_history(self):
- self.history = None
- self.framestack = None
- self.current_merge_points = None
- self.resumekey = None
-
- def set_blackhole_mode(self):
- self.history = history.BlackHole(self.cpu)
+ if self.staticdata.stats is not None:
+ self.staticdata.stats.history = self.history
def _all_constants(self, boxes):
for box in boxes:
@@ -803,7 +844,9 @@
@specialize.arg(1)
def execute_and_record(self, opnum, argboxes, descr=None):
- old_framestack = self.framestack
+ # detect recursions when using rop.CALL
+ if opnum == rop.CALL:
+ self.staticdata.globaldata.set_metainterp_doing_call(self)
# execute the operation first
history.check_descr(descr)
resbox = executor.execute(self.cpu, opnum, argboxes, descr)
@@ -820,23 +863,55 @@
else:
assert resbox is None or isinstance(resbox, Box)
if opnum == rop.CALL:
- # with executor.execute(rop.CALL), there is a risk of recursion
- if self.framestack is not old_framestack:
- if not we_are_translated():
- history.log.info('recursion detected')
- self.framestack = old_framestack
- self.set_blackhole_mode()
+ self.staticdata.globaldata.unset_metainterp_doing_call(self)
# record the operation if not constant-folded away
if not canfold:
self.history.record(opnum, argboxes, resbox, descr)
return resbox
+ def _save_recursive_call(self):
+ # A bit of a hack: we need to be safe against box.changevalue_xxx()
+ # called by cpu.execute_operations(), in case we are recursively
+ # in another MetaInterp. Temporarily save away the content of the
+ # boxes.
+ if not we_are_translated():
+ history.log.info('recursive call to execute_operations()!')
+ saved_env = []
+ for f in self.framestack:
+ newenv = []
+ for box in f.env:
+ if isinstance(box, Box):
+ saved_env.append(box.clonebox())
+ pseudoframe = instantiate(MIFrame)
+ pseudoframe.env = saved_env
+ self.framestack.append(pseudoframe)
+
+ def _restore_recursive_call(self):
+ if not we_are_translated():
+ history.log.info('recursion detected, restoring state')
+ assert not hasattr(self.framestack[-1], 'jitcode')
+ assert hasattr(self.framestack[-2], 'jitcode')
+ pseudoframe = self.framestack.pop()
+ saved_env = pseudoframe.env
+ i = 0
+ for f in self.framestack:
+ for box in f.env:
+ if isinstance(box, BoxInt):
+ box.changevalue_int(saved_env[i].getint())
+ i += 1
+ elif isinstance(box, BoxPtr):
+ box.changevalue_ptr(saved_env[i].getptr_base())
+ i += 1
+ else:
+ assert isinstance(box, Const)
+ assert i == len(saved_env)
+
def _interpret(self):
# Execute the frames forward until we raise a DoneWithThisFrame,
# a ContinueRunningNormally, or a GenerateMergePoint exception.
if not we_are_translated():
history.log.event('ENTER' + self.history.extratext)
- self.stats.enter_count += 1
+ self.staticdata.stats.enter_count += 1
else:
debug_print('~~~ ENTER', self.history.extratext)
try:
@@ -873,8 +948,8 @@
except GenerateMergePoint, gmp:
return self.designate_target_loop(gmp)
- def handle_guard_failure(self, guard_failure, key):
- self.initialize_state_from_guard_failure(guard_failure)
+ def handle_guard_failure(self, exec_result, key):
+ self.initialize_state_from_guard_failure(exec_result)
assert isinstance(key, compile.ResumeGuardDescr)
top_history = key.find_toplevel_history()
source_loop = top_history.source_link
@@ -882,8 +957,9 @@
original_boxes = source_loop.greenkey + top_history.inputargs
self.current_merge_points = [(original_boxes, 0)]
self.resumekey = key
+ guard_op = key.get_guard_op()
try:
- self.prepare_resume_from_failure(key.guard_op.opnum)
+ self.prepare_resume_from_failure(guard_op.opnum)
self.interpret()
assert False, "should always raise"
except GenerateMergePoint, gmp:
@@ -906,7 +982,7 @@
for j in range(len(self.current_merge_points)-1, -1, -1):
original_boxes, start = self.current_merge_points[j]
assert len(original_boxes) == len(live_arg_boxes)
- for i in range(self.num_green_args):
+ for i in range(self.staticdata.num_green_args):
box1 = original_boxes[i]
box2 = live_arg_boxes[i]
if not box1.equals(box2):
@@ -942,9 +1018,8 @@
raise GenerateMergePoint(live_arg_boxes, loop)
def designate_target_loop(self, gmp):
- self.delete_history()
loop = gmp.target_loop
- num_green_args = self.num_green_args
+ num_green_args = self.staticdata.num_green_args
residual_args = self.get_residual_args(loop,
gmp.argboxes[num_green_args:])
return (loop, residual_args)
@@ -958,23 +1033,24 @@
self.handle_exception()
def compile(self, original_boxes, live_arg_boxes):
- num_green_args = self.num_green_args
+ num_green_args = self.staticdata.num_green_args
self.history.inputargs = original_boxes[num_green_args:]
greenkey = original_boxes[:num_green_args]
- old_loops = self.compiled_merge_points.setdefault(greenkey, [])
+ glob = self.staticdata.globaldata
+ old_loops = glob.compiled_merge_points.setdefault(greenkey, [])
self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None)
loop = compile.compile_new_loop(self, old_loops, greenkey)
assert loop is not None
if not we_are_translated():
loop._call_history = self._debug_history
- self.debug_history = []
return loop
def compile_bridge(self, live_arg_boxes):
- num_green_args = self.num_green_args
+ num_green_args = self.staticdata.num_green_args
greenkey = live_arg_boxes[:num_green_args]
try:
- old_loops = self.compiled_merge_points[greenkey]
+ glob = self.staticdata.globaldata
+ old_loops = glob.compiled_merge_points[greenkey]
except KeyError:
return
self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None)
@@ -999,9 +1075,9 @@
target_loop = compile.compile_new_bridge(self, loops, self.resumekey)
assert target_loop is loops[0]
- def compile_exit_frame_with_exception(self, typebox, valuebox):
+ def compile_exit_frame_with_exception(self, valuebox):
# temporarily put a JUMP to a pseudo-loop
- self.history.record(rop.JUMP, [typebox, valuebox], None)
+ self.history.record(rop.JUMP, [valuebox], None)
loops = compile.loops_exit_frame_with_exception
target_loop = compile.compile_new_bridge(self, loops, self.resumekey)
assert target_loop is loops[0]
@@ -1045,14 +1121,14 @@
*args[1:])
def initialize_state_from_start(self, *args):
- self._recompute_class_sizes()
+ self.staticdata._recompute_class_sizes()
self.create_empty_history()
- num_green_args = self.num_green_args
+ num_green_args = self.staticdata.num_green_args
original_boxes = []
self._initialize_from_start(original_boxes, num_green_args, *args)
# ----- make a new frame -----
self.framestack = []
- f = self.newframe(self.portal_code)
+ f = self.newframe(self.staticdata.portal_code)
f.pc = 0
f.env = original_boxes[:]
return original_boxes
@@ -1061,7 +1137,8 @@
# guard failure: rebuild a complete MIFrame stack
resumedescr = guard_failure.descr
assert isinstance(resumedescr, compile.ResumeGuardDescr)
- must_compile = self.state.must_compile_from_failure(resumedescr)
+ warmrunnerstate = self.staticdata.state
+ must_compile = warmrunnerstate.must_compile_from_failure(resumedescr)
if must_compile:
guard_op = resumedescr.get_guard_op()
suboperations = guard_op.suboperations
@@ -1076,7 +1153,9 @@
self.history.operations.append(suboperations[i])
self.extra_rebuild_operations = extra
else:
- self.set_blackhole_mode()
+ self.history = history.BlackHole(self.cpu)
+ # the BlackHole is invalid because it doesn't start with
+ # guard_failure.key.guard_op.suboperations, but that's fine
self.rebuild_state_after_failure(resumedescr.resume_info,
guard_failure.args)
@@ -1108,24 +1187,6 @@
exception_target)
assert nbindex == len(newboxes), "too many newboxes!"
- # ____________________________________________________________
- # construction-time interface
-
- def _register_opcode(self, opname):
- assert len(self.opcode_implementations) < 256, \
- "too many implementations of opcodes!"
- name = "opimpl_" + opname
- self.opname_to_index[opname] = len(self.opcode_implementations)
- self.opcode_names.append(opname)
- self.opcode_implementations.append(getattr(MIFrame, name).im_func)
-
- def find_opcode(self, name):
- try:
- return self.opname_to_index[name]
- except KeyError:
- self._register_opcode(name)
- return self.opname_to_index[name]
-
class GenerateMergePoint(Exception):
def __init__(self, args, target_loop):
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py Wed Apr 8 14:23:00 2009
@@ -21,7 +21,8 @@
cpu = CPUClass(rtyper, stats, False)
graph = rtyper.annotator.translator.graphs[0]
opt = history.Options(specialize=False, listops=listops)
- metainterp = pyjitpl.OOMetaInterp(graph, [], cpu, stats, opt)
+ metainterp_sd = pyjitpl.MetaInterpStaticData(graph, [], cpu, stats, opt)
+ metainterp = pyjitpl.MetaInterp(metainterp_sd)
metainterp.num_green_args = 0
return metainterp, rtyper
@@ -68,16 +69,15 @@
metainterp, rtyper = get_metainterp(f, args, self.CPUClass,
self.type_system, policy=policy,
**kwds)
- cw = codewriter.CodeWriter(metainterp, policy)
+ cw = codewriter.CodeWriter(metainterp.staticdata, policy)
graph = rtyper.annotator.translator.graphs[0]
maingraph = cw.make_one_bytecode(graph, False)
while cw.unfinished_graphs:
graph, called_from = cw.unfinished_graphs.pop()
cw.make_one_bytecode(graph, False, called_from)
- metainterp.portal_code = maingraph
- metainterp.delete_history()
- metainterp.state = FakeWarmRunnerDesc()
- metainterp.DoneWithThisFrame = DoneWithThisFrame
+ metainterp.staticdata.portal_code = maingraph
+ metainterp.staticdata.state = FakeWarmRunnerDesc()
+ metainterp.staticdata.DoneWithThisFrame = DoneWithThisFrame
self.metainterp = metainterp
try:
metainterp.compile_and_run_once(*args)
@@ -89,7 +89,7 @@
raise Exception("FAILED")
def check_history_(self, expected=None, **isns):
- self.metainterp.stats.check_history(expected, **isns)
+ self.metainterp.staticdata.stats.check_history(expected, **isns)
class OOJitMixin(JitMixin):
type_system = 'ootype'
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py Wed Apr 8 14:23:00 2009
@@ -24,7 +24,6 @@
assert res == main(20)
def test_recursion_three_times(self):
- py.test.skip("in-progress")
myjitdriver = JitDriver(greens=[], reds=['n', 'm', 'total'])
def f(n):
m = n - 3
@@ -46,7 +45,7 @@
print '%3d %9d' % (i, f(i))
res = self.meta_interp(main, [10])
assert res == main(10)
- self.check_enter_count_at_most(6)
+ self.check_enter_count_at_most(10)
class TestLLtype(RecursiveTests, LLJitMixin):
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py Wed Apr 8 14:23:00 2009
@@ -15,7 +15,7 @@
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.jit.metainterp import support, history, pyjitpl
-from pypy.jit.metainterp.pyjitpl import OOMetaInterp, Options
+from pypy.jit.metainterp.pyjitpl import MetaInterpStaticData, MetaInterp
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp.policy import JitPolicy
@@ -108,11 +108,11 @@
self.build_meta_interp(**kwds)
self.make_args_specification()
self.rewrite_jit_merge_point()
- self.metainterp.generate_bytecode(policy)
+ self.metainterp_sd.generate_bytecode(policy)
self.make_enter_function()
self.rewrite_can_enter_jit()
- self.metainterp.num_green_args = self.num_green_args
- self.metainterp.state = self.state
+ self.metainterp_sd.num_green_args = self.num_green_args
+ self.metainterp_sd.state = self.state
def finish(self):
if self.cpu.translate_support_code:
@@ -124,7 +124,7 @@
def build_meta_interp(self, CPUClass=runner.CPU, view="auto",
translate_support_code=False, optimizer=None,
**kwds):
- opt = Options(**kwds)
+ opt = pyjitpl.Options(**kwds)
self.stats = history.Stats()
if translate_support_code:
self.annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
@@ -149,8 +149,9 @@
self.translator.graphs.append(graph)
self.portal_graph = graph
self.jitdriver = block.operations[pos].args[1].value
- self.metainterp = OOMetaInterp(graph, graphs, cpu, self.stats, opt,
- optimizer=optimizer)
+ self.metainterp_sd = MetaInterpStaticData(graph, graphs, cpu,
+ self.stats, opt,
+ optimizer=optimizer)
def make_enter_function(self):
WarmEnterState = make_state_class(self)
@@ -270,15 +271,13 @@
def __init__(self, resultbox):
self.resultbox = resultbox
def __str__(self):
- return 'DoneWithThisFrame(%s)' % (self.result,)
+ return 'DoneWithThisFrame(%s)' % (self.resultbox,)
class ExitFrameWithException(JitException):
- def __init__(self, typebox, valuebox):
- self.typebox = typebox
+ def __init__(self, valuebox):
self.valuebox = valuebox
def __str__(self):
- return 'ExitFrameWithException(%s, %s)' % (self.type,
- self.value)
+ return 'ExitFrameWithException(%s)' % (self.valuebox,)
class ContinueRunningNormally(JitException):
def __init__(self, args):
@@ -291,9 +290,9 @@
self.DoneWithThisFrame = DoneWithThisFrame
self.ExitFrameWithException = ExitFrameWithException
self.ContinueRunningNormally = ContinueRunningNormally
- self.metainterp.DoneWithThisFrame = DoneWithThisFrame
- self.metainterp.ExitFrameWithException = ExitFrameWithException
- self.metainterp.ContinueRunningNormally = ContinueRunningNormally
+ self.metainterp_sd.DoneWithThisFrame = DoneWithThisFrame
+ self.metainterp_sd.ExitFrameWithException = ExitFrameWithException
+ self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally
rtyper = self.translator.rtyper
portalfunc_ARGS = unrolling_iterable(list(enumerate(PORTALFUNC.ARGS)))
RESULT = PORTALFUNC.RESULT
@@ -313,9 +312,7 @@
except ExitFrameWithException, e:
value = e.valuebox.getptr(lltype.Ptr(rclass.OBJECT))
if not we_are_translated():
- type = e.typebox.getaddr(self.metainterp.cpu)
- type = llmemory.cast_adr_to_ptr(type, rclass.CLASSTYPE)
- raise LLException(type, value)
+ raise LLException(value.typeptr, value)
else:
value = cast_base_ptr_to_instance(Exception, value)
raise Exception, value
@@ -468,7 +465,8 @@
self.cells[argshash] = Counter(n)
return
#interp.debug_trace("jit_compile", *greenargs)
- metainterp = warmrunnerdesc.metainterp
+ metainterp_sd = warmrunnerdesc.metainterp_sd
+ metainterp = MetaInterp(metainterp_sd)
loop, boxes = metainterp.compile_and_run_once(*args)
else:
# machine code was already compiled for these greenargs
@@ -482,10 +480,13 @@
loop = cell.bridge
boxes = cell.fill_boxes(*args[num_green_args:])
# ---------- execute assembler ----------
+ warmrunnerdesc.metainterp_sd.globaldata.save_recursive_call()
while True: # until interrupted by an exception
- metainterp = warmrunnerdesc.metainterp
- fail_op = metainterp.cpu.execute_operations(loop, boxes)
- loop, boxes = fail_op.descr.handle_fail_op(metainterp, fail_op)
+ metainterp_sd = warmrunnerdesc.metainterp_sd
+ metainterp_sd.globaldata.assert_empty()
+ fail_op = metainterp_sd.cpu.execute_operations(loop, boxes)
+ loop, boxes = fail_op.descr.handle_fail_op(metainterp_sd,
+ fail_op)
maybe_compile_and_run._dont_inline_ = True
def handle_hash_collision(self, cell, argshash, *args):
More information about the Pypy-commit
mailing list