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