Пример #1
0
 def test_ops_offset(self):
     from pypy.rlib import debug
     i0 = BoxInt()
     i1 = BoxInt()
     i2 = BoxInt()
     looptoken = JitCellToken()
     targettoken = TargetToken()
     operations = [
         ResOperation(rop.LABEL, [i0], None, descr=targettoken),
         ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
         ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
         ResOperation(rop.JUMP, [i1], None, descr=targettoken),
         ]
     inputargs = [i0]
     debug._log = dlog = debug.DebugLog()
     info = self.cpu.compile_loop(inputargs, operations, looptoken)
     ops_offset = info.ops_offset
     debug._log = None
     #
     assert ops_offset is looptoken._x86_ops_offset
     # 2*(getfield_raw/int_add/setfield_raw) + ops + None
     assert len(ops_offset) == 2*3 + len(operations) + 1
     assert (ops_offset[operations[0]] <=
             ops_offset[operations[1]] <=
             ops_offset[operations[2]] <=
             ops_offset[None])
Пример #2
0
    def test_debugger_on(self):
        from pypy.tool.logparser import parse_log_file, extract_category
        from pypy.rlib import debug

        targettoken, preambletoken = TargetToken(), TargetToken()
        loop = """
        [i0]
        label(i0, descr=preambletoken)
        debug_merge_point('xyz', 0, 0)
        i1 = int_add(i0, 1)
        i2 = int_ge(i1, 10)
        guard_false(i2) []
        label(i1, descr=targettoken)
        debug_merge_point('xyz', 0, 0)
        i11 = int_add(i1, 1)
        i12 = int_ge(i11, 10)
        guard_false(i12) []
        jump(i11, descr=targettoken)
        """
        ops = parse(loop,
                    namespace={
                        'targettoken': targettoken,
                        'preambletoken': preambletoken
                    })
        debug._log = dlog = debug.DebugLog()
        try:
            self.cpu.assembler.set_debug(True)
            looptoken = JitCellToken()
            self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
            self.cpu.execute_token(looptoken, 0)
            # check debugging info
            struct = self.cpu.assembler.loop_run_counters[0]
            assert struct.i == 1
            struct = self.cpu.assembler.loop_run_counters[1]
            assert struct.i == 1
            struct = self.cpu.assembler.loop_run_counters[2]
            assert struct.i == 9
            self.cpu.finish_once()
        finally:
            debug._log = None
        l0 = ('debug_print', 'entry -1:1')
        l1 = ('debug_print', preambletoken.repr_of_descr() + ':1')
        l2 = ('debug_print', targettoken.repr_of_descr() + ':9')
        assert ('jit-backend-counts', [l0, l1, l2]) in dlog
Пример #3
0
    def test_debugger_on(self):
        from pypy.tool.logparser import parse_log_file, extract_category
        from pypy.rlib import debug

        targettoken, preambletoken = TargetToken(), TargetToken()
        loop = """
        [i0]
        label(i0, descr=preambletoken)
        debug_merge_point('xyz', 0)
        i1 = int_add(i0, 1)
        i2 = int_ge(i1, 10)
        guard_false(i2) []
        label(i1, descr=targettoken)
        debug_merge_point('xyz', 0)
        i11 = int_add(i1, 1)
        i12 = int_ge(i11, 10)
        guard_false(i12) []
        jump(i11, descr=targettoken)
        """
        ops = parse(loop, namespace={'targettoken': targettoken,
                                     'preambletoken': preambletoken})
        debug._log = dlog = debug.DebugLog()
        try:
            self.cpu.assembler.set_debug(True)
            looptoken = JitCellToken()
            self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
            self.cpu.execute_token(looptoken, 0)
            # check debugging info
            struct = self.cpu.assembler.loop_run_counters[0]
            assert struct.i == 1
            struct = self.cpu.assembler.loop_run_counters[1]
            assert struct.i == 1
            struct = self.cpu.assembler.loop_run_counters[2]
            assert struct.i == 9
            self.cpu.finish_once()
        finally:
            debug._log = None
        l0 = ('debug_print', 'entry -1:1')
        l1 = ('debug_print', preambletoken.repr_of_descr() + ':1')
        l2 = ('debug_print', targettoken.repr_of_descr() + ':9')
        assert ('jit-backend-counts', [l0, l1, l2]) in dlog
