def handle_async_forcing(self, force_token): from pypy.jit.metainterp.pyjitpl import MetaInterp from pypy.jit.metainterp.resume import force_from_resumedata # To handle the forcing itself, we create a temporary MetaInterp # as a convenience to move the various data to its proper place. metainterp_sd = self.metainterp_sd metainterp = MetaInterp(metainterp_sd) metainterp.history = None # blackholing liveboxes = metainterp_sd.cpu.make_boxes_from_latest_values(self) # expect_virtualizable = metainterp_sd.virtualizable_info is not None forced_data = force_from_resumedata(metainterp, liveboxes, self, expect_virtualizable) virtualizable_boxes, virtualref_boxes, all_virtuals = forced_data # # Handle virtualref_boxes: mark each JIT_VIRTUAL_REF as forced vrefinfo = metainterp_sd.virtualref_info for i in range(0, len(virtualref_boxes), 2): virtualbox = virtualref_boxes[i] vrefbox = virtualref_boxes[i+1] vrefinfo.forced_single_vref(vrefbox.getref_base(), virtualbox.getref_base()) # Handle virtualizable_boxes: store them on the real virtualizable now if expect_virtualizable: metainterp_sd.virtualizable_info.forced_vable(virtualizable_boxes) # Handle all_virtuals: keep them for later blackholing from the # future failure of the GUARD_NOT_FORCED self.save_data(force_token, all_virtuals)
def bound_reached(cell, *args): # bound reached, but we do a last check: if it is the first # time we reach the bound, or if another loop or bridge was # compiled since the last time we reached it, then decrease # the counter by a few percents instead. It should avoid # sudden bursts of JIT-compilation, and also corner cases # where we suddenly compile more than one loop because all # counters reach the bound at the same time, but where # compiling all but the first one is pointless. curgen = warmrunnerdesc.memory_manager.current_generation curgen = chr(intmask(curgen) & 0xFF) # only use 8 bits if we_are_translated() and curgen != cell.extra_delay: cell.counter = int(self.THRESHOLD_LIMIT * 0.98) cell.extra_delay = curgen return # if not confirm_enter_jit(*args): cell.counter = 0 return # start tracing from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd, jitdriver_sd) # set counter to -2, to mean "tracing in effect" cell.counter = -2 try: metainterp.compile_and_run_once(jitdriver_sd, *args) finally: if cell.counter == -2: cell.counter = 0
def _trace_and_compile_from_bridge(self, metainterp_sd, jitdriver_sd): # 'jitdriver_sd' corresponds to the outermost one, i.e. the one # of the jit_merge_point where we started the loop, even if the # loop itself may contain temporarily recursion into other # jitdrivers. from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd, jitdriver_sd) metainterp.handle_guard_failure(self)
def handle_fail(self, metainterp_sd): from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) token = metainterp_sd.cpu.get_latest_force_token() all_virtuals = self.fetch_data(token) if all_virtuals is None: all_virtuals = [] metainterp._already_allocated_resume_virtuals = all_virtuals return metainterp.handle_guard_failure(self)
def maybe_compile_and_run(*args): """Entry point to the JIT. Called at the point with the can_enter_jit() hint. """ globaldata = metainterp_sd.globaldata if NonConstant(False): # make sure we always see the saner optimizer from an # annotation point of view, otherwise we get lots of # blocked ops self.set_param_optimizer(OPTIMIZER_FULL) if vinfo is not None: virtualizable = args[vinfo.index_of_virtualizable] virtualizable = vinfo.cast_to_vtype(virtualizable) assert virtualizable != globaldata.blackhole_virtualizable, ( "reentering same frame via blackhole") # look for the cell corresponding to the current greenargs greenargs = args[:num_green_args] cell = get_jitcell(*greenargs) if cell.counter >= 0: # update the profiling counter n = cell.counter + self.increment_threshold if n <= self.THRESHOLD_LIMIT: # bound not reached cell.counter = n return # bound reached; start tracing from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) try: loop_token = metainterp.compile_and_run_once(*args) except ContinueRunningNormally: # the trace got too long, reset the counter cell.counter = 0 raise else: # machine code was already compiled for these greenargs # get the assembler and fill in the boxes set_future_values(*args[num_green_args:]) loop_token = cell.entry_loop_token # ---------- execute assembler ---------- while True: # until interrupted by an exception metainterp_sd.profiler.start_running() fail_index = metainterp_sd.cpu.execute_token(loop_token) metainterp_sd.profiler.end_running() fail_descr = globaldata.get_fail_descr_from_number(fail_index) loop_token = fail_descr.handle_fail(metainterp_sd)
def handle_fail(self, metainterp_sd): from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) return metainterp.handle_guard_failure(self)
def maybe_compile_and_run(threshold, *args): """Entry point to the JIT. Called at the point with the can_enter_jit() hint. """ if vinfo is not None: virtualizable = args[num_green_args + index_of_virtualizable] virtualizable = vinfo.cast_to_vtype(virtualizable) else: virtualizable = None # look for the cell corresponding to the current greenargs greenargs = args[:num_green_args] cell = get_jitcell(True, *greenargs) if cell.counter >= 0: # update the profiling counter n = cell.counter + threshold if n <= self.THRESHOLD_LIMIT: # bound not reached cell.counter = n return if not confirm_enter_jit(*args): cell.counter = 0 return # bound reached; start tracing from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd, jitdriver_sd) # set counter to -2, to mean "tracing in effect" cell.counter = -2 try: loop_token = metainterp.compile_and_run_once(jitdriver_sd, *args) finally: if cell.counter == -2: cell.counter = 0 else: if cell.counter == -2: # tracing already happening in some outer invocation of # this function. don't trace a second time. return assert cell.counter == -1 if not confirm_enter_jit(*args): return loop_token = cell.get_entry_loop_token() if loop_token is None: # it was a weakref that has been freed cell.counter = 0 return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes set_future_values(*args[num_green_args:]) # ---------- execute assembler ---------- while True: # until interrupted by an exception metainterp_sd.profiler.start_running() #debug_start("jit-running") fail_descr = warmrunnerdesc.execute_token(loop_token) #debug_stop("jit-running") metainterp_sd.profiler.end_running() loop_token = None # for test_memmgr if vinfo is not None: vinfo.reset_vable_token(virtualizable) loop_token = fail_descr.handle_fail(metainterp_sd, jitdriver_sd)
def maybe_compile_and_run(*args): """Entry point to the JIT. Called at the point with the can_enter_jit() hint. """ globaldata = metainterp_sd.globaldata if NonConstant(False): # make sure we always see the saner optimizer from an # annotation point of view, otherwise we get lots of # blocked ops self.set_param_optimizer(OPTIMIZER_FULL) if vinfo is not None: virtualizable = args[vinfo.index_of_virtualizable] virtualizable = vinfo.cast_to_vtype(virtualizable) else: virtualizable = None # look for the cell corresponding to the current greenargs greenargs = args[:num_green_args] cell = get_jitcell(*greenargs) if cell.counter >= 0: # update the profiling counter n = cell.counter + self.increment_threshold if n <= self.THRESHOLD_LIMIT: # bound not reached cell.counter = n return if not confirm_enter_jit(*args): cell.counter = 0 return # bound reached; start tracing from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) # set counter to -2, to mean "tracing in effect" cell.counter = -2 try: loop_token = metainterp.compile_and_run_once(*args) except ContinueRunningNormally: # the trace got too long, reset the counter cell.counter = 0 self.disable_noninlinable_function(metainterp) raise finally: if cell.counter == -2: cell.counter = 0 else: if cell.counter == -2: # tracing already happening in some outer invocation of # this function. don't trace a second time. return assert cell.counter == -1 if not confirm_enter_jit(*args): return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes set_future_values(*args[num_green_args:]) loop_token = cell.entry_loop_token # ---------- execute assembler ---------- while True: # until interrupted by an exception metainterp_sd.profiler.start_running() debug_start("jit-running") fail_descr = metainterp_sd.cpu.execute_token(loop_token) debug_stop("jit-running") metainterp_sd.profiler.end_running() if vinfo is not None: vinfo.reset_vable_token(virtualizable) loop_token = fail_descr.handle_fail(metainterp_sd)