def test_float_hf_call_mixed(self): if not self.cpu.supports_floats: py.test.skip("requires floats") cpu = self.cpu callargs = [] def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9): callargs.append(zip(range(12), [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9])) return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7 + f8 + f9 F = lltype.Float I = lltype.Signed FUNC = self.FuncType([F] * 7 + [I] + [F] + [I] + [F]* 2, F) FPTR = self.Ptr(FUNC) func_ptr = llhelper(FPTR, func) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) args = ([boxfloat(.1) for i in range(7)] + [BoxInt(1), boxfloat(.2), BoxInt(2), boxfloat(.3), boxfloat(.4)]) res = self.execute_operation(rop.CALL, [funcbox] + args, 'float', descr=calldescr) for i,j in enumerate(callargs[0]): box = args[i] if box.type == 'f': assert (i, args[i].getfloat()) == j else: assert (i, args[i].getint()) == j assert abs(res.getfloat() - 4.6) < 0.0001
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
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)
def test_unwrap(): S = lltype.GcStruct('S') RS = lltype.Struct('S') p = lltype.malloc(S) po = lltype.cast_opaque_ptr(llmemory.GCREF, p) assert unwrap(lltype.Void, BoxInt(42)) is None assert unwrap(lltype.Signed, BoxInt(42)) == 42 assert unwrap(lltype.Char, BoxInt(42)) == chr(42) assert unwrap(lltype.Float, boxfloat(42.5)) == 42.5 assert unwrap(lltype.Ptr(S), BoxPtr(po)) == p assert unwrap(lltype.Ptr(RS), BoxInt(0)) == lltype.nullptr(RS)
def get_int_tests(): for opnum, args, retvalue in (list(_int_binary_operations()) + list(_int_comparison_operations()) + list(_int_unary_operations())): yield opnum, [BoxInt(x) for x in args], retvalue if len(args) > 1: assert len(args) == 2 yield opnum, [BoxInt(args[0]), ConstInt(args[1])], retvalue yield opnum, [ConstInt(args[0]), BoxInt(args[1])], retvalue if args[0] == args[1]: commonbox = BoxInt(args[0]) yield opnum, [commonbox, commonbox], retvalue
def make_guards(self, box, guards): if self.has_lower and self.lower > MININT: bound = self.lower res = BoxInt() op = ResOperation(rop.INT_GE, [box, ConstInt(bound)], res) guards.append(op) op = ResOperation(rop.GUARD_TRUE, [res], None) guards.append(op) if self.has_upper and self.upper < MAXINT: bound = self.upper res = BoxInt() op = ResOperation(rop.INT_LE, [box, ConstInt(bound)], res) guards.append(op) op = ResOperation(rop.GUARD_TRUE, [res], None) guards.append(op)
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)
def test_execute(): cpu = FakeCPU() descr = FakeDescr() box = execute(cpu, None, rop.INT_ADD, None, BoxInt(40), ConstInt(2)) assert box.value == 42 box = execute(cpu, None, rop.NEW, descr) assert box.value.fakeargs == ('new', descr)
def test_intbounds(self): value1 = OptValue(BoxInt()) value1.intbound.make_ge(IntBound(0, 10)) value1.intbound.make_le(IntBound(20, 30)) info1 = NotVirtualStateInfo(value1) info2 = NotVirtualStateInfo(OptValue(BoxInt())) expected = """ [i0] i1 = int_ge(i0, 0) guard_true(i1) [] i2 = int_le(i0, 30) guard_true(i2) [] """ self.guards(info1, info2, BoxInt(15), expected) py.test.raises(InvalidLoop, self.guards, info1, info2, BoxInt(50), expected)
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()
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()
def make_guards(self, box): guards = [] level = self.getlevel() if level == LEVEL_CONSTANT: op = ResOperation(rop.GUARD_VALUE, [box, self.box], None) guards.append(op) elif level == LEVEL_KNOWNCLASS: op = ResOperation(rop.GUARD_NONNULL_CLASS, [box, self.known_class], None) guards.append(op) else: if level == LEVEL_NONNULL: op = ResOperation(rop.GUARD_NONNULL, [box], None) guards.append(op) if self.lenbound: lenbox = BoxInt() if self.lenbound.mode == MODE_ARRAY: op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox, self.lenbound.descr) elif self.lenbound.mode == MODE_STR: op = ResOperation(rop.STRLEN, [box], lenbox, self.lenbound.descr) elif self.lenbound.mode == MODE_UNICODE: op = ResOperation(rop.UNICODELEN, [box], lenbox, self.lenbound.descr) else: debug_print("Unknown lenbound mode") assert False guards.append(op) self.lenbound.bound.make_guards(lenbox, guards) return guards
def __init__(self, cpu, cliloop): self.setoptions() self.cpu = cpu self.name = cliloop.get_fresh_cli_name() self.cliloop = cliloop self.boxes = {} # box --> local var self.branches = [] self.branchlabels = [] self.consts = {} # object --> index self.meth_wrapper = self._get_meth_wrapper() self.il = self.meth_wrapper.get_il_generator() self.av_consts = MethodArgument(0, System.Type.GetType("System.Object[]")) t_InputArgs = dotnet.typeof(InputArgs) self.av_inputargs = MethodArgument(1, t_InputArgs) self.av_ovf_flag = BoxInt() self.exc_value_field = t_InputArgs.GetField('exc_value') if cpu.rtyper: self.av_OverflowError = ConstObj( ootype.cast_to_object(cpu.ll_ovf_exc)) self.av_ZeroDivisionError = ConstObj( ootype.cast_to_object(cpu.ll_zero_exc)) else: self.av_OverflowError = None self.av_ZeroDivisionError = None self.box2type = {}
def test_record_constptrs(self): class MyFakeCPU(object): def cast_adr_to_int(self, adr): assert adr == "some fake address" return 43 class MyFakeGCRefList(object): def get_address_of_gcref(self, s_gcref1): assert s_gcref1 == s_gcref return "some fake address" S = lltype.GcStruct('S') s = lltype.malloc(S) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) v_random_box = BoxPtr() v_result = BoxInt() operations = [ ResOperation(rop.PTR_EQ, [v_random_box, ConstPtr(s_gcref)], v_result), ] gc_ll_descr = self.gc_ll_descr gc_ll_descr.gcrefs = MyFakeGCRefList() gcrefs = [] operations = get_deep_immutable_oplist(operations) operations2 = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations, gcrefs) assert operations2 == operations assert gcrefs == [s_gcref]
def boxes_and_longevity(num): res = [] longevity = {} for i in range(num): box = BoxInt(0) res.append(box) longevity[box] = (0, 1) return res, longevity
def test_execute_varargs(): cpu = FakeCPU() descr = FakeCallDescr() argboxes = [ BoxInt(99999), BoxInt(321), constfloat(2.25), ConstInt(123), BoxPtr(), boxfloat(5.5) ] box = execute_varargs(cpu, FakeMetaInterp(), rop.CALL, argboxes, descr) assert box.getfloat() == 42.5 assert cpu.fakecalled == (99999, [321, 123], [ConstPtr.value], [ longlong.getfloatstorage(2.25), longlong.getfloatstorage(5.5) ], descr)
def test_ll_arraycopy_differing_descrs_nonconst_index(self): h = HeapCache() h.setarrayitem(box1, index1, box2, descr2) assert h.getarrayitem(box1, index1, descr2) is box2 h.invalidate_caches(rop.CALL, arraycopydescr1, [None, box3, box2, index1, index1, BoxInt()]) assert h.getarrayitem(box1, index1, descr2) is box2
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))
def test_stringitems(self): from rpython.rtyper.lltypesystem.rstr import STR ofs = symbolic.get_field_token(STR, 'chars', False)[0] ofs_items = symbolic.get_field_token(STR.chars, 'items', False)[0] res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ref') self.execute_operation( rop.STRSETITEM, [res, ConstInt(2), ConstInt(ord('d'))], 'void') resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs + ofs_items + 2] == 'd' self.execute_operation( rop.STRSETITEM, [res, BoxInt(2), ConstInt(ord('z'))], 'void') assert resbuf[ofs + ofs_items + 2] == 'z' r = self.execute_operation(rop.STRGETITEM, [res, BoxInt(2)], 'int') assert r.value == ord('z')
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))
def test_allocations(self): py.test.skip("rewrite or kill") from rpython.rtyper.lltypesystem import rstr allocs = [None] all = [] orig_new = self.cpu.gc_ll_descr.funcptr_for_new def f(size): allocs.insert(0, size) return orig_new(size) self.cpu.assembler.setup_once() self.cpu.gc_ll_descr.funcptr_for_new = f ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 7 # ------------------------------------------------------------ res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 7 # ------------------------------------------------------------ TP = lltype.GcArray(lltype.Signed) ofs = symbolic.get_field_token(TP, 'length', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) assert allocs[0] == 10 * WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 10 # ------------------------------------------------------------ res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], 'ref', descr) assert allocs[0] == 10 * WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 10
def test_getfield_setfield(self): TP = lltype.GcStruct('x', ('s', lltype.Signed), ('i', rffi.INT), ('f', lltype.Float), ('u', rffi.USHORT), ('c1', lltype.Char), ('c2', lltype.Char), ('c3', lltype.Char)) res = self.execute_operation(rop.NEW, [], 'ref', self.cpu.sizeof(TP)) ofs_s = self.cpu.fielddescrof(TP, 's') ofs_i = self.cpu.fielddescrof(TP, 'i') #ofs_f = self.cpu.fielddescrof(TP, 'f') ofs_u = self.cpu.fielddescrof(TP, 'u') ofsc1 = self.cpu.fielddescrof(TP, 'c1') ofsc2 = self.cpu.fielddescrof(TP, 'c2') ofsc3 = self.cpu.fielddescrof(TP, 'c3') self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(3)], 'void', ofs_s) # XXX ConstFloat #self.execute_operation(rop.SETFIELD_GC, [res, ofs_f, 1e100], 'void') # XXX we don't support shorts (at all) #self.execute_operation(rop.SETFIELD_GC, [res, ofs_u, ConstInt(5)], 'void') s = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_s) assert s.value == 3 self.execute_operation(rop.SETFIELD_GC, [res, BoxInt(3)], 'void', ofs_s) s = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_s) assert s.value == 3 self.execute_operation(rop.SETFIELD_GC, [res, BoxInt(1234)], 'void', ofs_i) i = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_i) assert i.value == 1234 #u = self.execute_operation(rop.GETFIELD_GC, [res, ofs_u], 'int') #assert u.value == 5 self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(1)], 'void', ofsc1) self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(3)], 'void', ofsc3) self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(2)], 'void', ofsc2) c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc1) assert c.value == 1 c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc2) assert c.value == 2 c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc3) assert c.value == 3
def _int_sub(string_optimizer, box1, box2): if isinstance(box2, ConstInt): if box2.value == 0: return box1 if isinstance(box1, ConstInt): return ConstInt(box1.value - box2.value) resbox = BoxInt() string_optimizer.emit_operation(ResOperation(rop.INT_SUB, [box1, box2], resbox)) return resbox
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))
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))
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))
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))
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
def do_int_mul_ovf(cpu, metainterp, box1, box2): a = box1.getint() b = box2.getint() try: z = ovfcheck(a * b) except OverflowError: assert metainterp is not None metainterp.execute_raised(OverflowError(), constant=True) z = 0 return BoxInt(z)
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