Example #1
0
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)
    nb_red_args = jitdriver_sd.num_red_args
    assert len(redargtypes) == nb_red_args
    inputargs = []
    for kind in redargtypes:
        if kind == history.INT:
            box = BoxInt()
        elif kind == history.REF:
            box = BoxPtr()
        elif kind == history.FLOAT:
            box = BoxFloat()
        else:
            raise AssertionError
        inputargs.append(box)
    k = jitdriver_sd.portal_runner_adr
    funcbox = history.ConstInt(heaptracker.adr2int(k))
    callargs = [funcbox] + greenboxes + inputargs
    #
    result_type = jitdriver_sd.result_type
    if result_type == history.INT:
        result = BoxInt()
    elif result_type == history.REF:
        result = BoxPtr()
    elif result_type == history.FLOAT:
        result = BoxFloat()
    elif result_type == history.VOID:
        result = None
    else:
        assert 0, "bad result_type"
    if result is not None:
        finishargs = [result]
    else:
        finishargs = []
    #
    jd = jitdriver_sd
    faildescr = jitdriver_sd.propagate_exc_descr
    operations = [
        ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr),
        ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr),
        ResOperation(rop.FINISH, finishargs, None, 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
Example #2
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(BoxInt())
     assert fm.get_frame_depth() == 3
     #
     f0 = BoxFloat()
     locf0 = fm.loc(f0)
     # can't be odd
     assert fm.get_loc_index(locf0) == 4
     assert fm.get_frame_depth() == 6
     #
     f1 = BoxFloat()
     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 = BoxInt()
     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 = BoxPtr()
     ploc = fm.loc(p0)
     assert fm.get_loc_index(ploc) == 0
     assert fm.get_frame_depth() == 8
     assert ploc != loc1
     p1 = BoxPtr()
     p1loc = fm.loc(p1)
     assert fm.get_loc_index(p1loc) == 3
     assert fm.get_frame_depth() == 8
     fm.mark_as_free(p0)
     p2 = BoxPtr()
     p2loc = fm.loc(p2)
     assert p2loc == ploc
     assert len(fm.freelist) == 0
     fm.mark_as_free(b2)
     f3 = BoxFloat()
     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)
Example #3
0
 def new_box_item(self, arraydescr):
     if arraydescr.is_array_of_pointers():
         return self.new_ptr_box()
     elif arraydescr.is_array_of_floats():
         return BoxFloat()
     else:
         return BoxInt()
Example #4
0
 def new_box(self, fieldofs):
     if fieldofs.is_pointer_field():
         return self.new_ptr_box()
     elif fieldofs.is_float_field():
         return BoxFloat()
     else:
         return BoxInt()
