Example #1
0
class NotVirtualStateInfo(AbstractVirtualStateInfo):
    def __init__(self, value):
        self.known_class = value.known_class
        self.level = value.level
        if value.intbound is None:
            self.intbound = IntUnbounded()
        else:
            self.intbound = value.intbound.clone()
        if value.is_constant():
            self.constbox = value.box
        else:
            self.constbox = None
        self.position_in_notvirtuals = -1
        self.lenbound = value.lenbound

    def generalization_of(self, other, renum, bad):
        # XXX This will always retrace instead of forcing anything which
        # might be what we want sometimes?
        assert self.position != -1
        if self.position in renum:
            if renum[self.position] == other.position:
                return True
            bad[self] = True
            bad[other] = True
            return False
        renum[self.position] = other.position
        if not isinstance(other, NotVirtualStateInfo):
            bad[self] = True
            bad[other] = True
            return False
        if other.level < self.level:
            bad[self] = True
            bad[other] = True
            return False
        if self.level == LEVEL_CONSTANT:
            if not self.constbox.same_constant(other.constbox):
                bad[self] = True
                bad[other] = True
                return False
        elif self.level == LEVEL_KNOWNCLASS:
            if not self.known_class.same_constant(other.known_class):
                bad[self] = True
                bad[other] = True
                return False
        if not self.intbound.contains_bound(other.intbound):
            bad[self] = True
            bad[other] = True
            return False
        if self.lenbound and other.lenbound:
            if self.lenbound.mode != other.lenbound.mode or \
               self.lenbound.descr != other.lenbound.descr or \
               not self.lenbound.bound.contains_bound(other.lenbound.bound):
                bad[self] = True
                bad[other] = True
                return False
        elif self.lenbound:
            bad[self] = True
            bad[other] = True
            return False
        return True

    def _generate_guards(self, other, box, cpu, extra_guards):
        if not isinstance(other, NotVirtualStateInfo):
            raise InvalidLoop('The VirtualStates does not match as a ' +
                              'virtual appears where a pointer is needed ' +
                              'and it is too late to force it.')

        if self.lenbound or other.lenbound:
            raise InvalidLoop('The array length bounds does not match.')

        if self.level == LEVEL_KNOWNCLASS and \
           box.nonnull() and \
           self.known_class.same_constant(cpu.ts.cls_of_box(box)):
            # Note: This is only a hint on what the class of box was
            # during the trace. There are actually no guarentees that this
            # box realy comes from a trace. The hint is used here to choose
            # between either eimtting a guard_class and jumping to an
            # excisting compiled loop or retracing the loop. Both
            # alternatives will always generate correct behaviour, but
            # performace will differ.
            op = ResOperation(rop.GUARD_NONNULL, [box], None)
            extra_guards.append(op)
            op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
            extra_guards.append(op)
            return

        if self.level == LEVEL_NONNULL and \
               other.level == LEVEL_UNKNOWN and \
               isinstance(box, BoxPtr) and \
               box.nonnull():
            op = ResOperation(rop.GUARD_NONNULL, [box], None)
            extra_guards.append(op)
            return

        if self.level == LEVEL_UNKNOWN and \
               other.level == LEVEL_UNKNOWN and \
               isinstance(box, BoxInt) and \
               self.intbound.contains(box.getint()):
            if self.intbound.has_lower:
                bound = self.intbound.lower
                if not (other.intbound.has_lower and \
                        other.intbound.lower >= bound):
                    res = BoxInt()
                    op = ResOperation(rop.INT_GE, [box, ConstInt(bound)], res)
                    extra_guards.append(op)
                    op = ResOperation(rop.GUARD_TRUE, [res], None)
                    extra_guards.append(op)
            if self.intbound.has_upper:
                bound = self.intbound.upper
                if not (other.intbound.has_upper and \
                        other.intbound.upper <= bound):
                    res = BoxInt()
                    op = ResOperation(rop.INT_LE, [box, ConstInt(bound)], res)
                    extra_guards.append(op)
                    op = ResOperation(rop.GUARD_TRUE, [res], None)
                    extra_guards.append(op)
            return

        # Remaining cases are probably not interesting
        raise InvalidLoop('Generating guards for making the VirtualStates ' +
                          'at hand match have not been implemented')
        if self.level == LEVEL_CONSTANT:
            import pdb; pdb.set_trace()
            raise NotImplementedError

    def enum_forced_boxes(self, boxes, value, optimizer):
        if self.level == LEVEL_CONSTANT:
            return
        assert 0 <= self.position_in_notvirtuals
        if optimizer:
            box = value.force_box(optimizer)
        else:
            if value.is_virtual():
                raise BadVirtualState
            box = value.get_key_box()
        boxes[self.position_in_notvirtuals] = box

    def _enum(self, virtual_state):
        if self.level == LEVEL_CONSTANT:
            return
        self.position_in_notvirtuals = len(virtual_state.notvirtuals)
        virtual_state.notvirtuals.append(self)

    def debug_print(self, indent, seen, bad):
        mark = ''
        if self in bad:
            mark = '*'
        if we_are_translated():
            l = {LEVEL_UNKNOWN: 'Unknown',
                 LEVEL_NONNULL: 'NonNull',
                 LEVEL_KNOWNCLASS: 'KnownClass',
                 LEVEL_CONSTANT: 'Constant',
                 }[self.level]
        else:
            l = {LEVEL_UNKNOWN: 'Unknown',
                 LEVEL_NONNULL: 'NonNull',
                 LEVEL_KNOWNCLASS: 'KnownClass(%r)' % self.known_class,
                 LEVEL_CONSTANT: 'Constant(%r)' % self.constbox,
                 }[self.level]

        lb = ''
        if self.lenbound:
            lb = ', ' + self.lenbound.bound.__repr__()

        debug_print(indent + mark + 'NotVirtualInfo(%d' % self.position +
                    ', ' + l + ', ' + self.intbound.__repr__() + lb + ')')
