VirtualBox

Changeset 104362 in vbox


Ignore:
Timestamp:
Apr 18, 2024 3:29:48 PM (10 months ago)
Author:
vboxsync
Message:

VMM/IEM: Don't unroll loops in TBs. bugref:10653

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp

    r104357 r104362  
    21522152     * Case 1: We've branched (RIP changed).
    21532153     *
     2154     * Loop check:  If the new PC (GCPhysPC) is within a opcode range of this
     2155     *              TB, end the TB here as it is most likely a loop and if it
     2156     *              made sense to unroll it, the guest code compiler should've
     2157     *              done it already.
     2158     *
    21542159     * Sub-case 1a: Same page, no TLB load (fTbCrossedPage is false).
    21552160     *         Req: 1 extra range, no extra phys.
     
    22102215                AssertCompile(RT_ELEMENTS(pTb->aGCPhysPages) == 2);
    22112216                RTGCPHYS const GCPhysNew = pVCpu->iem.s.GCPhysInstrBuf & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK;
     2217                uint8_t        idxPhysPage;
    22122218                if ((pTb->GCPhysPc & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK) == GCPhysNew)
    2213                     pTb->aRanges[idxRange].idxPhysPage = 0;
    2214                 else if (   pTb->aGCPhysPages[0] == NIL_RTGCPHYS
    2215                          || pTb->aGCPhysPages[0] == GCPhysNew)
     2219                    pTb->aRanges[idxRange].idxPhysPage = idxPhysPage = 0;
     2220                else if (pTb->aGCPhysPages[0] == NIL_RTGCPHYS)
    22162221                {
    22172222                    pTb->aGCPhysPages[0] = GCPhysNew;
    22182223                    pTb->aRanges[idxRange].idxPhysPage = 1;
     2224                    idxPhysPage = UINT8_MAX;
    22192225                }
    2220                 else if (   pTb->aGCPhysPages[1] == NIL_RTGCPHYS
    2221                          || pTb->aGCPhysPages[1] == GCPhysNew)
     2226                else if (pTb->aGCPhysPages[0] == GCPhysNew)
     2227                    pTb->aRanges[idxRange].idxPhysPage = idxPhysPage = 1;
     2228                else if (pTb->aGCPhysPages[1] == NIL_RTGCPHYS)
    22222229                {
    22232230                    pTb->aGCPhysPages[1] = GCPhysNew;
    22242231                    pTb->aRanges[idxRange].idxPhysPage = 2;
     2232                    idxPhysPage = UINT8_MAX;
    22252233                }
     2234                else if (pTb->aGCPhysPages[1] == GCPhysNew)
     2235                    pTb->aRanges[idxRange].idxPhysPage = idxPhysPage = 2;
    22262236                else
    22272237                {
    22282238                    Log8(("%04x:%08RX64: out of aGCPhysPages entires after branch\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip));
    22292239                    return false;
     2240                }
     2241
     2242                /* Loop check: We weave the loop check in here to optimize the lookup. */
     2243                if (idxPhysPage != UINT8_MAX)
     2244                {
     2245                    uint32_t const offPhysPc = pVCpu->iem.s.offCurInstrStart;
     2246                    for (uint8_t idxLoopRange = 0; idxLoopRange < idxRange; idxLoopRange++)
     2247                        if (   pTb->aRanges[idxLoopRange].idxPhysPage == idxPhysPage
     2248                            &&   offPhysPc - (uint32_t)pTb->aRanges[idxLoopRange].offPhysPage
     2249                               < (uint32_t)pTb->aRanges[idxLoopRange].cbOpcodes)
     2250                        {
     2251                            Log8(("%04x:%08RX64: loop detected after branch\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip));
     2252                            STAM_COUNTER_INC(&pVCpu->iem.s.StatTbLoopInTbDetected);
     2253                            return false;
     2254                        }
    22302255                }
    22312256
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r104361 r104362  
    450450        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatCheckNeedCsLimChecking, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
    451451                        "Needing CS.LIM checking TB after branch or on page crossing", "/IEM/CPU%u/re/CheckTbNeedCsLimChecking", idCpu);
     452# ifdef VBOX_WITH_STATISTICS
     453        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatTbLoopInTbDetected, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
     454                        "Detected loop within TB", "/IEM/CPU%u/re/LoopInTbDetected", idCpu);
     455#endif
    452456
    453457        STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatNativeExecMemInstrBufAllocFailed, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT,
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r104361 r104362  
    19091909    /** Statistics: Times a jump or page crossing required a TB with CS.LIM checking. */
    19101910    STAMCOUNTER             StatCheckNeedCsLimChecking;
     1911    /** Statistics: Times a loop was detected within a TB.. */
     1912    STAMCOUNTER             StatTbLoopInTbDetected;
    19111913    /** Exec memory allocator statistics: Number of times allocaintg executable memory failed. */
    19121914    STAMCOUNTER             StatNativeExecMemInstrBufAllocFailed;
     
    20692071    STAMCOUNTER             StatNativeTbExitObsoleteTb;
    20702072
    2071     uint64_t                au64Padding[5];
     2073    uint64_t                au64Padding[4];
    20722074    /** @} */
    20732075
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