예제 #1
0
 def test_frame_manager_basic(self):
     b0, b1 = newboxes(0, 1)
     fm = TFrameManager()
     loc0 = fm.loc(b0)
     assert fm.get_loc_index(loc0) == 0
     #
     assert fm.get(b1) is None
     loc1 = fm.loc(b1)
     assert fm.get_loc_index(loc1) == 1
     assert fm.get(b1) == loc1
     #
     loc0b = fm.loc(b0)
     assert loc0b == loc0
     #
     fm.loc(InputArgInt())
     assert fm.get_frame_depth() == 3
     #
     f0 = InputArgFloat()
     locf0 = fm.loc(f0)
     # can't be odd
     assert fm.get_loc_index(locf0) == 4
     assert fm.get_frame_depth() == 6
     #
     f1 = InputArgFloat()
     locf1 = fm.loc(f1)
     assert fm.get_loc_index(locf1) == 6
     assert fm.get_frame_depth() == 8
     fm.mark_as_free(b1)
     assert fm.freelist
     b2 = InputArgInt()
     fm.loc(b2) # should be in the same spot as b1 before
     assert fm.get(b1) is None
     assert fm.get(b2) == loc1
     fm.mark_as_free(b0)
     p0 = InputArgRef()
     ploc = fm.loc(p0)
     assert fm.get_loc_index(ploc) == 0
     assert fm.get_frame_depth() == 8
     assert ploc != loc1
     p1 = InputArgRef()
     p1loc = fm.loc(p1)
     assert fm.get_loc_index(p1loc) == 3
     assert fm.get_frame_depth() == 8
     fm.mark_as_free(p0)
     p2 = InputArgRef()
     p2loc = fm.loc(p2)
     assert p2loc == ploc
     assert len(fm.freelist) == 0
     fm.mark_as_free(b2)
     f3 = InputArgFloat()
     fm.mark_as_free(p2)
     floc = fm.loc(f3)
     assert fm.get_loc_index(floc) == 0
     for box in fm.bindings.keys():
         fm.mark_as_free(box)
예제 #2
0
 def __init__(self, cpu, builder_factory, r, startvars=None, output=None):
     self.cpu = cpu
     self.output = output
     if startvars is None:
         startvars = []
         if cpu.supports_floats:
             # pick up a single threshold for the whole 'inputargs', so
             # that some loops have no or mostly no FLOATs while others
             # have a lot of them
             k = r.random()
             # but make sure there is at least one INT
             at_least_once = r.randrange(0, pytest.config.option.n_vars)
         else:
             k = -1
             at_least_once = 0
         for i in range(pytest.config.option.n_vars):
             if r.random() < k and i != at_least_once:
                 startvars.append(InputArgFloat(r.random_float_storage()))
             else:
                 startvars.append(InputArgInt(r.random_integer()))
         allow_delay = True
     else:
         allow_delay = False
     assert len(dict.fromkeys(startvars)) == len(startvars)
     self.startvars = startvars
     self.prebuilt_ptr_consts = []
     self.r = r
     self.subloops = []
     self.build_random_loop(cpu, builder_factory, r, startvars, allow_delay)
예제 #3
0
    def test_call_many_float_args(self):
        from rpython.rtyper.annlowlevel import llhelper
        from rpython.jit.codewriter.effectinfo import EffectInfo

        seen = []

        def func(*args):
            seen.append(args)
            return -42

        F = lltype.Float
        I = lltype.Signed
        FUNC = self.FuncType([F] * 7 + [I] + [F] * 7 + [I] + [F], I)
        FPTR = self.Ptr(FUNC)
        func_ptr = llhelper(FPTR, func)
        cpu = self.cpu
        calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                    EffectInfo.MOST_GENERAL)
        funcbox = self.get_funcbox(cpu, func_ptr)
        argvals = [.1 * i for i in range(15)]
        argvals.insert(7, 77)
        argvals.insert(15, 1515)
        argvals = tuple(argvals)
        argboxes = []
        for x in argvals:
            if isinstance(x, float):
                argboxes.append(InputArgFloat(x))
            else:
                argboxes.append(InputArgInt(x))
        res = self.execute_operation(rop.CALL_I, [funcbox] + argboxes,
                                     'int',
                                     descr=calldescr)
        assert res == -42
        assert seen == [argvals]