Пример #4
0
 def insert_label(self, loop, position, r):
     assert not hasattr(loop, '_targettoken')
     for i in range(position):
         op = loop.operations[i]
         if (not op.has_no_side_effect()
                 or not isinstance(op.result, (BoxInt, BoxFloat))):
             position = i
             break  # cannot move the LABEL later
         randompos = r.randrange(0, len(self.startvars) + 1)
         self.startvars.insert(randompos, op.result)
     loop._targettoken = TargetToken()
     loop.operations.insert(
         position,
         ResOperation(rop.LABEL, self.startvars, None, loop._targettoken))
Пример #5
0
    def unroll_and_optimize(self, loop, call_pure_results=None):
        operations = loop.operations
        jumpop = operations[-1]
        assert jumpop.getopnum() == rop.JUMP
        inputargs = loop.inputargs

        jump_args = jumpop.getarglist()[:]
        operations = operations[:-1]
        cloned_operations = [op.clone() for op in operations]

        preamble = TreeLoop('preamble')
        preamble.inputargs = inputargs
        preamble.resume_at_jump_descr = FakeDescrWithSnapshot()

        token = JitCellToken()
        preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \
                              operations +  \
                              [ResOperation(rop.LABEL, jump_args, None, descr=token)]
        self._do_optimize_loop(preamble, call_pure_results)

        assert preamble.operations[-1].getopnum() == rop.LABEL

        inliner = Inliner(inputargs, jump_args)
        loop.resume_at_jump_descr = preamble.resume_at_jump_descr
        loop.operations = [preamble.operations[-1]] + \
                          [inliner.inline_op(op, clone=False) for op in cloned_operations] + \
                          [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args],
                                        None, descr=token)]
        #[inliner.inline_op(jumpop)]
        assert loop.operations[-1].getopnum() == rop.JUMP
        assert loop.operations[0].getopnum() == rop.LABEL
        loop.inputargs = loop.operations[0].getarglist()

        self._do_optimize_loop(loop, call_pure_results)
        extra_same_as = []
        while loop.operations[0].getopnum() != rop.LABEL:
            extra_same_as.append(loop.operations[0])
            del loop.operations[0]

        # Hack to prevent random order of same_as ops
        extra_same_as.sort(
            key=lambda op: str(preamble.operations).find(str(op.getarg(0))))

        for op in extra_same_as:
            preamble.operations.insert(-1, op)

        return preamble
Пример #6
0
 def test_debugger_checksum(self):
     loop = """
     [i0]
     label(i0, descr=targettoken)
     debug_merge_point('xyz', 0)
     i1 = int_add(i0, 1)
     i2 = int_ge(i1, 10)
     guard_false(i2) []
     jump(i1, descr=targettoken)
     """
     ops = parse(loop, namespace={'targettoken': TargetToken()})
     self.cpu.assembler.set_debug(True)
     looptoken = JitCellToken()
     self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
     self.cpu.execute_token(looptoken, 0)
     assert looptoken._x86_debug_checksum == sum([op.getopnum()
                                                  for op in ops.operations])
