Пример #1
0
    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
Пример #2
0
    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