VirtualBox

Changeset 72579 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Jun 16, 2018 2:32:26 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
123073
Message:

EM: Implemented a very simple history record replacement strategy. bugref:9044

File:
1 edited

Legend:

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

    r72570 r72579  
    529529     */
    530530    AssertCompile(RT_ELEMENTS(pVCpu->em.s.aExitRecords) == 1024);
    531 #define EM_EXIT_RECORDS_IDX_MASK 1023
     531#define EM_EXIT_RECORDS_IDX_MASK 0x3ff
    532532    uintptr_t  idxSlot  = ((uintptr_t)uFlatPC >> 1) & EM_EXIT_RECORDS_IDX_MASK;
    533533    PEMEXITREC pExitRec = &pVCpu->em.s.aExitRecords[idxSlot];
     
    537537        pHistEntry->idxSlot = (uint32_t)idxSlot;
    538538        if (pExitRec->uFlagsAndType == uFlagsAndType)
     539        {
    539540            pExitRec->uLastExitNo = uExitNo;
     541            STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecHits[0]);
     542        }
    540543        else
     544        {
     545            STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecTypeChanged[0]);
    541546            return emHistoryRecordInit(pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     547        }
    542548    }
    543549    else if (pExitRec->enmAction == EMEXITACTION_FREE_RECORD)
     550    {
     551        STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecNew[0]);
    544552        return emHistoryRecordInitNew(pVCpu, pHistEntry, idxSlot, pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     553    }
    545554    else
    546555    {
    547556        /*
    548          * Collision. Figure out later.
     557         * Collision.  We calculate a new hash for stepping away from the first,
     558         * doing up to 8 steps away before replacing the least recently used record.
    549559         */
    550         return NULL;
    551     }
    552 
     560        uintptr_t idxOldest     = idxSlot;
     561        uint64_t  uOldestExitNo = pExitRec->uLastExitNo;
     562        unsigned  iOldestStep   = 0;
     563        unsigned  iStep         = 1;
     564        uintptr_t const idxAdd  = (uintptr_t)(uFlatPC >> 11) & (EM_EXIT_RECORDS_IDX_MASK / 4);
     565        for (;;)
     566        {
     567            Assert(iStep < RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     568            AssertCompile(RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecNew)         == RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     569            AssertCompile(RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecReplaced)    == RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     570            AssertCompile(RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecTypeChanged) == RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecHits));
     571
     572            /* Step to the next slot. */
     573            idxSlot += idxAdd;
     574            idxSlot &= EM_EXIT_RECORDS_IDX_MASK;
     575            pExitRec = &pVCpu->em.s.aExitRecords[idxSlot];
     576
     577            /* Does it match? */
     578            if (pExitRec->uFlatPC == uFlatPC)
     579            {
     580                Assert(pExitRec->enmAction != EMEXITACTION_FREE_RECORD);
     581                pHistEntry->idxSlot = (uint32_t)idxSlot;
     582                if (pExitRec->uFlagsAndType == uFlagsAndType)
     583                {
     584                    pExitRec->uLastExitNo = uExitNo;
     585                    STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecHits[iStep]);
     586                    break;
     587                }
     588                STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecTypeChanged[iStep]);
     589                return emHistoryRecordInit(pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     590            }
     591
     592            /* Is it free? */
     593            if (pExitRec->enmAction == EMEXITACTION_FREE_RECORD)
     594            {
     595                STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecNew[iStep]);
     596                return emHistoryRecordInitNew(pVCpu, pHistEntry, idxSlot, pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     597            }
     598
     599            /* Is it the least recently used one? */
     600            if (pExitRec->uLastExitNo < uOldestExitNo)
     601            {
     602                uOldestExitNo = pExitRec->uLastExitNo;
     603                idxOldest     = idxSlot;
     604                iOldestStep   = iStep;
     605            }
     606
     607            /* Next iteration? */
     608            iStep++;
     609            Assert(iStep < RT_ELEMENTS(pVCpu->em.s.aStatHistoryRecReplaced));
     610            if (RT_LIKELY(iStep < 8 + 1))
     611            { /* likely */ }
     612            else
     613            {
     614                /* Replace the least recently used slot. */
     615                STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecReplaced[iOldestStep]);
     616                pExitRec = &pVCpu->em.s.aExitRecords[idxOldest];
     617                return emHistoryRecordInitNew(pVCpu, pHistEntry, idxOldest, pExitRec, uFlatPC, uFlagsAndType, uExitNo);
     618            }
     619        }
     620    }
    553621
    554622    /*
Note: See TracChangeset for help on using the changeset viewer.

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