def test_virtual_adder_make_varray(): b2s, b4s = [RefFrontendOp(0), IntFrontendOp(0)] b4s.setint(4) c1s = ConstInt(111) storage = Storage() memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, None, memo) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} v2 = info.ArrayPtrInfo(LLtypeMixin.arraydescr, size=2, is_virtual=True) b2s.set_forwarded(v2) v2._items = [b4s, c1s] modifier.register_virtual_fields(b2s, [b4s, c1s]) liveboxes = [] modifier._number_virtuals(liveboxes, 0) dump_storage(storage, liveboxes) storage.rd_consts = memo.consts[:] storage.rd_numb = Numbering([0]) # resume b1t, b3t, b4t = [IntFrontendOp(0), IntFrontendOp(0), IntFrontendOp(0)] b1t.setint(11) b3t.setint(33) b4t.setint(44) newboxes = _resume_remap( liveboxes, [ #b2s -- virtual b4s ], b4t) # resume metainterp = MyMetaInterp() reader = ResumeDataFakeReader(storage, newboxes, metainterp) assert len(reader.virtuals_cache.virtuals_ptr_cache) == 1 b2t = reader.decode_ref(tag(0, TAGVIRTUAL)) trace = metainterp.trace expected = [ (rop.NEW_ARRAY, [ConstInt(2)], b2t.getref_base(), LLtypeMixin.arraydescr), (rop.SETARRAYITEM_GC, [b2t, ConstInt(0), b4t], None, LLtypeMixin.arraydescr), (rop.SETARRAYITEM_GC, [b2t, ConstInt(1), c1s], None, LLtypeMixin.arraydescr), ] with CompareableConsts(): for x, y in zip(expected, trace): assert x == y # ptr = b2t.getref_base()._obj.container._as_ptr() assert lltype.typeOf(ptr) == lltype.Ptr(lltype.GcArray(lltype.Signed)) assert len(ptr) == 2 assert ptr[0] == 44 assert ptr[1] == 111
def test_virtual_adder_int_constants(): b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**16), ConstInt(-65)] storage, t = make_storage(b1s, b2s, b3s) metainterp_sd = FakeMetaInterpStaticData() memo = ResumeDataLoopMemo(metainterp_sd) i = t.get_iter() modifier = ResumeDataVirtualAdder(FakeOptimizer(i), storage, storage, i, memo) liveboxes = modifier.finish() cpu = MyCPU([]) reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage, "deadframe") reader.consume_vref_and_vable(None, None, None) reader.resumecodereader.jump(2) # framestack _next_section(reader, sys.maxint, 1, sys.maxint, 2**16) reader.resumecodereader.jump(2) # framestack _next_section(reader, 2, 3) reader.resumecodereader.jump(2) # framestack _next_section(reader, sys.maxint, 2**16, -65)
def test_virtual_adder_make_vstruct(): b2s, b4s = [RefFrontendOp(0), RefFrontendOp(0)] c1s = ConstInt(111) storage = Storage() memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, None, memo) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} v2 = info.StructPtrInfo(LLtypeMixin.ssize, is_virtual=True) b2s.set_forwarded(v2) v2.setfield(LLtypeMixin.adescr, b2s, c1s) v2.setfield(LLtypeMixin.abisdescr, b2s, c1s) v2.setfield(LLtypeMixin.bdescr, b2s, b4s) modifier.register_virtual_fields(b2s, [c1s, c1s, b4s]) liveboxes = [] modifier._number_virtuals(liveboxes, 0) dump_storage(storage, liveboxes) storage.rd_consts = memo.consts[:] storage.rd_numb = Numbering([0]) b4t = RefFrontendOp(0) newboxes = _resume_remap( liveboxes, [ #b2s -- virtual b4s ], b4t) # NULL = ConstPtr.value metainterp = MyMetaInterp() reader = ResumeDataFakeReader(storage, newboxes, metainterp) assert len(reader.virtuals_cache.virtuals_ptr_cache) == 1 b2t = reader.decode_ref(tag(0, TAGVIRTUAL)) trace = metainterp.trace expected = [ (rop.NEW, [], b2t.getref_base(), LLtypeMixin.ssize), (rop.SETFIELD_GC, [b2t, c1s], None, LLtypeMixin.adescr), (rop.SETFIELD_GC, [b2t, c1s], None, LLtypeMixin.abisdescr), (rop.SETFIELD_GC, [b2t, b4t], None, LLtypeMixin.bdescr), ] with CompareableConsts(): for x, y in zip(expected, trace): assert x == y # ptr = b2t.getref_base()._obj.container._as_ptr() assert lltype.typeOf(ptr) == lltype.Ptr(LLtypeMixin.S) assert ptr.a == 111 assert ptr.b == lltype.nullptr(LLtypeMixin.NODE)
def test_reuse_vinfo(): class FakeVInfo(object): def set_content(self, fieldnums): self.fieldnums = fieldnums def equals(self, fieldnums): return self.fieldnums == fieldnums class FakeVirtualValue(info.AbstractVirtualPtrInfo): def visitor_dispatch_virtual_type(self, *args): return FakeVInfo() modifier = ResumeDataVirtualAdder(None, None, None, None, None) v1 = FakeVirtualValue() vinfo1 = modifier.make_virtual_info(v1, [1, 2, 4]) vinfo2 = modifier.make_virtual_info(v1, [1, 2, 4]) assert vinfo1 is vinfo2 vinfo3 = modifier.make_virtual_info(v1, [1, 2, 6]) assert vinfo3 is not vinfo2 vinfo4 = modifier.make_virtual_info(v1, [1, 2, 6]) assert vinfo3 is vinfo4
def test_virtual_adder_make_constant(): py.test.skip("rewrite fake reader") b1s, b2s, b3s = [InputArgInt(1), InputArgRef(), InputArgInt(3)] b1s = ConstInt(111) storage = make_storage(b1s, b2s, b3s) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, memo) liveboxes = modifier.finish() b2t, b3t = [InputArgRef(demo55o), InputArgInt(33)] newboxes = _resume_remap(liveboxes, [b2s, b3s], b2t, b3t) metainterp = MyMetaInterp() reader = ResumeDataFakeReader(storage, newboxes, metainterp) lst = reader.consume_boxes() c1t = ConstInt(111) assert_same(lst, [c1t, b2t, b3t]) lst = reader.consume_boxes() assert_same(lst, [ConstInt(2), ConstInt(3)]) lst = reader.consume_boxes() assert_same(lst, [c1t, ConstInt(1), c1t, b2t]) assert metainterp.trace == []
def test_virtual_adder_no_op_renaming(): py.test.skip("rewrite fake reader") b1s, b2s, b3s = [InputArgInt(1), InputArgInt(2), InputArgInt(3)] storage = make_storage(b1s, b2s, b3s) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) b1_2 = InputArgInt() modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, memo) b1s.set_forwarded(b1_2) b2s.set_forwarded(b1_2) liveboxes = modifier.finish() assert storage.rd_snapshot is None b1t, b3t = [InputArgInt(11), InputArgInt(33)] newboxes = _resume_remap(liveboxes, [b1_2, b3s], b1t, b3t) metainterp = MyMetaInterp() reader = ResumeDataFakeReader(storage, newboxes, metainterp) lst = reader.consume_boxes() assert_same(lst, [b1t, b1t, b3t]) lst = reader.consume_boxes() assert_same(lst, [ConstInt(2), ConstInt(3)]) lst = reader.consume_boxes() assert_same(lst, [b1t, ConstInt(1), b1t, b1t]) assert metainterp.trace == []
def test_virtual_adder_memo_const_sharing(): b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**23), ConstInt(-65)] storage, t = make_storage(b1s, b2s, b3s) metainterp_sd = FakeMetaInterpStaticData() memo = ResumeDataLoopMemo(metainterp_sd) i = t.get_iter() modifier = ResumeDataVirtualAdder(FakeOptimizer(i), storage, storage, i, memo) modifier.finish() assert len(memo.consts) == 2 assert storage.rd_consts is memo.consts b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**24), ConstInt(-65)] storage2, t = make_storage(b1s, b2s, b3s) i = t.get_iter() modifier2 = ResumeDataVirtualAdder(FakeOptimizer(i), storage2, storage2, i, memo) modifier2.finish() assert len(memo.consts) == 3 assert storage2.rd_consts is memo.consts
def test_invalidation_needed(): class options: failargs_limit = 10 metainterp_sd = FakeMetaInterpStaticData() metainterp_sd.options = options memo = ResumeDataLoopMemo(metainterp_sd) modifier = ResumeDataVirtualAdder(None, None, None, None, memo) for i in range(5): assert not modifier._invalidation_needed(5, i) assert not modifier._invalidation_needed(7, 2) assert modifier._invalidation_needed(7, 3) assert not modifier._invalidation_needed(10, 2) assert not modifier._invalidation_needed(10, 3) assert modifier._invalidation_needed(10, 4)
def test_virtual_adder_make_virtual(): b2s, b3s, b4s, b5s = [RefFrontendOp(0), IntFrontendOp(0), RefFrontendOp(0), RefFrontendOp(0)] c1s = ConstInt(111) storage = Storage() memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, None, memo) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} vdescr = LLtypeMixin.nodesize2 ca = ConstInt(ptr2int(LLtypeMixin.node_vtable2)) v4 = info.InstancePtrInfo(vdescr, ca, True) b4s.set_forwarded(v4) v4.setfield(LLtypeMixin.nextdescr, ca, b2s) v4.setfield(LLtypeMixin.valuedescr, ca, b3s) v4.setfield(LLtypeMixin.otherdescr, ca, b5s) ca = ConstInt(ptr2int(LLtypeMixin.node_vtable)) v2 = info.InstancePtrInfo(LLtypeMixin.nodesize, ca, True) v2.setfield(LLtypeMixin.nextdescr, b4s, ca) v2.setfield(LLtypeMixin.valuedescr, c1s, ca) b2s.set_forwarded(v2) modifier.register_virtual_fields(b2s, [c1s, None, None, None, b4s]) modifier.register_virtual_fields(b4s, [b3s, None, None, None, b2s, b5s]) liveboxes = [] modifier._number_virtuals(liveboxes, 0) storage.rd_consts = memo.consts[:] storage.rd_numb = Numbering([0]) # resume b3t, b5t = [IntFrontendOp(0), RefFrontendOp(0)] b5t.setref_base(demo55o) b3t.setint(33) newboxes = _resume_remap(liveboxes, [#b2s -- virtual b3s, #b4s -- virtual #b2s -- again, shared #b3s -- again, shared b5s], b3t, b5t) metainterp = MyMetaInterp() reader = ResumeDataFakeReader(storage, newboxes, metainterp) assert len(reader.virtuals_cache.virtuals_ptr_cache) == 2 b2t = reader.decode_ref(modifier._gettagged(b2s)) b4t = reader.decode_ref(modifier._gettagged(b4s)) trace = metainterp.trace b2new = (rop.NEW_WITH_VTABLE, [], b2t.getref_base(), LLtypeMixin.nodesize) b4new = (rop.NEW_WITH_VTABLE, [], b4t.getref_base(), LLtypeMixin.nodesize2) b2set = [(rop.SETFIELD_GC, [b2t, b4t], None, LLtypeMixin.nextdescr), (rop.SETFIELD_GC, [b2t, c1s], None, LLtypeMixin.valuedescr)] b4set = [(rop.SETFIELD_GC, [b4t, b2t], None, LLtypeMixin.nextdescr), (rop.SETFIELD_GC, [b4t, b3t], None, LLtypeMixin.valuedescr), (rop.SETFIELD_GC, [b4t, b5t], None, LLtypeMixin.otherdescr)] expected = [b2new, b4new] + b4set + b2set # check that we get the operations in 'expected', in a possibly different # order. assert len(trace) == len(expected) orig = trace[:] with CompareableConsts(): for x in trace: assert x in expected expected.remove(x) ptr = b2t.getref_base()._obj.container._as_ptr() assert lltype.typeOf(ptr) == lltype.Ptr(LLtypeMixin.NODE) assert ptr.value == 111 ptr2 = ptr.next ptr2 = lltype.cast_pointer(lltype.Ptr(LLtypeMixin.NODE2), ptr2) assert ptr2.other == demo55 assert ptr2.parent.value == 33 assert ptr2.parent.next == ptr
def test_register_virtual_fields(): b1, b2 = IntFrontendOp(0), IntFrontendOp(1) vbox = RefFrontendOp(2) modifier = ResumeDataVirtualAdder(FakeOptimizer(), None, None, None, None) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} modifier.register_virtual_fields(vbox, [b1, b2]) assert modifier.liveboxes == {vbox: UNASSIGNEDVIRTUAL, b1: UNASSIGNED, b2: UNASSIGNED} assert modifier.vfieldboxes == {vbox: [b1, b2]} modifier = ResumeDataVirtualAdder(FakeOptimizer(), None, None, None, None) modifier.liveboxes_from_env = {vbox: tag(0, TAGVIRTUAL)} modifier.liveboxes = {} modifier.vfieldboxes = {} modifier.register_virtual_fields(vbox, [b1, b2, vbox]) assert modifier.liveboxes == {b1: UNASSIGNED, b2: UNASSIGNED, vbox: tag(0, TAGVIRTUAL)} assert modifier.vfieldboxes == {vbox: [b1, b2, vbox]}
def test_virtual_adder_pending_fields_and_arrayitems(): class Storage(object): pass storage = Storage() modifier = ResumeDataVirtualAdder(None, storage, storage, None, None) modifier._add_pending_fields([]) assert not storage.rd_pendingfields # class FieldDescr(AbstractDescr): def is_array_of_primitives(self): return False field_a = FieldDescr() storage = Storage() modifier = ResumeDataVirtualAdder(None, storage, storage, None, None) a = IntFrontendOp(0) b = IntFrontendOp(0) modifier.liveboxes_from_env = {a: rffi.cast(rffi.SHORT, 1042), b: rffi.cast(rffi.SHORT, 1061)} modifier._add_pending_fields( [ResOperation(rop.SETFIELD_GC, [a, b], descr=field_a)]) pf = storage.rd_pendingfields assert len(pf) == 1 assert (annlowlevel.cast_base_ptr_to_instance(FieldDescr, pf[0].lldescr) is field_a) assert rffi.cast(lltype.Signed, pf[0].num) == 1042 assert rffi.cast(lltype.Signed, pf[0].fieldnum) == 1061 assert rffi.cast(lltype.Signed, pf[0].itemindex) == -1 # array_a = FieldDescr() storage = Storage() modifier = ResumeDataVirtualAdder(None, storage, storage, None, None) a42 = IntFrontendOp(0) a61 = IntFrontendOp(0) a62 = IntFrontendOp(0) a63 = IntFrontendOp(0) modifier.liveboxes_from_env = {a42: rffi.cast(rffi.SHORT, 1042), a61: rffi.cast(rffi.SHORT, 1061), a62: rffi.cast(rffi.SHORT, 1062), a63: rffi.cast(rffi.SHORT, 1063)} modifier._add_pending_fields([ ResOperation(rop.SETARRAYITEM_GC, [a42, ConstInt(0), a61], descr=array_a), ResOperation(rop.SETARRAYITEM_GC, [a42, ConstInt(2147483647), a62], descr=array_a)]) pf = storage.rd_pendingfields assert len(pf) == 2 assert (annlowlevel.cast_base_ptr_to_instance(FieldDescr, pf[0].lldescr) is array_a) assert rffi.cast(lltype.Signed, pf[0].num) == 1042 assert rffi.cast(lltype.Signed, pf[0].fieldnum) == 1061 assert rffi.cast(lltype.Signed, pf[0].itemindex) == 0 assert (annlowlevel.cast_base_ptr_to_instance(FieldDescr, pf[1].lldescr) is array_a) assert rffi.cast(lltype.Signed, pf[1].num) == 1042 assert rffi.cast(lltype.Signed, pf[1].fieldnum) == 1062 assert rffi.cast(lltype.Signed, pf[1].itemindex) == 2147483647 # if sys.maxint >= 2147483648: with py.test.raises(TagOverflow): modifier._add_pending_fields( [ResOperation(rop.SETARRAYITEM_GC, [a42, ConstInt(2147483648), a63], descr=array_a)])
def test_virtual_adder_pending_fields(): b2s, b4s = [RefFrontendOp(0), RefFrontendOp(0)] storage = Storage() memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(None, storage, storage, None, memo) modifier.liveboxes_from_env = {} modifier.liveboxes = {} modifier.vfieldboxes = {} modifier.register_box(b2s) modifier.register_box(b4s) liveboxes = [] modifier._number_virtuals(liveboxes, 0) assert liveboxes == [b2s, b4s] or liveboxes == [b4s, b2s] modifier._add_pending_fields([ ResOperation(rop.SETFIELD_GC, [b2s, b4s], descr=LLtypeMixin.nextdescr)]) storage.rd_consts = memo.consts[:] storage.rd_numb = Numbering([0]) # resume demo55.next = lltype.nullptr(LLtypeMixin.NODE) b2t = RefFrontendOp(0) b2t.setref_base(demo55o) b4t = RefFrontendOp(0) b4t.setref_base(demo66o) newboxes = _resume_remap(liveboxes, [b2s, b4s], b2t, b4t) metainterp = MyMetaInterp() reader = ResumeDataFakeReader(storage, newboxes, metainterp) assert reader.virtuals_cache is None trace = metainterp.trace b2set = (rop.SETFIELD_GC, [b2t, b4t], None, LLtypeMixin.nextdescr) expected = [b2set] for x, y in zip(expected, trace): assert x == y assert len(expected) == len(trace) assert demo55.next == demo66