예제 #4
0
 def get_runtime_field(self, box, descr):
     struct = box.getref_base()
     if descr.is_pointer_field():
         return InputArgRef(self.cpu.bh_getfield_gc_r(struct, descr))
     elif descr.is_float_field():
         return InputArgFloat(self.cpu.bh_getfield_gc_f(struct, descr))
     else:
         return InputArgInt(self.cpu.bh_getfield_gc_i(struct, descr))
예제 #5
0
 def get_runtime_item(self, box, descr, i):
     array = box.getref_base()
     if descr.is_array_of_pointers():
         return InputArgRef(self.cpu.bh_getarrayitem_gc_r(array, i, descr))
     elif descr.is_array_of_floats():
         return InputArgFloat(self.cpu.bh_getarrayitem_gc_f(array, i, descr))
     else:
         return InputArgInt(self.cpu.bh_getarrayitem_gc_i(array, i, descr))
예제 #6
0
    def newinputarg(self, elem):
        if elem.startswith("i"):
            v = InputArgInt(0)
        elif elem.startswith("f"):
            v = InputArgFloat.fromfloat(0.0)
        else:
            from rpython.rtyper.lltypesystem import lltype, llmemory

            assert elem.startswith("p")
            v = InputArgRef(lltype.nullptr(llmemory.GCREF.TO))
        self.vars[elem] = v
        return v
예제 #7
0
파일: compile.py 프로젝트: Mu-L/pypy
def compile_tmp_callback(cpu,
                         jitdriver_sd,
                         greenboxes,
                         redargtypes,
                         memory_manager=None):
    """Make a LoopToken that corresponds to assembler code that just
    calls back the interpreter.  Used temporarily: a fully compiled
    version of the code may end up replacing it.
    """
    jitcell_token = make_jitcell_token(jitdriver_sd)
    #
    # record the target of a temporary callback to the interpreter
    jl.tmp_callback(jitcell_token)
    #
    nb_red_args = jitdriver_sd.num_red_args
    assert len(redargtypes) == nb_red_args
    inputargs = []
    for kind in redargtypes:
        if kind == history.INT:
            box = InputArgInt()
        elif kind == history.REF:
            box = InputArgRef()
        elif kind == history.FLOAT:
            box = InputArgFloat()
        else:
            raise AssertionError
        inputargs.append(box)
    k = jitdriver_sd.portal_runner_adr
    funcbox = history.ConstInt(adr2int(k))
    callargs = [funcbox] + greenboxes + inputargs
    #

    jd = jitdriver_sd
    opnum = OpHelpers.call_for_descr(jd.portal_calldescr)
    call_op = ResOperation(opnum, callargs, descr=jd.portal_calldescr)
    if call_op.type != 'v' is not None:
        finishargs = [call_op]
    else:
        finishargs = []
    #
    faildescr = jitdriver_sd.propagate_exc_descr
    operations = [
        call_op,
        ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=faildescr),
        ResOperation(rop.FINISH, finishargs, descr=jd.portal_finishtoken)
    ]
    operations[1].setfailargs([])
    operations = get_deep_immutable_oplist(operations)
    cpu.compile_loop(inputargs, operations, jitcell_token, log=False)

    if memory_manager is not None:  # for tests
        memory_manager.keep_loop_alive(jitcell_token)
    return jitcell_token
예제 #8
0
    def test_different_frame_width(self):
        class XRegisterManager(RegisterManager):
            pass

        fm = TFrameManager()
        b0 = InputArgInt()
        longevity = {b0: Lifetime(0, 1)}
        asm = MockAsm()
        rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
        f0 = InputArgFloat()
        longevity = {f0: Lifetime(0, 1)}
        xrm = XRegisterManager(longevity, frame_manager=fm, assembler=asm)
        xrm.loc(f0)
        rm.loc(b0)
        assert fm.get_frame_depth() == 3
예제 #9
0
파일: oparser.py 프로젝트: mozillazg/pypy
 def newinputarg(self, elem):
     if elem.startswith('i'):
         v = InputArgInt(0)
     elif elem.startswith('f'):
         v = InputArgFloat.fromfloat(0.0)
     elif elem.startswith('v'):
         v = InputArgVector()
         elem = self.update_vector(v, elem)
     else:
         from rpython.rtyper.lltypesystem import lltype, llmemory
         assert elem.startswith('p')
         v = InputArgRef(lltype.nullptr(llmemory.GCREF.TO))
     # ensure that the variable gets the proper naming
     self.update_memo(v, elem)
     self.vars[elem] = v
     return v