Пример #7
0
    def propagate_all_forward(self):
        loop = self.optimizer.loop
        self.optimizer.clear_newoperations()

        start_label = loop.operations[0]
        if start_label.getopnum() == rop.LABEL:
            loop.operations = loop.operations[1:]
            # We need to emit the label op before import_state() as emitting it
            # will clear heap caches
            self.optimizer.send_extra_operation(start_label)
        else:
            start_label = None            

        jumpop = loop.operations[-1]
        if jumpop.getopnum() == rop.JUMP or jumpop.getopnum() == rop.LABEL:
            loop.operations = loop.operations[:-1]
        else:
            jumpop = None

        self.import_state(start_label)
        self.optimizer.propagate_all_forward(clear=False)

        if not jumpop:
            return

        cell_token = jumpop.getdescr()
        assert isinstance(cell_token, JitCellToken)
        stop_label = ResOperation(rop.LABEL, jumpop.getarglist(), None, TargetToken(cell_token))

        
        if jumpop.getopnum() == rop.JUMP:
            if self.jump_to_already_compiled_trace(jumpop):
                # Found a compiled trace to jump to
                if self.short:
                    # Construct our short preamble
                    assert start_label
                    self.close_bridge(start_label)
                return

            if start_label and self.jump_to_start_label(start_label, stop_label):
                # Initial label matches, jump to it
                jumpop = ResOperation(rop.JUMP, stop_label.getarglist(), None,
                                      descr=start_label.getdescr())
                if self.short:
                    # Construct our short preamble
                    self.close_loop(start_label, jumpop)
                else:
                    self.optimizer.send_extra_operation(jumpop)
                return

            if cell_token.target_tokens:
                limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
                if cell_token.retraced_count < limit:
                    cell_token.retraced_count += 1
                    debug_print('Retracing (%d/%d)' % (cell_token.retraced_count, limit))
                else:
                    debug_print("Retrace count reached, jumping to 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

        # Found nothing to jump to, emit a label instead
        
        if self.short:
            # Construct our short preamble
            assert start_label
            self.close_bridge(start_label)

        self.optimizer.flush()
        KillHugeIntBounds(self.optimizer).apply()

        loop.operations = self.optimizer.get_newoperations()
        self.export_state(stop_label)
        loop.operations.append(stop_label)
Пример #8
0
class BaseTestRegalloc(object):
    cpu = CPU(None, None)
    cpu.setup_once()

    def raising_func(i):
        if i:
            raise LLException(zero_division_error,
                              zero_division_value)
    FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
    raising_fptr = llhelper(FPTR, raising_func)
    zero_division_tp, zero_division_value = cpu.get_zero_division_error()
    zd_addr = cpu.cast_int_to_adr(zero_division_tp)
    zero_division_error = llmemory.cast_adr_to_ptr(zd_addr,
                                            lltype.Ptr(rclass.OBJECT_VTABLE))
    raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
                                        EffectInfo.MOST_GENERAL)

    targettoken = TargetToken()
    targettoken2 = TargetToken()
    fdescr1 = BasicFailDescr(1)
    fdescr2 = BasicFailDescr(2)
    fdescr3 = BasicFailDescr(3)

    def setup_method(self, meth):
        self.targettoken._x86_loop_code = 0
        self.targettoken2._x86_loop_code = 0

    def f1(x):
        return x+1

    def f2(x, y):
        return x*y

    def f10(*args):
        assert len(args) == 10
        return sum(args)

    F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
    F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*2, lltype.Signed))
    F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*10, lltype.Signed))
    f1ptr = llhelper(F1PTR, f1)
    f2ptr = llhelper(F2PTR, f2)
    f10ptr = llhelper(F10PTR, f10)

    f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT,
                                   EffectInfo.MOST_GENERAL)
    f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT,
                                   EffectInfo.MOST_GENERAL)
    f10_calldescr= cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT,
                                   EffectInfo.MOST_GENERAL)

    namespace = locals().copy()
    type_system = 'lltype'

    def parse(self, s, boxkinds=None):
        return parse(s, self.cpu, self.namespace,
                     type_system=self.type_system,
                     boxkinds=boxkinds)

    def interpret(self, ops, args, run=True):
        loop = self.parse(ops)
        looptoken = JitCellToken()
        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
        arguments = []
        for arg in args:
            if isinstance(arg, int):
                arguments.append(arg)
            elif isinstance(arg, float):
                arg = longlong.getfloatstorage(arg)
                arguments.append(arg)
            else:
                assert isinstance(lltype.typeOf(arg), lltype.Ptr)
                llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg)
                arguments.append(llgcref)
        loop._jitcelltoken = looptoken
        if run:
            self.cpu.execute_token(looptoken, *arguments)
        return loop

    def prepare_loop(self, ops):
        loop = self.parse(ops)
        regalloc = RegAlloc(self.cpu.assembler, False)
        regalloc.prepare_loop(loop.inputargs, loop.operations,
                              loop.original_jitcell_token, [])
        return regalloc

    def getint(self, index):
        return self.cpu.get_latest_value_int(index)

    def getfloat(self, index):
        return self.cpu.get_latest_value_float(index)

    def getints(self, end):
        return [self.cpu.get_latest_value_int(index) for
                index in range(0, end)]

    def getfloats(self, end):
        return [longlong.getrealfloat(self.cpu.get_latest_value_float(index))
                for index in range(0, end)]

    def getptr(self, index, T):
        gcref = self.cpu.get_latest_value_ref(index)
        return lltype.cast_opaque_ptr(T, gcref)

    def attach_bridge(self, ops, loop, guard_op_index, **kwds):
        guard_op = loop.operations[guard_op_index]
        assert guard_op.is_guard()
        bridge = self.parse(ops, **kwds)
        assert ([box.type for box in bridge.inputargs] ==
                [box.type for box in guard_op.getfailargs()])
        faildescr = guard_op.getdescr()
        self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations,
                                loop._jitcelltoken)
        return bridge

    def run(self, loop, *arguments):
        return self.cpu.execute_token(loop._jitcelltoken, *arguments)
