Author: Armin Rigo <[email protected]>
Branch: guard-compatible
Changeset: r84615:2bf1ceeab1d7
Date: 2016-05-23 10:48 +0200
http://bitbucket.org/pypy/pypy/changeset/2bf1ceeab1d7/
Log: Move gcmap to the GuardCompatibleDescr. Maybe we can do that in
general? It would shrink each generate_quick_failure() code by
removing the need to push separately the gcmap.
diff --git a/rpython/jit/backend/x86/guard_compat.py
b/rpython/jit/backend/x86/guard_compat.py
--- a/rpython/jit/backend/x86/guard_compat.py
+++ b/rpython/jit/backend/x86/guard_compat.py
@@ -39,11 +39,11 @@
# ofs(_backend_choices)
# - _backend_sequel_label: points to the <sequel> label
# - _backend_failure_recovery: points to the <failure_recovery> label
+# - _backend_gcmap: a copy of the gcmap at this point
#
# The '_backend_choices' object itself is a separate GC struct/array
# with the following fields:
#
-# - bc_gcmap: a copy of the gcmap at this point
# - bc_faildescr: a copy of the faildescr of that guard
# - bc_most_recent: 1 pair (gcref, asmaddr)
# - bc_list: N pairs (gcref, asmaddr) sorted according to gcref
@@ -110,19 +110,18 @@
# not_found:
# <save all registers to the jitframe RBP,
# reading and popping the original RAX and RDX off the stack>
-# MOV RDI, [RSP]
-# MOV R11, [RDI + bc_gcmap]
-# MOV [RBP + jf_gcmap], R11
-# <call invoke_find_compatible(_backend_choices=RDI, value=RAX)>
+# <call invoke_find_compatible(_backend_choices=[RSP], value=RAX),
+# jitframe=RBP>
# <_reload_frame_if_necessary>
# MOV R11, RAX
# <restore the non-saved registers>
# JMP *R11
#
#
-# invoke_find_compatible(bchoices, new_gcref):
+# invoke_find_compatible(bchoices, new_gcref, jitframe):
# descr = bchoices.bc_faildescr
# try:
+# jitframe.jf_gcmap = descr._backend_gcmap
# result = descr.find_compatible(cpu, new_gcref)
# if result == 0:
# result = descr._backend_failure_recovery
@@ -133,6 +132,7 @@
# descr.bchoices_addr[0] = bchoices # GC table
# bchoices.bc_most_recent.gcref = new_gcref
# bchoices.bc_most_recent.asmaddr = result
+# jitframe.jf_gcmap = 0
# return result
# except: # oops!
# return descr._backend_failure_recovery
@@ -155,18 +155,35 @@
#
# ____________________________________________________________
+# Possible optimization: GUARD_COMPATIBLE(reg, const-ptr) could emit
+# first assembler that is similar to a GUARD_VALUE. As soon as a
+# second case is seen, this assembler is patched (once) to turn it
+# into the general switching version above. The entry in the GC table
+# at ofs(_backend_choices) starts with the regular const-ptr, and the
+# BACKEND_CHOICES object is only allocated when the assembler is
+# patched. The original assembler can be similar to a GUARD_VALUE:
+#
+# MOV reg2, [RIP + ofs(const-ptr)] # == ofs(_backend_choices)
+# CMP reg, reg2
+# JE sequel
+# PUSH [RIP + ofs(guard_compatible_descr)]
+# JMP guard_compat_second_case
+# <padding to make the code large enough for patching>
+# <ends with one byte which tells the size of this block>
+# sequel:
+#
+# ____________________________________________________________
+
PAIR = lltype.Struct('PAIR', ('gcref', llmemory.GCREF),
('asmaddr', lltype.Signed))
BACKEND_CHOICES = lltype.GcStruct('BACKEND_CHOICES',
- ('bc_gcmap', lltype.Ptr(jitframe.GCMAP)),
('bc_faildescr', llmemory.GCREF),
('bc_most_recent', PAIR),
('bc_list', lltype.Array(PAIR)))
def _getofs(name):
return llmemory.offsetof(BACKEND_CHOICES, name)
-BCGCMAP = _getofs('bc_gcmap')
BCFAILDESCR = _getofs('bc_faildescr')
BCMOSTRECENT = _getofs('bc_most_recent')
BCLIST = _getofs('bc_list')
@@ -270,7 +287,6 @@
# reallocate
new_bchoices = lltype.malloc(BACKEND_CHOICES, length * 2 + 1,
zero=True)
# --- no GC below: it would mess up the order of bc_list ---
- new_bchoices.bc_gcmap = bchoices.bc_gcmap
new_bchoices.bc_faildescr = bchoices.bc_faildescr
new_bchoices.bc_most_recent.gcref = bchoices.bc_most_recent.gcref
new_bchoices.bc_most_recent.asmaddr = bchoices.bc_most_recent.asmaddr
@@ -300,7 +316,6 @@
def initial_bchoices(guard_compat_descr, initial_gcref):
bchoices = lltype.malloc(BACKEND_CHOICES, 1)
- # bchoices.bc_gcmap: patch_guard_compatible()
bchoices.bc_faildescr = cast_instance_to_gcref(guard_compat_descr)
bchoices.bc_most_recent.gcref = initial_gcref
# bchoices.bc_most_recent.asmaddr: patch_guard_compatible()
@@ -331,12 +346,12 @@
guard_compat_descr._backend_choices_addr = choices_addr
guard_compat_descr._backend_sequel_label = sequel_label
guard_compat_descr._backend_failure_recovery = failure_recovery
+ guard_compat_descr._backend_gcmap = gcmap
#
bchoices = descr_to_bchoices(guard_compat_descr)
assert len(bchoices.bc_list) == 1
assert (cast_gcref_to_instance(GuardCompatibleDescr, bchoices.bc_faildescr)
is guard_compat_descr)
- bchoices.bc_gcmap = gcmap
bchoices.bc_most_recent.asmaddr = sequel_label
bchoices.bc_list[0].asmaddr = sequel_label
@@ -412,19 +427,15 @@
assembler._push_all_regs_to_frame(mc, [regloc.eax, regloc.edx],
withfloats=True)
- bc_gcmap = _real_number(BCGCMAP)
- jf_gcmap = assembler.cpu.get_ofs_of_frame_field('jf_gcmap')
mc.MOV_rs(rdi, 0) # MOV RDI, [RSP]
mc.MOV_rr(regloc.esi.value, rax) # MOV RSI, RAX
- mc.MOV_rm(r11, (rdi, bc_gcmap)) # MOV R11, [RDI + bc_gcmap]
- mc.MOV_br(jf_gcmap, r11) # MOV [RBP + jf_gcmap], R11
+ mc.MOV_rr(regloc.edx.value, # MOV RDX, RBP
+ regloc.ebp.value)
invoke_find_compatible = make_invoke_find_compatible(assembler.cpu)
llfunc = llhelper(INVOKE_FIND_COMPATIBLE_FUNC, invoke_find_compatible)
llfunc = assembler.cpu.cast_ptr_to_int(llfunc)
mc.CALL(regloc.imm(llfunc)) # CALL invoke_find_compatible
assembler._reload_frame_if_necessary(mc)
- mc.MOV_bi(jf_gcmap, 0) # MOV [RBP + jf_gcmap], 0
-
mc.MOV_rr(r11, rax) # MOV R11, RAX
# restore the registers that the CALL has clobbered. Other other
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit