VirtualBox

Changeset 102569 in vbox for trunk


Ignore:
Timestamp:
Dec 11, 2023 1:37:11 PM (10 months ago)
Author:
vboxsync
Message:

VMM/IEM: Little unmap assertion fix / optimization. bugref:10371

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py

    r102510 r102569  
    271271        # collections as we go along.
    272272        #
     273
    273274        def freeVariable(aoStmts, iStmt, oVarInfo, dFreedVars, dVars, fIncludeReferences = True):
    274275            sVarName = oVarInfo.oStmt.sVarName;
     
    368369                        if oVarInfo.isArg():
    369370                            self.raiseProblem('Unused argument variable: %s' % (oVarInfo.oStmt.sVarName,));
     371
     372                elif oStmt.sName in ('IEM_MC_MEM_COMMIT_AND_UNMAP_RW', 'IEM_MC_MEM_COMMIT_AND_UNMAP_RO',
     373                                     'IEM_MC_MEM_COMMIT_AND_UNMAP_WO', 'IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO',
     374                                     'IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO'):
     375                    #
     376                    # The unmap info variable passed to IEM_MC_MEM_COMMIT_AND_UNMAP_RW
     377                    # and friends is implictly freed and we must make sure it wasn't
     378                    # used any later.  IEM_MC_MEM_COMMIT_AND_UNMAP_FOR_FPU_STORE_WO takes
     379                    # an additional a_u16FSW argument, which receives the same treatement.
     380                    #
     381                    for sParam in oStmt.asParams:
     382                        oVarInfo = dVars.get(sParam);
     383                        if oVarInfo:
     384                            dFreedVars[sParam] = oVarInfo;
     385                            del dVars[sParam];
     386                        else:
     387                            self.raiseProblem('Variable %s was used after implictly frees by %s!' % (sParam, oStmt.sName,));
    370388                else:
    371389                    #
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r102558 r102569  
    37753775 *                          been allocated as such already and won't need moving,
    37763776 *                          just freeing.
     3777 * @param   fKeepVars       Mask of variables that should keep their register
     3778 *                          assignments.  Caller must take care to handle these.
    37773779 */
    37783780DECL_HIDDEN_THROW(uint32_t)
    3779 iemNativeRegMoveAndFreeAndFlushAtCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cArgs)
     3781iemNativeRegMoveAndFreeAndFlushAtCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cArgs, uint32_t fKeepVars = 0)
    37803782{
    37813783    Assert(cArgs <= IEMNATIVE_CALL_MAX_ARG_COUNT);
     3784
     3785    /* fKeepVars will reduce this mask. */
     3786    uint32_t fRegsToFree = IEMNATIVE_CALL_VOLATILE_GREG_MASK;
    37823787
    37833788    /*
     
    38113816                    Assert(pReNative->Core.bmVars & RT_BIT_32(idxVar));
    38123817                    Assert(pReNative->Core.aVars[idxVar].idxReg == idxReg);
    3813                     Log12(("iemNativeRegMoveAndFreeAndFlushAtCall: idxVar=%d enmKind=%d idxReg=%d\n",
    3814                            idxVar, pReNative->Core.aVars[idxVar].enmKind, pReNative->Core.aVars[idxVar].idxReg));
    3815                     if (pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack)
    3816                         pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX;
     3818                    if (!(RT_BIT_32(idxVar) & fKeepVars))
     3819                    {
     3820                        Log12(("iemNativeRegMoveAndFreeAndFlushAtCall: idxVar=%d enmKind=%d idxReg=%d\n",
     3821                               idxVar, pReNative->Core.aVars[idxVar].enmKind, pReNative->Core.aVars[idxVar].idxReg));
     3822                        if (pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack)
     3823                            pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX;
     3824                        else
     3825                            off = iemNativeRegMoveOrSpillStackVar(pReNative, off, idxVar);
     3826                    }
    38173827                    else
    3818                         off = iemNativeRegMoveOrSpillStackVar(pReNative, off, idxVar);
     3828                        fRegsToFree &= ~RT_BIT_32(idxReg);
    38193829                    continue;
    38203830                }
     
    38443854     * Do the actual freeing.
    38453855     */
    3846     if (pReNative->Core.bmHstRegs & IEMNATIVE_CALL_VOLATILE_GREG_MASK)
    3847         Log12(("iemNativeRegMoveAndFreeAndFlushAtCall: bmHstRegs %#x -> %#x\n", pReNative->Core.bmHstRegs, pReNative->Core.bmHstRegs & ~IEMNATIVE_CALL_VOLATILE_GREG_MASK));
    3848     pReNative->Core.bmHstRegs &= ~IEMNATIVE_CALL_VOLATILE_GREG_MASK;
     3856    if (pReNative->Core.bmHstRegs & fRegsToFree)
     3857        Log12(("iemNativeRegMoveAndFreeAndFlushAtCall: bmHstRegs %#x -> %#x\n",
     3858               pReNative->Core.bmHstRegs, pReNative->Core.bmHstRegs & ~fRegsToFree));
     3859    pReNative->Core.bmHstRegs &= ~fRegsToFree;
    38493860
    38503861    /* If there are guest register shadows in any call-volatile register, we
    38513862       have to clear the corrsponding guest register masks for each register. */
    3852     uint32_t fHstRegsWithGstShadow = pReNative->Core.bmHstRegsWithGstShadow & IEMNATIVE_CALL_VOLATILE_GREG_MASK;
     3863    uint32_t fHstRegsWithGstShadow = pReNative->Core.bmHstRegsWithGstShadow & fRegsToFree;
    38533864    if (fHstRegsWithGstShadow)
    38543865    {
     
    62896300 *                      Will throw VERR_IEM_VAR_NOT_INITIALIZED if this is not
    62906301 *                      the case.
    6291  */
    6292 DECL_HIDDEN_THROW(uint8_t) iemNativeVarRegisterAcquire(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar,
    6293                                                        uint32_t *poff, bool fInitialized = false)
     6302 * @param  idxRegPref   Preferred register number or UINT8_MAX.
     6303 */
     6304DECL_HIDDEN_THROW(uint8_t) iemNativeVarRegisterAcquire(PIEMRECOMPILERSTATE pReNative, uint8_t idxVar, uint32_t *poff,
     6305                                                       bool fInitialized = false, uint8_t idxRegPref = UINT8_MAX)
    62946306{
    62956307    IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVar);
     
    63406352        Log11(("iemNativeVarRegisterAcquire: idxVar=%u idxReg=%u (matching arg %u)\n", idxVar, idxReg, uArgNo));
    63416353    }
    6342     else
     6354    else if (   idxRegPref < RT_ELEMENTS(pReNative->Core.aHstRegs)
     6355             || (pReNative->Core.bmHstRegs & RT_BIT_32(idxRegPref)))
    63436356    {
    63446357        uint32_t const fNotArgsMask = ~g_afIemNativeCallRegs[RT_MIN(pReNative->cArgs, IEMNATIVE_CALL_ARG_GREG_COUNT)];
     
    63636376            Log11(("iemNativeVarRegisterAcquire: idxVar=%u idxReg=%u (slow, uArgNo=%u)\n", idxVar, idxReg, uArgNo));
    63646377        }
     6378    }
     6379    else
     6380    {
     6381        idxReg = idxRegPref;
     6382        iemNativeRegClearGstRegShadowing(pReNative, idxReg, *poff);
     6383        Log11(("iemNativeVarRegisterAcquire: idxVar=%u idxReg=%u (preferred)\n", idxVar, idxReg));
    63656384    }
    63666385    iemNativeRegMarkAllocated(pReNative, idxReg, kIemNativeWhat_Var, idxVar);
     
    1014510164        default: AssertFailed();
    1014610165    }
     10166#else
     10167    RT_NOREF(fAccess);
    1014710168#endif
    1014810169
     
    1015910180    /*
    1016010181     * Move/spill/flush stuff out of call-volatile registers.
     10182     *
     10183     * We exclude any register holding the bUnmapInfo variable, as we'll be
     10184     * checking it after returning from the call and will free it afterwards.
    1016110185     */
    1016210186    /** @todo save+restore active registers and maybe guest shadows in miss
    1016310187     *        scenario. */
    10164     off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 0 /* vacate all non-volatile regs */);
     10188    off = iemNativeRegMoveAndFreeAndFlushAtCall(pReNative, off, 0 /* vacate all non-volatile regs */, RT_BIT_32(idxVarUnmapInfo));
    1016510189
    1016610190    /*
    1016710191     * If idxVarUnmapInfo is zero, we can skip all this. Otherwise we'll have
    1016810192     * to call the unmap helper function.
    10169      */
    10170 //pReNative->pInstrBuf[off++] = 0xcc;
    10171     RT_NOREF(fAccess);
    10172 
     10193     *
     10194     * The likelyhood of it being zero is higher than for the TLB hit when doing
     10195     * the mapping, as a TLB miss for an well aligned and unproblematic memory
     10196     * access should also end up with a mapping that won't need special unmapping.
     10197     */
     10198    /** @todo Go over iemMemMapJmp and implement the no-unmap-needed case!  That
     10199     *        should speed up things for the pure interpreter as well when TLBs
     10200     *        are enabled. */
    1017310201#ifdef RT_ARCH_AMD64
    1017410202    if (pReNative->Core.aVars[idxVarUnmapInfo].idxReg == UINT8_MAX)
     
    1018510213#endif
    1018610214    {
    10187         uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxVarUnmapInfo, &off);
     10215        uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxVarUnmapInfo, &off,
     10216                                                              true /*fInitialized*/, IEMNATIVE_CALL_ARG1_GREG /*idxRegPref*/);
    1018810217        off = iemNativeEmitTestAnyBitsInGpr8(pReNative, off, idxVarReg, 0xff);
    1018910218        iemNativeVarRegisterRelease(pReNative, idxVarUnmapInfo);
     
    1020110230#endif
    1020210231
    10203     /* IEMNATIVE_CALL_ARG1_GREG = idxVarUnmapInfo */
     10232    /* IEMNATIVE_CALL_ARG1_GREG = idxVarUnmapInfo (first!) */
    1020410233    off = iemNativeEmitLoadArgGregFromStackVar(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxVarUnmapInfo);
    1020510234
     
    1020910238    /* Done setting up parameters, make the call. */
    1021010239    off = iemNativeEmitCallImm(pReNative, off, pfnFunction);
     10240
     10241    /* The bUnmapInfo variable is implictly free by these MCs. */
     10242    iemNativeVarFreeLocal(pReNative, idxVarUnmapInfo);
    1021110243
    1021210244    /*
  • trunk/src/VBox/VMM/include/IEMMc.h

    r102510 r102569  
    22602260/** Commits the memory and unmaps guest memory previously mapped RW.
    22612261 * @remarks     May return.
     2262 * @note        Implictly frees the a_bMapInfo variable.
    22622263 */
    22632264#ifndef IEM_WITH_SETJMP
     
    22692270/** Commits the memory and unmaps guest memory previously mapped W.
    22702271 * @remarks     May return.
     2272 * @note        Implictly frees the a_bMapInfo variable.
    22712273 */
    22722274#ifndef IEM_WITH_SETJMP
     
    22782280/** Commits the memory and unmaps guest memory previously mapped R.
    22792281 * @remarks     May return.
     2282 * @note        Implictly frees the a_bMapInfo variable.
    22802283 */
    22812284#ifndef IEM_WITH_SETJMP
     
    22942297 *
    22952298 * @remarks     May in theory return - for now.
     2299 * @note        Implictly frees both the a_bMapInfo and a_u16FSW variables.
    22962300 */
    22972301#ifndef IEM_WITH_SETJMP
     
    23152319#endif
    23162320
    2317 /** Rolls back (conceptually only, assumes no writes) and unmaps the guest  memory. */
     2321/** Rolls back (conceptually only, assumes no writes) and unmaps the guest memory.
     2322 * @note        Implictly frees the a_bMapInfo variable. */
    23182323#ifndef IEM_WITH_SETJMP
    23192324# define IEM_MC_MEM_ROLLBACK_AND_UNMAP_WO(a_bMapInfo)       iemMemRollbackAndUnmap(pVCpu, a_bMapInfo)
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r102512 r102569  
    32153215        Assert(!(RT_BIT_32(idxRegVar) & IEMNATIVE_CALL_VOLATILE_GREG_MASK));
    32163216        if (!offAddend)
    3217             off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegArg, idxRegVar);
     3217        {
     3218            if (idxRegArg != idxRegVar)
     3219                off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegArg, idxRegVar);
     3220        }
    32183221        else
    32193222            off = iemNativeEmitLoadGprFromGprWithAddend(pReNative, off, idxRegArg, idxRegVar, offAddend);
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