Пример #9
0
class TestRegallocMoreRegisters(BaseTestRegalloc):

    cpu = BaseTestRegalloc.cpu
    targettoken = TargetToken()

    S = lltype.GcStruct('S', ('field', lltype.Char))
    fielddescr = cpu.fielddescrof(S, 'field')

    A = lltype.GcArray(lltype.Char)
    arraydescr = cpu.arraydescrof(A)

    namespace = locals().copy()

    def test_int_is_true(self):
        ops = '''
        [i0, i1, i2, i3, i4, i5, i6, i7]
        i10 = int_is_true(i0)
        i11 = int_is_true(i1)
        i12 = int_is_true(i2)
        i13 = int_is_true(i3)
        i14 = int_is_true(i4)
        i15 = int_is_true(i5)
        i16 = int_is_true(i6)
        i17 = int_is_true(i7)
        finish(i10, i11, i12, i13, i14, i15, i16, i17)
        '''
        self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333])
        assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1]

    def test_comparison_ops(self):
        ops = '''
        [i0, i1, i2, i3, i4, i5, i6]
        i10 = int_lt(i0, i1)
        i11 = int_le(i2, i3)
        i12 = int_ge(i4, i5)
        i13 = int_eq(i5, i6)
        i14 = int_gt(i6, i2)
        i15 = int_ne(i2, i6)
        finish(i10, i11, i12, i13, i14, i15)
        '''
        self.interpret(ops, [0, 1, 2, 3, 4, 5, 6])
        assert self.getints(6) == [1, 1, 0, 0, 1, 1]

    def test_strsetitem(self):
        ops = '''
        [p0, i]
        strsetitem(p0, 1, i)
        finish()
        '''
        llstr  = rstr.mallocstr(10)
        self.interpret(ops, [llstr, ord('a')])
        assert llstr.chars[1] == 'a'

    def test_setfield_char(self):
        ops = '''
        [p0, i]
        setfield_gc(p0, i, descr=fielddescr)
        finish()
        '''
        s = lltype.malloc(self.S)
        self.interpret(ops, [s, ord('a')])
        assert s.field == 'a'

    def test_setarrayitem_gc(self):
        ops = '''
        [p0, i]
        setarrayitem_gc(p0, 1, i, descr=arraydescr)
        finish()
        '''
        s = lltype.malloc(self.A, 3)
        self.interpret(ops, [s, ord('a')])
        assert s[1] == 'a'

    def test_division_optimized(self):
        ops = '''
        [i7, i6]
        label(i7, i6, descr=targettoken)
        i18 = int_floordiv(i7, i6)
        i19 = int_xor(i7, i6)
        i21 = int_lt(i19, 0)
        i22 = int_mod(i7, i6)
        i23 = int_is_true(i22)
        i24 = int_eq(i6, 4)
        guard_false(i24) [i18]
        jump(i18, i6, descr=targettoken)
        '''
        self.interpret(ops, [10, 4])
        assert self.getint(0) == 2
