Author: Armin Rigo <[email protected]>
Branch:
Changeset: r90680:43b8bd691613
Date: 2017-03-14 12:51 +0100
http://bitbucket.org/pypy/pypy/changeset/43b8bd691613/
Log: Factor out the logic to write a forward jump, too
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -349,8 +349,7 @@
#
mc.MOV(eax, heap(self.cpu.pos_exception()))
mc.TEST_rr(eax.value, eax.value)
- mc.J_il8(rx86.Conditions['NZ'], 0)
- jnz_location = mc.get_relative_pos()
+ jnz_location = mc.emit_forward_jump('NZ')
#
mc.RET()
#
@@ -832,8 +831,7 @@
ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
mc.CMP_bi(ofs, 0xffffff) # force writing 32 bit
stack_check_cmp_ofs = mc.get_relative_pos() - 4
- mc.J_il8(rx86.Conditions['GE'], 0)
- jg_location = mc.get_relative_pos()
+ jg_location = mc.emit_forward_jump('GE')
mc.MOV_si(WORD, 0xffffff) # force writing 32 bit
ofs2 = mc.get_relative_pos() - 4
self.push_gcmap(mc, gcmap, store=True)
@@ -853,8 +851,7 @@
ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
mc.CMP_bi(ofs, 0xffffff)
stack_check_cmp_ofs = mc.get_relative_pos() - 4
- mc.J_il8(rx86.Conditions['GE'], 0)
- jg_location = mc.get_relative_pos()
+ jg_location = mc.emit_forward_jump('GE')
mc.MOV_rr(edi.value, ebp.value)
mc.MOV_ri(esi.value, 0xffffff)
ofs2 = mc.get_relative_pos() - 4
@@ -996,8 +993,7 @@
self.mc.MOV(eax, heap(endaddr)) # MOV eax, [start]
self.mc.SUB(eax, esp) # SUB eax, current
self.mc.CMP(eax, heap(lengthaddr)) # CMP eax, [length]
- self.mc.J_il8(rx86.Conditions['BE'], 0) # JBE .skip
- jb_location = self.mc.get_relative_pos()
+ jb_location = self.mc.emit_forward_jump('BE')#JBE .skip
self.mc.CALL(imm(self.stack_check_slowpath))# CALL slowpath
# patch the JB above # .skip:
self.mc.patch_forward_jump(jb_location)
@@ -1234,8 +1230,7 @@
return genop_cmp
def _if_parity_clear_zero_and_carry(self):
- self.mc.J_il8(rx86.Conditions['NP'], 0)
- jnp_location = self.mc.get_relative_pos()
+ jnp_location = self.mc.emit_forward_jump('NP')
# CMP EBP, 0: as EBP cannot be null here, that operation should
# always clear zero and carry
self.mc.CMP_ri(ebp.value, 0)
@@ -1718,10 +1713,11 @@
# jump to jump over this GUARD_NO_EXCEPTION as well, if we can
if self._find_nearby_operation(-1).getopnum() in (
rop.COND_CALL, rop.COND_CALL_VALUE_I, rop.COND_CALL_VALUE_R):
- jmp_adr = self.previous_cond_call_jcond
- offset = self.mc.get_relative_pos() - jmp_adr
- if offset <= 127:
- self.mc.patch_forward_jump(jmp_adr)
+ j_location = self.previous_cond_call_jcond
+ try:
+ self.mc.patch_forward_jump(j_location)
+ except codebuf.ShortJumpTooFar:
+ pass # ignore this case
def genop_guard_guard_not_invalidated(self, guard_op, guard_token,
locs, ign):
@@ -1832,8 +1828,7 @@
def genop_guard_guard_nonnull_class(self, guard_op, guard_token, locs,
ign):
self.mc.CMP(locs[0], imm1)
# Patched below
- self.mc.J_il8(rx86.Conditions['B'], 0)
- jb_location = self.mc.get_relative_pos()
+ jb_location = self.mc.emit_forward_jump('B')
self._cmp_guard_class(locs)
# patch the JB above
self.mc.patch_forward_jump(jb_location)
@@ -2211,15 +2206,13 @@
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
self.mc.CMP(mem(eax, ofs), imm(value))
# patched later
- self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get
'done_with_this_frame'
- return self.mc.get_relative_pos()
+ return self.mc.emit_forward_jump('E') # goto B if we get
'done_with_this_frame'
def _call_assembler_patch_je(self, result_loc, je_location):
if (IS_X86_32 and isinstance(result_loc, FrameLoc) and
result_loc.type == FLOAT):
self.mc.FSTPL_b(result_loc.value)
- self.mc.JMP_l8(0) # jump to done, patched later
- jmp_location = self.mc.get_relative_pos()
+ jmp_location = self.mc.emit_forward_jump_uncond() # jump to the end
#
self.mc.patch_forward_jump(je_location)
self.mc.force_frame_size(DEFAULT_FRAME_BYTES)
@@ -2272,16 +2265,14 @@
else:
loc = addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs)
mc.TEST8(loc, imm(mask))
- mc.J_il8(rx86.Conditions['Z'], 0) # patched later
- jz_location = mc.get_relative_pos()
+ jz_location = mc.emit_forward_jump('Z') # patched later
# for cond_call_gc_wb_array, also add another fast path:
# if GCFLAG_CARDS_SET, then we can just set one bit and be done
if card_marking:
# GCFLAG_CARDS_SET is in this byte at 0x80, so this fact can
# been checked by the status flags of the previous TEST8
- mc.J_il8(rx86.Conditions['S'], 0) # patched later
- js_location = mc.get_relative_pos()
+ js_location = mc.emit_forward_jump('S') # patched later
else:
js_location = 0
@@ -2310,8 +2301,7 @@
# The helper ends again with a check of the flag in the object.
# So here, we can simply write again a 'JNS', which will be
# taken if GCFLAG_CARDS_SET is still not set.
- mc.J_il8(rx86.Conditions['NS'], 0) # patched later
- jns_location = mc.get_relative_pos()
+ jns_location = mc.emit_forward_jump('NS') # patched later
#
# patch the JS above
mc.patch_forward_jump(js_location)
@@ -2385,9 +2375,8 @@
def cond_call(self, gcmap, imm_func, arglocs, resloc=None):
assert self.guard_success_cc >= 0
- self.mc.J_il8(rx86.invert_condition(self.guard_success_cc), 0)
- # patched later
- jmp_adr = self.mc.get_relative_pos()
+ j_location = self.mc.emit_forward_jump_cond(
+ rx86.invert_condition(self.guard_success_cc))
self.guard_success_cc = rx86.cond_none
#
self.push_gcmap(self.mc, gcmap, store=True)
@@ -2437,22 +2426,21 @@
v = gpr_reg_mgr_cls.all_reg_indexes[eax.value]
self.mc.MOV_rb(eax.value, v * WORD + base_ofs)
#
- self.mc.patch_forward_jump(jmp_adr)
+ self.mc.patch_forward_jump(j_location)
# might be overridden again to skip over the following
# guard_no_exception too
- self.previous_cond_call_jcond = jmp_adr
+ self.previous_cond_call_jcond = j_location
def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap):
assert size & (WORD-1) == 0 # must be correctly aligned
self.mc.MOV(ecx, heap(nursery_free_adr))
self.mc.LEA_rm(edx.value, (ecx.value, size))
self.mc.CMP(edx, heap(nursery_top_adr))
- self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
- jmp_adr = self.mc.get_relative_pos()
+ jna_location = self.mc.emit_forward_jump('NA') # patched later
# save the gcmap
self.push_gcmap(self.mc, gcmap, store=True)
self.mc.CALL(imm(follow_jump(self.malloc_slowpath)))
- self.mc.patch_forward_jump(jmp_adr)
+ self.mc.patch_forward_jump(jna_location)
self.mc.MOV(heap(nursery_free_adr), edx)
def malloc_cond_varsize_frame(self, nursery_free_adr, nursery_top_adr,
@@ -2466,12 +2454,11 @@
else:
self.mc.LEA_ra(edx.value, (ecx.value, sizeloc.value, 0, 0))
self.mc.CMP(edx, heap(nursery_top_adr))
- self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
- jmp_adr = self.mc.get_relative_pos()
+ jna_location = self.mc.emit_forward_jump('NA') # patched later
# save the gcmap
self.push_gcmap(self.mc, gcmap, store=True)
self.mc.CALL(imm(follow_jump(self.malloc_slowpath)))
- self.mc.patch_forward_jump(jmp_adr)
+ self.mc.patch_forward_jump(jna_location)
self.mc.MOV(heap(nursery_free_adr), edx)
def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr,
@@ -2489,8 +2476,7 @@
varsizeloc = edx
self.mc.CMP(varsizeloc, imm(maxlength))
- self.mc.J_il8(rx86.Conditions['A'], 0) # patched later
- jmp_adr0 = self.mc.get_relative_pos()
+ ja_location = self.mc.emit_forward_jump('A') # patched later
self.mc.MOV(ecx, heap(nursery_free_adr))
if valid_addressing_size(itemsize):
@@ -2514,10 +2500,9 @@
# now edx contains the total size in bytes, rounded up to a multiple
# of WORD, plus nursery_free_adr
self.mc.CMP(edx, heap(nursery_top_adr))
- self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
- jmp_adr1 = self.mc.get_relative_pos()
+ jna_location = self.mc.emit_forward_jump('NA') # patched later
#
- self.mc.patch_forward_jump(jmp_adr0)
+ self.mc.patch_forward_jump(ja_location)
# save the gcmap
self.push_gcmap(self.mc, gcmap, store=True)
if kind == rewrite.FLAG_ARRAY:
@@ -2533,10 +2518,9 @@
addr = self.malloc_slowpath_unicode
self.mc.MOV(edx, lengthloc)
self.mc.CALL(imm(follow_jump(addr)))
- self.mc.JMP_l8(0) # jump to done, patched later
- jmp_location = self.mc.get_relative_pos()
+ jmp_location = self.mc.emit_forward_jump_uncond() # jump to later
#
- self.mc.patch_forward_jump(jmp_adr1)
+ self.mc.patch_forward_jump(jna_location)
self.mc.force_frame_size(DEFAULT_FRAME_BYTES)
# write down the tid, but not if it's the result of the CALL
self.mc.MOV(mem(ecx, 0), imm(arraydescr.tid))
diff --git a/rpython/jit/backend/x86/callbuilder.py
b/rpython/jit/backend/x86/callbuilder.py
--- a/rpython/jit/backend/x86/callbuilder.py
+++ b/rpython/jit/backend/x86/callbuilder.py
@@ -341,23 +341,20 @@
# thread. So here we check if the shadowstack pointer
# is still the same as before we released the GIL (saved
# in 'ebx'), and if not, we fall back to 'reacqgil_addr'.
- mc.J_il8(rx86.Conditions['NE'], 0)
- jne_location = mc.get_relative_pos()
+ jne_location = mc.emit_forward_jump('NE')
# here, ecx (=old_value) is zero (so rpy_fastgil was in 'released'
# state before the XCHG, but the XCHG acquired it by writing 1)
rst = gcrootmap.get_root_stack_top_addr()
mc = self.mc
mc.CMP(ebx, heap(rst))
- mc.J_il8(rx86.Conditions['E'], 0)
- je_location = mc.get_relative_pos()
+ je_location = mc.emit_forward_jump('E')
# revert the rpy_fastgil acquired above, so that the
# general 'reacqgil_addr' below can acquire it again...
mc.MOV(heap(fastgil), ecx)
# patch the JNE above
mc.patch_forward_jump(jne_location)
else:
- mc.J_il8(rx86.Conditions['E'], 0)
- je_location = mc.get_relative_pos()
+ je_location = mc.emit_forward_jump('E')
#
# Yes, we need to call the reacqgil() function
if not self.result_value_saved_early:
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
@@ -1,12 +1,13 @@
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.objectmodel import specialize
from rpython.rlib.debug import debug_start, debug_print, debug_stop
from rpython.rlib.debug import have_debug_prints
from rpython.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
from rpython.jit.backend.x86.rx86 import X86_32_CodeBuilder, X86_64_CodeBuilder
from rpython.jit.backend.x86.regloc import LocationCodeBuilder
from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64, WORD
-from rpython.jit.backend.x86 import valgrind
+from rpython.jit.backend.x86 import rx86, valgrind
# XXX: Seems nasty to change the superclass of MachineCodeBlockWrapper
# like this
@@ -17,6 +18,9 @@
codebuilder_cls = X86_64_CodeBuilder
backend_name = 'x86_64'
+class ShortJumpTooFar(Exception):
+ pass
+
class MachineCodeBlockWrapper(BlockBuilderMixin,
LocationCodeBuilder,
@@ -54,7 +58,21 @@
valgrind.discard_translations(addr, self.get_relative_pos())
self._dump(addr, "jit-backend-dump", backend_name)
+ @specialize.arg(1)
+ def emit_forward_jump(self, condition_string):
+ return self.emit_forward_jump_cond(rx86.Conditions[condition_string])
+
+ def emit_forward_jump_cond(self, cond):
+ self.J_il8(cond, 0)
+ return self.get_relative_pos()
+
+ def emit_forward_jump_uncond(self):
+ self.JMP_l8(0)
+ return self.get_relative_pos()
+
def patch_forward_jump(self, jcond_location):
offset = self.get_relative_pos() - jcond_location
- assert 0 <= offset <= 127
+ assert offset >= 0
+ if offset > 127:
+ raise ShortJumpTooFar
self.overwrite(jcond_location-1, chr(offset))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit