def test_cast_adr_to_int_and_back(): X = lltype.Struct('X', ('foo', lltype.Signed)) x = lltype.malloc(X, immortal=True) x.foo = 42 a = llmemory.cast_ptr_to_adr(x) i = heaptracker.adr2int(a) assert lltype.typeOf(i) is lltype.Signed a2 = heaptracker.int2adr(i) assert llmemory.cast_adr_to_ptr(a2, lltype.Ptr(X)) == x assert heaptracker.adr2int(llmemory.NULL) == 0 assert heaptracker.int2adr(0) == llmemory.NULL
def test_cast_adr_to_int_and_back(): X = lltype.Struct("X", ("foo", lltype.Signed)) x = lltype.malloc(X, immortal=True) x.foo = 42 a = llmemory.cast_ptr_to_adr(x) i = heaptracker.adr2int(a) assert lltype.typeOf(i) is lltype.Signed a2 = heaptracker.int2adr(i) assert llmemory.cast_adr_to_ptr(a2, lltype.Ptr(X)) == x assert heaptracker.adr2int(llmemory.NULL) == 0 assert heaptracker.int2adr(0) == llmemory.NULL
def test_assemble_cast_consts(): ssarepr = SSARepr("test") S = lltype.GcStruct('S') s = lltype.malloc(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))), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x58" "\x01\xFF" "\x01\xFE" "\x02\xFF") assert assembler.insns == {'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2} f_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(f)) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) assert jitcode.constants_r == [s_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', lltype.Signed), ('forced', rclass.OBJECTPTR)) self.jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, flavor='raw', immortal=True) self.jit_virtual_ref_vtable.name = rclass.alloc_array_name( 'jit_virtual_ref') # build some constants adr = llmemory.cast_ptr_to_adr(self.jit_virtual_ref_vtable) adr = heaptracker.adr2int(adr) 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') # # 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)
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: return history.BoxPtr(value) else: adr = llmemory.cast_ptr_to_adr(value) value = heaptracker.adr2int(adr) # fall through to the end of the function elif isinstance(lltype.typeOf(value), ootype.OOType): value = ootype.cast_to_object(value) if in_const_box: return history.ConstObj(value) else: return history.BoxObj(value) elif isinstance(value, float): value = longlong.getfloatstorage(value) if in_const_box: return history.ConstFloat(value) else: return history.BoxFloat(value) elif isinstance(value, str) or isinstance(value, unicode): assert len(value) == 1 # must be a character value = ord(value) else: value = intmask(value) if in_const_box: return history.ConstInt(value) else: return history.BoxInt(value)
def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes, memory_manager=None): """Make a LoopToken that corresponds to assembler code that just calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ jitcell_token = make_jitcell_token(jitdriver_sd) nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args inputargs = [] for kind in redargtypes: if kind == history.INT: box = BoxInt() elif kind == history.REF: box = BoxPtr() elif kind == history.FLOAT: box = BoxFloat() else: raise AssertionError inputargs.append(box) k = jitdriver_sd.portal_runner_adr funcbox = history.ConstInt(heaptracker.adr2int(k)) callargs = [funcbox] + greenboxes + inputargs # result_type = jitdriver_sd.result_type if result_type == history.INT: result = BoxInt() elif result_type == history.REF: result = BoxPtr() elif result_type == history.FLOAT: result = BoxFloat() elif result_type == history.VOID: result = None else: assert 0, "bad result_type" if result is not None: finishargs = [result] else: finishargs = [] # jd = jitdriver_sd faildescr = PropagateExceptionDescr() operations = [ ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr), ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken) ] operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, jitcell_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(jitcell_token) return jitcell_token
def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes, memory_manager=None): """Make a LoopToken that corresponds to assembler code that just calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ jitcell_token = make_jitcell_token(jitdriver_sd) nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args inputargs = [] for kind in redargtypes: if kind == history.INT: box = BoxInt() elif kind == history.REF: box = BoxPtr() elif kind == history.FLOAT: box = BoxFloat() else: raise AssertionError inputargs.append(box) k = jitdriver_sd.portal_runner_adr funcbox = history.ConstInt(heaptracker.adr2int(k)) callargs = [funcbox] + greenboxes + inputargs # result_type = jitdriver_sd.result_type if result_type == history.INT: result = BoxInt() elif result_type == history.REF: result = BoxPtr() elif result_type == history.FLOAT: result = BoxFloat() elif result_type == history.VOID: result = None else: assert 0, "bad result_type" if result is not None: finishargs = [result] else: finishargs = [] # jd = jitdriver_sd faildescr = PropagateExceptionDescr() operations = [ ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr), ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken), ] operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, jitcell_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(jitcell_token) return jitcell_token
def test_malloc_new_with_vtable(): vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) S = lltype.GcStruct("S", ("parent", rclass.OBJECT)) heaptracker.set_testing_vtable_for_gcstruct(S, vtable, "S") v = varoftype(lltype.Ptr(S)) op = SpaceOperation("malloc", [Constant(S, lltype.Void), Constant({"flavor": "gc"}, lltype.Void)], v) cpu = FakeCPU() op1 = Transformer(cpu).rewrite_operation(op) assert op1.opname == "new_with_vtable" assert op1.args == [("sizedescr", S)] # assert heaptracker.descr2vtable(cpu, op1.args[0]) == vtable [type check] vtable_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(vtable)) assert heaptracker.vtable2descr(cpu, vtable_int) == op1.args[0]
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: adr = llmemory.cast_ptr_to_adr(value) return heaptracker.adr2int(adr) elif isinstance(lltype.typeOf(value), ootype.OOType): return ootype.cast_to_object(value) elif isinstance(value, float): return longlong.getfloatstorage(value) else: return lltype.cast_primitive(lltype.Signed, value)
def _new(x): "NOT_RPYTHON" T = lltype.typeOf(x) kind = getkind(T) if kind == "int": if isinstance(T, lltype.Ptr): intval = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) else: intval = lltype.cast_primitive(lltype.Signed, x) return ConstInt(intval) elif kind == "ref": return cpu.ts.new_ConstRef(x) elif kind == "float": return ConstFloat(longlong.getfloatstorage(x)) else: raise NotImplementedError(kind)
def test_malloc_new_with_vtable(): vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) S = lltype.GcStruct('S', ('parent', rclass.OBJECT)) heaptracker.set_testing_vtable_for_gcstruct(S, vtable, 'S') v = varoftype(lltype.Ptr(S)) op = SpaceOperation( 'malloc', [Constant(S, lltype.Void), Constant({'flavor': 'gc'}, lltype.Void)], v) cpu = FakeCPU() op1 = Transformer(cpu).rewrite_operation(op) assert op1.opname == 'new_with_vtable' assert op1.args == [('sizedescr', S)] #assert heaptracker.descr2vtable(cpu, op1.args[0]) == vtable [type check] vtable_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(vtable)) assert heaptracker.vtable2descr(cpu, vtable_int) == op1.args[0]
def emit_const(self, const, kind, allow_short=False): value = const.value if kind == 'int': TYPE = const.concretetype if isinstance(TYPE, lltype.Ptr): assert TYPE.TO._gckind == 'raw' self.see_raw_object(value) value = llmemory.cast_ptr_to_adr(value) TYPE = llmemory.Address if TYPE == llmemory.Address: value = heaptracker.adr2int(value) if TYPE is lltype.SingleFloat: value = longlong.singlefloat2int(value) if not isinstance(value, (llmemory.AddressAsInt, ComputedIntSymbolic)): value = lltype.cast_primitive(lltype.Signed, value) if allow_short: try: short_num = -128 <= value <= 127 except TypeError: # "Symbolics cannot be compared!" short_num = False if short_num: # emit the constant as a small integer self.code.append(chr(value & 0xFF)) return True constants = self.constants_i elif kind == 'ref': value = lltype.cast_opaque_ptr(llmemory.GCREF, value) constants = self.constants_r elif kind == 'float': if const.concretetype == lltype.Float: value = longlong.getfloatstorage(value) else: assert longlong.is_longlong(const.concretetype) value = rffi.cast(lltype.SignedLongLong, value) constants = self.constants_f else: raise AssemblerError('unimplemented %r in %r' % (const, self.ssareprname)) key = (kind, Constant(value)) if key not in self.constants_dict: constants.append(value) self.constants_dict[key] = 256 - len(constants) # emit the constant normally, as one byte that is an index in the # list of constants self.code.append(chr(self.constants_dict[key])) return False
def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redboxes, memory_manager=None): """Make a LoopToken that corresponds to assembler code that just calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ # 'redboxes' is only used to know the types of red arguments. inputargs = [box.clonebox() for box in redboxes] loop_token = make_loop_token(len(inputargs), jitdriver_sd) # 'nb_red_args' might be smaller than len(redboxes), # because it doesn't include the virtualizable boxes. nb_red_args = jitdriver_sd.num_red_args k = jitdriver_sd.portal_runner_adr funcbox = history.ConstInt(heaptracker.adr2int(k)) callargs = [funcbox] + greenboxes + inputargs[:nb_red_args] # result_type = jitdriver_sd.result_type if result_type == history.INT: result = BoxInt() elif result_type == history.REF: result = BoxPtr() elif result_type == history.FLOAT: result = BoxFloat() elif result_type == history.VOID: result = None else: assert 0, "bad result_type" if result is not None: finishargs = [result] else: finishargs = [] # jd = jitdriver_sd faildescr = propagate_exception_descr operations = [ ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr), ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken), ] operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, loop_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(loop_token) return loop_token
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", lltype.Signed), ("forced", rclass.OBJECTPTR) ) self.jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, flavor="raw", immortal=True) self.jit_virtual_ref_vtable.name = rclass.alloc_array_name("jit_virtual_ref") # build some constants adr = llmemory.cast_ptr_to_adr(self.jit_virtual_ref_vtable) adr = heaptracker.adr2int(adr) 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") # # 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)
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: return history.BoxPtr(value) else: adr = llmemory.cast_ptr_to_adr(value) value = heaptracker.adr2int(adr) # fall through to the end of the function elif isinstance(lltype.typeOf(value), ootype.OOType): value = ootype.cast_to_object(value) if in_const_box: return history.ConstObj(value) else: return history.BoxObj(value) 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: return history.BoxFloat(value) 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: return history.BoxInt(value)
def test_assemble_cast_consts(): ssarepr = SSARepr("test") S = lltype.GcStruct('S') s = lltype.malloc(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))), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x58" "\x01\xFF" "\x01\xFE" "\x02\xFF") assert assembler.insns == { 'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2 } f_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(f)) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) assert jitcode.constants_r == [s_gcref]
def get_malloc_fn_addr(self, funcname): ll_func = self.get_malloc_fn(funcname) return heaptracker.adr2int(llmemory.cast_ptr_to_adr(ll_func))
def pos_exception(): addr = llop.get_exception_addr(llmemory.Address) return heaptracker.adr2int(addr)
def cls_of_box(self, box): obj = box.getref(lltype.Ptr(rclass.OBJECT)) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(heaptracker.adr2int(cls))
def cast_vtable_to_hashable(self, cpu, ptr): adr = llmemory.cast_ptr_to_adr(ptr) return heaptracker.adr2int(adr)
def ptr_to_int(obj): from pypy.jit.codewriter.heaptracker import adr2int from pypy.rpython.lltypesystem import llmemory return adr2int(llmemory.cast_ptr_to_adr(obj))
def get_fnaddr_as_int(self): return heaptracker.adr2int(self.fnaddr)
def ConstAddr(addr, cpu): return ConstInt(heaptracker.adr2int(addr))
def ConstAddr(addr, cpu): # compatibility return ConstInt(heaptracker.adr2int(addr))
def get_latest_force_token(self): token = llimpl.get_frame_forced_token(self.latest_frame) return heaptracker.adr2int(token)
def get_funcbox(cls, cpu, func_ptr): addr = llmemory.cast_ptr_to_adr(func_ptr) return ConstInt(heaptracker.adr2int(addr))
def pos_exc_value(): addr = llop.get_exc_value_addr(llmemory.Address) return heaptracker.adr2int(addr)
def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) result = struct.typeptr result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) return heaptracker.adr2int(result_adr)
def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) return heaptracker.adr2int(result_adr)