Пример #10
0
    def test_compile_bridge_check_profile_info(self):
        py.test.skip("does not work, reinvestigate")
        class FakeProfileAgent(object):
            def __init__(self):
                self.functions = []
            def native_code_written(self, name, address, size):
                self.functions.append((name, address, size))
        self.cpu.profile_agent = agent = FakeProfileAgent()

        i0 = BoxInt()
        i1 = BoxInt()
        i2 = BoxInt()
        targettoken = TargetToken()
        faildescr1 = BasicFailDescr(1)
        faildescr2 = BasicFailDescr(2)
        looptoken = JitCellToken()
        looptoken.number = 17
        class FakeString(object):
            def __init__(self, val):
                self.val = val

            def _get_str(self):
                return self.val

        operations = [
            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("hello"), 0], None),
            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
            ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
            ]
        inputargs = [i0]
        operations[-2].setfailargs([i1])
        self.cpu.compile_loop(inputargs, operations, looptoken)
        name, loopaddress, loopsize = agent.functions[0]
        assert name == "Loop # 17: hello (loop counter 0)"
        assert loopaddress <= looptoken._x86_loop_code
        assert loopsize >= 40 # randomish number

        i1b = BoxInt()
        i3 = BoxInt()
        bridge = [
            ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
            ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2),
            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("bye"), 0], None),
            ResOperation(rop.JUMP, [i1b], None, descr=targettoken),
        ]
        bridge[1].setfailargs([i1b])

        self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken)
        name, address, size = agent.functions[1]
        assert name == "Bridge # 0: bye (loop counter 1)"
        # Would be exactly ==, but there are some guard failure recovery
        # stubs in-between
        assert address >= loopaddress + loopsize
        assert size >= 10 # randomish number

        fail = self.cpu.execute_token(looptoken, 2)
        assert fail.identifier == 2
        res = self.cpu.get_latest_value_int(0)
        assert res == 20
Пример #11
0
def compile_loop(metainterp,
                 greenkey,
                 start,
                 inputargs,
                 jumpargs,
                 resume_at_jump_descr,
                 full_preamble_needed=True):
    """Try to compile a new procedure by closing the current history back
    to the first operation.
    """
    from pypy.jit.metainterp.optimizeopt import optimize_trace

    metainterp_sd = metainterp.staticdata
    jitdriver_sd = metainterp.jitdriver_sd
    history = metainterp.history

    jitcell_token = make_jitcell_token(jitdriver_sd)
    part = create_empty_loop(metainterp)
    part.inputargs = inputargs[:]
    h_ops = history.operations
    part.resume_at_jump_descr = resume_at_jump_descr
    part.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(jitcell_token))] + \
                      [h_ops[i].clone() for i in range(start, len(h_ops))] + \
                      [ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token)]

    try:
        optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts)
    except InvalidLoop:
        return None
    target_token = part.operations[0].getdescr()
    assert isinstance(target_token, TargetToken)
    all_target_tokens = [target_token]

    loop = create_empty_loop(metainterp)
    loop.inputargs = part.inputargs
    loop.operations = part.operations
    loop.quasi_immutable_deps = {}
    if part.quasi_immutable_deps:
        loop.quasi_immutable_deps.update(part.quasi_immutable_deps)
    while part.operations[-1].getopnum() == rop.LABEL:
        inliner = Inliner(inputargs, jumpargs)
        part.quasi_immutable_deps = None
        part.operations = [part.operations[-1]] + \
                          [inliner.inline_op(h_ops[i]) for i in range(start, len(h_ops))] + \
                          [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jumpargs],
                                        None, descr=jitcell_token)]
        target_token = part.operations[0].getdescr()
        assert isinstance(target_token, TargetToken)
        all_target_tokens.append(target_token)
        inputargs = jumpargs
        jumpargs = part.operations[-1].getarglist()

        try:
            optimize_trace(metainterp_sd, part,
                           jitdriver_sd.warmstate.enable_opts)
        except InvalidLoop:
            return None

        loop.operations = loop.operations[:-1] + part.operations
        if part.quasi_immutable_deps:
            loop.quasi_immutable_deps.update(part.quasi_immutable_deps)

    if not loop.quasi_immutable_deps:
        loop.quasi_immutable_deps = None
    for box in loop.inputargs:
        assert isinstance(box, Box)

    loop.original_jitcell_token = jitcell_token
    for label in all_target_tokens:
        assert isinstance(label, TargetToken)
        if label.virtual_state and label.short_preamble:
            metainterp_sd.logger_ops.log_short_preamble([],
                                                        label.short_preamble)
    jitcell_token.target_tokens = all_target_tokens
    propagate_original_jitcell_token(loop)
    send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
    record_loop_or_bridge(metainterp_sd, loop)
    return all_target_tokens[0]
