def test_liveranges(self): i0, i1, i2 = IntFrontendOp(0), IntFrontendOp(0), IntFrontendOp(0) t = Trace([i0, i1, i2], metainterp_sd) p0 = FakeOp(t.record_op(rop.NEW_WITH_VTABLE, [], descr=SomeDescr())) t.record_op(rop.GUARD_TRUE, [i0]) resume.capture_resumedata([], [i1, i2, p0], [p0, i1], t) assert t.get_live_ranges() == [4, 4, 4, 4]
def test_read_snapshot_interface(self): i0, i1, i2 = IntFrontendOp(0), IntFrontendOp(0), IntFrontendOp(0) t = Trace([i0, i1, i2], metainterp_sd) t.record_op(rop.GUARD_TRUE, [i1]) frame0 = FakeFrame(1, JitCode(2), [i0, i1]) frame1 = FakeFrame(3, JitCode(4), [i2, i2]) resume.capture_resumedata([frame0, frame1], None, [], t) t.record_op(rop.GUARD_TRUE, [i1]) resume.capture_resumedata([frame0, frame1], None, [], t) (i0, i1, i2), l, iter = self.unpack(t) pos = l[0].rd_resume_position snapshot_iter = iter.get_snapshot_iter(pos) assert snapshot_iter.vable_array == [] assert snapshot_iter.vref_array == [] framestack = snapshot_iter.framestack jc_index, pc = snapshot_iter.unpack_jitcode_pc(framestack[1]) assert jc_index == 4 assert pc == 3 assert snapshot_iter.unpack_array(framestack[1].box_array) == [i2, i2] jc_index, pc = snapshot_iter.unpack_jitcode_pc(framestack[0]) assert jc_index == 2 assert pc == 1 assert snapshot_iter.unpack_array(framestack[0].box_array) == [i0, i1] pos = l[1].rd_resume_position snapshot_iter = iter.get_snapshot_iter(pos) framestack = snapshot_iter.framestack assert snapshot_iter.vable_array == [] assert snapshot_iter.vref_array == [] jc_index, pc = snapshot_iter.unpack_jitcode_pc(framestack[1]) assert jc_index == 4 assert pc == 3 assert snapshot_iter.unpack_array(framestack[1].box_array) == [i2, i2]
def test_tag_overflow(self): t = Trace([], metainterp_sd) i0 = FakeOp(100000) # if we overflow, we can keep recording for i in range(10): t.record_op(rop.FINISH, [i0]) assert t.unpack() == ([], []) assert t.tag_overflow
def test_virtualizable_virtualref(self): i0, i1, i2 = IntFrontendOp(0), IntFrontendOp(0), IntFrontendOp(0) t = Trace([i0, i1, i2], metainterp_sd) p0 = FakeOp(t.record_op(rop.NEW_WITH_VTABLE, [], descr=SomeDescr())) t.record_op(rop.GUARD_TRUE, [i0]) resume.capture_resumedata([], [i1, i2, p0], [p0, i1], t) (i0, i1, i2), l, iter = self.unpack(t) assert not l[1].framestack assert l[1].virtualizables == [l[0], i1, i2] assert l[1].vref_boxes == [l[0], i1]
def set_inputargs(self, inpargs, metainterp_sd): from rpython.jit.metainterp.opencoder import Trace self.trace = Trace(inpargs, metainterp_sd) self.inputargs = inpargs if self._cache is not None: # hack to record the ops *after* we know our inputargs for (opnum, argboxes, op, descr) in self._cache: pos = self.trace.record_op(opnum, argboxes, descr) op.set_position(pos) self._cache = None
def test_simple_iterator(self): i0, i1 = IntFrontendOp(0), IntFrontendOp(0) t = Trace([i0, i1], metainterp_sd) add = FakeOp(t.record_op(rop.INT_ADD, [i0, i1])) t.record_op(rop.INT_ADD, [add, ConstInt(1)]) (i0, i1), l, _ = self.unpack(t) assert len(l) == 2 assert l[0].opnum == rop.INT_ADD assert l[1].opnum == rop.INT_ADD assert l[1].getarg(1).getint() == 1 assert l[1].getarg(0) is l[0] assert l[0].getarg(0) is i0 assert l[0].getarg(1) is i1
def test_cut_trace_from(self): i0, i1, i2 = IntFrontendOp(0), IntFrontendOp(0), IntFrontendOp(0) t = Trace([i0, i1, i2], metainterp_sd) add1 = FakeOp(t.record_op(rop.INT_ADD, [i0, i1])) cut_point = t.cut_point() add2 = FakeOp(t.record_op(rop.INT_ADD, [add1, i1])) t.record_op(rop.GUARD_TRUE, [add2]) resume.capture_resumedata([FakeFrame(3, JitCode(4), [add2, add1, i1])], None, [], t) t.record_op(rop.INT_SUB, [add2, add1]) t2 = t.cut_trace_from(cut_point, [add1, i1]) (i0, i1), l, iter = self.unpack(t2) assert len(l) == 3 assert l[0].getarglist() == [i0, i1]
def xxx_test_random_snapshot(self, lst): inputargs, ops = lst t = Trace(inputargs, metainterp_sd) for op in ops: newop = FakeOp(t.record_op(op.getopnum(), op.getarglist())) newop.orig_op = op if newop.is_guard(): resume.capture_resumedata(op.framestack, None, [], t) op.position = newop.get_position() inpargs, l, iter = self.unpack(t) loop1 = TreeLoop("loop1") loop1.inputargs = inputargs loop1.operations = ops loop2 = TreeLoop("loop2") loop2.inputargs = inpargs loop2.operations = l BaseTest.assert_equal(loop1, loop2)
def test_ResumeDataLoopMemo_random(lst): inpargs = [box for box in lst if not isinstance(box, Const)] metainterp_sd = FakeMetaInterpStaticData() t = Trace(inpargs, metainterp_sd) t.append(0) i = t.get_iter() t.create_top_snapshot(FakeJitCode("", 0), 0, Frame(lst), False, [], []) memo = ResumeDataLoopMemo(metainterp_sd) numb_state = memo.number(0, i) numb = numb_state.create_numbering() l = unpack_numbering(numb) assert l[0] == len(l) assert l[1] == 0 assert l[1] == 0 assert l[2] == 0 assert l[3] == 0 assert l[4] == 0 mapping = dict(zip(inpargs, i.inputargs)) for i, item in enumerate(lst): v, tag = untag(l[i + 6]) if tag == TAGBOX: assert l[i + 6] == numb_state.liveboxes[mapping[item]] elif tag == TAGCONST: assert memo.consts[v].getint() == item.getint() elif tag == TAGINT: assert v == item.getint()
def convert_loop_to_trace(loop, metainterp_sd, skip_last=False): from rpython.jit.metainterp.opencoder import Trace from rpython.jit.metainterp.test.test_opencoder import FakeFrame from rpython.jit.metainterp import history, resume def get(a): if isinstance(a, history.Const): return a return mapping[a] class jitcode: index = 200 inputargs = [ pick_cls(inparg)(i) for i, inparg in enumerate(loop.inputargs) ] mapping = {} for one, two in zip(loop.inputargs, inputargs): mapping[one] = two trace = Trace(inputargs, metainterp_sd) ops = loop.operations if skip_last: ops = ops[:-1] for op in ops: newpos = trace.record_op(op.getopnum(), [get(arg) for arg in op.getarglist()], op.getdescr()) if rop.is_guard(op.getopnum()): failargs = [] if op.getfailargs(): failargs = [get(arg) for arg in op.getfailargs()] frame = FakeFrame(100, jitcode, failargs) resume.capture_resumedata([frame], None, [], trace) if op.type != 'v': newop = pick_cls(op)(newpos) mapping[op] = newop trace._mapping = mapping # for tests return trace
def convert_loop_to_trace(loop, metainterp_sd, skip_last=False): from rpython.jit.metainterp.opencoder import Trace from rpython.jit.metainterp.test.test_opencoder import FakeFrame from rpython.jit.metainterp import history, resume def get(a): if isinstance(a, history.Const): return a return mapping[a] class jitcode: index = 200 inputargs = [pick_cls(inparg)(i) for i, inparg in enumerate(loop.inputargs)] mapping = {} for one, two in zip(loop.inputargs, inputargs): mapping[one] = two trace = Trace(inputargs, metainterp_sd) ops = loop.operations if skip_last: ops = ops[:-1] for op in ops: newpos = trace.record_op(op.getopnum(), [get(arg) for arg in op.getarglist()], op.getdescr()) if rop.is_guard(op.getopnum()): failargs = [] if op.getfailargs(): failargs = [get(arg) for arg in op.getfailargs()] frame = FakeFrame(100, jitcode, failargs) resume.capture_resumedata([frame], None, [], trace) if op.type != 'v': newop = pick_cls(op)(newpos) mapping[op] = newop trace._mapping = mapping # for tests return trace
def make_storage(b1, b2, b3): t = Trace([box for box in [b1, b2, b3] if not isinstance(box, Const)], FakeMetaInterpStaticData()) t.append(0) storage = Storage() snap1 = t.create_snapshot(FakeJitCode("code3", 41), 42, Frame([b1, ConstInt(1), b1, b2]), False) snap2 = t.create_snapshot(FakeJitCode("code2", 31), 32, Frame([ConstInt(2), ConstInt(3)]), False) snap3 = t.create_top_snapshot(FakeJitCode("code1", 21), 22, Frame([b1, b2, b3]), False, [], []) snap3.prev = snap2 snap2.prev = snap1 storage.rd_resume_position = 0 return storage, t
def test_rd_snapshot(self): i0, i1 = IntFrontendOp(0), IntFrontendOp(0) t = Trace([i0, i1], metainterp_sd) add = FakeOp(t.record_op(rop.INT_ADD, [i0, i1])) t.record_op(rop.GUARD_FALSE, [add]) # now we write rd_snapshot and friends frame0 = FakeFrame(1, JitCode(2), [i0, i1]) frame1 = FakeFrame(3, JitCode(4), [i0, i0, add]) framestack = [frame0] resume.capture_resumedata(framestack, None, [], t) (i0, i1), l, iter = self.unpack(t) assert l[1].opnum == rop.GUARD_FALSE assert l[1].framestack[0].boxes == [i0, i1] t.record_op(rop.GUARD_FALSE, [add]) resume.capture_resumedata([frame0, frame1], None, [], t) t.record_op(rop.INT_ADD, [add, add]) (i0, i1), l, iter = self.unpack(t) assert l[1].opnum == rop.GUARD_FALSE assert l[1].framestack[0].boxes == [i0, i1] assert l[2].opnum == rop.GUARD_FALSE fstack = l[2].framestack assert fstack[0].boxes == [i0, i1] assert fstack[1].boxes == [i0, i0, l[0]]
def test_deadranges(self): i0, i1, i2 = IntFrontendOp(0), IntFrontendOp(0), IntFrontendOp(0) t = Trace([i0, i1, i2], metainterp_sd) p0 = FakeOp(t.record_op(rop.NEW_WITH_VTABLE, [], descr=SomeDescr())) t.record_op(rop.GUARD_TRUE, [i0]) resume.capture_resumedata([], [i1, i2, p0], [p0, i1], t) i3 = FakeOp(t.record_op(rop.INT_ADD, [i1, ConstInt(1)])) i4 = FakeOp(t.record_op(rop.INT_ADD, [i3, ConstInt(1)])) t.record_op(rop.ESCAPE_N, [ConstInt(3)]) t.record_op(rop.ESCAPE_N, [ConstInt(3)]) t.record_op(rop.ESCAPE_N, [ConstInt(3)]) t.record_op(rop.ESCAPE_N, [ConstInt(3)]) t.record_op(rop.ESCAPE_N, [ConstInt(3)]) t.record_op(rop.FINISH, [i4]) assert t.get_dead_ranges() == [0, 0, 0, 0, 0, 3, 4, 5]
def test_tag_overflow(self): t = Trace([], metainterp_sd) i0 = FakeOp(100000) py.test.raises(FrontendTagOverflow, t.record_op, rop.FINISH, [i0]) assert t.unpack() == ([], [])
def test_ResumeDataLoopMemo_number(): b1, b2, b3, b4, b5 = [IntFrontendOp(0), IntFrontendOp(1), IntFrontendOp(2), RefFrontendOp(3), RefFrontendOp(4)] c1, c2, c3, c4 = [ConstInt(1), ConstInt(2), ConstInt(3), ConstInt(4)] env = [b1, c1, b2, b1, c2] metainterp_sd = FakeMetaInterpStaticData() t = Trace([b1, b2, b3, b4, b5], metainterp_sd) snap = t.create_snapshot(FakeJitCode("jitcode", 0), 0, Frame(env), False) env1 = [c3, b3, b1, c1] t.append(0) # descr index snap1 = t.create_top_snapshot(FakeJitCode("jitcode", 0), 2, Frame(env1), False, [], []) snap1.prev = snap env2 = [c3, b3, b1, c3] env3 = [c3, b3, b1, c3] env4 = [c3, b4, b1, c3] env5 = [b1, b4, b5] memo = ResumeDataLoopMemo(metainterp_sd) iter = t.get_iter() b1, b2, b3, b4, b5 = iter.inputargs numb_state = memo.number(0, iter) numb = numb_state.create_numbering() assert numb_state.num_virtuals == 0 assert numb_state.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), b3: tag(2, TAGBOX)} base = [0, 0, tag(0, TAGBOX), tag(1, TAGINT), tag(1, TAGBOX), tag(0, TAGBOX), tag(2, TAGINT)] assert unpack_numbering(numb) == [17, 0, 0, 0] + base + [0, 2, tag(3, TAGINT), tag(2, TAGBOX), tag(0, TAGBOX), tag(1, TAGINT)] t.append(0) snap2 = t.create_top_snapshot(FakeJitCode("jitcode", 0), 2, Frame(env2), False, [], []) snap2.prev = snap numb_state2 = memo.number(1, iter) numb2 = numb_state2.create_numbering() assert numb_state2.num_virtuals == 0 assert numb_state2.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), b3: tag(2, TAGBOX)} assert numb_state2.liveboxes is not numb_state.liveboxes assert unpack_numbering(numb2) == [17, 0, 0, 0] + base + [0, 2, tag(3, TAGINT), tag(2, TAGBOX), tag(0, TAGBOX), tag(3, TAGINT)] t.append(0) snap3 = t.create_top_snapshot(FakeJitCode("jitcode", 0), 2, Frame([]), False, [], env3) snap3.prev = snap class FakeVirtualInfo(info.AbstractVirtualPtrInfo): def __init__(self, virt): self._is_virtual = virt def is_virtual(self): return self._is_virtual # renamed b3.set_forwarded(c4) numb_state3 = memo.number(2, iter) numb3 = numb_state3.create_numbering() assert numb_state3.num_virtuals == 0 assert numb_state3.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)} assert unpack_numbering(numb3) == ([17, 0, 0, 2, tag(3, TAGINT), tag(4, TAGINT), tag(0, TAGBOX), tag(3, TAGINT)] + base + [0, 2]) # virtual t.append(0) snap4 = t.create_top_snapshot(FakeJitCode("jitcode", 0), 2, Frame([]), False, [], env4) snap4.prev = snap b4.set_forwarded(FakeVirtualInfo(True)) numb_state4 = memo.number(3, iter) numb4 = numb_state4.create_numbering() assert numb_state4.num_virtuals == 1 assert numb_state4.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), b4: tag(0, TAGVIRTUAL)} assert unpack_numbering(numb4) == [17, 0, 0, 2, tag(3, TAGINT), tag(0, TAGVIRTUAL), tag(0, TAGBOX), tag(3, TAGINT)] + base + [0, 2] t.append(0) snap4 = t.create_snapshot(FakeJitCode("jitcode", 2), 1, Frame(env4), False) t.append(0) snap4.prev = snap snap5 = t.create_top_snapshot(FakeJitCode("jitcode", 0), 0, Frame([]), False, env5, []) snap5.prev = snap4 b4.set_forwarded(FakeVirtualInfo(True)) b5.set_forwarded(FakeVirtualInfo(True)) numb_state5 = memo.number(4, iter) numb5 = numb_state5.create_numbering() assert numb_state5.num_virtuals == 2 assert numb_state5.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), b4: tag(0, TAGVIRTUAL), b5: tag(1, TAGVIRTUAL)} assert unpack_numbering(numb5) == [22, 0, 3, tag(0, TAGBOX), tag(0, TAGVIRTUAL), tag(1, TAGVIRTUAL), 0] + base + [ 2, 1, tag(3, TAGINT), tag(0, TAGVIRTUAL), tag(0, TAGBOX), tag(3, TAGINT) ] + [0, 0]
class History(object): ends_with_jump = False trace = None def __init__(self): self.descr_cache = {} self.descrs = {} self.consts = [] self._cache = [] def set_inputargs(self, inpargs, metainterp_sd): from rpython.jit.metainterp.opencoder import Trace self.trace = Trace(inpargs, metainterp_sd) self.inputargs = inpargs if self._cache is not None: # hack to record the ops *after* we know our inputargs for (opnum, argboxes, op, descr) in self._cache: pos = self.trace.record_op(opnum, argboxes, descr) op.set_position(pos) self._cache = None def length(self): return self.trace._count - len(self.trace.inputargs) def trace_tag_overflow(self): return self.trace.tag_overflow def get_trace_position(self): return self.trace.cut_point() def cut(self, cut_at): self.trace.cut_at(cut_at) def any_operation(self): return self.trace._count > self.trace._start @specialize.argtype(2) def set_op_value(self, op, value): if value is None: return elif isinstance(value, bool): op.setint(int(value)) elif lltype.typeOf(value) == lltype.Signed: op.setint(value) elif lltype.typeOf(value) is longlong.FLOATSTORAGE: op.setfloatstorage(value) else: assert lltype.typeOf(value) == llmemory.GCREF op.setref_base(value) def _record_op(self, opnum, argboxes, descr=None): return self.trace.record_op(opnum, argboxes, descr) @specialize.argtype(3) def record(self, opnum, argboxes, value, descr=None): if self.trace is None: pos = 2**14 - 1 else: pos = self._record_op(opnum, argboxes, descr) if value is None: op = FrontendOp(pos) elif isinstance(value, bool): op = IntFrontendOp(pos) elif lltype.typeOf(value) == lltype.Signed: op = IntFrontendOp(pos) elif lltype.typeOf(value) is longlong.FLOATSTORAGE: op = FloatFrontendOp(pos) else: op = RefFrontendOp(pos) if self.trace is None: self._cache.append((opnum, argboxes, op, descr)) self.set_op_value(op, value) return op def record_nospec(self, opnum, argboxes, descr=None): tp = opclasses[opnum].type pos = self._record_op(opnum, argboxes, descr) if tp == 'v': return FrontendOp(pos) elif tp == 'i': return IntFrontendOp(pos) elif tp == 'f': return FloatFrontendOp(pos) assert tp == 'r' return RefFrontendOp(pos) def record_default_val(self, opnum, argboxes, descr=None): assert rop.is_same_as(opnum) op = self.record_nospec(opnum, argboxes, descr) op.copy_value_from(argboxes[0]) return op
class History(object): ends_with_jump = False trace = None def __init__(self): self.descr_cache = {} self.descrs = {} self.consts = [] self._cache = [] def set_inputargs(self, inpargs, metainterp_sd): from rpython.jit.metainterp.opencoder import Trace self.trace = Trace(inpargs, metainterp_sd) self.inputargs = inpargs if self._cache is not None: # hack to record the ops *after* we know our inputargs for (opnum, argboxes, op, descr) in self._cache: pos = self.trace.record_op(opnum, argboxes, descr) op.set_position(pos) self._cache = None def length(self): return self.trace._count - len(self.trace.inputargs) def get_trace_position(self): return self.trace.cut_point() def cut(self, cut_at): self.trace.cut_at(cut_at) def any_operation(self): return self.trace._count > self.trace._start @specialize.argtype(2) def set_op_value(self, op, value): if value is None: return elif isinstance(value, bool): op.setint(int(value)) elif lltype.typeOf(value) == lltype.Signed: op.setint(value) elif lltype.typeOf(value) is longlong.FLOATSTORAGE: op.setfloatstorage(value) else: assert lltype.typeOf(value) == llmemory.GCREF op.setref_base(value) def _record_op(self, opnum, argboxes, descr=None): from rpython.jit.metainterp.opencoder import FrontendTagOverflow try: return self.trace.record_op(opnum, argboxes, descr) except FrontendTagOverflow: # note that with the default settings this one should not # happen - however if we hit that case, we don't get # anything disabled raise SwitchToBlackhole(Counters.ABORT_TOO_LONG) @specialize.argtype(3) def record(self, opnum, argboxes, value, descr=None): if self.trace is None: pos = 2**14 - 1 else: pos = self._record_op(opnum, argboxes, descr) if value is None: op = FrontendOp(pos) elif isinstance(value, bool): op = IntFrontendOp(pos) elif lltype.typeOf(value) == lltype.Signed: op = IntFrontendOp(pos) elif lltype.typeOf(value) is longlong.FLOATSTORAGE: op = FloatFrontendOp(pos) else: op = RefFrontendOp(pos) if self.trace is None: self._cache.append((opnum, argboxes, op, descr)) self.set_op_value(op, value) return op def record_nospec(self, opnum, argboxes, descr=None): tp = opclasses[opnum].type pos = self._record_op(opnum, argboxes, descr) if tp == 'v': return FrontendOp(pos) elif tp == 'i': return IntFrontendOp(pos) elif tp == 'f': return FloatFrontendOp(pos) assert tp == 'r' return RefFrontendOp(pos) def record_default_val(self, opnum, argboxes, descr=None): assert rop.is_same_as(opnum) op = self.record_nospec(opnum, argboxes, descr) op.copy_value_from(argboxes[0]) return op
def test_tag_overflow(self): t = Trace([], metainterp_sd) i0 = FakeOp(100000) py.test.raises(SwitchToBlackhole, t.record_op, rop.FINISH, [i0]) assert t.unpack() == ([], [])