Changeset 102557 in vbox
- Timestamp:
- Dec 8, 2023 10:13:00 PM (15 months ago)
- svn:sync-xref-src-repo-rev:
- 160703
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
r102471 r102557 3064 3064 'IEM_MC_POP_U32': (McBlock.parseMcGeneric, True, False, ), 3065 3065 'IEM_MC_POP_U64': (McBlock.parseMcGeneric, True, False, ), 3066 'IEM_MC_PREPARE_AVX_USAGE': (McBlock.parseMcGeneric, False, False,),3067 'IEM_MC_PREPARE_FPU_USAGE': (McBlock.parseMcGeneric, False, False,),3068 'IEM_MC_PREPARE_SSE_USAGE': (McBlock.parseMcGeneric, False, False,),3066 'IEM_MC_PREPARE_AVX_USAGE': (McBlock.parseMcGeneric, False, True), 3067 'IEM_MC_PREPARE_FPU_USAGE': (McBlock.parseMcGeneric, False, True), 3068 'IEM_MC_PREPARE_SSE_USAGE': (McBlock.parseMcGeneric, False, True), 3069 3069 'IEM_MC_PUSH_FPU_RESULT': (McBlock.parseMcGeneric, True, False, ), 3070 3070 'IEM_MC_PUSH_FPU_RESULT_MEM_OP': (McBlock.parseMcGeneric, True, False, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r102555 r102557 512 512 AssertMsgReturn(cbReq > 32 && cbReq < _512K, ("%#x\n", cbReq), NULL); 513 513 514 /* 515 * Adjust the request size so it'll fit the allocator alignment/whatnot. 516 * 517 * For the RTHeapSimple allocator this means to follow the logic described 518 * in iemExecMemAllocatorGrow and attempt to allocate it from one of the 519 * existing chunks if we think we've got sufficient free memory around. 520 * 521 * While for the alternative one we just align it up to a whole unit size. 522 */ 514 515 for (unsigned iIteration = 0;; iIteration++) 516 { 517 /* 518 * Adjust the request size so it'll fit the allocator alignment/whatnot. 519 * 520 * For the RTHeapSimple allocator this means to follow the logic described 521 * in iemExecMemAllocatorGrow and attempt to allocate it from one of the 522 * existing chunks if we think we've got sufficient free memory around. 523 * 524 * While for the alternative one we just align it up to a whole unit size. 525 */ 523 526 #ifdef IEMEXECMEM_USE_ALT_SUB_ALLOCATOR 524 cbReq = RT_ALIGN_32(cbReq, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE);527 cbReq = RT_ALIGN_32(cbReq, IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SIZE); 525 528 #else 526 cbReq = RT_ALIGN_32(cbReq + pExecMemAllocator->cbHeapBlockHdr, 64) - pExecMemAllocator->cbHeapBlockHdr; 527 #endif 528 if (cbReq <= pExecMemAllocator->cbFree) 529 { 530 uint32_t const cChunks = pExecMemAllocator->cChunks; 531 uint32_t const idxChunkHint = pExecMemAllocator->idxChunkHint < cChunks ? pExecMemAllocator->idxChunkHint : 0; 532 for (uint32_t idxChunk = idxChunkHint; idxChunk < cChunks; idxChunk++) 529 cbReq = RT_ALIGN_32(cbReq + pExecMemAllocator->cbHeapBlockHdr, 64) - pExecMemAllocator->cbHeapBlockHdr; 530 #endif 531 if (cbReq <= pExecMemAllocator->cbFree) 533 532 { 533 uint32_t const cChunks = pExecMemAllocator->cChunks; 534 uint32_t const idxChunkHint = pExecMemAllocator->idxChunkHint < cChunks ? pExecMemAllocator->idxChunkHint : 0; 535 for (uint32_t idxChunk = idxChunkHint; idxChunk < cChunks; idxChunk++) 536 { 537 void *pvRet = iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk, cbReq); 538 if (pvRet) 539 return pvRet; 540 } 541 for (uint32_t idxChunk = 0; idxChunk < idxChunkHint; idxChunk++) 542 { 543 void *pvRet = iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk, cbReq); 544 if (pvRet) 545 return pvRet; 546 } 547 } 548 549 /* 550 * Can we grow it with another chunk? 551 */ 552 if (pExecMemAllocator->cChunks < pExecMemAllocator->cMaxChunks) 553 { 554 int rc = iemExecMemAllocatorGrow(pVCpu, pExecMemAllocator); 555 AssertLogRelRCReturn(rc, NULL); 556 557 uint32_t const idxChunk = pExecMemAllocator->cChunks - 1; 534 558 void *pvRet = iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk, cbReq); 535 559 if (pvRet) 536 560 return pvRet; 561 AssertFailed(); 537 562 } 538 for (uint32_t idxChunk = 0; idxChunk < idxChunkHint; idxChunk++) 563 564 /* 565 * Try prune native TBs once. 566 */ 567 if (iIteration == 0) 568 iemTbAllocatorFreeupNativeSpace(pVCpu, cbReq / sizeof(IEMNATIVEINSTR)); 569 else 539 570 { 540 void *pvRet = iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk, cbReq); 541 if (pvRet) 542 return pvRet; 571 /** @todo stats... */ 572 return NULL; 543 573 } 544 574 } 545 575 546 /*547 * Can we grow it with another chunk?548 */549 if (pExecMemAllocator->cChunks < pExecMemAllocator->cMaxChunks)550 {551 int rc = iemExecMemAllocatorGrow(pVCpu, pExecMemAllocator);552 AssertLogRelRCReturn(rc, NULL);553 554 uint32_t const idxChunk = pExecMemAllocator->cChunks - 1;555 void *pvRet = iemExecMemAllocatorAllocInChunk(pExecMemAllocator, idxChunk, cbReq);556 if (pvRet)557 return pvRet;558 AssertFailed();559 }560 561 /* What now? Prune native translation blocks from the cache? */562 AssertFailed();563 return NULL;564 576 } 565 577 -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp
r102394 r102557 967 967 * function before making any TB or executable memory allocations respectively. 968 968 */ 969 void iemTbAllocatorProcessDelayedFrees(PVMCPU pVCpu, PIEMTBALLOCATOR pTbAllocator)969 void iemTbAllocatorProcessDelayedFrees(PVMCPUCC pVCpu, PIEMTBALLOCATOR pTbAllocator) 970 970 { 971 971 PIEMTB pTb = pTbAllocator->pDelayedFreeHead; … … 975 975 PIEMTB const pTbNext = pTb->pNext; 976 976 Assert(pVCpu->iem.s.pCurTbR3 != pTb); 977 iemTbAlloc torScheduleForFree(pVCpu, pTb);977 iemTbAllocatorFree(pVCpu, pTb); 978 978 pTb = pTbNext; 979 979 } … … 1169 1169 } 1170 1170 1171 1172 /** 1173 * This is called when we're out of space for native TBs. 1174 * 1175 * This uses a variation on the pruning in iemTbAllocatorAllocSlow. 1176 * The difference is that we only prune native TBs and will only free any if 1177 * there are least two in a group. The conditions under which we're called are 1178 * different - there will probably be free TBs in the table when we're called. 1179 * Therefore we increase the group size and max scan length, though we'll stop 1180 * scanning once we've reached the requested size (@a cNeededInstrs) and freed 1181 * up at least 8 TBs. 1182 */ 1183 void iemTbAllocatorFreeupNativeSpace(PVMCPUCC pVCpu, uint32_t cNeededInstrs) 1184 { 1185 PIEMTBALLOCATOR const pTbAllocator = pVCpu->iem.s.pTbAllocatorR3; 1186 AssertReturnVoid(pTbAllocator && pTbAllocator->uMagic == IEMTBALLOCATOR_MAGIC); 1187 1188 STAM_REL_PROFILE_START(&pTbAllocator->StatPruneNative, a); 1189 1190 /* 1191 * Flush the delayed free list before we start freeing TBs indiscriminately. 1192 */ 1193 iemTbAllocatorProcessDelayedFrees(pVCpu, pTbAllocator); 1194 1195 /* 1196 * Scan and free TBs. 1197 */ 1198 uint32_t const msNow = pVCpu->iem.s.msRecompilerPollNow; 1199 uint32_t const cTbsToPrune = 128 * 8; 1200 uint32_t const cTbsPerGroup = 4 * 4; 1201 uint32_t cFreedTbs = 0; 1202 uint32_t cMaxInstrs = 0; 1203 uint32_t idxTbPruneFrom = pTbAllocator->iPruneNativeFrom & ~(uint32_t)(cTbsPerGroup - 1); 1204 for (uint32_t i = 0; i < cTbsToPrune; i += cTbsPerGroup, idxTbPruneFrom += cTbsPerGroup) 1205 { 1206 if (idxTbPruneFrom >= pTbAllocator->cTotalTbs) 1207 idxTbPruneFrom = 0; 1208 uint32_t idxChunk = IEMTBALLOC_IDX_TO_CHUNK(pTbAllocator, idxTbPruneFrom); 1209 uint32_t idxInChunk = IEMTBALLOC_IDX_TO_INDEX_IN_CHUNK(pTbAllocator, idxTbPruneFrom, idxChunk); 1210 PIEMTB pTb = &pTbAllocator->aChunks[idxChunk].paTbs[idxInChunk]; 1211 uint32_t cMsAge = pTb->fFlags & IEMTB_F_TYPE_NATIVE ? msNow - pTb->msLastUsed : msNow; 1212 uint8_t cNativeTbs = (pTb->fFlags & IEMTB_F_TYPE_NATIVE) != 0; 1213 1214 for (uint32_t j = 1, idxChunk2 = idxChunk, idxInChunk2 = idxInChunk + 1; j < cTbsPerGroup; j++, idxInChunk2++) 1215 { 1216 if (idxInChunk2 < pTbAllocator->cTbsPerChunk) 1217 { /* likely */ } 1218 else 1219 { 1220 idxInChunk2 = 0; 1221 idxChunk2 += 1; 1222 if (idxChunk2 >= pTbAllocator->cAllocatedChunks) 1223 idxChunk2 = 0; 1224 } 1225 PIEMTB const pTb2 = &pTbAllocator->aChunks[idxChunk2].paTbs[idxInChunk2]; 1226 if (pTb2->fFlags & IEMTB_F_TYPE_NATIVE) 1227 { 1228 cNativeTbs += 1; 1229 uint32_t const cMsAge2 = msNow - pTb2->msLastUsed; 1230 if ( cMsAge2 > cMsAge 1231 || ( cMsAge2 == cMsAge 1232 && ( pTb2->cUsed < pTb->cUsed 1233 || ( pTb2->cUsed == pTb->cUsed 1234 && pTb2->Native.cInstructions > pTb->Native.cInstructions))) 1235 || !(pTb->fFlags & IEMTB_F_TYPE_NATIVE)) 1236 { 1237 pTb = pTb2; 1238 idxChunk = idxChunk2; 1239 idxInChunk = idxInChunk2; 1240 cMsAge = cMsAge2; 1241 } 1242 } 1243 } 1244 1245 /* Free the TB if we found at least two native one in this group. */ 1246 if (cNativeTbs >= 2) 1247 { 1248 cMaxInstrs = RT_MAX(cMaxInstrs, pTb->Native.cInstructions); 1249 iemTbAllocatorFreeInner(pVCpu, pTbAllocator, pTb, idxChunk, idxInChunk); 1250 cFreedTbs++; 1251 if (cFreedTbs >= 8 && cMaxInstrs >= cNeededInstrs) 1252 break; 1253 } 1254 } 1255 pTbAllocator->iPruneNativeFrom = idxTbPruneFrom; 1256 1257 STAM_REL_PROFILE_STOP(&pTbAllocator->StatPruneNative, a); 1258 } 1171 1259 1172 1260 -
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r102077 r102557 335 335 "Time spent freeing up TBs when full at alloc", "/IEM/CPU%u/re/TbPruningAlloc", idCpu); 336 336 # endif 337 STAMR3RegisterF(pVM, (void *)&pTbAllocator->StatPruneNative, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, 338 "Time spent freeing up native TBs when out of executable memory", "/IEM/CPU%u/re/TbPruningNative", idCpu); 337 339 STAMR3RegisterF(pVM, (void *)&pTbAllocator->cAllocatedChunks, STAMTYPE_U16, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 338 340 "Populated TB chunks", "/IEM/CPU%u/re/cTbChunks", idCpu); -
trunk/src/VBox/VMM/include/IEMInternal.h
r102528 r102557 1213 1213 /** Hint about which bit to start scanning the bitmap from. */ 1214 1214 uint32_t iStartHint; 1215 /** Where to start pruning native TBs from when we're out of executable memory. 1216 * See iemTbAllocatorFreeupNativeSpace for details. */ 1217 uint32_t iPruneNativeFrom; 1218 uint32_t uPadding; 1215 1219 1216 1220 /** Statistics: Number of TB allocation calls. */ … … 1220 1224 /** Statistics: Time spend pruning. */ 1221 1225 STAMPROFILE StatPrune; 1226 /** Statistics: Time spend pruning native TBs. */ 1227 STAMPROFILE StatPruneNative; 1222 1228 1223 1229 /** The delayed free list (see iemTbAlloctorScheduleForFree). */ … … 5587 5593 uint64_t cbInitialExec, uint64_t cbMaxExec, uint32_t cbChunkExec); 5588 5594 void iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb, bool fSafeToFree); 5589 void iemTbAllocatorProcessDelayedFrees(PVMCPU pVCpu, PIEMTBALLOCATOR pTbAllocator); 5595 void iemTbAllocatorProcessDelayedFrees(PVMCPUCC pVCpu, PIEMTBALLOCATOR pTbAllocator); 5596 void iemTbAllocatorFreeupNativeSpace(PVMCPUCC pVCpu, uint32_t cNeededInstrs); 5590 5597 5591 5598
Note:
See TracChangeset
for help on using the changeset viewer.