Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit