def test_jump_target_other(self): looptoken = JitCellToken() looptoken.I_am_a_descr = True # for the mock case x = ''' [] jump(descr=looptoken) ''' loop = self.parse(x, namespace=locals()) assert loop.operations[0].getdescr() is looptoken
def setup_method(self, method): cpu = CPU(None, None) self.a = AssemblerARM(cpu) self.a.setup_once() token = JitCellToken() clt = CompiledLoopToken(cpu, 0) clt.allgcrefs = [] token.compiled_loop_token = clt self.a.setup(token)
def test_wrong_result(self): # generated by: # ../test/ test/test_zll_random.py -l -k arm -s --block-length=10 --random-seed=7389 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) faildescr4 = BasicFailDescr(4) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() tmp16 = BoxInt() tmp17 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_IS_TRUE, [v3], tmp16), ResOperation(rop.GUARD_TRUE, [tmp16], None, descr=faildescr1), ResOperation(rop.INT_AND, [v7, ConstInt(31)], tmp17), ResOperation(rop.INT_RSHIFT, [v5, tmp17], v11), ResOperation(rop.INT_OR, [v6, v8], v12), ResOperation(rop.GUARD_VALUE, [v11, ConstInt(-2)], None, descr=faildescr2), ResOperation(rop.INT_LE, [ConstInt(1789569706), v10], v13), ResOperation(rop.INT_IS_TRUE, [v4], v14), ResOperation(rop.INT_XOR, [v14, v3], v15), ResOperation(rop.GUARD_VALUE, [v8, ConstInt(-8)], None, descr=faildescr3), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr4), ] operations[1].setfailargs([v9, v1]) operations[5].setfailargs([v10, v2, v11, v3]) operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8]) operations[-1].setfailargs([v1, v2, v9]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [0, -2, 24, 1, -4, 13, -95, 33, 2, -44] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == -4 assert cpu.get_int_value(deadframe, 1) == -95 assert cpu.get_int_value(deadframe, 2) == 45 assert cpu.get_int_value(deadframe, 3) == 1 assert cpu.get_int_value(deadframe, 4) == -2 assert cpu.get_int_value(deadframe, 5) == 0 assert cpu.get_int_value(deadframe, 6) == 33
def test_compile_loop_many_int_args(self): for numargs in range(2, 30): ops = [] arglist = "[%s]\n" % ", ".join(["i%d" % i for i in range(numargs)]) ops.append(arglist) arg1 = 0 arg2 = 1 res = numargs for i in range(numargs - 1): op = "i%d = int_add(i%d, i%d)\n" % (res, arg1, arg2) arg1 = res res += 1 arg2 += 1 ops.append(op) ops.append("finish(i%d)" % (res - 1)) ops = "".join(ops) loop = parse(ops) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * numargs RES = lltype.Signed args = [i + 1 for i in range(numargs)] deadframe = self.cpu.execute_token(looptoken, *args) assert self.cpu.get_int_value(deadframe, 0) == sum(args)
def test_bug_int_is_true_1(): v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() zero = BoxInt() tmp5 = BoxInt() inputargs = [v1] operations = [ ResOperation(rop.INT_MUL, [v1, v1], v2), ResOperation(rop.INT_MUL, [v2, v1], v3), ResOperation(rop.INT_IS_TRUE, [v2], tmp5), ResOperation(rop.INT_IS_ZERO, [tmp5], v4), ResOperation(rop.SAME_AS, [ConstInt(0)], zero), ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr()) ] operations[-2].setfailargs([v4, v3, tmp5]) cpu = CPU(None, None) cpu.setup_once() looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, -10) assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == -1000 assert cpu.get_int_value(deadframe, 2) == 1
def test_call_argument_spilling(self): # bug when we have a value in r0, that is overwritten by an argument # and needed after the call, so that the register gets spilled after it # was overwritten with the argument to the call def func(a): return a + 16 I = lltype.Signed FUNC = self.FuncType([I], I) FPTR = self.Ptr(FUNC) func_ptr = llhelper(FPTR, func) calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(self.cpu, func_ptr) args = ', '.join(['i%d' % i for i in range(11)]) ops = """ [%s] i99 = call(ConstClass(func_ptr), 22, descr=calldescr) guard_true(i0) [%s, i99] finish()""" % (args, args) loop = parse(ops, namespace=locals()) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) args = [x for x in range(11)] deadframe = self.cpu.execute_token(looptoken, *args) for x in range(11): assert self.cpu.get_int_value(deadframe, x) == x assert self.cpu.get_int_value(deadframe, 11) == 38
def test_shadowstack_collecting_call_float(self): cpu = self.cpu def float_return(i, f): # mark frame for write barrier frame = rffi.cast(lltype.Ptr(JITFRAME), i) frame.hdr |= 1 return 1.2 + f FUNC = lltype.FuncType([lltype.Signed, lltype.Float], lltype.Float) fptr = llhelper(lltype.Ptr(FUNC), float_return) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) loop = self.parse(""" [f0] i = force_token() f1 = call_f(ConstClass(fptr), i, f0, descr=calldescr) finish(f1, descr=finaldescr) """, namespace={'fptr': fptr, 'calldescr': calldescr, 'finaldescr': BasicFinalDescr(1)}) token = JitCellToken() cpu.gc_ll_descr.init_nursery(20) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) arg = longlong.getfloatstorage(2.3) frame = cpu.execute_token(token, arg) ofs = cpu.get_baseofs_of_frame_field() f = cpu.read_float_at_mem(frame, ofs) f = longlong.getrealfloat(f) assert f == 2.3 + 1.2
def unroll_and_optimize(self, loop, call_pure_results=None, jump_values=None): self.add_guard_future_condition(loop) jump_op = loop.operations[-1] assert jump_op.getopnum() == rop.JUMP celltoken = JitCellToken() runtime_boxes = self.pack_into_boxes(jump_op, jump_values) jump_op.setdescr(celltoken) call_pure_results = self._convert_call_pure_results(call_pure_results) t = convert_loop_to_trace(loop, self.metainterp_sd) preamble_data = compile.PreambleCompileData( t, runtime_boxes, call_pure_results, enable_opts=self.enable_opts) start_state, preamble_ops = preamble_data.optimize_trace( self.metainterp_sd, None, {}) preamble_data.forget_optimization_info() loop_data = compile.UnrolledLoopData(preamble_data.trace, celltoken, start_state, call_pure_results, enable_opts=self.enable_opts) loop_info, ops = loop_data.optimize_trace(self.metainterp_sd, None, {}) preamble = TreeLoop('preamble') preamble.inputargs = start_state.renamed_inputargs start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs) preamble.operations = ([start_label] + preamble_ops + loop_info.extra_same_as + [loop_info.label_op]) loop.inputargs = loop_info.label_op.getarglist()[:] loop.operations = [loop_info.label_op] + ops return Info(preamble, loop_info.target_token.short_preamble, start_state.virtual_state)
def test_result_is_spilled(self): cpu = self.cpu inp = [InputArgInt(i) for i in range(1, 15)] looptoken = JitCellToken() targettoken = TargetToken() operations = [ ResOperation(rop.LABEL, inp, descr=targettoken), ResOperation(rop.INT_ADD, [inp[0], inp[1]]), ResOperation(rop.INT_ADD, [inp[2], inp[3]]), ResOperation(rop.INT_ADD, [inp[4], inp[5]]), ResOperation(rop.INT_ADD, [inp[6], inp[7]]), ResOperation(rop.INT_ADD, [inp[8], inp[9]]), ResOperation(rop.INT_ADD, [inp[10], inp[11]]), ResOperation(rop.INT_ADD, [inp[12], inp[13]]), ResOperation(rop.INT_ADD, [inp[0], inp[1]]), ResOperation(rop.INT_ADD, [inp[2], inp[3]]), ResOperation(rop.INT_ADD, [inp[4], inp[5]]), ResOperation(rop.INT_ADD, [inp[6], inp[7]]), ResOperation(rop.INT_ADD, [inp[8], inp[9]]), ResOperation(rop.INT_ADD, [inp[10], inp[11]]), ResOperation(rop.INT_ADD, [inp[12], inp[13]]), ResOperation(rop.GUARD_FALSE, [inp[1]], descr=BasicFailDescr(1)), ResOperation(rop.FINISH, [inp[1]], descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(operations[1:15]) cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [ self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15) ] expected = [3, 7, 11, 15, 19, 23, 27, 3, 7, 11, 15, 19, 23, 27] assert output == expected
def test_nullity_with_guard(self): allops = [rop.INT_IS_TRUE] guards = [rop.GUARD_TRUE, rop.GUARD_FALSE] p = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcStruct('x'))) nullptr = lltype.nullptr(llmemory.GCREF.TO) f = InputArgInt() for op in allops: for guard in guards: if op == rop.INT_IS_TRUE: bp = InputArgInt(1) n = InputArgInt(0) else: bp = InputArgRef(p) n = InputArgRef(nullptr) for b in (bp, n): i1 = ResOperation(rop.SAME_AS_I, [ConstInt(1)]) f = ResOperation(op, [b]) ops = [ i1, f, ResOperation(guard, [f], descr=BasicFailDescr()), ResOperation(rop.FINISH, [ConstInt(0)], descr=BasicFinalDescr()), ] ops[-2].setfailargs([i1]) looptoken = JitCellToken() self.cpu.compile_loop([b], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, b.getint()) result = self.cpu.get_int_value(deadframe, 0) if guard == rop.GUARD_FALSE: assert result == execute(self.cpu, None, op, None, b) else: assert result != execute(self.cpu, None, op, None, b)
def test_malloc_1(self): cpu = self.cpu sizeof = cpu.sizeof(self.S, None) sizeof.tid = 0 size = sizeof.size loop = self.parse(""" [] p0 = call_malloc_nursery(%d) p1 = call_malloc_nursery(%d) p2 = call_malloc_nursery(%d) # this overflows guard_nonnull(p2, descr=faildescr) [p0, p1, p2] finish(p2, descr=finaldescr) """ % (size, size, size), namespace={'sizedescr': sizeof, 'finaldescr': BasicFinalDescr(), 'faildescr': BasicFailDescr()}) token = JitCellToken() cpu.gc_ll_descr.collections = [[0, sizeof.size]] cpu.gc_ll_descr.init_nursery(2 * sizeof.size) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) frame = cpu.execute_token(token) # now we should be able to track everything from the frame frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) thing = frame.jf_frame[unpack_gcmap(frame)[0]] assert thing == rffi.cast(lltype.Signed, cpu.gc_ll_descr.nursery) assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame
def test_shadowstack_cond_call(self): cpu = self.cpu cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() def check(i, frame): frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) assert frame.jf_gcmap[0] # is not empty is good enough CHECK = lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Void) checkptr = llhelper(lltype.Ptr(CHECK), check) checkdescr = cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT, EffectInfo.MOST_GENERAL) loop = self.parse(""" [i0, p0] p = force_token() cond_call(i0, ConstClass(funcptr), i0, p, descr=calldescr) guard_false(i0, descr=faildescr) [p0] """, namespace={ 'faildescr': BasicFailDescr(), 'funcptr': checkptr, 'calldescr': checkdescr, }) token = JitCellToken() cpu.compile_loop(loop.inputargs, loop.operations, token) S = self.S s = lltype.malloc(S) cpu.execute_token(token, 1, s)
def test_unicodesetitem_really_needs_temploc(self): u_box = self.alloc_unicode(u"abcdsdasdsaddefg") targettoken = TargetToken() finaldescr = BasicFinalDescr(1) loop = parse(''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, p10] label(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, p10, descr=targettoken) unicodesetitem(p10, i6, 123) i11 = int_add(i0, i1) i12 = int_add(i11, i2) i13 = int_add(i12, i3) i14 = int_add(i13, i4) i15 = int_add(i14, i5) i16 = int_add(i15, i6) i17 = int_add(i16, i7) i18 = int_add(i17, i8) i19 = int_add(i18, i9) finish(i19, descr=finaldescr) ''', namespace={ 'targettoken': targettoken, 'finaldescr': finaldescr }) looptoken = JitCellToken() args = [(i + 1) for i in range(10)] + [u_box.getref_base()] self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, *args) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 1 res = self.cpu.get_int_value(deadframe, 0) assert res == sum(args[:10])
def test_compile_more_than_32k(self): # the guard_true needs a "b.cond" jumping forward more than 32 kb looptoken = JitCellToken() targettoken = TargetToken() ops = [ '[i0]', 'label(i0, descr=targettoken)', 'i1 = int_le(i0, 9)', 'guard_true(i1, descr=faildescr) [i0]', ] NUM = 8193 iprevious = 'i0' for i in range(NUM): inext = 'i%d' % (i + 2, ) ops.append('%s = int_add(%s, 1)' % (inext, iprevious)) iprevious = inext ops.append('jump(%s, descr=targettoken)' % (iprevious, )) loop = parse('\n'.join(ops), namespace={ 'targettoken': targettoken, 'faildescr': BasicFailDescr(5) }) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, -42) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 5 res = self.cpu.get_int_value(deadframe, 0) assert res == -42 + NUM
def test_evenodd_pair_extensive(self, value): instrs = [] failargs = [] values = [] j = 0 mapping = (('int_floordiv', lambda x, y: x // y), ('int_mod', lambda x, y: x % y), ('int_mul_ovf', lambda x, y: x * y)) for i in range(20): name, func = mapping[j] instrs.append("i{d} = {i}(i0, {d})".format(d=i + 1, i=name)) values.append((name, func(value, i + 1))) failargs.append("i" + str(i + 1)) j += 1 if j >= len(mapping): j = 0 code = """ [i0] {instrs} i99 = int_add(i0, 1) i100 = int_eq(i0,i99) guard_true(i100) [{failargs}] # will always fail!! finish(i0, descr=faildescr) """.format(instrs=('\n' + ' ' * 8).join(instrs), failargs=','.join(failargs)) # the guard forces 3 spills because after 4 divisions # all even slots of the managed registers are full loop = parse(code, namespace={'faildescr': BasicFinalDescr(1)}) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, value) fail = self.cpu.get_latest_descr(deadframe) for i, (name, v) in enumerate(values): assert self.cpu.get_int_value(deadframe, i) == v
def parse_loop(self, ops, add_label=True): loop = self.parse(ops) loop.operations = filter( lambda op: op.getopnum() != rop.DEBUG_MERGE_POINT, loop.operations) token = JitCellToken() if add_label: label = ResOperation(rop.LABEL, loop.inputargs, descr=TargetToken(token)) else: label = loop.operations[0] label.setdescr(TargetToken(token)) jump = loop.operations[-1] loop = VectorLoop(label, loop.operations[0:-1], jump) loop.jump.setdescr(token) class Optimizer(object): metainterp_sd = FakeMetaInterpStaticData(self.cpu) jitdriver_sd = FakeJitDriverStaticData() opt = Optimizer() opt.jitdriver_sd.vec = True for op in loop.operations: if op.is_guard() and not op.getdescr(): descr = invent_fail_descr_for_op(op.getopnum(), opt) op.setdescr(descr) return loop
def run(inputargs, ops): cpu = CPU(None, None) cpu.setup_once() loop = parse(ops, cpu, namespace=locals()) looptoken = JitCellToken() cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = cpu.execute_token(looptoken, *inputargs) return cpu, deadframe
def test_call_aligned_with_spilled_values(self): cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') def func(*args): return float(sum(args)) F = lltype.Float I = lltype.Signed floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 13, -42, 1111, 95, 1] for case in range(256): local_floats = list(floats) local_ints = list(ints) args = [] spills = [] funcargs = [] float_count = 0 int_count = 0 for i in range(8): if case & (1 << i): args.append('f%d' % float_count) spills.append('force_spill(f%d)' % float_count) float_count += 1 funcargs.append(F) else: args.append('i%d' % int_count) spills.append('force_spill(i%d)' % int_count) int_count += 1 funcargs.append(I) arguments = ', '.join(args) spill_ops = '\n'.join(spills) FUNC = self.FuncType(funcargs, 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) ops = '[%s]\n' % arguments ops += '%s\n' % spill_ops ops += 'f99 = call(ConstClass(func_ptr), %s, descr=calldescr)\n' % arguments ops += 'i99 = same_as(0)\n' ops += 'guard_true(i99) [f99, %s]\n' % arguments ops += 'finish()\n' loop = parse(ops, namespace=locals()) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) x = longlong.getrealfloat(cpu.get_float_value(deadframe, 0)) assert abs(x - expected_result) < 0.0001
def test_call_release_gil(self): py.test.skip("xxx fix this test: the code is now assuming that " "'before' is just rgil.release_gil(), and 'after' is " "only needed if 'rpy_fastgil' was not changed.") # note that we can't test floats here because when untranslated # people actually wreck xmm registers cpu = self.cpu l = [] copied_stack = [None] def before(): # put nonsense on the top of shadowstack frame = rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.gcrootmap.stack[0]) assert getmap(frame).count('1') == 7 # copied_stack[0] = cpu.gc_ll_descr.gcrootmap.stack[0] cpu.gc_ll_descr.gcrootmap.stack[0] = -42 l.append("before") def after(): cpu.gc_ll_descr.gcrootmap.stack[0] = copied_stack[0] l.append("after") invoke_around_extcall(before, after) def f(frame, x): # all the gc pointers are alive p1 -> p7 (but not p0) assert x == 1 return 2 FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) loop = self.parse(""" [i0, p1, p2, p3, p4, p5, p6, p7] p0 = force_token() i1 = call_release_gil(ConstClass(fptr), p0, i0, descr=calldescr) guard_not_forced(descr=faildescr) [p1, p2, p3, p4, p5, p6, p7] finish(i1, descr=finaldescr) """, namespace={ 'fptr': fptr, 'calldescr': calldescr, 'faildescr': BasicFailDescr(), 'finaldescr': BasicFinalDescr() }) token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)] frame = cpu.execute_token(token, 1, *args) frame = rffi.cast(JITFRAMEPTR, frame) assert frame.jf_frame[0] == 2 assert l == ['before', 'after']
def test_label_float_in_reg_and_on_stack(self): targettoken = TargetToken() ops = """ [i0, f3] i2 = same_as_i(i0) # but forced to be in a register force_spill(i2) force_spill(f3) f4 = float_add(f3, 5.0) label(f3, f4, descr=targettoken) force_spill(f3) f5 = same_as_f(f3) # but forced to be in a register finish(f5) """ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops2 = """ [i0, f1] i1 = same_as_i(i0) f2 = same_as_f(f1) f3 = float_add(f1, 10.0) force_spill(f3) force_spill(i1) f4 = float_add(f3, f1) jump(f3, f4, descr=targettoken) """ loop2 = parse(ops2, self.cpu, namespace=locals()) looptoken2 = JitCellToken() info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) assert res == -13.5 # deadframe = self.cpu.execute_token(looptoken2, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) assert res == -3.5
def test_jump(self): namespace = {'target': JitCellToken()} namespace['target'].number = 3 inp = ''' [i0] jump(i0, descr=target) ''' loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop) assert output.splitlines()[-1] == "jump(i0, descr=<Loop3>)" pure_parse(output)
def test_wrong_guard3(self): # random seed: 8029 # block length: 10 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) faildescr4 = BasicFailDescr(4) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() v16 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.UINT_LT, [ConstInt(-11), v7], v11), ResOperation(rop.INT_GE, [v3, v5], v12), ResOperation(rop.INT_INVERT, [v9], v13), ResOperation(rop.GUARD_VALUE, [v13, ConstInt(14)], None, descr=faildescr3), ResOperation(rop.INT_IS_ZERO, [v12], v14), ResOperation(rop.INT_SUB, [v2, v13], v15), ResOperation(rop.GUARD_VALUE, [v15, ConstInt(-32)], None, descr=faildescr4), ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(805306366)], v16), ResOperation(rop.GUARD_VALUE, [v15, ConstInt(0)], None, descr=faildescr1), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr2), ] operations[3].setfailargs([]) operations[-4].setfailargs([v15]) operations[-2].setfailargs([v9, v4, v10, v11, v14]) operations[-1].setfailargs([v10, v8, v1, v6, v4]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 1 assert cpu.get_int_value(deadframe, 0) == -15 assert cpu.get_int_value(deadframe, 1) == -9 assert cpu.get_int_value(deadframe, 2) == 536870912 assert cpu.get_int_value(deadframe, 3) == 0 assert cpu.get_int_value(deadframe, 4) == 0
def test_wrong_guard(self): # generated by: # ../test/ test/test_zll_random.py -l -k arm -s --block-length=10 --random-seed=4338 faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) faildescr4 = BasicFailDescr(4) v1 = BoxInt(32) v2 = BoxInt(41) v3 = BoxInt(-9) v4 = BoxInt(12) v5 = BoxInt(-18) v6 = BoxInt(46) v7 = BoxInt(15) v8 = BoxInt(17) v9 = BoxInt(10) v10 = BoxInt(12) v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() tmp15 = BoxInt() tmp16 = BoxInt() tmp17 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_IS_TRUE, [v1], tmp15), ResOperation(rop.GUARD_TRUE, [tmp15], None, descr=faildescr1), ResOperation(rop.INT_GT, [v4, v5], v11), ResOperation(rop.INT_XOR, [ConstInt(-4), v7], v12), ResOperation(rop.INT_MUL, [ConstInt(23), v11], v13), ResOperation(rop.UINT_GE, [ConstInt(1), v13], v14), ResOperation(rop.INT_IS_ZERO, [v14], tmp16), ResOperation(rop.GUARD_TRUE, [tmp16], None, descr=faildescr2), ResOperation(rop.INT_IS_TRUE, [v12], tmp17), ResOperation(rop.GUARD_FALSE, [tmp17], None, descr=faildescr3), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr4), ] looptoken = JitCellToken() operations[1].setfailargs([v8, v6, v1]) operations[7].setfailargs([v4]) operations[9].setfailargs([v10, v13]) operations[-1].setfailargs([v8, v10, v6, v3, v2, v9]) args = [32 , 41 , -9 , 12 , -18 , 46 , 15 , 17 , 10 , 12] cpu.compile_loop(inputargs, operations, looptoken) deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_latest_descr(deadframe).identifier == 3 assert cpu.get_int_value(deadframe, 0) == 12 assert cpu.get_int_value(deadframe, 1) == 23
def test_overflow(self): faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) faildescr3 = BasicFailDescr(3) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() v16 = BoxInt() v17 = BoxInt() v18 = BoxInt() cpu = CPU(None, None) cpu.setup_once() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.INT_SUB, [ConstInt(21), v5], v11), ResOperation(rop.INT_MUL_OVF, [v8, v4], v12), ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1), ResOperation(rop.UINT_LT, [v10, v3], v13), ResOperation(rop.INT_IS_TRUE, [v3], v14), ResOperation(rop.INT_XOR, [v9, v8], v15), ResOperation(rop.INT_LE, [v12, v6], v16), ResOperation(rop.UINT_GT, [v15, v5], v17), ResOperation(rop.UINT_LE, [ConstInt(-9), v13], v18), ResOperation(rop.GUARD_FALSE, [v13], None, descr=faildescr2), ResOperation(rop.GUARD_FALSE, [v1], None, descr=faildescr3), ] operations[2].setfailargs([v10, v6]) operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1]) operations[-1].setfailargs([v7, v1, v2]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0] deadframe = cpu.execute_token(looptoken, *args) assert cpu.get_int_value(deadframe, 0) == 105 assert cpu.get_int_value(deadframe, 1) == 63 assert cpu.get_int_value(deadframe, 2) == 0 assert cpu.get_int_value(deadframe, 3) == 0 assert cpu.get_int_value(deadframe, 4) == 16 assert cpu.get_int_value(deadframe, 5) == 1 assert cpu.get_int_value(deadframe, 6) == 16
def test_subi_range(self): for i in [-32769, -32768, -32767, 32767, 32768, 32769]: ops = ''' [i0] i1 = int_sub(i0, %d) i2 = int_sub_ovf(i1, %d) finish(i2) ''' % (i, i) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 10000000) assert self.cpu.get_int_value(deadframe, 0) == 10000000 - 2 * i
def unroll_and_optimize(self, loop, call_pure_results=None): self.add_guard_future_condition(loop) 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 token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] start_state = self._do_optimize_loop(preamble, call_pure_results, export_state=True) assert preamble.operations[-1].getopnum() == rop.LABEL inliner = Inliner(inputargs, jump_args) 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, start_state, export_state=False) 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
def _compile_and_run(self, source, args_values, float=True, ns={}): loop = parse(source, namespace=ns) cpu = self.CPUClass(rtyper=None, stats=None) cpu.setup_once() # looptoken = JitCellToken() cpu.compile_loop(loop.inputargs, loop.operations, looptoken) #import pdb; pdb.set_trace() deadframe = cpu.execute_token(looptoken, *args_values) print(source) if float: return cpu.get_float_value(deadframe, 0) else: return cpu.get_int_value(deadframe, 0)
def test_call_may_force_gcmap(self): cpu = self.cpu def f(frame, arg, x): assert not arg if self.cpu.backend_name != 'asmjs': assert frame.jf_gcmap[0] & 31 == 0 assert getmap(frame).count('1') == 3 # p1, p2, p3, but # not in registers frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 return lltype.nullptr(llmemory.GCREF.TO) FUNC = lltype.FuncType([JITFRAMEPTR, llmemory.GCREF, lltype.Signed], llmemory.GCREF) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) A = lltype.GcArray(lltype.Ptr(lltype.GcArray(lltype.Signed))) a = lltype.malloc(A, 3, zero=True) loop = self.parse(""" [i0, p0] pf = force_token() p1 = getarrayitem_gc(p0, 0, descr=arraydescr) p2 = getarrayitem_gc(p0, 1, descr=arraydescr) p3 = getarrayitem_gc(p0, 2, descr=arraydescr) pdying = getarrayitem_gc(p0, 0, descr=arraydescr) px = call_may_force(ConstClass(fptr), pf, pdying, i0, descr=calldescr) guard_not_forced(descr=faildescr) [p1, p2, p3, px] finish(px, descr=finaldescr) """, namespace={ 'fptr': fptr, 'calldescr': calldescr, 'arraydescr': cpu.arraydescrof(A), 'faildescr': BasicFailDescr(1), 'finaldescr': BasicFinalDescr(2) }) token = JitCellToken() cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) assert getmap(frame).count('1') == 4
def test_call_aligned_explicit_check(self): if (not platform.machine().startswith('arm') and sys.maxint == 2**31 - 1): # XXX is still necessary on x86? py.test.skip("libffi on 32bit is broken") cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') func_addr = self.make_function_returning_stack_pointer() F = lltype.Float I = lltype.Signed floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 13, -42, 1111, 95, 1] for case in range(256): args = [] funcargs = [] float_count = 0 int_count = 0 for i in range(8): if case & (1 << i): args.append('f%d' % float_count) float_count += 1 funcargs.append(F) else: args.append('i%d' % int_count) int_count += 1 funcargs.append(I) arguments = ', '.join(args) FUNC = self.FuncType(funcargs, I) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) ops = '[%s]\n' % arguments ops += 'i99 = call(%d, %s, descr=calldescr)\n' % (func_addr, arguments) ops += 'finish(i99)\n' loop = parse(ops, namespace=locals()) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = self.cpu.execute_token(looptoken, *argvals) x = cpu.get_int_value(deadframe, 0) align_req = self.get_alignment_requirements() assert x % align_req == 0
def runjitcelltoken(self): if self.startvars == self.loop.inputargs: return self.loop._jitcelltoken if not hasattr(self, '_initialjumploop_celltoken'): self._initialjumploop_celltoken = JitCellToken() args = [] for box in self.startvars: if box not in self.loop.inputargs: box = constbox(box) args.append(box) self.cpu.compile_loop( self.loop.inputargs, [ResOperation(rop.JUMP, args, descr=self.loop._targettoken)], self._initialjumploop_celltoken) return self._initialjumploop_celltoken
def optimize_bridge(self, loops, bridge, expected, expected_target="Loop", **boxvalues): if isinstance(loops, str): loops = (loops,) loops = [self.parse(loop) for loop in loops] bridge = self.parse(bridge) for loop in loops: loop.preamble = self.unroll_and_optimize(loop) preamble = loops[0].preamble token = JitCellToken() token.target_tokens = [l.operations[0].getdescr() for l in [preamble] + loops] boxes = {} for b in bridge.inputargs + [op.result for op in bridge.operations]: boxes[str(b)] = b for b, v in boxvalues.items(): boxes[b].value = v bridge.operations[-1].setdescr(token) self._do_optimize_bridge(bridge, None) if bridge.operations[-1].getopnum() == rop.LABEL: assert expected == "RETRACE" return print "\n".join([str(o) for o in bridge.operations]) expected = self.parse(expected) self.assert_equal(bridge, expected) if expected_target == "Preamble": assert bridge.operations[-1].getdescr() is preamble.operations[0].getdescr() elif expected_target == "Loop": assert len(loops) == 1 assert bridge.operations[-1].getdescr() is loops[0].operations[0].getdescr() elif expected_target.startswith("Loop"): n = int(expected_target[4:]) assert bridge.operations[-1].getdescr() is loops[n].operations[0].getdescr() else: assert False
def test_call_alignment_call_assembler(self): cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') fdescr3 = BasicFinalDescr(3) fdescr4 = BasicFinalDescr(4) def assembler_helper(failindex, virtualizable): assert 0, 'should not be called, but was with failindex (%d)' % failindex return 13 FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Signed)) class FakeJitDriverSD: index_of_virtualizable = -1 _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( _assembler_helper_ptr) floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 42, -42, 1111, 95, 1] for case in range(256): float_count = 0 int_count = 0 args = [] called_ops = '' total_index = -1 for i in range(8): if case & (1<<i): args.append('f%d' % float_count) else: args.append('i%d' % int_count) called_ops += 'f%d = cast_int_to_float(i%d)\n' % ( float_count, int_count) int_count += 1 if total_index == -1: total_index = float_count float_count += 1 else: called_ops += 'f%d = float_add(f%d, f%d)\n' % ( float_count + 1, total_index, float_count) total_index = float_count + 1 float_count += 2 arguments = ', '.join(args) called_ops = '[%s]\n' % arguments + called_ops called_ops += 'finish(f%d, descr=fdescr3)\n' % total_index # compile called loop called_loop = parse(called_ops, namespace=locals()) called_looptoken = JitCellToken() called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD() done_descr = called_loop.operations[-1].getdescr() self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) deadframe = cpu.execute_token(called_looptoken, *argvals) assert cpu.get_latest_descr(deadframe) == fdescr3 t = longlong.getrealfloat(cpu.get_float_value(deadframe, 0)) assert abs(t - expected_result) < 0.0001 ARGS = [] RES = lltype.Float for x in args: if x[0] == 'f': ARGS.append(lltype.Float) else: ARGS.append(lltype.Signed) FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES, EffectInfo.MOST_GENERAL) ops = ''' [%s] f99 = call_assembler_f(%s, descr=called_looptoken) guard_not_forced()[] finish(f99, descr=fdescr4) ''' % (arguments, arguments) loop = parse(ops, namespace=locals()) # we want to take the fast path self.cpu.done_with_this_frame_descr_float = done_descr try: othertoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # prepare call to called_loop argvals, _ = self._prepare_args(args, floats, ints) deadframe = cpu.execute_token(othertoken, *argvals) x = longlong.getrealfloat( cpu.get_float_value(deadframe, 0)) assert cpu.get_latest_descr(deadframe) == fdescr4 assert abs(x - expected_result) < 0.0001 finally: del self.cpu.done_with_this_frame_descr_float
def make_jitcell_token(jitdriver_sd): jitcell_token = JitCellToken() jitcell_token.outermost_jitdriver_sd = jitdriver_sd return jitcell_token
def check_rewrite(self, frm_operations, to_operations, **namespace): S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed)) sdescr = get_size_descr(self.gc_ll_descr, S) sdescr.tid = 1234 # T = lltype.GcStruct('T', ('y', lltype.Signed), ('z', lltype.Ptr(S)), ('t', lltype.Signed)) tdescr = get_size_descr(self.gc_ll_descr, T) tdescr.tid = 5678 tzdescr = get_field_descr(self.gc_ll_descr, T, 'z') # A = lltype.GcArray(lltype.Signed) adescr = get_array_descr(self.gc_ll_descr, A) adescr.tid = 4321 alendescr = adescr.lendescr # B = lltype.GcArray(lltype.Char) bdescr = get_array_descr(self.gc_ll_descr, B) bdescr.tid = 8765 blendescr = bdescr.lendescr # C = lltype.GcArray(lltype.Ptr(S)) cdescr = get_array_descr(self.gc_ll_descr, C) cdescr.tid = 8111 clendescr = cdescr.lendescr # E = lltype.GcStruct('Empty') edescr = get_size_descr(self.gc_ll_descr, E) edescr.tid = 9000 # vtable_descr = self.gc_ll_descr.fielddescr_vtable O = lltype.GcStruct('O', ('parent', rclass.OBJECT), ('x', lltype.Signed)) o_descr = self.cpu.sizeof(O, True) o_vtable = globals()['o_vtable'] # tiddescr = self.gc_ll_descr.fielddescr_tid wbdescr = self.gc_ll_descr.write_barrier_descr WORD = globals()['WORD'] # strdescr = self.gc_ll_descr.str_descr unicodedescr = self.gc_ll_descr.unicode_descr strlendescr = strdescr.lendescr unicodelendescr = unicodedescr.lendescr strhashdescr = self.gc_ll_descr.str_hash_descr unicodehashdescr = self.gc_ll_descr.unicode_hash_descr casmdescr = JitCellToken() clt = FakeLoopToken() clt._ll_initial_locs = [0, 8] frame_info = lltype.malloc(jitframe.JITFRAMEINFO, flavor='raw') clt.frame_info = frame_info frame_info.jfi_frame_depth = 13 frame_info.jfi_frame_size = 255 framedescrs = self.gc_ll_descr.getframedescrs(self.cpu) framelendescr = framedescrs.arraydescr.lendescr jfi_frame_depth = framedescrs.jfi_frame_depth jfi_frame_size = framedescrs.jfi_frame_size jf_frame_info = framedescrs.jf_frame_info jf_savedata = framedescrs.jf_savedata jf_force_descr = framedescrs.jf_force_descr jf_descr = framedescrs.jf_descr jf_guard_exc = framedescrs.jf_guard_exc jf_forward = framedescrs.jf_forward jf_extra_stack_depth = framedescrs.jf_extra_stack_depth signedframedescr = self.cpu.signedframedescr floatframedescr = self.cpu.floatframedescr casmdescr.compiled_loop_token = clt # guarddescr = AbstractFailDescr() # namespace.update(locals()) # for funcname in self.gc_ll_descr._generated_functions: namespace[funcname] = self.gc_ll_descr.get_malloc_fn(funcname) namespace[funcname + '_descr'] = getattr(self.gc_ll_descr, '%s_descr' % funcname) # ops = parse(frm_operations, namespace=namespace) expected = parse(to_operations % Evaluator(namespace), namespace=namespace) operations = self.gc_ll_descr.rewrite_assembler(self.cpu, ops.operations, []) remap = {} for a, b in zip(ops.inputargs, expected.inputargs): remap[b] = a equaloplists(operations, expected.operations, remap=remap) lltype.free(frame_info, flavor='raw')
def setup_class(cls): if cls.runappdirect: py.test.skip("Can't run this test with -A") w_f = cls.space.appexec([], """(): def function(): pass return function """) cls.w_f = w_f ll_code = cast_instance_to_base_ptr(w_f.code) code_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, ll_code) logger = Logger(MockSD()) oplist = parse(""" [i1, i2, p2] i3 = int_add(i1, i2) debug_merge_point(0, 0, 0, 0, 0, ConstPtr(ptr0)) guard_nonnull(p2) [] guard_true(i3) [] """, namespace={'ptr0': code_gcref}).operations greenkey = [ConstInt(0), ConstInt(0), ConstPtr(code_gcref)] offset = {} for i, op in enumerate(oplist): if i != 1: offset[op] = i token = JitCellToken() token.number = 0 di_loop = JitDebugInfo(MockJitDriverSD, logger, token, oplist, 'loop', greenkey) di_loop_optimize = JitDebugInfo(MockJitDriverSD, logger, JitCellToken(), oplist, 'loop', greenkey) di_loop.asminfo = AsmInfo(offset, 0x42, 12) di_bridge = JitDebugInfo(MockJitDriverSD, logger, JitCellToken(), oplist, 'bridge', fail_descr=BasicFailDescr()) di_bridge.asminfo = AsmInfo(offset, 0, 0) def interp_on_compile(): di_loop.oplist = cls.oplist pypy_hooks.after_compile(di_loop) def interp_on_compile_bridge(): pypy_hooks.after_compile_bridge(di_bridge) def interp_on_optimize(): di_loop_optimize.oplist = cls.oplist pypy_hooks.before_compile(di_loop_optimize) def interp_on_abort(): pypy_hooks.on_abort(Counters.ABORT_TOO_LONG, pypyjitdriver, greenkey, 'blah', Logger(MockSD), []) space = cls.space cls.w_on_compile = space.wrap(interp2app(interp_on_compile)) cls.w_on_compile_bridge = space.wrap(interp2app(interp_on_compile_bridge)) cls.w_on_abort = space.wrap(interp2app(interp_on_abort)) cls.w_int_add_num = space.wrap(rop.INT_ADD) cls.w_dmp_num = space.wrap(rop.DEBUG_MERGE_POINT) cls.w_on_optimize = space.wrap(interp2app(interp_on_optimize)) cls.orig_oplist = oplist cls.w_sorted_keys = space.wrap(sorted(Counters.counter_names))
def check_rewrite(self, frm_operations, to_operations, **namespace): # objects to use inside the test A = lltype.GcArray(lltype.Signed) adescr = get_array_descr(self.gc_ll_descr, A) adescr.tid = 4321 alendescr = adescr.lendescr # pinned_obj_type = lltype.GcStruct('PINNED_STRUCT', ('my_int', lltype.Signed)) pinned_obj_my_int_descr = get_field_descr(self.gc_ll_descr, pinned_obj_type, 'my_int') pinned_obj_ptr = lltype.malloc(pinned_obj_type) pinned_obj_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, pinned_obj_ptr) assert rgc.pin(pinned_obj_gcref) # notpinned_obj_type = lltype.GcStruct('NOT_PINNED_STRUCT', ('my_int', lltype.Signed)) notpinned_obj_my_int_descr = get_field_descr(self.gc_ll_descr, notpinned_obj_type, 'my_int') notpinned_obj_ptr = lltype.malloc(notpinned_obj_type) notpinned_obj_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, notpinned_obj_ptr) # ptr_array_descr = self.cpu.arraydescrof(MovableObjectTracker.ptr_array_type) # vtable_descr = self.gc_ll_descr.fielddescr_vtable O = lltype.GcStruct('O', ('parent', rclass.OBJECT), ('x', lltype.Signed)) o_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) # tiddescr = self.gc_ll_descr.fielddescr_tid wbdescr = self.gc_ll_descr.write_barrier_descr WORD = globals()['WORD'] # strdescr = self.gc_ll_descr.str_descr unicodedescr = self.gc_ll_descr.unicode_descr strlendescr = strdescr.lendescr unicodelendescr = unicodedescr.lendescr casmdescr = JitCellToken() clt = FakeLoopToken() clt._ll_initial_locs = [0, 8] frame_info = lltype.malloc(jitframe.JITFRAMEINFO, flavor='raw') clt.frame_info = frame_info frame_info.jfi_frame_depth = 13 frame_info.jfi_frame_size = 255 framedescrs = self.gc_ll_descr.getframedescrs(self.cpu) framelendescr = framedescrs.arraydescr.lendescr jfi_frame_depth = framedescrs.jfi_frame_depth jfi_frame_size = framedescrs.jfi_frame_size jf_frame_info = framedescrs.jf_frame_info signedframedescr = self.cpu.signedframedescr floatframedescr = self.cpu.floatframedescr casmdescr.compiled_loop_token = clt tzdescr = None # noone cares # namespace.update(locals()) # for funcname in self.gc_ll_descr._generated_functions: namespace[funcname] = self.gc_ll_descr.get_malloc_fn(funcname) namespace[funcname + '_descr'] = getattr(self.gc_ll_descr, '%s_descr' % funcname) # ops = parse(frm_operations, namespace=namespace) operations = self.gc_ll_descr.rewrite_assembler(self.cpu, ops.operations, []) # make the array containing the GCREF's accessible inside the tests. # This must be done after we call 'rewrite_assembler'. Before that # call 'last_moving_obj_tracker' is None or filled with some old # value. namespace['ptr_array_gcref'] = self.gc_ll_descr.last_moving_obj_tracker.ptr_array_gcref expected = parse(to_operations % Evaluator(namespace), namespace=namespace) equaloplists(operations, expected.operations) lltype.free(frame_info, flavor='raw')
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, 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._ll_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, 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 deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 res = self.cpu.get_int_value(deadframe, 0) assert res == 20
def check_rewrite(self, frm_operations, to_operations, **namespace): S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed)) sdescr = get_size_descr(self.gc_ll_descr, S) sdescr.tid = 1234 # T = lltype.GcStruct('T', ('y', lltype.Signed), ('z', lltype.Ptr(S)), ('t', lltype.Signed)) tdescr = get_size_descr(self.gc_ll_descr, T) tdescr.tid = 5678 tzdescr = get_field_descr(self.gc_ll_descr, T, 'z') # A = lltype.GcArray(lltype.Signed) adescr = get_array_descr(self.gc_ll_descr, A) adescr.tid = 4321 alendescr = adescr.lendescr # B = lltype.GcArray(lltype.Char) bdescr = get_array_descr(self.gc_ll_descr, B) bdescr.tid = 8765 blendescr = bdescr.lendescr # C = lltype.GcArray(lltype.Ptr(S)) cdescr = get_array_descr(self.gc_ll_descr, C) cdescr.tid = 8111 clendescr = cdescr.lendescr # E = lltype.GcStruct('Empty') edescr = get_size_descr(self.gc_ll_descr, E) edescr.tid = 9000 # vtable_descr = self.gc_ll_descr.fielddescr_vtable O = lltype.GcStruct('O', ('parent', rclass.OBJECT), ('x', lltype.Signed)) o_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) register_known_gctype(self.cpu, o_vtable, O) # tiddescr = self.gc_ll_descr.fielddescr_tid wbdescr = self.gc_ll_descr.write_barrier_descr WORD = globals()['WORD'] # strdescr = self.gc_ll_descr.str_descr unicodedescr = self.gc_ll_descr.unicode_descr strlendescr = strdescr.lendescr unicodelendescr = unicodedescr.lendescr casmdescr = JitCellToken() clt = FakeLoopToken() clt._ll_initial_locs = [0, 8] frame_info = lltype.malloc(jitframe.JITFRAMEINFO, flavor='raw') clt.frame_info = frame_info frame_info.jfi_frame_depth = 13 frame_info.jfi_frame_size = 255 framedescrs = self.gc_ll_descr.getframedescrs(self.cpu) framelendescr = framedescrs.arraydescr.lendescr jfi_frame_depth = framedescrs.jfi_frame_depth jfi_frame_size = framedescrs.jfi_frame_size jf_frame_info = framedescrs.jf_frame_info signedframedescr = self.cpu.signedframedescr floatframedescr = self.cpu.floatframedescr casmdescr.compiled_loop_token = clt tzdescr = None # noone cares # namespace.update(locals()) # for funcname in self.gc_ll_descr._generated_functions: namespace[funcname] = self.gc_ll_descr.get_malloc_fn(funcname) namespace[funcname + '_descr'] = getattr(self.gc_ll_descr, '%s_descr' % funcname) # ops = parse(frm_operations, namespace=namespace) expected = parse(to_operations % Evaluator(namespace), namespace=namespace) operations = self.gc_ll_descr.rewrite_assembler(self.cpu, ops.operations, []) equaloplists(operations, expected.operations) lltype.free(frame_info, flavor='raw')