Author: Maciej Fijalkowski <fij...@gmail.com> Branch: better-jit-hooks Changeset: r51178:b3dd81a62153 Date: 2012-01-09 19:49 +0200 http://bitbucket.org/pypy/pypy/changeset/b3dd81a62153/
Log: improve the situation with arguments of the hooks 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 @@ -141,7 +141,6 @@ self._compile_loop_or_bridge(c, inputargs, operations, clt) old, oldindex = faildescr._compiled_fail llimpl.compile_redirect_fail(old, oldindex, c) - return None, 0, 0 def compile_loop(self, inputargs, operations, jitcell_token, log=True, name=''): @@ -156,7 +155,6 @@ clt.compiled_version = c jitcell_token.compiled_loop_token = clt self._compile_loop_or_bridge(c, inputargs, operations, clt) - return None, 0, 0 def free_loop_and_bridges(self, compiled_loop_token): for c in compiled_loop_token.loop_and_bridges: diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -7,6 +7,7 @@ from pypy.rpython.lltypesystem import lltype, rffi, rstr, llmemory from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper +from pypy.rlib.jit import AsmInfo from pypy.jit.backend.model import CompiledLoopToken from pypy.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs, _get_scale, gpr_reg_mgr_cls, _valid_addressing_size) @@ -477,8 +478,8 @@ name = "Loop # %s: %s" % (looptoken.number, loopname) self.cpu.profile_agent.native_code_written(name, rawstart, full_size) - return (ops_offset, rawstart + looppos, - size_excluding_failure_stuff - looppos) + return AsmInfo(ops_offset, rawstart + looppos, + size_excluding_failure_stuff - looppos) def assemble_bridge(self, faildescr, inputargs, operations, original_loop_token, log): @@ -492,7 +493,7 @@ except ValueError: debug_print("Bridge out of guard", descr_number, "was already compiled!") - raise + return self.setup(original_loop_token) if log: @@ -540,7 +541,7 @@ name = "Bridge # %s" % (descr_number,) self.cpu.profile_agent.native_code_written(name, rawstart, fullsize) - return ops_offset, startpos + rawstart, codeendpos - startpos + return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) def write_pending_failure_recoveries(self): # for each pending guard, generate the code of the recovery stub 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 @@ -5,6 +5,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import debug_start, debug_stop, debug_print from pypy.rlib import rstack +from pypy.rlib.jit import JitDebugInfo from pypy.conftest import option from pypy.tool.sourcetools import func_with_new_name @@ -307,32 +308,36 @@ if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks - hooks.before_compile(jitdriver_sd.jitdriver, metainterp_sd.logger_ops, - original_jitcell_token, loop.operations, type, - greenkey) + debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, + original_jitcell_token, loop.operations, + type, greenkey) + hooks.before_compile(debug_info) else: + debug_info = None hooks = None operations = get_deep_immutable_oplist(loop.operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: - tp = metainterp_sd.cpu.compile_loop(loop.inputargs, operations, - original_jitcell_token, - name=loopname) - ops_offset, asmstart, asmlen = tp + asminfo = metainterp_sd.cpu.compile_loop(loop.inputargs, operations, + original_jitcell_token, + name=loopname) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: - hooks.after_compile(jitdriver_sd.jitdriver, metainterp_sd.logger_ops, - original_jitcell_token, loop.operations, type, - greenkey, ops_offset, asmstart, asmlen) + debug_info.asminfo = asminfo + hooks.after_compile(debug_info) metainterp_sd.stats.add_new_loop(loop) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new " + type) # loopname = jitdriver_sd.warmstate.get_location_str(greenkey) + if asminfo is not None: + ops_offset = asminfo.ops_offset + else: + ops_offset = None metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n, type, ops_offset, name=loopname) @@ -349,31 +354,34 @@ TreeLoop.check_consistency_of_branch(operations, seen) if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks - hooks.before_compile_bridge(jitdriver_sd.jitdriver, - metainterp_sd.logger_ops, - original_loop_token, operations, n) + debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, + original_loop_token, operations, 'bridge', + fail_descr_no=n) + hooks.before_compile_bridge(debug_info) else: hooks = None + debug_info = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: - tp = metainterp_sd.cpu.compile_bridge(faildescr, inputargs, operations, - original_loop_token) - ops_offset, asmstart, asmlen = tp + asminfo = metainterp_sd.cpu.compile_bridge(faildescr, inputargs, + operations, + original_loop_token) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: - hooks.after_compile_bridge(jitdriver_sd.jitdriver, - metainterp_sd.logger_ops, - original_loop_token, operations, n, - ops_offset, - asmstart, asmlen) + debug_info.asminfo = asminfo + hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # + if asminfo is not None: + ops_offset = asminfo.ops_offset + else: + ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, n, ops_offset) # #if metainterp_sd.warmrunnerdesc is not None: # for tests diff --git a/pypy/jit/metainterp/test/test_jitiface.py b/pypy/jit/metainterp/test/test_jitiface.py --- a/pypy/jit/metainterp/test/test_jitiface.py +++ b/pypy/jit/metainterp/test/test_jitiface.py @@ -45,22 +45,18 @@ called = [] class MyJitIface(JitHookInterface): - def after_compile(self, jitdriver, logger, looptoken, operations, - type, greenkey, ops_offset, asmaddr, asmlen): - assert asmaddr == 0 - assert asmlen == 0 - called.append(("compile", greenkey[1].getint(), - greenkey[0].getint(), type)) + def after_compile(self, di): + called.append(("compile", di.greenkey[1].getint(), + di.greenkey[0].getint(), di.type)) - def before_compile(self, jitdriver, logger, looptoken, oeprations, - type, greenkey): - called.append(("optimize", greenkey[1].getint(), - greenkey[0].getint(), type)) + def before_compile(self, di): + called.append(("optimize", di.greenkey[1].getint(), + di.greenkey[0].getint(), di.type)) - def before_optimize(self, jitdriver, logger, looptoken, oeprations, - type, greenkey): - called.append(("trace", greenkey[1].getint(), - greenkey[0].getint(), type)) + #def before_optimize(self, jitdriver, logger, looptoken, oeprations, + # type, greenkey): + # called.append(("trace", greenkey[1].getint(), + # greenkey[0].getint(), type)) iface = MyJitIface() @@ -89,18 +85,13 @@ called = [] class MyJitIface(JitHookInterface): - def after_compile(self, jitdriver, logger, looptoken, operations, - type, greenkey, ops_offset, asmaddr, asmlen): - assert asmaddr == 0 - assert asmlen == 0 + def after_compile(self, di): called.append("compile") - def after_compile_bridge(self, jitdriver, logger, orig_token, - operations, n, ops_offset, asmstart, asmlen): + def after_compile_bridge(self, di): called.append("compile_bridge") - def before_compile_bridge(self, jitdriver, logger, orig_token, - operations, n): + def before_compile_bridge(self, di): called.append("before_compile_bridge") driver = JitDriver(greens = ['n', 'm'], reds = ['i']) diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py --- a/pypy/module/pypyjit/interp_resop.py +++ b/pypy/module/pypyjit/interp_resop.py @@ -107,9 +107,15 @@ cache.in_recursion = NonConstant(False) def wrap_oplist(space, logops, operations, ops_offset): - return [WrappedOp(jit_hooks._cast_to_gcref(op), - ops_offset.get(op, 0), - logops.repr_of_resop(op)) for op in operations] + l_w = [] + for op in operations: + if ops_offset is None: + ofs = -1 + else: + ofs = ops_offset.get(op, 0) + l_w.append(WrappedOp(jit_hooks._cast_to_gcref(op), ofs, + logops.repr_of_resop(op))) + return l_w class WrappedBox(Wrappable): """ A class representing a single box diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -725,72 +725,104 @@ return hop.genop('jit_marker', vlist, resulttype=lltype.Void) +class AsmInfo(object): + """ An addition to JitDebugInfo concerning assembler. Attributes: + + ops_offset - dict of offsets of operations or None + asmaddr - (int) raw address of assembler block + asmlen - assembler block length + """ + def __init__(self, ops_offset, asmaddr, asmlen): + self.ops_offset = ops_offset + self.asmaddr = asmaddr + self.asmlen = asmlen + +class JitDebugInfo(object): + """ An object representing debug info. Attributes meanings: + + greenkey - a list of green boxes or None for bridge + logger - an instance of jit.metainterp.logger.LogOperations + type - either 'loop', 'entry bridge' or 'bridge' + looptoken - description of a loop + fail_descr_no - number of failing descr for bridges, -1 otherwise + asminfo - extra assembler information + """ + + asminfo = None + def __init__(self, jitdriver_sd, logger, looptoken, operations, type, + greenkey=None, fail_descr_no=-1): + self.jitdriver_sd = jitdriver_sd + self.logger = logger + self.looptoken = looptoken + self.operations = operations + self.type = type + if type == 'bridge': + assert fail_descr_no != -1 + else: + assert greenkey is not None + self.greenkey = greenkey + self.fail_descr_no = fail_descr_no + + def get_jitdriver(self): + """ Return where the jitdriver on which the jitting started + """ + return self.jitdriver_sd.jitdriver + + def get_greenkey_repr(self): + """ Return the string repr of a greenkey + """ + return self.jitdriver_sd.warmstate.get_location_str(self.greenkey) + class JitHookInterface(object): """ This is the main connector between the JIT and the interpreter. Several methods on this class will be invoked at various stages of JIT running like JIT loops compiled, aborts etc. An instance of this class will be available as policy.jithookiface. - - each hook will accept some of the following args: - - - greenkey - a list of green boxes - jitdriver - an instance of jitdriver where tracing started - logger - an instance of jit.metainterp.logger.LogOperations - ops_offset - asmaddr - (int) raw address of assembler block - asmlen - assembler block length - type - either 'loop' or 'entry bridge' """ def on_abort(self, reason, jitdriver, greenkey): """ A hook called each time a loop is aborted with jitdriver and greenkey where it started, reason is a string why it got aborted """ - #def before_optimize(self, jitdriver, logger, looptoken, operations, - # type, greenkey): - # """ A hook called before optimizer is run, args described in class - # docstring. Overwrite for custom behavior + #def before_optimize(self, debug_info): + # """ A hook called before optimizer is run, called with instance of + # JitDebugInfo. Overwrite for custom behavior # """ # DISABLED - def before_compile(self, jitdriver, logger, looptoken, operations, type, - greenkey): + def before_compile(self, debug_info): """ A hook called after a loop is optimized, before compiling assembler, - args described ni class docstring. Overwrite for custom behavior + called with JitDebugInfo instance. Overwrite for custom behavior """ - def after_compile(self, jitdriver, logger, looptoken, operations, type, - greenkey, ops_offset, asmaddr, asmlen): + def after_compile(self, debug_info): """ A hook called after a loop has compiled assembler, - args described in class docstring. Overwrite for custom behavior + called with JitDebugInfo instance. Overwrite for custom behavior """ - #def before_optimize_bridge(self, jitdriver, logger, orig_looptoken, + #def before_optimize_bridge(self, debug_info): # operations, fail_descr_no): # """ A hook called before a bridge is optimized. - # Args described in class docstring, Overwrite for + # Called with JitDebugInfo instance, overwrite for # custom behavior # """ # DISABLED - def before_compile_bridge(self, jitdriver, logger, orig_looptoken, - operations, fail_descr_no): + def before_compile_bridge(self, debug_info): """ A hook called before a bridge is compiled, but after optimizations - are performed. Args described in class docstring, Overwrite for + are performed. Called with instance of debug_info, overwrite for custom behavior """ - def after_compile_bridge(self, jitdriver, logger, orig_looptoken, - operations, fail_descr_no, ops_offset, asmaddr, - asmlen): - """ A hook called after a bridge is compiled, args described in class - docstring, Overwrite for custom behavior + def after_compile_bridge(self, debug_info): + """ A hook called after a bridge is compiled, called with JitDebugInfo + instance, overwrite for custom behavior """ def get_stats(self): """ Returns various statistics """ + raise NotImplementedError def record_known_class(value, cls): """ _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit