Author: Armin Rigo <[email protected]>
Branch: guard-compatible
Changeset: r90029:c0a1749a2014
Date: 2017-02-09 17:45 +0100
http://bitbucket.org/pypy/pypy/changeset/c0a1749a2014/
Log: in-progress
diff --git a/rpython/jit/backend/llsupport/guard_compat.py
b/rpython/jit/backend/llsupport/guard_compat.py
--- a/rpython/jit/backend/llsupport/guard_compat.py
+++ b/rpython/jit/backend/llsupport/guard_compat.py
@@ -97,24 +97,29 @@
return rffi.cast(lltype.Unsigned, gcref)
+P_ARG = lltype.Struct('P_ARG', ('new_gcref', llmemory.GCREF),
+ ('bchoices', lltype.Ptr(BACKEND_CHOICES)),
+ ('jump_to', lltype.Signed))
+
INVOKE_FIND_COMPATIBLE_FUNC = lltype.Ptr(lltype.FuncType(
- [lltype.Ptr(BACKEND_CHOICES), llmemory.GCREF,
- lltype.Ptr(jitframe.JITFRAME)],
+ [lltype.Ptr(P_ARG), lltype.Ptr(jitframe.JITFRAME)],
lltype.Signed))
@specialize.memo()
def make_invoke_find_compatible(cpu):
- def invoke_find_compatible(bchoices, new_gcref, jitframe):
+ def invoke_find_compatible(p_arg, jitframe):
+ bchoices = p_arg.bchoices
+ new_gcref = p_arg.new_gcref
descr = bchoices.bc_faildescr
descr = cast_gcref_to_instance(GuardCompatibleDescr, descr)
try:
- jitframe.jf_gcmap = descr._backend_gcmap
+ jitframe.jf_gcmap = bchoices.bc_gcmap
result = descr.find_compatible(cpu, new_gcref)
if result == 0:
- result = descr._backend_failure_recovery
+ result = cpu.assembler.guard_compat_recovery
else:
if result == -1:
- result = descr._backend_sequel_label
+ result = descr.adr_jump_offset
bchoices = add_in_tree(bchoices, new_gcref, result)
# ---no GC operation---
choices_addr = descr._backend_choices_addr # GC table
@@ -129,9 +134,10 @@
if not we_are_translated():
import sys, pdb
pdb.post_mortem(sys.exc_info()[2])
- result = descr._backend_failure_recovery
+ result = cpu.assembler.guard_compat_recovery
jitframe.jf_gcmap = lltype.nullptr(lltype.typeOf(jitframe.jf_gcmap).TO)
- return result
+ p_arg.bchoices = bchoices
+ p_arg.jump_to = result
return invoke_find_compatible
def add_in_tree(bchoices, new_gcref, new_asmaddr):
@@ -175,7 +181,7 @@
pairs_quicksort(addr, length)
return bchoices
-def initial_bchoices(guard_compat_descr, initial_gcref):
+def initial_bchoices(guard_compat_descr):
bchoices = lltype.malloc(BACKEND_CHOICES, 1)
bchoices.bc_faildescr = cast_instance_to_gcref(guard_compat_descr)
bchoices.bc_gc_table_tracer = lltype.nullptr(llmemory.GCREF.TO) # (*)
diff --git a/rpython/jit/backend/llsupport/rewrite.py
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -981,10 +981,8 @@
from rpython.jit.backend.llsupport import guard_compat
# don't use _gcref_index here: we need our own index for
# the _backend_choices object
- c = op.getarg(1)
- assert isinstance(c, ConstPtr)
descr = op.getdescr()
- bchoices = guard_compat.initial_bchoices(descr, c.value)
+ bchoices = guard_compat.initial_bchoices(descr)
bcindex = len(self.gcrefs_output_list)
gcref = lltype.cast_opaque_ptr(llmemory.GCREF, bchoices)
self.gcrefs_output_list.append(gcref)
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
@@ -126,8 +126,10 @@
# JMP *[RSP+array_element_2] # may jump to guard_compat_recovery
#
#
-# invoke_find_compatible(bchoices, new_gcref, jitframe):
+# invoke_find_compatible(p_arg, jitframe):
# IN PSEUDO-CODE:
+# bchoices = p_arg[0]
+# new_gcref = p_arg[1]
# result = bchoices.bc_faildescr.find_compatible(cpu, new_gcref)
# if result == 0:
# result = descr._backend_failure_recovery
@@ -183,7 +185,6 @@
mc = codebuf.MachineCodeBlockWrapper()
mc.force_frame_size(frame_size)
- mc.INT3()
if IS_X86_32: # save edi as an extra scratch register
XXX
mc.MOV_sr(3*WORD, rdi)
@@ -240,20 +241,21 @@
mc.MOV_rs(rdi, 3*WORD)
# The _backend_choices object is still referenced from [RSP+16]
- # (which becomes [RSP+8] after the POP), where it is the first of a
- # two-words array passed as argument to invoke_find_compatible().
- # The second word is the value, from RAX, which we store now.
- mc.MOV_sr(3*WORD, rax) # MOV [RSP+24], RAX
+ # (which becomes [RSP+8] after the POP), where it is the second of a
+ # three-words array passed as argument to invoke_find_compatible().
+ # The first word is the value, from RAX, which we store in (*)
+ # below.
# restore RAX and RCX
mc.MOV_rs(rcx, 1*WORD) # MOV RCX, [RSP+8]
+ mc.MOV_sr(1*WORD, rax) # MOV [RSP+8], RAX (*)
mc.POP_r(rax) # POP RAX
# save all registers to the jitframe RBP
assembler._push_all_regs_to_frame(mc, [], withfloats=True)
if IS_X86_64:
- mc.LEA_rs(rdi, 2 * WORD) # LEA RDI, [RSP+8]
+ mc.MOV_rr(rdi, regloc.esp.value) # MOV RDI, RSP
mc.MOV_rr(regloc.esi.value, # MOV RSI, RBP
regloc.ebp.value)
elif IS_X86_32:
@@ -273,13 +275,13 @@
# restore them all.
assembler._pop_all_regs_from_frame(mc, [], withfloats=True)
- # jump to 'array_element_2'. In case this goes to
- # guard_compat_recovery, we also reload the _backend_choices
- # object from 'array_element_1' (the GC may have moved it, or
- # it may be a completely new object).
+ # jump to the result, which is passed as the third word of the
+ # array. In case this goes to guard_compat_recovery, we also reload
+ # the _backend_choices object from the second word of the array (the
+ # GC may have moved it, or it may be a completely new object).
if IS_X86_64:
- mc.MOV_rs(r11, 1*WORD) # MOV R11, [RSP+8]
- mc.JMP_s(2*WORD) # JMP *[RSP+16]
+ mc.MOV_rs(r11, 0) # MOV R11, [RSP]
+ mc.JMP_s(2 * WORD) # JMP *[RSP+16]
elif IS_X86_32:
XXX
mc.JMP_s(0)
diff --git a/rpython/jit/backend/x86/test/test_compatible.py
b/rpython/jit/backend/x86/test/test_compatible.py
--- a/rpython/jit/backend/x86/test/test_compatible.py
+++ b/rpython/jit/backend/x86/test/test_compatible.py
@@ -32,14 +32,16 @@
mc.SUB(regloc.esp, regloc.imm(144 - 2*WORD)) # make a frame, and align
stack
mc.MOV(regloc.ebp, regloc.ecx)
#
+ mc.MOV(regloc.ecx, regloc.imm(0xdddd))
mc.PUSH(regloc.imm(0xaaaa))
# jump to guard_compat_search_tree, but carefully: don't overwrite R11
mc.MOV(regloc.esi, regloc.imm(cpu.assembler.guard_compat_search_tree))
mc.JMP_r(regloc.esi.value)
+ mc.INT3()
sequel = mc.get_relative_pos()
#
mc.force_frame_size(144)
- mc.SUB(regloc.eax, regloc.edx)
+ mc.SUB(regloc.eax, regloc.ecx)
mc.ADD(regloc.esp, regloc.imm(144 - 2*WORD))
mc.POP(regloc.ebp)
mc.RET()
@@ -61,8 +63,7 @@
rawstart + 4 * WORD)
guard_compat_descr = GuardCompatibleDescr()
- bchoices = initial_bchoices(guard_compat_descr,
- rffi.cast(llmemory.GCREF, 111111))
+ bchoices = initial_bchoices(guard_compat_descr)
llop.raw_store(lltype.Void, rawstart, 3 * WORD, bchoices)
class FakeGuardToken:
@@ -78,6 +79,10 @@
lltype.nullptr(llmemory.GCREF.TO),
9999)
+ # fill in the first choice manually
+ bchoices.bc_list[0].gcref = r_uint(111111)
+ bchoices.bc_list[0].asmaddr = rawstart + sequel
+
# ---- ready ----
frame_info = lltype.malloc(jitframe.JITFRAMEINFO, flavor='raw')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit