def test_execute_varargs(): cpu = FakeCPU() descr = FakeCallDescr() argboxes = [BoxInt(99999), BoxInt(321), constfloat(2.25), ConstInt(123), BoxPtr(), boxfloat(5.5)] box = execute_varargs(cpu, FakeMetaInterp(), rop.CALL, argboxes, descr) assert box.getfloat() == 42.5 assert cpu.fakecalled == (99999, descr, [321, 123], [ConstPtr.value], [longlong.getfloatstorage(2.25), longlong.getfloatstorage(5.5)])
def callback(asm): c = ConstFloat(longlong.getfloatstorage(-42.5)) loc = self.xrm.convert_to_imm(c) asm.mov(loc, xmm5) asm.regalloc_push(xmm5) asm.regalloc_pop(xmm0) asm.mc.CVTTSD2SI(eax, xmm0)
def test_call_stubs(): c0 = GcCache(False) ARGS = [lltype.Char, lltype.Signed] RES = lltype.Char descr1 = get_call_descr(c0, ARGS, RES) def f(a, b): return 'c' call_stub = descr1.call_stub fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) res = call_stub(rffi.cast(lltype.Signed, fnptr), [1, 2], None, None) assert res == ord('c') ARRAY = lltype.GcArray(lltype.Signed) ARGS = [lltype.Float, lltype.Ptr(ARRAY)] RES = lltype.Float def f(a, b): return float(b[0]) + a fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) descr2 = get_call_descr(c0, ARGS, RES) a = lltype.malloc(ARRAY, 3) opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) a[0] = 1 res = descr2.call_stub(rffi.cast(lltype.Signed, fnptr), [], [opaquea], [longlong.getfloatstorage(3.5)]) assert longlong.getrealfloat(res) == 4.5
def test_ResumeDataLoopMemo_other(): memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) const = ConstFloat(longlong.getfloatstorage(-1.0)) tagged = memo.getconst(const) index, tagbits = untag(tagged) assert tagbits == TAGCONST assert memo.consts[index] is const
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 callback(asm): c = ConstFloat(longlong.getfloatstorage(-42.5)) loc = self.xrm.convert_to_imm(c) asm.mov(loc, xmm5) asm.regalloc_push(xmm5) asm.regalloc_pop(xmm0) asm.mc.CVTTSD2SI(eax, xmm0)
def test_assemble_float_consts(): ssarepr = SSARepr("test") ssarepr.insns = [ ('float_return', Register('float', 13)), ('float_return', Constant(18.0, lltype.Float)), ('float_return', Constant(-4.0, lltype.Float)), ('float_return', Constant(128.1, lltype.Float)), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x0D" "\x00\xFF" "\x00\xFE" "\x00\xFD") assert assembler.insns == {'float_return/f': 0} assert jitcode.constants_f == [ longlong.getfloatstorage(18.0), longlong.getfloatstorage(-4.0), longlong.getfloatstorage(128.1) ]
def test_assemble_float_consts(): ssarepr = SSARepr("test") ssarepr.insns = [ ('float_return', Register('float', 13)), ('float_return', Constant(18.0, lltype.Float)), ('float_return', Constant(-4.0, lltype.Float)), ('float_return', Constant(128.1, lltype.Float)), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x0D" "\x00\xFF" "\x00\xFE" "\x00\xFD") assert assembler.insns == {'float_return/f': 0} assert jitcode.constants_f == [longlong.getfloatstorage(18.0), longlong.getfloatstorage(-4.0), longlong.getfloatstorage(128.1)]
def callback(asm): c = ConstFloat(longlong.getfloatstorage(-42.5)) loc = self.xrm.convert_to_imm(c) loc2 = self.fm.frame_pos(4, FLOAT) asm.mc.SUB_ri(esp.value, 64) asm.mov(loc, xmm5) asm.regalloc_push(xmm5) asm.regalloc_pop(loc2) asm.mov(loc2, xmm0) asm.mc.ADD_ri(esp.value, 64) asm.mc.CVTTSD2SI(eax, xmm0)
def callback(asm): c = ConstFloat(longlong.getfloatstorage(-42.5)) loc = self.xrm.convert_to_imm(c) loc2 = self.fm.frame_pos(4, FLOAT) asm.mc.SUB_ri(esp.value, 64) asm.mov(loc, xmm5) asm.regalloc_push(xmm5) asm.regalloc_pop(loc2) asm.mov(loc2, xmm0) asm.mc.ADD_ri(esp.value, 64) asm.mc.CVTTSD2SI(eax, xmm0)
def _new(x): "NOT_RPYTHON" kind = getkind(lltype.typeOf(x)) if kind == "int": intval = lltype.cast_primitive(lltype.Signed, x) return BoxInt(intval) elif kind == "ref": # XXX add ootype support? ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) return BoxPtr(ptrval) elif kind == "float": return BoxFloat(longlong.getfloatstorage(x)) else: raise NotImplementedError(kind)
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" kind = getkind(lltype.typeOf(x)) if kind == "int": intval = lltype.cast_primitive(lltype.Signed, x) return BoxInt(intval) elif kind == "ref": # XXX add ootype support? ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x) return BoxPtr(ptrval) elif kind == "float": return BoxFloat(longlong.getfloatstorage(x)) else: raise NotImplementedError(kind)
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 _prepare_args(self, args, floats, ints): local_floats = list(floats) local_ints = list(ints) expected_result = 0.0 for i in range(len(args)): x = args[i] if x[0] == 'f': x = local_floats.pop() t = longlong.getfloatstorage(x) self.cpu.set_future_value_float(i, t) else: x = local_ints.pop() self.cpu.set_future_value_int(i, x) expected_result += x return expected_result
def _prepare_args(self, args, floats, ints): local_floats = list(floats) local_ints = list(ints) expected_result = 0.0 arguments = [] for i in range(len(args)): x = args[i] if x[0] == 'f': x = local_floats.pop() t = longlong.getfloatstorage(x) arguments.append(t) else: x = local_ints.pop() arguments.append(x) expected_result += x return arguments, expected_result
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 _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_call_stubs_2(): c0 = GcCache(False) ARRAY = lltype.GcArray(lltype.Signed) ARGS = [lltype.Float, lltype.Ptr(ARRAY)] RES = lltype.Float def f2(a, b): return float(b[0]) + a fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f2) descr2 = get_call_descr(c0, ARGS, RES) a = lltype.malloc(ARRAY, 3) opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) a[0] = 1 res = descr2.call_stub_f(rffi.cast(lltype.Signed, fnptr), [], [opaquea], [longlong.getfloatstorage(3.5)]) assert longlong.getrealfloat(res) == 4.5
def interpret(self, ops, args, run=True): loop = self.parse(ops) self.cpu.compile_loop(loop.inputargs, loop.operations, loop.token) for i, arg in enumerate(args): if isinstance(arg, int): self.cpu.set_future_value_int(i, arg) elif isinstance(arg, float): arg = longlong.getfloatstorage(arg) self.cpu.set_future_value_float(i, arg) else: assert isinstance(lltype.typeOf(arg), lltype.Ptr) llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) self.cpu.set_future_value_ref(i, llgcref) if run: self.cpu.execute_token(loop.token) return loop
def _prepare_args(self, args, floats, ints): local_floats = list(floats) local_ints = list(ints) expected_result = 0.0 arguments = [] for i in range(len(args)): x = args[i] if x[0] == 'f': x = local_floats.pop() t = longlong.getfloatstorage(x) arguments.append(t) else: x = local_ints.pop() arguments.append(x) expected_result += x return arguments, expected_result
def set_future_value(cpu, j, value, typecode): if typecode == 'ref': refvalue = cpu.ts.cast_to_ref(value) cpu.set_future_value_ref(j, refvalue) elif typecode == 'int': intvalue = lltype.cast_primitive(lltype.Signed, value) cpu.set_future_value_int(j, intvalue) elif typecode == 'float': if lltype.typeOf(value) is lltype.Float: value = longlong.getfloatstorage(value) else: assert longlong.is_longlong(lltype.typeOf(value)) value = rffi.cast(lltype.SignedLongLong, value) cpu.set_future_value_float(j, value) else: assert False
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 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 test_call_stubs_2(): c0 = GcCache(False) ARRAY = lltype.GcArray(lltype.Signed) ARGS = [lltype.Float, lltype.Ptr(ARRAY)] RES = lltype.Float def f2(a, b): return float(b[0]) + a fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f2) descr2 = get_call_descr(c0, ARGS, RES) a = lltype.malloc(ARRAY, 3) opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) a[0] = 1 res = descr2.call_stub_f(rffi.cast(lltype.Signed, fnptr), [], [opaquea], [longlong.getfloatstorage(3.5)]) assert longlong.getrealfloat(res) == 4.5
def interpret(self, ops, args, run=True): loop = self.parse(ops) looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) arguments = [] for arg in args: if isinstance(arg, int): arguments.append(arg) elif isinstance(arg, float): arg = longlong.getfloatstorage(arg) arguments.append(arg) else: assert isinstance(lltype.typeOf(arg), lltype.Ptr) llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) arguments.append(llgcref) loop._jitcelltoken = looptoken if run: self.cpu.execute_token(looptoken, *arguments) return loop
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_make_set_future_values(): future_values = {} class FakeCPU: def set_future_value_int(self, j, value): future_values[j] = "int", value def set_future_value_float(self, j, value): future_values[j] = "float", value class FakeWarmRunnerDesc: cpu = FakeCPU() memory_manager = None class FakeJitDriverSD: _red_args_types = ["int", "float"] virtualizable_info = None # state = WarmEnterState(FakeWarmRunnerDesc(), FakeJitDriverSD()) set_future_values = state.make_set_future_values() set_future_values(5, 42.5) assert future_values == { 0: ("int", 5), 1: ("float", longlong.getfloatstorage(42.5)), } assert set_future_values is state.make_set_future_values()
def _run_with_blackhole(testself, args): from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder cw = testself.cw blackholeinterpbuilder = BlackholeInterpBuilder(cw) blackholeinterp = blackholeinterpbuilder.acquire_interp() count_i = count_r = count_f = 0 for value in args: T = lltype.typeOf(value) if T == lltype.Signed: blackholeinterp.setarg_i(count_i, value) count_i += 1 elif T == llmemory.GCREF: blackholeinterp.setarg_r(count_r, value) count_r += 1 elif T == lltype.Float: value = longlong.getfloatstorage(value) blackholeinterp.setarg_f(count_f, value) count_f += 1 else: raise TypeError(T) [jitdriver_sd] = cw.callcontrol.jitdrivers_sd blackholeinterp.setposition(jitdriver_sd.mainjitcode, 0) blackholeinterp.run() return blackholeinterp._final_result_anytype()
def _run_with_blackhole(testself, args): from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder cw = testself.cw blackholeinterpbuilder = BlackholeInterpBuilder(cw) blackholeinterp = blackholeinterpbuilder.acquire_interp() count_i = count_r = count_f = 0 for value in args: T = lltype.typeOf(value) if T == lltype.Signed: blackholeinterp.setarg_i(count_i, value) count_i += 1 elif T == llmemory.GCREF: blackholeinterp.setarg_r(count_r, value) count_r += 1 elif T == lltype.Float: value = longlong.getfloatstorage(value) blackholeinterp.setarg_f(count_f, value) count_f += 1 else: raise TypeError(T) [jitdriver_sd] = cw.callcontrol.jitdrivers_sd blackholeinterp.setposition(jitdriver_sd.mainjitcode, 0) blackholeinterp.run() return blackholeinterp._final_result_anytype()
def do_failure_recovery_func(withfloats): import random S = lltype.GcStruct('S') def get_random_int(): return random.randrange(-10000, 10000) def get_random_ptr(): return lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) def get_random_float(): # Returns <float>, <low word>, <high word> # NB: on 64-bit, <low word> will be the entire float and <high word> # will be random garbage from malloc! assert withfloats value = random.random() - 0.5 # make sure it fits into 64 bits tmp = lltype.malloc(rffi.LONGP.TO, 2, flavor='raw', track_allocation=False) rffi.cast(rffi.DOUBLEP, tmp)[0] = value return rffi.cast(rffi.DOUBLEP, tmp)[0], tmp[0], tmp[1] if IS_X86_32: main_registers = X86RegisterManager.all_regs xmm_registers = X86XMMRegisterManager.all_regs elif IS_X86_64: main_registers = X86_64_RegisterManager.all_regs xmm_registers = X86_64_XMMRegisterManager.all_regs # memory locations: 26 integers, 26 pointers, 26 floats # main registers: half of them as signed and the other half as ptrs # xmm registers: all floats, from xmm0 to xmm(7|15) # holes: 8 locations = [] baseloc = 4 for i in range(26+26+26): if baseloc < 128: baseloc += random.randrange(2, 20) else: baseloc += random.randrange(2, 1000) locations.append(baseloc) random.shuffle(locations) content = ([('int', locations.pop()) for _ in range(26)] + [('ptr', locations.pop()) for _ in range(26)] + [(['int', 'ptr'][random.randrange(0, 2)], reg) for reg in main_registers]) if withfloats: content += ([('float', locations.pop()) for _ in range(26)] + [('float', reg) for reg in xmm_registers]) for i in range(8): content.append(('hole', None)) random.shuffle(content) # prepare the expected target arrays, the descr_bytecode, # the 'registers' and the 'stack' arrays according to 'content' xmmregisters = lltype.malloc(rffi.LONGP.TO, 16+ACTUAL_CPU.NUM_REGS+1, flavor='raw', immortal=True) registers = rffi.ptradd(xmmregisters, 16) stacklen = baseloc + 30 stack = lltype.malloc(rffi.LONGP.TO, stacklen, flavor='raw', immortal=True) expected_ints = [0] * len(content) expected_ptrs = [lltype.nullptr(llmemory.GCREF.TO)] * len(content) expected_floats = [longlong.ZEROF] * len(content) def write_in_stack(loc, value): assert loc >= 0 ofs = get_ebp_ofs(loc) assert ofs < 0 assert (ofs % WORD) == 0 stack[stacklen + ofs//WORD] = value descr_bytecode = [] for i, (kind, loc) in enumerate(content): if kind == 'hole': num = Assembler386.CODE_HOLE else: if kind == 'float': value, lo, hi = get_random_float() expected_floats[i] = longlong.getfloatstorage(value) kind = Assembler386.DESCR_FLOAT if isinstance(loc, RegLoc): if WORD == 4: xmmregisters[2*loc.value] = lo xmmregisters[2*loc.value+1] = hi elif WORD == 8: xmmregisters[loc.value] = lo else: if WORD == 4: write_in_stack(loc, hi) write_in_stack(loc+1, lo) elif WORD == 8: write_in_stack(loc, lo) else: if kind == 'int': value = get_random_int() expected_ints[i] = value kind = Assembler386.DESCR_INT elif kind == 'ptr': value = get_random_ptr() expected_ptrs[i] = value kind = Assembler386.DESCR_REF value = rffi.cast(rffi.LONG, value) else: assert 0, kind if isinstance(loc, RegLoc): registers[loc.value] = value else: write_in_stack(loc, value) if isinstance(loc, RegLoc): num = kind + 4*loc.value else: num = kind + Assembler386.CODE_FROMSTACK + (4*loc) while num >= 0x80: descr_bytecode.append((num & 0x7F) | 0x80) num >>= 7 descr_bytecode.append(num) descr_bytecode.append(Assembler386.CODE_STOP) descr_bytecode.append(0xC3) # fail_index = 0x1C3 descr_bytecode.append(0x01) descr_bytecode.append(0x00) descr_bytecode.append(0x00) descr_bytecode.append(0xCC) # end marker descr_bytes = lltype.malloc(rffi.UCHARP.TO, len(descr_bytecode), flavor='raw', immortal=True) for i in range(len(descr_bytecode)): assert 0 <= descr_bytecode[i] <= 255 descr_bytes[i] = rffi.cast(rffi.UCHAR, descr_bytecode[i]) registers[ACTUAL_CPU.NUM_REGS] = rffi.cast(rffi.LONG, descr_bytes) registers[ebp.value] = rffi.cast(rffi.LONG, stack) + WORD*stacklen # run! assembler = Assembler386(FakeCPU()) assembler.fail_boxes_int.get_addr_for_num(len(content)-1) # preallocate assembler.fail_boxes_ptr.get_addr_for_num(len(content)-1) assembler.fail_boxes_float.get_addr_for_num(len(content)-1) res = assembler.failure_recovery_func(registers) assert res == 0x1C3 # check the fail_boxes for i in range(len(content)): assert assembler.fail_boxes_int.getitem(i) == expected_ints[i] assert assembler.fail_boxes_ptr.getitem(i) == expected_ptrs[i] # note: we expect *exact* results below. If you have only # an approximate result, it might mean that only the first 32 # bits of the float were correctly saved and restored. assert assembler.fail_boxes_float.getitem(i) == expected_floats[i] # verify that until clear_latest_values() is called, reading the # same values multiple times work for i in range(len(content)): assert assembler.fail_boxes_int.getitem(i) == expected_ints[i] assert assembler.fail_boxes_ptr.getitem(i) == expected_ptrs[i] assert assembler.fail_boxes_float.getitem(i) == expected_floats[i]
def boxfloat(x): return BoxFloat(longlong.getfloatstorage(x))
def convert_to_floatstorage(arg): from pypy.jit.codewriter import longlong return longlong.getfloatstorage(float(arg))
def do_failure_recovery_func(withfloats): import random S = lltype.GcStruct('S') def get_random_int(): return random.randrange(-10000, 10000) def get_random_ptr(): return lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) def get_random_float(): # Returns <float>, <low word>, <high word> # NB: on 64-bit, <low word> will be the entire float and <high word> # will be random garbage from malloc! assert withfloats value = random.random() - 0.5 # make sure it fits into 64 bits tmp = lltype.malloc(rffi.LONGP.TO, 2, flavor='raw', track_allocation=False) rffi.cast(rffi.DOUBLEP, tmp)[0] = value return rffi.cast(rffi.DOUBLEP, tmp)[0], tmp[0], tmp[1] if IS_X86_32: main_registers = X86RegisterManager.all_regs xmm_registers = X86XMMRegisterManager.all_regs elif IS_X86_64: main_registers = X86_64_RegisterManager.all_regs xmm_registers = X86_64_XMMRegisterManager.all_regs # memory locations: 26 integers, 26 pointers, 26 floats # main registers: half of them as signed and the other half as ptrs # xmm registers: all floats, from xmm0 to xmm(7|15) # holes: 8 locations = [] baseloc = 4 for i in range(26 + 26 + 26): if baseloc < 128: baseloc += random.randrange(2, 20) else: baseloc += random.randrange(2, 1000) locations.append(baseloc) random.shuffle(locations) content = ([('int', locations.pop()) for _ in range(26)] + [('ptr', locations.pop()) for _ in range(26)] + [(['int', 'ptr'][random.randrange(0, 2)], reg) for reg in main_registers]) if withfloats: content += ([('float', locations.pop()) for _ in range(26)] + [('float', reg) for reg in xmm_registers]) for i in range(8): content.append(('hole', None)) random.shuffle(content) # prepare the expected target arrays, the descr_bytecode, # the 'registers' and the 'stack' arrays according to 'content' xmmregisters = lltype.malloc(rffi.LONGP.TO, 16 + ACTUAL_CPU.NUM_REGS + 1, flavor='raw', immortal=True) registers = rffi.ptradd(xmmregisters, 16) stacklen = baseloc + 30 stack = lltype.malloc(rffi.LONGP.TO, stacklen, flavor='raw', immortal=True) expected_ints = [0] * len(content) expected_ptrs = [lltype.nullptr(llmemory.GCREF.TO)] * len(content) expected_floats = [longlong.ZEROF] * len(content) def write_in_stack(loc, value): assert loc >= 0 ofs = get_ebp_ofs(loc) assert ofs < 0 assert (ofs % WORD) == 0 stack[stacklen + ofs // WORD] = value descr_bytecode = [] for i, (kind, loc) in enumerate(content): if kind == 'hole': num = Assembler386.CODE_HOLE else: if kind == 'float': value, lo, hi = get_random_float() expected_floats[i] = longlong.getfloatstorage(value) kind = Assembler386.DESCR_FLOAT if isinstance(loc, RegLoc): if WORD == 4: xmmregisters[2 * loc.value] = lo xmmregisters[2 * loc.value + 1] = hi elif WORD == 8: xmmregisters[loc.value] = lo else: if WORD == 4: write_in_stack(loc, hi) write_in_stack(loc + 1, lo) elif WORD == 8: write_in_stack(loc, lo) else: if kind == 'int': value = get_random_int() expected_ints[i] = value kind = Assembler386.DESCR_INT elif kind == 'ptr': value = get_random_ptr() expected_ptrs[i] = value kind = Assembler386.DESCR_REF value = rffi.cast(rffi.LONG, value) else: assert 0, kind if isinstance(loc, RegLoc): registers[loc.value] = value else: write_in_stack(loc, value) if isinstance(loc, RegLoc): num = kind + 4 * loc.value else: num = kind + Assembler386.CODE_FROMSTACK + (4 * loc) while num >= 0x80: descr_bytecode.append((num & 0x7F) | 0x80) num >>= 7 descr_bytecode.append(num) descr_bytecode.append(Assembler386.CODE_STOP) descr_bytecode.append(0xC3) # fail_index = 0x1C3 descr_bytecode.append(0x01) descr_bytecode.append(0x00) descr_bytecode.append(0x00) descr_bytecode.append(0xCC) # end marker descr_bytes = lltype.malloc(rffi.UCHARP.TO, len(descr_bytecode), flavor='raw', immortal=True) for i in range(len(descr_bytecode)): assert 0 <= descr_bytecode[i] <= 255 descr_bytes[i] = rffi.cast(rffi.UCHAR, descr_bytecode[i]) registers[ACTUAL_CPU.NUM_REGS] = rffi.cast(rffi.LONG, descr_bytes) registers[ebp.value] = rffi.cast(rffi.LONG, stack) + WORD * stacklen # run! assembler = Assembler386(FakeCPU()) assembler.fail_boxes_int.get_addr_for_num(len(content) - 1) # preallocate assembler.fail_boxes_ptr.get_addr_for_num(len(content) - 1) assembler.fail_boxes_float.get_addr_for_num(len(content) - 1) res = assembler.failure_recovery_func(registers) assert res == 0x1C3 # check the fail_boxes for i in range(len(content)): assert assembler.fail_boxes_int.getitem(i) == expected_ints[i] assert assembler.fail_boxes_ptr.getitem(i) == expected_ptrs[i] # note: we expect *exact* results below. If you have only # an approximate result, it might mean that only the first 32 # bits of the float were correctly saved and restored. assert assembler.fail_boxes_float.getitem(i) == expected_floats[i] # verify that until clear_latest_values() is called, reading the # same values multiple times work for i in range(len(content)): assert assembler.fail_boxes_int.getitem(i) == expected_ints[i] assert assembler.fail_boxes_ptr.getitem(i) == expected_ptrs[i] assert assembler.fail_boxes_float.getitem(i) == expected_floats[i]
def get_random_float_storage(): x = get_random_float() return longlong.getfloatstorage(x)
def boxfloat(x): return BoxFloat(longlong.getfloatstorage(x))
def test_functions(): xll = longlong.getfloatstorage(3.5) assert longlong.getrealfloat(xll) == 3.5 assert isinstance(longlong.gethash(xll), int)
def constfloat(x): return ConstFloat(longlong.getfloatstorage(x))
def bh_call_f(self, func, calldescr, args_i, args_r, args_f): self.fakecalled = (func, calldescr, args_i, args_r, args_f) return longlong.getfloatstorage(42.5)
def test_functions(): xll = longlong.getfloatstorage(3.5) assert longlong.getrealfloat(xll) == 3.5 assert is_valid_int(longlong.gethash(xll))
def convert_to_floatstorage(arg): from pypy.jit.codewriter import longlong return longlong.getfloatstorage(float(arg))
def test_functions(): xll = longlong.getfloatstorage(3.5) assert longlong.getrealfloat(xll) == 3.5 assert is_valid_int(longlong.gethash(xll))
def get_random_float_storage(): x = get_random_float() return longlong.getfloatstorage(x)
def test_functions(): xll = longlong.getfloatstorage(3.5) assert longlong.getrealfloat(xll) == 3.5 assert isinstance(longlong.gethash(xll), int)
def constfloat(x): return ConstFloat(longlong.getfloatstorage(x))