Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r75449:dde0fac9f1a4 Date: 2015-01-20 15:02 +0100 http://bitbucket.org/pypy/pypy/changeset/dde0fac9f1a4/
Log: If a JMP and CALL instruction goes straight to a further JMP, emit the original JMP or CALL to go directly to the target. diff --git a/rpython/jit/backend/x86/codebuf.py b/rpython/jit/backend/x86/codebuf.py --- a/rpython/jit/backend/x86/codebuf.py +++ b/rpython/jit/backend/x86/codebuf.py @@ -46,9 +46,9 @@ def copy_to_raw_memory(self, addr): self._copy_to_raw_memory(addr) if self.relocations is not None: - for reloc in self.relocations: + for reloc in self.relocations: # for 32-bit only p = addr + reloc - adr = rffi.cast(rffi.LONGP, p - WORD) - adr[0] = intmask(adr[0] - p) + adr = rffi.cast(rffi.INTP, p - 4) + adr[0] = rffi.cast(rffi.INT, intmask(adr[0]) - p) valgrind.discard_translations(addr, self.get_relative_pos()) self._dump(addr, "jit-backend-dump", backend_name) diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -516,6 +516,10 @@ if code == possible_code: val = getattr(loc, "value_" + possible_code)() if possible_code == 'i': + # This is for CALL or JMP only. If target is + # immediately starting with another JMP instruction, + # follow it now. + val = self._follow_jump_instructions(val) if self.WORD == 4: _rx86_getattr(self, name + "_l")(val) self.add_pending_relocation() @@ -533,6 +537,17 @@ return func_with_new_name(INSN, "INSN_" + name) + _do_follow_jump_instructions = True + + def _follow_jump_instructions(self, addr): + if not self._do_follow_jump_instructions or addr == 0: # for tests + return addr + # 'addr' is an absolute address here + while rffi.cast(rffi.CCHARP, addr)[0] == '\xE9': # JMP <4 bytes> + addr += 5 + addr += intmask(rffi.cast(rffi.INTP, addr - 4)[0]) + return addr + def _addr_as_reg_offset(self, addr): # Encodes a (64-bit) address as an offset from the scratch register. # If we are within a "reuse_scratch_register" block, we remember the diff --git a/rpython/jit/backend/x86/test/test_regloc.py b/rpython/jit/backend/x86/test/test_regloc.py --- a/rpython/jit/backend/x86/test/test_regloc.py +++ b/rpython/jit/backend/x86/test/test_regloc.py @@ -4,6 +4,7 @@ from rpython.jit.backend.x86.test.test_rx86 import CodeBuilder32, CodeBuilder64, assert_encodes_as from rpython.jit.backend.x86.assembler import heap from rpython.jit.backend.x86.arch import IS_X86_64, IS_X86_32 +from rpython.jit.backend.x86 import codebuf from rpython.rlib.rarithmetic import intmask import py.test @@ -62,11 +63,11 @@ def test_relocation(): from rpython.rtyper.lltypesystem import lltype, rffi - from rpython.jit.backend.x86 import codebuf for target in [0x01020304, -0x05060708, 0x0102030405060708]: if target > sys.maxint: continue mc = codebuf.MachineCodeBlockWrapper() + mc._do_follow_jump_instructions = False mc.CALL(ImmedLoc(target)) length = mc.get_relative_pos() buf = lltype.malloc(rffi.CCHARP.TO, length, flavor='raw') @@ -96,6 +97,38 @@ assert ''.join([buf[i] for i in range(length)]) == expected lltype.free(buf, flavor='raw') +def test_follow_jump_instructions_32(): + buf = lltype.malloc(rffi.CCHARP.TO, 80, flavor='raw') + raw = rffi.cast(lltype.Signed, buf) + mc = codebuf.MachineCodeBlockWrapper(); mc.WORD = 4; mc.relocations = [] + mc.RET() + mc.copy_to_raw_memory(raw) + mc = codebuf.MachineCodeBlockWrapper(); mc.WORD = 4; mc.relocations = [] + mc.JMP(imm(raw)) + mc.copy_to_raw_memory(raw + 20) + assert buf[20] == '\xE9' # JMP + assert buf[21] == '\xE7' # -25 + assert buf[22] == '\xFF' + assert buf[23] == '\xFF' + assert buf[24] == '\xFF' + mc = codebuf.MachineCodeBlockWrapper(); mc.WORD = 4; mc.relocations = [] + mc.JMP(imm(raw + 20)) + mc.copy_to_raw_memory(raw + 40) + assert buf[40] == '\xE9' # JMP + assert buf[41] == '\xD3' # -45 + assert buf[42] == '\xFF' + assert buf[43] == '\xFF' + assert buf[44] == '\xFF' + mc = codebuf.MachineCodeBlockWrapper(); mc.WORD = 4; mc.relocations = [] + mc.CALL(imm(raw + 40)) + mc.copy_to_raw_memory(raw + 60) + assert buf[60] == '\xE8' # CALL + assert buf[61] == '\xBF' # -65 + assert buf[62] == '\xFF' + assert buf[63] == '\xFF' + assert buf[64] == '\xFF' + lltype.free(buf, flavor='raw') + class Test64Bits: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit