Changeset 72579 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jun 16, 2018 2:32:26 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123073
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r72570 r72579 529 529 */ 530 530 AssertCompile(RT_ELEMENTS(pVCpu->em.s.aExitRecords) == 1024); 531 #define EM_EXIT_RECORDS_IDX_MASK 1023531 #define EM_EXIT_RECORDS_IDX_MASK 0x3ff 532 532 uintptr_t idxSlot = ((uintptr_t)uFlatPC >> 1) & EM_EXIT_RECORDS_IDX_MASK; 533 533 PEMEXITREC pExitRec = &pVCpu->em.s.aExitRecords[idxSlot]; … … 537 537 pHistEntry->idxSlot = (uint32_t)idxSlot; 538 538 if (pExitRec->uFlagsAndType == uFlagsAndType) 539 { 539 540 pExitRec->uLastExitNo = uExitNo; 541 STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecHits[0]); 542 } 540 543 else 544 { 545 STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecTypeChanged[0]); 541 546 return emHistoryRecordInit(pExitRec, uFlatPC, uFlagsAndType, uExitNo); 547 } 542 548 } 543 549 else if (pExitRec->enmAction == EMEXITACTION_FREE_RECORD) 550 { 551 STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecNew[0]); 544 552 return emHistoryRecordInitNew(pVCpu, pHistEntry, idxSlot, pExitRec, uFlatPC, uFlagsAndType, uExitNo); 553 } 545 554 else 546 555 { 547 556 /* 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. 549 559 */ 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 } 553 621 554 622 /*
Note:
See TracChangeset
for help on using the changeset viewer.