예제 #10
0
 def newinputarg(self, elem):
     if elem.startswith('i'):
         v = InputArgInt(0)
     elif elem.startswith('f'):
         v = InputArgFloat.fromfloat(0.0)
     elif elem.startswith('v'):
         v = InputArgVector()
         elem = self.update_vector(v, elem)
     else:
         from rpython.rtyper.lltypesystem import lltype, llmemory
         assert elem.startswith('p')
         v = InputArgRef(lltype.nullptr(llmemory.GCREF.TO))
     # ensure that the variable gets the proper naming
     self.update_memo(v, elem)
     self.vars[elem] = v
     return v
예제 #11
0
    def build_bridge(self):
        def exc_handling(guard_op):
            # operations need to start with correct GUARD_EXCEPTION
            if guard_op._exc_box is None:
                op = ResOperation(rop.GUARD_NO_EXCEPTION, [])
            else:
                op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box])
            op.setdescr(self.builder.getfaildescr())
            op.setfailargs([])
            return op

        if self.dont_generate_more:
            return False
        r = self.r
        guard_op = self.guard_op
        fail_args = guard_op.getfailargs()
        fail_descr = guard_op.getdescr()
        op = self.should_fail_by
        if not op.getfailargs():
            return False
        for _fail_box in fail_args:
            _fail_box.set_forwarded(None)
        # generate the branch: a sequence of operations that ends in a FINISH
        subloop = DummyLoop([])
        self.subloops.append(subloop)  # keep around for debugging
        if rop.is_guard_exception(guard_op.getopnum()):
            subloop.operations.append(exc_handling(guard_op))
        bridge_builder = self.builder.fork(self.builder.cpu, subloop,
                                           op.getfailargs()[:])
        self.generate_ops(bridge_builder, r, subloop, op.getfailargs()[:])
        # note that 'self.guard_op' now points to the guard that will fail in
        # this new bridge, while 'guard_op' still points to the guard that
        # has just failed.

        if r.random() < 0.1 and self.guard_op is None:
            # Occasionally, instead of ending in a FINISH, we end in a jump
            # to another loop.  We don't do it, however, if the new bridge's
            # execution will hit 'self.guard_op', but only if it executes
            # to the FINISH normally.  (There is no point to the extra
            # complexity, as we might get the same effect by two calls
            # to build_bridge().)

            # First make up the other loop...
            #
            # New restriction: must have the same argument count and types
            # as the original loop
            subset = []
            for box in self.loop.inputargs:
                srcbox = r.choice(fail_args)
                if srcbox.type != box.type:
                    if box.type == INT:
                        srcbox = ConstInt(r.random_integer())
                    elif box.type == FLOAT:
                        srcbox = ConstFloat(r.random_float_storage())
                    else:
                        raise AssertionError(box.type)
                subset.append(srcbox)
            #
            args = []
            for x in subset:
                if x.type == INT:
                    args.append(InputArgInt(getint(x)))
                elif x.type == FLOAT:
                    args.append(InputArgFloat(getfloatstorage(x)))
                else:
                    assert 0, x.type
            rl = RandomLoop(self.builder.cpu, self.builder.fork, r, args)
            # done
            self.should_fail_by = rl.should_fail_by
            self.expected = rl.expected
            assert len(rl.loop.inputargs) == len(args)
            # The new bridge's execution will end normally at its FINISH.
            # Just replace the FINISH with the JUMP to the new loop.
            jump_op = ResOperation(rop.JUMP,
                                   subset,
                                   descr=rl.loop._targettoken)
            subloop.operations[-1] = jump_op
            self.guard_op = rl.guard_op
            self.prebuilt_ptr_consts += rl.prebuilt_ptr_consts
            self.loop._jitcelltoken.record_jump_to(rl.loop._jitcelltoken)
            self.dont_generate_more = True
        if r.random() < .05:
            return False
        dump(subloop)
        self.builder.cpu.compile_bridge(fail_descr, fail_args,
                                        subloop.operations,
                                        self.loop._jitcelltoken)

        if self.output:
            bridge_builder.print_loop(self.output, fail_descr, fail_args)
        return True
예제 #12
0
def boxfloat(x):
    return InputArgFloat(longlong.getfloatstorage(x))