VirtualBox

Changeset 103376 in vbox


Ignore:
Timestamp:
Feb 15, 2024 1:09:23 AM (10 months ago)
Author:
vboxsync
Message:

VMM/IEM: Experimental alternative to throw/longjmp when executing native TBs. bugref:10370

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veHlpA.asm

    r102737 r103376  
    3737extern NAME(iemThreadedFunc_BltIn_LogCpuStateWorker)
    3838extern NAME(iemNativeHlpCheckTlbLookup)
     39
     40
     41;;
     42; This does the epilogue of a TB, given the RBP for the frame and eax value to return.
     43;
     44; @param    pFrame  (gcc:rdi, msc:rcx)  The frame pointer.
     45; @param    rc      (gcc:esi, msc:edx)  The return value.
     46;
     47; @note This doesn't really work for MSC since xmm6 thru xmm15 are non-volatile
     48;       and since we don't save them in the TB prolog we'll potentially return
     49;       with different values if any functions on the calling stack uses them
     50;       as they're unlikely to restore them till they return.
     51;
     52;       For the GCC calling convention all xmm registers are volatile and the
     53;       only worry would be someone fiddling the control bits of MXCSR or FCW
     54;       without restoring them.  This is highly unlikely, unless we're doing
     55;       it ourselves, I think.
     56;
     57BEGINPROC   iemNativeTbLongJmp
     58%ifdef ASM_CALL64_MSC
     59        mov     rbp, rcx
     60        mov     eax, edx
     61%else
     62        mov     rbp, rdi
     63        mov     eax, esi
     64%endif
     65        SEH64_PUSH_xBP      ; non-sense, but whatever.
     66SEH64_END_PROLOGUE
     67
     68        ;
     69        ; This must exactly match what iemNativeEmitEpilog does.
     70        ;
     71%ifdef ASM_CALL64_MSC
     72        lea     rsp, [rbp - 5 * 8]
     73%else
     74        lea     rsp, [rbp - 7 * 8]
     75%endif
     76        pop     r15
     77        pop     r14
     78        pop     r13
     79        pop     r12
     80%ifdef ASM_CALL64_MSC
     81        pop     rdi
     82        pop     rsi
     83%endif
     84        pop     rbx
     85        leave
     86        ret
     87ENDPROC     iemNativeTbLongJmp
     88
    3989
    4090
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r103375 r103376  
    59485948    pbCodeBuf[off++] = 0x50 + X86_GREG_x15 - 8;
    59495949
     5950# ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     5951    /* Save the frame pointer. */
     5952    off = iemNativeEmitStoreGprToVCpuU64Ex(pbCodeBuf, off, X86_GREG_xBP, RT_UOFFSETOF(VMCPUCC, iem.s.pvTbFramePointerR3));
     5953# endif
     5954
    59505955    off = iemNativeEmitSubGprImm(pReNative, off,    /* sub rsp, byte 28h */
    59515956                                 X86_GREG_xSP,
     
    60026007    /* mov r27, r1  */
    60036008    off = iemNativeEmitLoadGprFromGpr(pReNative, off, IEMNATIVE_REG_FIXED_PCPUMCTX, IEMNATIVE_CALL_ARG1_GREG);
     6009
     6010# ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     6011    /* Save the frame pointer. */
     6012    off = iemNativeEmitStoreGprToVCpuU64Ex(pbCodeBuf, off, ARMV8_A64_REG_BP, RT_UOFFSETOF(VMCPUCC, iem.s.pvTbFramePointerR3),
     6013                                           ARMV8_A64_REG_X2);
     6014# endif
    60046015
    60056016#else
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp

    r103189 r103376  
    24852485        VBOXSTRICTRC const rcStrict = ((PFNIEMTBNATIVE)pTb->Native.paInstructions)(pVCpu, &pVCpu->cpum.GstCtx);
    24862486# endif
     2487# ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     2488        pVCpu->iem.s.pvTbFramePointerR3 = NULL;
     2489# endif
    24872490        if (RT_LIKELY(   rcStrict == VINF_SUCCESS
    24882491                      && pVCpu->iem.s.rcPassUp == VINF_SUCCESS /** @todo this isn't great. */))
     
    27362739        {
    27372740            pVCpu->iem.s.cLongJumps++;
     2741#ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     2742            pVCpu->iem.s.pvTbFramePointerR3 = NULL;
     2743#endif
    27382744            if (pVCpu->iem.s.cActiveMappings > 0)
    27392745                iemMemRollback(pVCpu);
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r103318 r103376  
    8686#endif
    8787
     88/** @def VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     89 * Enables a quicker alternative to throw/longjmp for IEM_DO_LONGJMP when
     90 * executing native translation blocks.
     91 *
     92 * This exploits the fact that we save all non-volatile registers in the TB
     93 * prologue and thus just need to do the same as the TB epilogue to get the
     94 * effect of a longjmp/throw.  Since MSC marks XMM6 thru XMM15 as
     95 * non-volatile (and does something even more crazy for ARM), this probably
     96 * won't work reliably on Windows. */
     97#if defined(DOXYGEN_RUNNING) /*|| defined(RT_ARCH_AMD64)*/
     98# define VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     99#endif
     100#ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     101# if !defined(IN_RING3) \
     102  || !defined(RT_ARCH_AMD64) \
     103  || !defined(VBOX_WITH_IEM_RECOMPILER) \
     104  || !defined(VBOX_WITH_IEM_NATIVE_RECOMPILER)
     105#  undef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     106# elif defined(RT_OS_WINDOWS)
     107#  pragma message("VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP is not safe to use on windows")
     108# endif
     109#endif
     110
     111
    88112/** @def IEM_DO_LONGJMP
    89113 *
     
    95119#if defined(IEM_WITH_SETJMP) || defined(DOXYGEN_RUNNING)
    96120# ifdef IEM_WITH_THROW_CATCH
    97 #  define IEM_DO_LONGJMP(a_pVCpu, a_rc)  throw int(a_rc)
     121#  ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     122#   define IEM_DO_LONGJMP(a_pVCpu, a_rc) do { \
     123            if ((a_pVCpu)->iem.s.pvTbFramePointerR3) \
     124                iemNativeTbLongJmp((a_pVCpu)->iem.s.pvTbFramePointerR3, (a_rc)); \
     125            throw int(a_rc); \
     126        } while (0)
     127#  else
     128#   define IEM_DO_LONGJMP(a_pVCpu, a_rc) throw int(a_rc)
     129#  endif
    98130# else
    99131#  define IEM_DO_LONGJMP(a_pVCpu, a_rc)  longjmp(*(a_pVCpu)->iem.s.CTX_SUFF(pJmpBuf), (a_rc))
     
    16501682     * This can either be one being executed or one being compiled. */
    16511683    R3PTRTYPE(PIEMTB)       pCurTbR3;
     1684#ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER_LONGJMP
     1685    /** Frame pointer for the last native TB to execute. */
     1686    R3PTRTYPE(void *)       pvTbFramePointerR3;
     1687#else
     1688    R3PTRTYPE(void *)       pvUnusedR3;
     1689#endif
    16521690    /** Fixed TB used for threaded recompilation.
    16531691     * This is allocated once with maxed-out sizes and re-used afterwards. */
     
    17981836    STAMCOUNTER             StatNativeLivenessEflOtherRequired;
    17991837
    1800     //uint64_t                au64Padding[3];
     1838    uint64_t                au64Padding[7];
    18011839    /** @} */
    18021840
     
    58375875int                 iemExecMemAllocatorInit(PVMCPU pVCpu, uint64_t cbMax, uint64_t cbInitial, uint32_t cbChunk);
    58385876void                iemExecMemAllocatorFree(PVMCPU pVCpu, void *pv, size_t cb);
     5877DECLASM(DECL_NO_RETURN(void)) iemNativeTbLongJmp(void *pvFramePointer, int rc) RT_NOEXCEPT;
    58395878
    58405879
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette