def finilize_short_preamble(self, start_label): short = self.short assert short[-1].getopnum() == rop.JUMP target_token = start_label.getdescr() assert isinstance(target_token, TargetToken) # Turn guards into conditional jumps to the preamble for i in range(len(short)): op = short[i] if op.is_guard(): op = op.clone() op.setfailargs(None) descr = target_token.resume_at_jump_descr.clone_if_mutable() op.setdescr(descr) short[i] = op # Clone ops and boxes to get private versions and short_inputargs = short[0].getarglist() boxmap = {} newargs = [None] * len(short_inputargs) for i in range(len(short_inputargs)): a = short_inputargs[i] if a in boxmap: newargs[i] = boxmap[a] else: newargs[i] = a.clonebox() boxmap[a] = newargs[i] inliner = Inliner(short_inputargs, newargs) target_token.assumed_classes = {} for i in range(len(short)): op = short[i] newop = inliner.inline_op(op) if op.result and op.result in self.short_boxes.assumed_classes: target_token.assumed_classes[newop.result] = self.short_boxes.assumed_classes[op.result] short[i] = newop target_token.resume_at_jump_descr = target_token.resume_at_jump_descr.clone_if_mutable() inliner.inline_descr_inplace(target_token.resume_at_jump_descr) # Forget the values to allow them to be freed for box in short[0].getarglist(): box.forget_value() for op in short: if op.result: op.result.forget_value() target_token.short_preamble = self.short target_token.exported_state = None
def jump_to_already_compiled_trace(self, jumpop): assert jumpop.getopnum() == rop.JUMP cell_token = jumpop.getdescr() assert isinstance(cell_token, JitCellToken) if not cell_token.target_tokens: return False if not self.inline_short_preamble: assert cell_token.target_tokens[0].virtual_state is None jumpop.setdescr(cell_token.target_tokens[0]) self.optimizer.send_extra_operation(jumpop) return True args = jumpop.getarglist() modifier = VirtualStateAdder(self.optimizer) virtual_state = modifier.get_virtual_state(args) debug_start('jit-log-virtualstate') virtual_state.debug_print("Looking for ") for target in cell_token.target_tokens: if not target.virtual_state: continue ok = False extra_guards = [] bad = {} debugmsg = 'Did not match ' if target.virtual_state.generalization_of(virtual_state, bad): ok = True debugmsg = 'Matched ' else: try: cpu = self.optimizer.cpu target.virtual_state.generate_guards(virtual_state, args, cpu, extra_guards) ok = True debugmsg = 'Guarded to match ' except InvalidLoop: pass target.virtual_state.debug_print(debugmsg, bad) if ok: debug_stop('jit-log-virtualstate') values = [self.getvalue(arg) for arg in jumpop.getarglist()] args = target.virtual_state.make_inputargs(values, self.optimizer, keyboxes=True) short_inputargs = target.short_preamble[0].getarglist() inliner = Inliner(short_inputargs, args) for guard in extra_guards: if guard.is_guard(): descr = target.resume_at_jump_descr.clone_if_mutable() inliner.inline_descr_inplace(descr) guard.setdescr(descr) self.optimizer.send_extra_operation(guard) try: for shop in target.short_preamble[1:]: newop = inliner.inline_op(shop) self.optimizer.send_extra_operation(newop) if shop.result in target.assumed_classes: classbox = self.getvalue(newop.result).get_constant_class(self.optimizer.cpu) if not classbox or not classbox.same_constant(target.assumed_classes[shop.result]): raise InvalidLoop('The class of an opaque pointer at the end ' + 'of the bridge does not mach the class ' + 'it has at the start of the target loop') except InvalidLoop: #debug_print("Inlining failed unexpectedly", # "jumping to preamble instead") assert cell_token.target_tokens[0].virtual_state is None jumpop.setdescr(cell_token.target_tokens[0]) self.optimizer.send_extra_operation(jumpop) return True debug_stop('jit-log-virtualstate') return False