def deserialize_optheap(self, triples_struct, triples_array): for box1, descr, box2 in triples_struct: parent_descr = descr.get_parent_descr() assert parent_descr.is_object() if box1.is_constant(): structinfo = info.ConstPtrInfo(box1) else: structinfo = box1.get_forwarded() if not isinstance(structinfo, info.AbstractVirtualPtrInfo): structinfo = info.InstancePtrInfo(parent_descr) structinfo.init_fields(parent_descr, descr.get_index()) box1.set_forwarded(structinfo) cf = self.field_cache(descr) structinfo.setfield(descr, box1, box2, optheap=self, cf=cf) for box1, index, descr, box2 in triples_array: if box1.is_constant(): arrayinfo = info.ConstPtrInfo(box1) else: arrayinfo = box1.get_forwarded() if not isinstance(arrayinfo, info.AbstractVirtualPtrInfo): arrayinfo = info.ArrayPtrInfo(descr) box1.set_forwarded(arrayinfo) cf = self.arrayitem_cache(descr, index) arrayinfo.setitem(descr, index, box1, box2, optheap=self, cf=cf)
def setinfo_from_preamble(self, op, preamble_info, exported_infos): op = self.get_box_replacement(op) if op.get_forwarded() is not None: return if op.is_constant(): return # nothing we can learn if isinstance(preamble_info, info.PtrInfo): if preamble_info.is_virtual(): op.set_forwarded(preamble_info) self.setinfo_from_preamble_list(preamble_info.all_items(), exported_infos) return if preamble_info.is_constant(): # but op is not op.set_forwarded(preamble_info.getconst()) return if preamble_info.get_descr() is not None: if isinstance(preamble_info, info.StructPtrInfo): op.set_forwarded(info.StructPtrInfo( preamble_info.get_descr())) if isinstance(preamble_info, info.InstancePtrInfo): op.set_forwarded(info.InstancePtrInfo( preamble_info.get_descr())) known_class = preamble_info.get_known_class(self.cpu) if known_class: self.make_constant_class(op, known_class, False) if isinstance(preamble_info, info.ArrayPtrInfo): arr_info = info.ArrayPtrInfo(preamble_info.descr) bound = preamble_info.getlenbound(None).clone() assert isinstance(bound, intutils.IntBound) arr_info.lenbound = bound op.set_forwarded(arr_info) if isinstance(preamble_info, StrPtrInfo): str_info = StrPtrInfo(preamble_info.mode) bound = preamble_info.getlenbound(None).clone() assert isinstance(bound, intutils.IntBound) str_info.lenbound = bound op.set_forwarded(str_info) if preamble_info.is_nonnull(): self.make_nonnull(op) elif isinstance(preamble_info, intutils.IntBound): fix_lo = preamble_info.has_lower and preamble_info.lower >= MININT/2 fix_up = preamble_info.has_upper and preamble_info.upper <= MAXINT/2 if fix_lo or fix_up: intbound = self.getintbound(op) if fix_lo: intbound.has_lower = True intbound.lower = preamble_info.lower if fix_up: intbound.has_upper = True intbound.upper = preamble_info.upper elif isinstance(preamble_info, info.FloatConstInfo): op.set_forwarded(preamble_info._const)
def deserialize_optheap(self, triples): for box1, descr, box2 in triples: parent_descr = descr.get_parent_descr() assert parent_descr.is_object() structinfo = box1.get_forwarded() if not isinstance(structinfo, info.AbstractVirtualPtrInfo): structinfo = info.InstancePtrInfo(parent_descr) structinfo.init_fields(parent_descr, descr.get_index()) box1.set_forwarded(structinfo) cf = self.field_cache(descr) structinfo.setfield(descr, box1, box2, optheap=self, cf=cf)
def ensure_ptr_info_arg0(self, op): from rpython.jit.metainterp.optimizeopt import vstring arg0 = self.get_box_replacement(op.getarg(0)) if arg0.is_constant(): return info.ConstPtrInfo(arg0) opinfo = arg0.get_forwarded() if isinstance(opinfo, info.AbstractVirtualPtrInfo): return opinfo elif opinfo is not None: last_guard_pos = opinfo.get_last_guard_pos() else: last_guard_pos = -1 assert opinfo is None or opinfo.__class__ is info.NonNullPtrInfo opnum = op.opnum if (rop.is_getfield(opnum) or opnum == rop.SETFIELD_GC or opnum == rop.QUASIIMMUT_FIELD): descr = op.getdescr() parent_descr = descr.get_parent_descr() if parent_descr.is_object(): opinfo = info.InstancePtrInfo(parent_descr) else: opinfo = info.StructPtrInfo(parent_descr) opinfo.init_fields(parent_descr, descr.get_index()) elif (rop.is_getarrayitem(opnum) or opnum == rop.SETARRAYITEM_GC or opnum == rop.ARRAYLEN_GC): opinfo = info.ArrayPtrInfo(op.getdescr()) elif opnum in (rop.GUARD_CLASS, rop.GUARD_NONNULL_CLASS): opinfo = info.InstancePtrInfo() elif opnum in (rop.STRLEN, ): opinfo = vstring.StrPtrInfo(vstring.mode_string) elif opnum in (rop.UNICODELEN, ): opinfo = vstring.StrPtrInfo(vstring.mode_unicode) else: assert False, "operations %s unsupported" % op assert isinstance(opinfo, info.NonNullPtrInfo) opinfo.last_guard_pos = last_guard_pos arg0.set_forwarded(opinfo) return opinfo
def make_constant_class(self, op, class_const, update_last_guard=True): op = op.get_box_replacement() opinfo = op.get_forwarded() if isinstance(opinfo, info.InstancePtrInfo): opinfo._known_class = class_const else: if opinfo is not None: last_guard_pos = opinfo.get_last_guard_pos() else: last_guard_pos = -1 opinfo = info.InstancePtrInfo(None, class_const) opinfo.last_guard_pos = last_guard_pos op.set_forwarded(opinfo) if update_last_guard: opinfo.mark_last_guard(self.optimizer) return opinfo
def make_virtual(self, known_class, source_op, descr): opinfo = info.InstancePtrInfo(descr, known_class, is_virtual=True) opinfo.init_fields(descr, 0) newop = self.replace_op_with(source_op, source_op.getopnum()) newop.set_forwarded(opinfo) return opinfo
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