def _setup_frame_realloc(self, translate_support_code): FUNC_TP = lltype.Ptr( lltype.FuncType([llmemory.GCREF, lltype.Signed], llmemory.GCREF)) base_ofs = self.get_baseofs_of_frame_field() def realloc_frame(frame, size): try: if not we_are_translated(): assert not self._exception_emulator[0] frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date frame.jf_frame_info.update_frame_depth(base_ofs, size) new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc # all other fields are empty llop.gc_writebarrier(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) except Exception as e: print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO) def realloc_frame_crash(frame, size): print "frame", frame, "size", size return lltype.nullptr(llmemory.GCREF.TO) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) else: FUNC = FUNC_TP.TO args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = lltype_to_annotation(FUNC.RESULT) mixlevelann = MixLevelHelperAnnotator(self.rtyper) graph = mixlevelann.getgraph(realloc_frame, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() self.realloc_frame = ptr2int(fptr) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame_crash) else: FUNC = FUNC_TP.TO args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS] s_result = lltype_to_annotation(FUNC.RESULT) mixlevelann = MixLevelHelperAnnotator(self.rtyper) graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result) fptr = mixlevelann.graph2delayed(graph, FUNC) mixlevelann.finish() self.realloc_frame_crash = ptr2int(fptr)
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) exc_box = ConstInt(ptr2int(exc)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op)
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) if self.opnum == rop.COND_CALL: RESULT_TYPE = lltype.Void v_cond = builder.get_bool_var(r) else: RESULT_TYPE = lltype.Signed v_cond = r.choice(builder.intvars) subset = builder.subset_of_intvars(r)[:4] for i in range(len(subset)): if r.random() < 0.35: subset[i] = ConstInt(r.random_integer()) # seen = [] def call_me(*args): if len(seen) == 0: seen.append(args) else: assert seen[0] == args if RESULT_TYPE is lltype.Signed: return len(args) - 42000 # TP = lltype.FuncType([lltype.Signed] * len(subset), RESULT_TYPE) ptr = llhelper(lltype.Ptr(TP), call_me) c_addr = ConstInt(ptr2int(ptr)) args = [v_cond, c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) op = ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=builder.getfaildescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op)
def handle_call_assembler(self, op): descrs = self.gc_ll_descr.getframedescrs(self.cpu) loop_token = op.getdescr() assert isinstance(loop_token, JitCellToken) llfi = ptr2int(loop_token.compiled_loop_token.frame_info) frame = self.gen_malloc_frame(llfi) self.emit_setfield(frame, ConstInt(llfi), descr=descrs.jf_frame_info) arglist = op.getarglist() index_list = loop_token.compiled_loop_token._ll_initial_locs for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) assert self.cpu.JITFRAME_FIXED_SIZE & 1 == 0 _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr) array_offset = index_list[i] # index, already measured in bytes # emit GC_STORE _, basesize, _ = unpack_arraydescr(descr) offset = basesize + array_offset args = [frame, ConstInt(offset), arg, ConstInt(itemsize)] self.emit_op(ResOperation(rop.GC_STORE, args)) descr = op.getdescr() assert isinstance(descr, JitCellToken) jd = descr.outermost_jitdriver_sd args = [frame] if jd and jd.index_of_virtualizable >= 0: args = [frame, arglist[jd.index_of_virtualizable]] else: args = [frame] call_asm = ResOperation(op.getopnum(), args, descr=op.getdescr()) self.replace_op_with(self.get_box_replacement(op), call_asm) self.emit_op(call_asm)
def test_assemble_cast_consts(): ssarepr = SSARepr("test") S = lltype.GcStruct('S') s = lltype.malloc(S) np = lltype.nullptr(S) F = lltype.FuncType([], lltype.Signed) f = lltype.functionptr(F, 'f') ssarepr.insns = [ ('int_return', Constant('X', lltype.Char)), ('int_return', Constant(unichr(0x1234), lltype.UniChar)), ('int_return', Constant(f, lltype.Ptr(F))), ('ref_return', Constant(s, lltype.Ptr(S))), ('ref_return', Constant(np, lltype.Ptr(S))), ('ref_return', Constant(s, lltype.Ptr(S))), ('ref_return', Constant(np, lltype.Ptr(S))), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x58" "\x01\xFF" "\x01\xFE" "\x02\xFF" "\x02\xFE" "\x02\xFF" "\x02\xFE") assert assembler.insns == { 'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2 } f_int = ptr2int(f) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) np_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, np) assert jitcode.constants_r == [s_gcref, np_gcref]
def __init__(self, warmrunnerdesc): self.warmrunnerdesc = warmrunnerdesc self.cpu = warmrunnerdesc.cpu # we make the low-level type of an RPython class directly self.JIT_VIRTUAL_REF = lltype.GcStruct( 'JitVirtualRef', ('super', rclass.OBJECT), ('virtual_token', llmemory.GCREF), ('forced', rclass.OBJECTPTR)) self.jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, flavor='raw', immortal=True) if hasattr(self.cpu, 'gc_ll_descr'): heaptracker.setup_cache_gcstruct2vtable(self.cpu.gc_ll_descr) self.cpu.gc_ll_descr._cache_gcstruct2vtable[ self.JIT_VIRTUAL_REF] = self.jit_virtual_ref_vtable # # record the type JIT_VIRTUAL_REF explicitly in the rtyper, too if hasattr(self.warmrunnerdesc, 'rtyper'): # <-- for tests self.warmrunnerdesc.rtyper.set_type_for_typeptr( self.jit_virtual_ref_vtable, self.JIT_VIRTUAL_REF) self.descr = self.cpu.sizeof(self.JIT_VIRTUAL_REF, vtable=self.jit_virtual_ref_vtable) self.jit_virtual_ref_vtable.name = rclass.alloc_array_name( 'jit_virtual_ref') # build some constants adr = ptr2int(self.jit_virtual_ref_vtable) self.jit_virtual_ref_const_class = history.ConstInt(adr) fielddescrof = self.cpu.fielddescrof self.descr_virtual_token = fielddescrof(self.JIT_VIRTUAL_REF, 'virtual_token') self.descr_forced = fielddescrof(self.JIT_VIRTUAL_REF, 'forced')
def produce_into(self, builder, r): subset, f = self.non_raising_func_code(builder, r) RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) _, vtableptr = builder.get_random_structure_type_and_vtable(r) exc_box = ConstInt(ptr2int(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(builder.subset_of_intvars(r)) op._exc_box = None builder.should_fail_by = op builder.guard_op = op builder.loop.operations.append(op)
def cast_to_int(x): TP = lltype.typeOf(x) if isinstance(TP, lltype.Ptr): return ptr2int(x) if TP == llmemory.Address: return adr2int(x) if TP is lltype.SingleFloat: return longlong.singlefloat2int(x) return lltype.cast_primitive(lltype.Signed, x)
def unspecialize_value(value): """Casts 'value' to a Signed, a GCREF or a FLOATSTORAGE.""" if isinstance(lltype.typeOf(value), lltype.Ptr): if lltype.typeOf(value).TO._gckind == 'gc': return lltype.cast_opaque_ptr(llmemory.GCREF, value) else: return ptr2int(value) elif isinstance(value, float): return longlong.getfloatstorage(value) else: return lltype.cast_primitive(lltype.Signed, value)
def produce_into(self, builder, r): subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstInt(ptr2int(ptr)) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) while True: _, vtableptr = builder.get_random_structure_type_and_vtable(r) if vtableptr != exc: break other_box = ConstInt(ptr2int(vtableptr)) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], descr=builder.getfaildescr()) op._exc_box = ConstInt(ptr2int(exc)) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op builder.loop.operations.append(op)
def gen_guard(self, builder, r): if r.random() < 0.5: return GuardClassOperation.gen_guard(self, builder, r) else: NULL = lltype.nullptr(llmemory.GCREF.TO) op = ResOperation(rop.SAME_AS_R, [ConstPtr(NULL)]) builder.loop.operations.append(op) v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable2 = S2._hints['vtable']._as_ptr() c_vtable2 = ConstInt(ptr2int(vtable2)) op = ResOperation(self.opnum, [op, c_vtable2], None) return op, False
def test_guard_class(self): loop = """ [p0] guard_class(p0, ConstClass(node_vtable)) [] jump(p0) """ es, loop, preamble = self.optimize(loop) p0 = preamble.inputargs[0] expected_class = ptr2int(self.node_vtable) assert expected_class == es.exported_infos[p0]._known_class.getint() vs = es.virtual_state assert vs.state[0].level == LEVEL_KNOWNCLASS assert vs.state[0].known_class.getint() == expected_class
def _new(x): "NOT_RPYTHON" T = lltype.typeOf(x) kind = getkind(T) if kind == "int": if isinstance(T, lltype.Ptr): intval = ptr2int(x) else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) elif kind == "float": return ConstFloat(longlong.getfloatstorage(x)) else: raise NotImplementedError(kind)
def gen_guard(self, builder, r): ptrvars = [(v, S) for (v, S) in builder.ptrvars if isinstance(S, lltype.Struct) and S._names[0] == 'parent'] if not ptrvars: raise test_random.CannotProduceOperation v, S = r.choice(ptrvars) if r.random() < 0.3: v2, S2 = v, S else: v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable = S._hints['vtable']._as_ptr() vtable2 = S2._hints['vtable']._as_ptr() c_vtable2 = ConstInt(ptr2int(vtable2)) op = ResOperation(self.opnum, [v, c_vtable2], None) return op, (vtable == vtable2)
def wrap(cpu, value, in_const_box=False): if isinstance(lltype.typeOf(value), lltype.Ptr): if lltype.typeOf(value).TO._gckind == 'gc': value = lltype.cast_opaque_ptr(llmemory.GCREF, value) if in_const_box: return history.ConstPtr(value) else: res = history.RefFrontendOp(0) res.setref_base(value) return res else: value = ptr2int(value) # fall through to the end of the function elif (isinstance(value, float) or longlong.is_longlong(lltype.typeOf(value))): if isinstance(value, float): value = longlong.getfloatstorage(value) else: value = rffi.cast(lltype.SignedLongLong, value) if in_const_box: return history.ConstFloat(value) else: res = history.FloatFrontendOp(0) res.setfloatstorage(value) return res elif isinstance(value, str) or isinstance(value, unicode): assert len(value) == 1 # must be a character value = ord(value) elif lltype.typeOf(value) is lltype.SingleFloat: value = longlong.singlefloat2int(value) else: value = intmask(value) if in_const_box: return history.ConstInt(value) else: res = history.IntFrontendOp(0) res.setint(value) return res
def cls_of_box(self, box): obj = lltype.cast_opaque_ptr(OBJECTPTR, box.getref_base()) return ConstInt(ptr2int(obj.typeptr))
def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) return ptr2int(struct.typeptr)
def get_malloc_fn_addr(self, funcname): ll_func = self.get_malloc_fn(funcname) return ptr2int(ll_func)
def get_vtable(self): return ptr2int(self.vtable)
def ptr_to_int(obj): return ptr2int(obj)
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 get_funcbox(cls, cpu, func_ptr): return ConstInt(ptr2int(func_ptr))