Пример #12
0
class TestRegallocGcIntegration(BaseTestRegalloc):

    cpu = CPU(None, None)
    cpu.gc_ll_descr = MockGcDescr(False)
    cpu.setup_once()

    S = lltype.GcForwardReference()
    S.become(
        lltype.GcStruct('S', ('field', lltype.Ptr(S)), ('int', lltype.Signed)))

    fielddescr = cpu.fielddescrof(S, 'field')

    struct_ptr = lltype.malloc(S)
    struct_ref = lltype.cast_opaque_ptr(llmemory.GCREF, struct_ptr)
    child_ptr = lltype.nullptr(S)
    struct_ptr.field = child_ptr

    descr0 = cpu.fielddescrof(S, 'int')
    ptr0 = struct_ref

    targettoken = TargetToken()

    namespace = locals().copy()

    def test_basic(self):
        ops = '''
        [p0]
        p1 = getfield_gc(p0, descr=fielddescr)
        finish(p1)
        '''
        self.interpret(ops, [self.struct_ptr])
        assert not self.getptr(0, lltype.Ptr(self.S))

    def test_rewrite_constptr(self):
        ops = '''
        []
        p1 = getfield_gc(ConstPtr(struct_ref), descr=fielddescr)
        finish(p1)
        '''
        self.interpret(ops, [])
        assert not self.getptr(0, lltype.Ptr(self.S))

    def test_bug_0(self):
        ops = '''
        [i0, i1, i2, i3, i4, i5, i6, i7, i8]
        label(i0, i1, i2, i3, i4, i5, i6, i7, i8, descr=targettoken)
        guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8]
        guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8]
        i11 = getfield_gc(i4, descr=descr0)
        guard_nonnull(i11) [i4, i5, i6, i7, i0, i1, i11, i8]
        i13 = getfield_gc(i11, descr=descr0)
        guard_isnull(i13) [i4, i5, i6, i7, i0, i1, i11, i8]
        i15 = getfield_gc(i4, descr=descr0)
        i17 = int_lt(i15, 0)
        guard_false(i17) [i4, i5, i6, i7, i0, i1, i11, i15, i8]
        i18 = getfield_gc(i11, descr=descr0)
        i19 = int_ge(i15, i18)
        guard_false(i19) [i4, i5, i6, i7, i0, i1, i11, i15, i8]
        i20 = int_lt(i15, 0)
        guard_false(i20) [i4, i5, i6, i7, i0, i1, i11, i15, i8]
        i21 = getfield_gc(i11, descr=descr0)
        i22 = getfield_gc(i11, descr=descr0)
        i23 = int_mul(i15, i22)
        i24 = int_add(i21, i23)
        i25 = getfield_gc(i4, descr=descr0)
        i27 = int_add(i25, 1)
        setfield_gc(i4, i27, descr=descr0)
        i29 = getfield_raw(144839744, descr=descr0)
        i31 = int_and(i29, -2141192192)
        i32 = int_is_true(i31)
        guard_false(i32) [i4, i6, i7, i0, i1, i24]
        i33 = getfield_gc(i0, descr=descr0)
        guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24]
        jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24, descr=targettoken)
        '''
        self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False)