Example #2
0
class NotVirtualStateInfo(AbstractVirtualStateInfo):
    def __init__(self, value):
        self.known_class = value.known_class
        self.level = value.level
        if value.intbound is None:
            self.intbound = IntUnbounded()
        else:
            self.intbound = value.intbound.clone()
        if value.is_constant():
            self.constbox = value.box
        else:
            self.constbox = None
        self.position_in_notvirtuals = -1
        self.lenbound = value.lenbound

    def generalization_of(self, other, renum, bad):
        # XXX This will always retrace instead of forcing anything which
        # might be what we want sometimes?
        assert self.position != -1
        if self.position in renum:
            if renum[self.position] == other.position:
                return True
            bad[self] = True
            bad[other] = True
            return False
        renum[self.position] = other.position
        if not isinstance(other, NotVirtualStateInfo):
            bad[self] = True
            bad[other] = True
            return False
        if other.level < self.level:
            bad[self] = True
            bad[other] = True
            return False
        if self.level == LEVEL_CONSTANT:
            if not self.constbox.same_constant(other.constbox):
                bad[self] = True
                bad[other] = True
                return False
        elif self.level == LEVEL_KNOWNCLASS:
            if not self.known_class.same_constant(other.known_class):
                bad[self] = True
                bad[other] = True
                return False
        if not self.intbound.contains_bound(other.intbound):
            bad[self] = True
            bad[other] = True
            return False
        if self.lenbound and other.lenbound:
            if self.lenbound.mode != other.lenbound.mode or \
               self.lenbound.descr != other.lenbound.descr or \
               not self.lenbound.bound.contains_bound(other.lenbound.bound):
                bad[self] = True
                bad[other] = True
                return False
        elif self.lenbound:
            bad[self] = True
            bad[other] = True
            return False
        return True

    def _generate_guards(self, other, box, cpu, extra_guards):
        if not isinstance(other, NotVirtualStateInfo):
            raise InvalidLoop('The VirtualStates does not match as a ' +
                              'virtual appears where a pointer is needed ' +
                              'and it is too late to force it.')

        if self.lenbound or other.lenbound:
            raise InvalidLoop('The array length bounds does not match.')

        if self.level == LEVEL_KNOWNCLASS and \
           box.nonnull() and \
           self.known_class.same_constant(cpu.ts.cls_of_box(box)):
            # Note: This is only a hint on what the class of box was
            # during the trace. There are actually no guarentees that this
            # box realy comes from a trace. The hint is used here to choose
            # between either eimtting a guard_class and jumping to an
            # excisting compiled loop or retracing the loop. Both
            # alternatives will always generate correct behaviour, but
            # performace will differ.
            op = ResOperation(rop.GUARD_NONNULL, [box], None)
            extra_guards.append(op)
            op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
            extra_guards.append(op)
            return

        if self.level == LEVEL_NONNULL and \
               other.level == LEVEL_UNKNOWN and \
               isinstance(box, BoxPtr) and \
               box.nonnull():
            op = ResOperation(rop.GUARD_NONNULL, [box], None)
            extra_guards.append(op)
            return

        if self.level == LEVEL_UNKNOWN and \
               other.level == LEVEL_UNKNOWN and \
               isinstance(box, BoxInt) and \
               self.intbound.contains(box.getint()):
            if self.intbound.has_lower:
                bound = self.intbound.lower
                if not (other.intbound.has_lower and \
                        other.intbound.lower >= bound):
                    res = BoxInt()
                    op = ResOperation(rop.INT_GE, [box, ConstInt(bound)], res)
                    extra_guards.append(op)
                    op = ResOperation(rop.GUARD_TRUE, [res], None)
                    extra_guards.append(op)
            if self.intbound.has_upper:
                bound = self.intbound.upper
                if not (other.intbound.has_upper and \
                        other.intbound.upper <= bound):
                    res = BoxInt()
                    op = ResOperation(rop.INT_LE, [box, ConstInt(bound)], res)
                    extra_guards.append(op)
                    op = ResOperation(rop.GUARD_TRUE, [res], None)
                    extra_guards.append(op)
            return

        # Remaining cases are probably not interesting
        raise InvalidLoop('Generating guards for making the VirtualStates ' +
                          'at hand match have not been implemented')
        if self.level == LEVEL_CONSTANT:
            import pdb
            pdb.set_trace()
            raise NotImplementedError

    def enum_forced_boxes(self, boxes, value, optimizer):
        if self.level == LEVEL_CONSTANT:
            return
        assert 0 <= self.position_in_notvirtuals
        if optimizer:
            box = value.force_box(optimizer)
        else:
            if value.is_virtual():
                raise BadVirtualState
            box = value.get_key_box()
        boxes[self.position_in_notvirtuals] = box

    def _enum(self, virtual_state):
        if self.level == LEVEL_CONSTANT:
            return
        self.position_in_notvirtuals = len(virtual_state.notvirtuals)
        virtual_state.notvirtuals.append(self)

    def debug_print(self, indent, seen, bad):
        mark = ''
        if self in bad:
            mark = '*'
        if we_are_translated():
            l = {
                LEVEL_UNKNOWN: 'Unknown',
                LEVEL_NONNULL: 'NonNull',
                LEVEL_KNOWNCLASS: 'KnownClass',
                LEVEL_CONSTANT: 'Constant',
            }[self.level]
        else:
            l = {
                LEVEL_UNKNOWN: 'Unknown',
                LEVEL_NONNULL: 'NonNull',
                LEVEL_KNOWNCLASS: 'KnownClass(%r)' % self.known_class,
                LEVEL_CONSTANT: 'Constant(%r)' % self.constbox,
            }[self.level]

        lb = ''
        if self.lenbound:
            lb = ', ' + self.lenbound.bound.__repr__()

        debug_print(indent + mark + 'NotVirtualInfo(%d' % self.position +
                    ', ' + l + ', ' + self.intbound.__repr__() + lb + ')')