Example #5
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 BoxFloat while others
             # have a lot of them
             k = r.random()
             # but make sure there is at least one BoxInt
             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(BoxFloat(r.random_float_storage()))
             else:
                 startvars.append(BoxInt(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)
Example #6
0
def do_getarrayitem_raw(cpu, _, arraybox, indexbox, arraydescr):
    array = arraybox.getint()
    index = indexbox.getint()
    assert not arraydescr.is_array_of_pointers()
    if arraydescr.is_array_of_floats():
        return BoxFloat(cpu.bh_getarrayitem_raw_f(array, index, arraydescr))
    else:
        return BoxInt(cpu.bh_getarrayitem_raw_i(array, index, arraydescr))
Example #7
0
def do_getfield_gc(cpu, _, structbox, fielddescr):
    struct = structbox.getref_base()
    if fielddescr.is_pointer_field():
        return BoxPtr(cpu.bh_getfield_gc_r(struct, fielddescr))
    elif fielddescr.is_float_field():
        return BoxFloat(cpu.bh_getfield_gc_f(struct, fielddescr))
    else:
        return BoxInt(cpu.bh_getfield_gc_i(struct, fielddescr))
Example #8
0
def do_getarrayitem_gc(cpu, _, arraybox, indexbox, arraydescr):
    array = arraybox.getref_base()
    index = indexbox.getint()
    if arraydescr.is_array_of_pointers():
        return BoxPtr(cpu.bh_getarrayitem_gc_r(array, index, arraydescr))
    elif arraydescr.is_array_of_floats():
        return BoxFloat(cpu.bh_getarrayitem_gc_f(array, index, arraydescr))
    else:
        return BoxInt(cpu.bh_getarrayitem_gc_i(array, index, arraydescr))
Example #9
0
def do_raw_load(cpu, _, addrbox, offsetbox, arraydescr):
    addr = addrbox.getint()
    offset = offsetbox.getint()
    if arraydescr.is_array_of_pointers():
        raise AssertionError("cannot store GC pointers in raw store")
    elif arraydescr.is_array_of_floats():
        return BoxFloat(cpu.bh_raw_load_f(addr, offset, arraydescr))
    else:
        return BoxInt(cpu.bh_raw_load_i(addr, offset, arraydescr))
Example #10
0
def do_getfield_raw(cpu, _, structbox, fielddescr):
    check_descr(fielddescr)
    struct = structbox.getint()
    if fielddescr.is_pointer_field():
        return BoxPtr(cpu.bh_getfield_raw_r(struct, fielddescr))
    elif fielddescr.is_float_field():
        return BoxFloat(cpu.bh_getfield_raw_f(struct, fielddescr))
    else:
        return BoxInt(cpu.bh_getfield_raw_i(struct, fielddescr))
Example #11
0
def do_getinteriorfield_gc(cpu, _, arraybox, indexbox, descr):
    array = arraybox.getref_base()
    index = indexbox.getint()
    if descr.is_pointer_field():
        return BoxPtr(cpu.bh_getinteriorfield_gc_r(array, index, descr))
    elif descr.is_float_field():
        return BoxFloat(cpu.bh_getinteriorfield_gc_f(array, index, descr))
    else:
        return BoxInt(cpu.bh_getinteriorfield_gc_i(array, index, descr))
Example #12
0
    def _optimize_CALL_ARRAYCOPY(self, op):
        length = self.get_constant_box(op.getarg(5))
        if length and length.getint() == 0:
            return True  # 0-length arraycopy

        source_value = self.getvalue(op.getarg(1))
        dest_value = self.getvalue(op.getarg(2))
        source_start_box = self.get_constant_box(op.getarg(3))
        dest_start_box = self.get_constant_box(op.getarg(4))
        extrainfo = op.getdescr().get_extra_info()
        if (source_start_box and dest_start_box and length
                and (dest_value.is_virtual() or length.getint() <= 8)
                and (source_value.is_virtual() or length.getint() <= 8)
                and len(extrainfo.write_descrs_arrays) == 1):  # <-sanity check
            from rpython.jit.metainterp.optimizeopt.virtualize import VArrayValue
            source_start = source_start_box.getint()
            dest_start = dest_start_box.getint()
            # XXX fish fish fish
            arraydescr = extrainfo.write_descrs_arrays[0]
            if arraydescr.is_array_of_structs():
                return False  # not supported right now
            for index in range(length.getint()):
                if source_value.is_virtual():
                    assert isinstance(source_value, VArrayValue)
                    val = source_value.getitem(index + source_start)
                else:
                    if arraydescr.is_array_of_pointers():
                        resbox = BoxPtr()
                    elif arraydescr.is_array_of_floats():
                        resbox = BoxFloat()
                    else:
                        resbox = BoxInt()
                    newop = ResOperation(
                        rop.GETARRAYITEM_GC,
                        [op.getarg(1),
                         ConstInt(index + source_start)],
                        resbox,
                        descr=arraydescr)
                    self.optimizer.send_extra_operation(newop)
                    val = self.getvalue(resbox)
                if val is None:
                    continue
                if dest_value.is_virtual():
                    dest_value.setitem(index + dest_start, val)
                else:
                    newop = ResOperation(rop.SETARRAYITEM_GC, [
                        op.getarg(2),
                        ConstInt(index + dest_start),
                        val.get_key_box()
                    ],
                                         None,
                                         descr=arraydescr)
                    self.emit_operation(newop)
            return True
        return False
Example #13
0
def test_wrap():
    def _is(box1, box2):
        return (box1.__class__ == box2.__class__ and
                box1.value == box2.value)
    p = lltype.malloc(lltype.GcStruct('S'))
    po = lltype.cast_opaque_ptr(llmemory.GCREF, p)
    assert _is(wrap(None, 42), BoxInt(42))
    assert _is(wrap(None, 42.5), boxfloat(42.5))
    assert _is(wrap(None, p), BoxPtr(po))
    assert _is(wrap(None, 42, in_const_box=True), ConstInt(42))
    assert _is(wrap(None, 42.5, in_const_box=True), constfloat(42.5))
    assert _is(wrap(None, p, in_const_box=True), ConstPtr(po))
    if longlong.supports_longlong:
        import sys
        from rpython.rlib.rarithmetic import r_longlong, r_ulonglong
        value = r_longlong(-sys.maxint*17)
        assert _is(wrap(None, value), BoxFloat(value))
        assert _is(wrap(None, value, in_const_box=True), ConstFloat(value))
        value_unsigned = r_ulonglong(-sys.maxint*17)
        assert _is(wrap(None, value_unsigned), BoxFloat(value))
    sfval = r_singlefloat(42.5)
    ival = longlong.singlefloat2int(sfval)
    assert _is(wrap(None, sfval), BoxInt(ival))
    assert _is(wrap(None, sfval, in_const_box=True), ConstInt(ival))
Example #14
0
    def test_different_frame_width(self):
        class XRegisterManager(RegisterManager):
            pass

        fm = TFrameManager()
        b0 = BoxInt()
        longevity = {b0: (0, 1)}
        asm = MockAsm()
        rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
        f0 = BoxFloat()
        longevity = {f0: (0, 1)}
        xrm = XRegisterManager(longevity, frame_manager=fm, assembler=asm)
        xrm.loc(f0)
        rm.loc(b0)
        assert fm.get_frame_depth() == 3
Example #15
0
def test_count_reg_args():
    assert count_reg_args([BoxPtr()]) == 1
    assert count_reg_args([BoxPtr()] * 2) == 2
    assert count_reg_args([BoxPtr()] * 3) == 3
    assert count_reg_args([BoxPtr()] * 4) == 4
    assert count_reg_args([BoxPtr()] * 5) == 4
    assert count_reg_args([BoxFloat()] * 1) == 1
    assert count_reg_args([BoxFloat()] * 2) == 2
    assert count_reg_args([BoxFloat()] * 3) == 2

    assert count_reg_args([BoxInt(), BoxInt(), BoxFloat()]) == 3
    assert count_reg_args([BoxInt(), BoxFloat(), BoxInt()]) == 2

    assert count_reg_args([BoxInt(), BoxFloat(), BoxInt()]) == 2
    assert count_reg_args([BoxInt(), BoxInt(), BoxInt(), BoxFloat()]) == 3
Example #16
0
 def do(cpu, _, *argboxes):
     newargs = ()
     for argtype in argtypes:
         if argtype == 'cpu':
             value = cpu
         elif argtype == 'd':
             value = argboxes[-1]
             assert isinstance(value, AbstractDescr)
             argboxes = argboxes[:-1]
         else:
             argbox = argboxes[0]
             argboxes = argboxes[1:]
             if argtype == 'i': value = argbox.getint()
             elif argtype == 'r': value = argbox.getref_base()
             elif argtype == 'f': value = argbox.getfloatstorage()
         newargs = newargs + (value, )
     assert not argboxes
     #
     result = func(*newargs)
     #
     if resulttype == 'i': return BoxInt(result)
     if resulttype == 'r': return BoxPtr(result)
     if resulttype == 'f': return BoxFloat(result)
     return None
Example #17
0
def boxfloat(x):
    return BoxFloat(longlong.getfloatstorage(x))
Example #18
0
            result = 0
        return BoxInt(result)
    if rettype == REF:
        try:
            result = cpu.bh_call_r(func, args_i, args_r, args_f, descr)
        except Exception, e:
            metainterp.execute_raised(e)
            result = NULL
        return BoxPtr(result)
    if rettype == FLOAT or rettype == 'L':  # *L*ong long
        try:
            result = cpu.bh_call_f(func, args_i, args_r, args_f, descr)
        except Exception, e:
            metainterp.execute_raised(e)
            result = longlong.ZEROF
        return BoxFloat(result)
    if rettype == VOID:
        try:
            cpu.bh_call_v(func, args_i, args_r, args_f, descr)
        except Exception, e:
            metainterp.execute_raised(e)
        return None
    raise AssertionError("bad rettype")


do_call_loopinvariant = do_call
do_call_may_force = do_call


def do_cond_call(cpu, metainterp, argboxes, descr):
    condbox = argboxes[0]