def do_test(self, callback): from pypy.jit.backend.x86.regalloc import X86FrameManager from pypy.jit.backend.x86.regalloc import X86XMMRegisterManager class FakeToken: class compiled_loop_token: asmmemmgr_blocks = None cpu = ACTUAL_CPU(None, None) cpu.setup() looptoken = FakeToken() asm = cpu.assembler asm.setup_once() asm.setup(looptoken) self.fm = X86FrameManager() self.xrm = X86XMMRegisterManager(None, frame_manager=self.fm, assembler=asm) callback(asm) asm.mc.RET() rawstart = asm.materialize_loop(looptoken) # F = ctypes.CFUNCTYPE(ctypes.c_long) fn = ctypes.cast(rawstart, F) res = fn() return res
def test_mark_gc_roots(self): cpu = CPU(None, None) cpu.setup_once() regalloc = RegAlloc(MockAssembler(cpu, MockGcDescr(False))) regalloc.assembler.datablockwrapper = 'fakedatablockwrapper' boxes = [BoxPtr() for i in range(len(X86RegisterManager.all_regs))] longevity = {} for box in boxes: longevity[box] = (0, 1) regalloc.fm = X86FrameManager() regalloc.rm = X86RegisterManager(longevity, regalloc.fm, assembler=regalloc.assembler) regalloc.xrm = X86XMMRegisterManager(longevity, regalloc.fm, assembler=regalloc.assembler) cpu = regalloc.assembler.cpu for box in boxes: regalloc.rm.try_allocate_reg(box) TP = lltype.FuncType([], lltype.Signed) calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT, EffectInfo.MOST_GENERAL) regalloc.rm._check_invariants() box = boxes[0] regalloc.position = 0 regalloc.consider_call( ResOperation(rop.CALL, [box], BoxInt(), calldescr)) assert len(regalloc.assembler.movs) == 3 # mark = regalloc.get_mark_gc_roots(cpu.gc_ll_descr.gcrootmap) assert mark[0] == 'compressed' base = -WORD * FRAME_FIXED_SIZE expected = ['ebx', 'esi', 'edi', base, base - WORD, base - WORD * 2] assert dict.fromkeys(mark[1:]) == dict.fromkeys(expected)
def test_write_failure_recovery_description(): assembler = Assembler386(FakeCPU()) mc = FakeMC() failargs = [BoxInt(), BoxPtr(), BoxFloat()] * 3 failargs.insert(6, None) failargs.insert(7, None) locs = [X86FrameManager.frame_pos(0, INT), X86FrameManager.frame_pos(1, REF), X86FrameManager.frame_pos(10, FLOAT), X86FrameManager.frame_pos(100, INT), X86FrameManager.frame_pos(101, REF), X86FrameManager.frame_pos(110, FLOAT), None, None, ebx, esi, xmm2] assert len(failargs) == len(locs) assembler.write_failure_recovery_description(mc, failargs, locs) base = 8 + 8*IS_X86_64 nums = [Assembler386.DESCR_INT + 4*(base+0), Assembler386.DESCR_REF + 4*(base+1), Assembler386.DESCR_FLOAT + 4*(base+10), Assembler386.DESCR_INT + 4*(base+100), Assembler386.DESCR_REF + 4*(base+101), Assembler386.DESCR_FLOAT + 4*(base+110), Assembler386.CODE_HOLE, Assembler386.CODE_HOLE, Assembler386.DESCR_INT + 4*ebx.value, Assembler386.DESCR_REF + 4*esi.value, Assembler386.DESCR_FLOAT + 4*xmm2.value] double_byte_nums = [] for num in nums[3:6]: double_byte_nums.append((num & 0x7F) | 0x80) double_byte_nums.append(num >> 7) assert mc.content == (nums[:3] + double_byte_nums + nums[6:] + [assembler.CODE_STOP]) # also test rebuild_faillocs_from_descr(), which should not # reproduce the holes at all bytecode = lltype.malloc(rffi.UCHARP.TO, len(mc.content), flavor='raw', immortal=True) for i in range(len(mc.content)): assert 0 <= mc.content[i] <= 255 bytecode[i] = rffi.cast(rffi.UCHAR, mc.content[i]) bytecode_addr = rffi.cast(lltype.Signed, bytecode) newlocs = assembler.rebuild_faillocs_from_descr(bytecode_addr) assert ([loc.assembler() for loc in newlocs] == [loc.assembler() for loc in locs if loc is not None])
def test_write_failure_recovery_description(): assembler = Assembler386(FakeCPU()) mc = FakeMC() failargs = [BoxInt(), BoxPtr(), BoxFloat()] * 3 failargs.insert(6, None) failargs.insert(7, None) locs = [ X86FrameManager.frame_pos(0, INT), X86FrameManager.frame_pos(1, REF), X86FrameManager.frame_pos(10, FLOAT), X86FrameManager.frame_pos(100, INT), X86FrameManager.frame_pos(101, REF), X86FrameManager.frame_pos(110, FLOAT), None, None, ebx, esi, xmm2 ] assert len(failargs) == len(locs) assembler.write_failure_recovery_description(mc, failargs, locs) base = 8 + 8 * IS_X86_64 nums = [ Assembler386.DESCR_INT + 4 * (base + 0), Assembler386.DESCR_REF + 4 * (base + 1), Assembler386.DESCR_FLOAT + 4 * (base + 10), Assembler386.DESCR_INT + 4 * (base + 100), Assembler386.DESCR_REF + 4 * (base + 101), Assembler386.DESCR_FLOAT + 4 * (base + 110), Assembler386.CODE_HOLE, Assembler386.CODE_HOLE, Assembler386.DESCR_INT + 4 * ebx.value, Assembler386.DESCR_REF + 4 * esi.value, Assembler386.DESCR_FLOAT + 4 * xmm2.value ] double_byte_nums = [] for num in nums[3:6]: double_byte_nums.append((num & 0x7F) | 0x80) double_byte_nums.append(num >> 7) assert mc.content == (nums[:3] + double_byte_nums + nums[6:] + [assembler.CODE_STOP]) # also test rebuild_faillocs_from_descr(), which should not # reproduce the holes at all bytecode = lltype.malloc(rffi.UCHARP.TO, len(mc.content), flavor='raw', immortal=True) for i in range(len(mc.content)): assert 0 <= mc.content[i] <= 255 bytecode[i] = rffi.cast(rffi.UCHAR, mc.content[i]) bytecode_addr = rffi.cast(lltype.Signed, bytecode) newlocs = assembler.rebuild_faillocs_from_descr(bytecode_addr) assert ([loc.assembler() for loc in newlocs ] == [loc.assembler() for loc in locs if loc is not None])
def test_write_failure_recovery_description(): assembler = Assembler386(FakeCPU()) mc = FakeMC() failargs = [BoxInt(), BoxPtr(), BoxFloat()] * 3 failargs.insert(6, None) failargs.insert(7, None) locs = [X86FrameManager.frame_pos(0, 1), X86FrameManager.frame_pos(1, 1), X86FrameManager.frame_pos(10, 2), X86FrameManager.frame_pos(100, 1), X86FrameManager.frame_pos(101, 1), X86FrameManager.frame_pos(110, 2), None, None, ebx, esi, xmm2] assert len(failargs) == len(locs) assembler.write_failure_recovery_description(mc, failargs, locs) nums = [Assembler386.DESCR_INT + 4*(8+0), Assembler386.DESCR_REF + 4*(8+1), Assembler386.DESCR_FLOAT + 4*(8+10), Assembler386.DESCR_INT + 4*(8+100), Assembler386.DESCR_REF + 4*(8+101), Assembler386.DESCR_FLOAT + 4*(8+110), Assembler386.CODE_HOLE, Assembler386.CODE_HOLE, Assembler386.DESCR_INT + 4*ebx.op, Assembler386.DESCR_REF + 4*esi.op, Assembler386.DESCR_FLOAT + 4*xmm2.op] double_byte_nums = [] for num in nums[3:6]: double_byte_nums.append((num & 0x7F) | 0x80) double_byte_nums.append(num >> 7) assert mc.content == (nums[:3] + double_byte_nums + nums[6:] + [assembler.CODE_STOP]) # also test rebuild_faillocs_from_descr(), which should not # reproduce the holes at all bytecode = lltype.malloc(rffi.UCHARP.TO, len(mc.content), flavor='raw') for i in range(len(mc.content)): assert 0 <= mc.content[i] <= 255 bytecode[i] = rffi.cast(rffi.UCHAR, mc.content[i]) bytecode_addr = rffi.cast(lltype.Signed, bytecode) newlocs = assembler.rebuild_faillocs_from_descr(bytecode_addr) assert ([loc.assembler() for loc in newlocs] == [loc.assembler() for loc in locs if loc is not None]) # finally, test make_boxes_from_latest_values(), which should # reproduce the holes expected_classes = [BoxInt, BoxPtr, BoxFloat, BoxInt, BoxPtr, BoxFloat, type(None), type(None), BoxInt, BoxPtr, BoxFloat] ptrvalues = {} S = lltype.GcStruct('S') for i, cls in enumerate(expected_classes): if cls == BoxInt: assembler.fail_boxes_int.setitem(i, 1000 + i) elif cls == BoxPtr: s = lltype.malloc(S) s_ref = lltype.cast_opaque_ptr(llmemory.GCREF, s) ptrvalues[i] = s_ref assembler.fail_boxes_ptr.setitem(i, s_ref) elif cls == BoxFloat: assembler.fail_boxes_float.setitem(i, 42.5 + i) boxes = assembler.make_boxes_from_latest_values(bytecode_addr) assert len(boxes) == len(locs) == len(expected_classes) for i, (box, expected_class) in enumerate(zip(boxes, expected_classes)): assert type(box) is expected_class if expected_class == BoxInt: assert box.value == 1000 + i elif expected_class == BoxPtr: assert box.value == ptrvalues[i] elif expected_class == BoxFloat: assert box.value == 42.5 + i