Changeset 101163 in vbox
- Timestamp:
- Sep 18, 2023 8:44:24 PM (12 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 1 added
- 7 edited
-
Config.kmk (modified) (1 diff)
-
Makefile.kmk (modified) (1 diff)
-
VMMAll/IEMAllN8veRecompiler.cpp (added)
-
VMMAll/IEMAllThrdFuncsBltIn.cpp (modified) (1 diff)
-
VMMAll/IEMAllThrdRecompiler.cpp (modified) (16 diffs)
-
VMMR3/IEMR3.cpp (modified) (3 diffs)
-
include/IEMInline.h (modified) (6 diffs)
-
include/IEMInternal.h (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Config.kmk
r100109 r101163 70 70 ifdef VBOX_WITH_IEM_RECOMPILER # Selectely removing hwvirt doesn't work yet with the recompiler. Python code doesn't check #ifdefs. 71 71 VMM_COMMON_DEFS += VBOX_WITH_IEM_RECOMPILER IEM_WITH_CODE_TLB IEM_WITH_DATA_TLB 72 ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER 73 VMM_COMMON_DEFS += VBOX_WITH_IEM_NATIVE_RECOMPILER 74 endif 72 75 VMM_COMMON_DEFS += VBOX_WITH_NESTED_HWVIRT_VMX 73 76 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT # Busted with TLB enabled. -
trunk/src/VBox/VMM/Makefile.kmk
r101103 r101163 258 258 VMMAll/IEMAllThrdFuncs.cpp \ 259 259 VMMAll/IEMAllThrdFuncsBltIn.cpp 260 ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER 261 VBoxVMM_SOURCES += \ 262 VMMAll/IEMAllN8veRecompiler.cpp 263 endif 260 264 VMMAll/IEMAllThrdFuncs.cpp_CXXFLAGS.win = /bigobj 261 265 endif -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncsBltIn.cpp
r100829 r101163 73 73 static VBOXSTRICTRC iemThreadeFuncWorkerObsoleteTb(PVMCPUCC pVCpu) 74 74 { 75 iemThreadedTbObsolete(pVCpu, pVCpu->iem.s.pCurTbR3); 75 /* We set fSafeToFree to false where as we're being called in the context 76 of a TB callback function, which for native TBs means we cannot release 77 the executable memory till we've returned our way back to iemTbExec as 78 that return path codes via the native code generated for the TB. */ 79 iemThreadedTbObsolete(pVCpu, pVCpu->iem.s.pCurTbR3, false /*fSafeToFree*/); 76 80 return VINF_IEM_REEXEC_BREAK; 77 81 } -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp
r101111 r101163 115 115 * Internal Functions * 116 116 *********************************************************************************************************************************/ 117 static VBOXSTRICTRC iemThreadedTbExec(PVMCPUCC pVCpu, PIEMTB pTb);118 117 static void iemTbAllocatorFree(PVMCPUCC pVCpu, PIEMTB pTb); 119 118 … … 650 649 if (pTb->x86.fAttr == (uint16_t)pVCpu->cpum.GstCtx.cs.Attr.u) 651 650 { 652 pTb->cUsed++;653 pTb->msLastUsed = pVCpu->iem.s.msRecompilerPollNow;654 651 STAM_COUNTER_INC(&pTbCache->cLookupHits); 655 652 AssertMsg(cLeft > 0, ("%d\n", cLeft)); 653 654 pTb->msLastUsed = pVCpu->iem.s.msRecompilerPollNow; 655 pTb->cUsed++; 656 #ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER 657 if ((pTb->fFlags & IEMTB_F_TYPE_NATIVE) || pTb->cUsed != 16) 658 return pTb; 659 return iemNativeRecompile(pVCpu, pTb); 660 #else 656 661 return pTb; 662 #endif 657 663 } 658 664 Log11(("TB miss: CS: %#x, wanted %#x\n", pTb->x86.fAttr, (uint16_t)pVCpu->cpum.GstCtx.cs.Attr.u)); … … 706 712 * 707 713 * @returns VBox status code. 708 * @param pVM The VM handle. 709 * @param cInitialTbs The initial number of translation blocks to 710 * preallocator. 711 * @param cMaxTbs The max number of translation blocks allowed. 714 * @param pVM The VM handle. 715 * @param cInitialTbs The initial number of translation blocks to 716 * preallocator. 717 * @param cMaxTbs The max number of translation blocks allowed. 718 * @param cbInitialExec The initial size of the executable memory allocator. 719 * @param cbMaxExec The max size of the executable memory allocator. 720 * @param cbChunkExec The chunk size for executable memory allocator. Zero 721 * or UINT32_MAX for automatically determining this. 712 722 * @thread EMT 713 723 */ 714 DECLCALLBACK(int) iemTbInit(PVMCC pVM, uint32_t cInitialTbs, uint32_t cMaxTbs) 724 DECLCALLBACK(int) iemTbInit(PVMCC pVM, uint32_t cInitialTbs, uint32_t cMaxTbs, 725 uint64_t cbInitialExec, uint64_t cbMaxExec, uint32_t cbChunkExec) 715 726 { 716 727 PVMCPUCC pVCpu = VMMGetCpu(pVM); … … 820 831 pVCpu->iem.s.pTbCacheR3 = pTbCache; 821 832 833 /* 834 * Initialize the native executable memory allocator. 835 */ 836 #ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER 837 int rc = iemExecMemAllocatorInit(pVCpu, cbMaxExec, cbInitialExec, cbChunkExec); 838 AssertLogRelRCReturn(rc, rc); 839 #else 840 RT_NOREF(cbMaxExec, cbInitialExec, cbChunkExec); 841 #endif 842 822 843 return VINF_SUCCESS; 823 844 } … … 849 870 RTMemFree(pTb->Thrd.paCalls); 850 871 break; 872 #ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER 851 873 case IEMTB_F_TYPE_NATIVE: 852 874 pTbAllocator->cNativeTbs -= 1; 853 RTMemFree(pTb->Native.pbCode); /// @todo native: fix me 875 iemExecMemAllocatorFree(pVCpu, pTb->Native.paInstructions, 876 pTb->Native.cInstructions * sizeof(pTb->Native.paInstructions[0])); 854 877 break; 878 #endif 855 879 default: 856 880 AssertFailed(); … … 880 904 * @param pVCpu The cross context virtual CPU structure of the calling 881 905 * thread. 882 * @param pTb The translation block to free. .906 * @param pTb The translation block to free. 883 907 * @thread EMT(pVCpu) 884 908 */ … … 899 923 */ 900 924 iemTbAllocatorFreeInner(pVCpu, pTbAllocator, pTb, idxChunk, (uint32_t)idxInChunk); 925 } 926 927 928 /** 929 * Schedules a native TB for freeing when it's not longer being executed and 930 * part of the caller's call stack. 931 * 932 * The TB will be removed from the translation block cache, though, so it isn't 933 * possible to executed it again and the IEMTB::pNext member can be used to link 934 * it together with other TBs awaiting freeing. 935 * 936 * @param pVCpu The cross context virtual CPU structure of the calling 937 * thread. 938 * @param pTb The translation block to schedule for freeing. 939 */ 940 static void iemTbAlloctorScheduleForFree(PVMCPUCC pVCpu, PIEMTB pTb) 941 { 942 /* 943 * Validate state. 944 */ 945 PIEMTBALLOCATOR const pTbAllocator = pVCpu->iem.s.pTbAllocatorR3; 946 Assert(pTbAllocator && pTbAllocator->uMagic == IEMTBALLOCATOR_MAGIC); 947 Assert(pTb->idxAllocChunk < pTbAllocator->cAllocatedChunks); 948 Assert((uintptr_t)(pTb - pTbAllocator->aChunks[pTb->idxAllocChunk].paTbs) < pTbAllocator->cTbsPerChunk); 949 Assert(ASMBitTest(&pTbAllocator->bmAllocated, 950 IEMTBALLOC_IDX_MAKE(pTbAllocator, pTb->idxAllocChunk, 951 (uintptr_t)(pTb - pTbAllocator->aChunks[pTb->idxAllocChunk].paTbs)))); 952 Assert((pTb->fFlags & IEMTB_F_TYPE_MASK) == IEMTB_F_TYPE_NATIVE); 953 954 /* 955 * Remove it from the cache and prepend it to the allocator's todo list. 956 */ 957 iemTbCacheRemove(pVCpu->iem.s.pTbCacheR3, pTb); 958 959 pTb->pNext = pTbAllocator->pDelayedFreeHead; 960 pTbAllocator->pDelayedFreeHead = pTb; 961 } 962 963 964 /** 965 * Processes the delayed frees. 966 * 967 * This is called by the allocator function as well as the native recompile 968 * function before making any TB or executable memory allocations respectively. 969 */ 970 void iemTbAllocatorProcessDelayedFrees(PVMCPU pVCpu, PIEMTBALLOCATOR pTbAllocator) 971 { 972 PIEMTB pTb = pTbAllocator->pDelayedFreeHead; 973 pTbAllocator->pDelayedFreeHead = NULL; 974 while (pTb) 975 { 976 PIEMTB const pTbNext = pTb->pNext; 977 Assert(pVCpu->iem.s.pCurTbR3 != pTb); 978 iemTbAlloctorScheduleForFree(pVCpu, pTb); 979 pTb = pTbNext; 980 } 901 981 } 902 982 … … 1078 1158 Assert(pTbAllocator && pTbAllocator->uMagic == IEMTBALLOCATOR_MAGIC); 1079 1159 1160 /* Free any pending TBs before we proceed. */ 1161 if (!pTbAllocator->pDelayedFreeHead) 1162 { /* probably likely */ } 1163 else 1164 iemTbAllocatorProcessDelayedFrees(pVCpu, pTbAllocator); 1165 1080 1166 /* If the allocator is full, take slow code path.*/ 1081 1167 if (RT_LIKELY(pTbAllocator->cInUseTbs < pTbAllocator->cTotalTbs)) … … 1084 1170 } 1085 1171 1172 1173 1174 /********************************************************************************************************************************* 1175 * Threaded Recompiler Core * 1176 *********************************************************************************************************************************/ 1086 1177 1087 1178 /** … … 1258 1349 * Called by opcode verifier functions when they detect a problem. 1259 1350 */ 1260 void iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb) 1261 { 1262 iemTbAllocatorFree(pVCpu, pTb); 1351 void iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb, bool fSafeToFree) 1352 { 1353 /* Unless it's safe, we can only immediately free threaded TB, as we will 1354 have more code left to execute in native TBs when fSafeToFree == false. */ 1355 if (fSafeToFree || (pTb->fFlags & IEMTB_F_TYPE_THREADED)) 1356 iemTbAllocatorFree(pVCpu, pTb); 1357 else 1358 iemTbAlloctorScheduleForFree(pVCpu, pTb); 1263 1359 } 1264 1360 … … 2113 2209 2114 2210 2211 2212 /********************************************************************************************************************************* 2213 * Recompiled Execution Core * 2214 *********************************************************************************************************************************/ 2215 2115 2216 /** 2116 2217 * Executes a translation block. … … 2121 2222 * @param pTb The translation block to execute. 2122 2223 */ 2123 static VBOXSTRICTRC iemThreadedTbExec(PVMCPUCC pVCpu, PIEMTB pTb) IEM_NOEXCEPT_MAY_LONGJMP 2124 { 2125 /* Check the opcodes in the first page before starting execution. */ 2224 static VBOXSTRICTRC iemTbExec(PVMCPUCC pVCpu, PIEMTB pTb) IEM_NOEXCEPT_MAY_LONGJMP 2225 { 2226 /* 2227 * Check the opcodes in the first page before starting execution. 2228 */ 2126 2229 Assert(!(pVCpu->iem.s.GCPhysInstrBuf & (RTGCPHYS)GUEST_PAGE_OFFSET_MASK)); 2127 2230 Assert(pTb->aRanges[0].cbOpcodes <= pVCpu->iem.s.cbInstrBufTotal - pVCpu->iem.s.offInstrNextByte); … … 2131 2234 { 2132 2235 Log7(("TB obsolete: %p GCPhys=%RGp\n", pTb, pTb->GCPhysPc)); 2133 iemThreadedTbObsolete(pVCpu, pTb );2236 iemThreadedTbObsolete(pVCpu, pTb, true /*fSafeToFree*/); 2134 2237 return VINF_SUCCESS; 2135 2238 } 2136 2239 2137 /* Set the current TB so CIMPL function may get at it. */ 2240 /* 2241 * Set the current TB so CIMPL functions may get at it. 2242 */ 2138 2243 pVCpu->iem.s.pCurTbR3 = pTb; 2139 pVCpu->iem.s.cTbExec++; 2140 2141 /* The execution loop. */ 2142 #ifdef LOG_ENABLED 2143 uint64_t uRipPrev = UINT64_MAX; 2144 #endif 2145 PCIEMTHRDEDCALLENTRY pCallEntry = pTb->Thrd.paCalls; 2146 uint32_t cCallsLeft = pTb->Thrd.cCalls; 2147 while (cCallsLeft-- > 0) 2148 { 2149 #ifdef LOG_ENABLED 2150 if (pVCpu->cpum.GstCtx.rip != uRipPrev) 2151 { 2152 uRipPrev = pVCpu->cpum.GstCtx.rip; 2153 iemThreadedLogCurInstr(pVCpu, "EX"); 2154 } 2155 Log9(("%04x:%08RX64: #%d/%d - %d %s\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, 2156 pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->idxInstr, pCallEntry->enmFunction, 2157 g_apszIemThreadedFunctions[pCallEntry->enmFunction])); 2158 #endif 2159 VBOXSTRICTRC const rcStrict = g_apfnIemThreadedFunctions[pCallEntry->enmFunction](pVCpu, 2160 pCallEntry->auParams[0], 2161 pCallEntry->auParams[1], 2162 pCallEntry->auParams[2]); 2244 2245 /* 2246 * Execute the block. 2247 */ 2248 #ifdef VBOX_WITH_IEM_NATIVE_RECOMPILER 2249 if (pTb->fFlags & IEMTB_F_TYPE_NATIVE) 2250 { 2251 pVCpu->iem.s.cTbExecNative++; 2252 typedef IEM_DECL_IMPL_TYPE(int, FNIEMNATIVETB, (PVMCPUCC pVCpu, PIEMTB pTb)); 2253 # ifdef LOG_ENABLED 2254 iemThreadedLogCurInstr(pVCpu, "EXn"); 2255 # endif 2256 VBOXSTRICTRC const rcStrict = ((FNIEMNATIVETB *)pTb->Native.paInstructions)(pVCpu, pTb); 2163 2257 if (RT_LIKELY( rcStrict == VINF_SUCCESS 2164 2258 && pVCpu->iem.s.rcPassUp == VINF_SUCCESS /** @todo this isn't great. */)) 2165 pCallEntry++;2259 { /* likely */ } 2166 2260 else 2167 2261 { 2168 pVCpu->iem.s.cInstructions += pCallEntry->idxInstr; /* This may be one short, but better than zero. */2169 pVCpu->iem.s.pCurTbR3 = NULL;2262 /* pVCpu->iem.s.cInstructions is incremented by iemNativeHlpExecStatusCodeFiddling. */ 2263 pVCpu->iem.s.pCurTbR3 = NULL; 2170 2264 STAM_REL_COUNTER_INC(&pVCpu->iem.s.StatTbExecBreaks); 2171 2265 2172 /* Some status codes are just to get us out of this loop and2173 continue in a different translation block. */2266 /* VINF_IEM_REEXEC_BREAK should be treated as VINF_SUCCESS as it's 2267 only to break out of TB execution early. */ 2174 2268 if (rcStrict == VINF_IEM_REEXEC_BREAK) 2175 2269 return iemExecStatusCodeFiddling(pVCpu, VINF_SUCCESS); 2176 2270 return iemExecStatusCodeFiddling(pVCpu, rcStrict); 2271 } 2272 } 2273 else 2274 #endif /* VBOX_WITH_IEM_NATIVE_RECOMPILER */ 2275 { 2276 /* 2277 * The threaded execution loop. 2278 */ 2279 pVCpu->iem.s.cTbExecThreaded++; 2280 #ifdef LOG_ENABLED 2281 uint64_t uRipPrev = UINT64_MAX; 2282 #endif 2283 PCIEMTHRDEDCALLENTRY pCallEntry = pTb->Thrd.paCalls; 2284 uint32_t cCallsLeft = pTb->Thrd.cCalls; 2285 while (cCallsLeft-- > 0) 2286 { 2287 #ifdef LOG_ENABLED 2288 if (pVCpu->cpum.GstCtx.rip != uRipPrev) 2289 { 2290 uRipPrev = pVCpu->cpum.GstCtx.rip; 2291 iemThreadedLogCurInstr(pVCpu, "EXt"); 2292 } 2293 Log9(("%04x:%08RX64: #%d/%d - %d %s\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, 2294 pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->idxInstr, pCallEntry->enmFunction, 2295 g_apszIemThreadedFunctions[pCallEntry->enmFunction])); 2296 #endif 2297 VBOXSTRICTRC const rcStrict = g_apfnIemThreadedFunctions[pCallEntry->enmFunction](pVCpu, 2298 pCallEntry->auParams[0], 2299 pCallEntry->auParams[1], 2300 pCallEntry->auParams[2]); 2301 if (RT_LIKELY( rcStrict == VINF_SUCCESS 2302 && pVCpu->iem.s.rcPassUp == VINF_SUCCESS /** @todo this isn't great. */)) 2303 pCallEntry++; 2304 else 2305 { 2306 pVCpu->iem.s.cInstructions += pCallEntry->idxInstr; /* This may be one short, but better than zero. */ 2307 pVCpu->iem.s.pCurTbR3 = NULL; 2308 STAM_REL_COUNTER_INC(&pVCpu->iem.s.StatTbExecBreaks); 2309 2310 /* VINF_IEM_REEXEC_BREAK should be treated as VINF_SUCCESS as it's 2311 only to break out of TB execution early. */ 2312 if (rcStrict == VINF_IEM_REEXEC_BREAK) 2313 return iemExecStatusCodeFiddling(pVCpu, VINF_SUCCESS); 2314 return iemExecStatusCodeFiddling(pVCpu, rcStrict); 2315 } 2177 2316 } 2178 2317 } … … 2320 2459 pTb = iemTbCacheLookup(pVCpu, pTbCache, GCPhysPc, fExtraFlags); 2321 2460 if (pTb) 2322 { 2323 if (pTb->fFlags & IEMTB_F_TYPE_THREADED) 2324 rcStrict = iemThreadedTbExec(pVCpu, pTb); 2325 else 2326 AssertFailedStmt(rcStrict = VERR_INTERNAL_ERROR_4); 2327 } 2461 rcStrict = iemTbExec(pVCpu, pTb); 2328 2462 else 2329 2463 rcStrict = iemThreadedCompile(pVM, pVCpu, GCPhysPc, fExtraFlags); … … 2346 2480 if (RT_LIKELY( (iIterations & cPollRate) != 0 2347 2481 || !TMTimerPollBoolWith32BitMilliTS(pVM, pVCpu, &pVCpu->iem.s.msRecompilerPollNow))) 2348 { 2349 2350 } 2482 pTb = NULL; /* Clear it before looping so iemTbCacheLookup can safely do native recompilation. */ 2351 2483 else 2352 2484 return VINF_SUCCESS; … … 2365 2497 iemMemRollback(pVCpu); 2366 2498 2367 #if 0 /** @todo do we need to clean up anything? */2368 /* If pTb isn't NULL we're in iemT hreadedTbExec. */2499 #if 0 /** @todo do we need to clean up anything? If not, we can drop the pTb = NULL some lines up and change the scope. */ 2500 /* If pTb isn't NULL we're in iemTbExec. */ 2369 2501 if (!pTb) 2370 2502 { -
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r101096 r101163 140 140 "InitialTbCount value %u (%#x) is higher than the MaxTbCount value %u (%#x)", 141 141 cInitialTbs, cInitialTbs, cMaxTbs, cMaxTbs); 142 #endif 142 143 /** @cfgm{/IEM/MaxExecMem, uint64_t, 512 MiB} 144 * Max executable memory for recompiled code per EMT. */ 145 uint64_t cbMaxExec = 0; 146 rc = CFGMR3QueryU64Def(pIem, "MaxExecMem", &cbMaxExec, _512M); 147 AssertLogRelRCReturn(rc, rc); 148 if (cbMaxExec < _1M || cbMaxExec > 16*_1G64) 149 return VMSetError(pVM, VERR_OUT_OF_RANGE, RT_SRC_POS, 150 "MaxExecMem value %'RU64 (%#RX64) is out of range (min %'RU64, max %'RU64)", 151 cbMaxExec, cbMaxExec, (uint64_t)_1M, 16*_1G64); 152 153 /** @cfgm{/IEM/ExecChunkSize, uint32_t, 0 (auto)} 154 * The executable memory allocator chunk size. */ 155 uint32_t cbChunkExec = 0; 156 rc = CFGMR3QueryU32Def(pIem, "ExecChunkSize", &cbChunkExec, 0); 157 AssertLogRelRCReturn(rc, rc); 158 if (cbChunkExec != 0 && cbChunkExec != UINT32_MAX && (cbChunkExec < _1M || cbChunkExec > _256M)) 159 return VMSetError(pVM, VERR_OUT_OF_RANGE, RT_SRC_POS, 160 "ExecChunkSize value %'RU32 (%#RX32) is out of range (min %'RU32, max %'RU32)", 161 cbChunkExec, cbChunkExec, _1M, _256M); 162 163 /** @cfgm{/IEM/InitialExecMemSize, uint64_t, 1} 164 * The initial executable memory allocator size (per EMT). The value is 165 * rounded up to the nearest chunk size, so 1 byte means one chunk. */ 166 uint64_t cbInitialExec = 0; 167 rc = CFGMR3QueryU64Def(pIem, "InitialExecMemSize", &cbInitialExec, 0); 168 AssertLogRelRCReturn(rc, rc); 169 if (cbInitialExec > cbMaxExec) 170 return VMSetError(pVM, VERR_OUT_OF_RANGE, RT_SRC_POS, 171 "InitialExecMemSize value %'RU64 (%#RX64) is out of range (max %'RU64)", 172 cbInitialExec, cbInitialExec, cbMaxExec); 173 174 #endif /* VBOX_WITH_IEM_RECOMPILER*/ 143 175 144 176 /* … … 228 260 * the allocations. 229 261 */ 230 rc = VMR3ReqCallWait(pVM, VMCPUID_ALL, (PFNRT)iemTbInit, 3, pVM, cInitialTbs, cMaxTbs); 262 rc = VMR3ReqCallWait(pVM, VMCPUID_ALL, (PFNRT)iemTbInit, 6, 263 pVM, cInitialTbs, cMaxTbs, cbInitialExec, cbMaxExec, cbChunkExec); 231 264 AssertLogRelRCReturn(rc, rc); 232 265 #endif … … 286 319 287 320 #ifdef VBOX_WITH_IEM_RECOMPILER 288 STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.cTbExec, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 289 "Executed translation block", "/IEM/CPU%u/re/cTbExec", idCpu); 321 STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.cTbExecNative, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 322 "Executed native translation block", "/IEM/CPU%u/re/cTbExecNative", idCpu); 323 STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.cTbExecThreaded, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, 324 "Executed threaded translation block", "/IEM/CPU%u/re/cTbExecThreaded", idCpu); 290 325 STAMR3RegisterF(pVM, (void *)&pVCpu->iem.s.StatTbExecBreaks, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 291 326 "Times TB execution was interrupted/broken off", "/IEM/CPU%u/re/cTbExecBreaks", idCpu); -
trunk/src/VBox/VMM/include/IEMInline.h
r100998 r101163 332 332 } 333 333 334 #ifdef VBOX_INCLUDED_vmm_dbgf_h /* VM::dbgf.ro.cEnabledHwBreakpoints is only accessible if VBox/vmm/dbgf.h is included. */ 334 335 335 336 /** … … 392 393 } 393 394 395 #endif /* VBOX_INCLUDED_vmm_dbgf_h */ 396 394 397 395 398 #ifndef IEM_WITH_OPAQUE_DECODER_STATE 396 399 397 400 # if defined(VBOX_INCLUDED_vmm_dbgf_h) || defined(DOXYGEN_RUNNING) /* dbgf.ro.cEnabledHwBreakpoints */ 401 398 402 /** 399 403 * Initializes the execution state. … … 458 462 # endif /* VBOX_STRICT */ 459 463 } 460 # endif /* VBOX_INCLUDED_vmm_dbgf_h */ 461 462 463 # if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX) 464 465 466 # if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX) 464 467 /** 465 468 * Performs a minimal reinitialization of the execution state. … … 477 480 iemOpcodeFlushHeavy(pVCpu, cbInstr); 478 481 } 479 # endif 480 482 # endif 483 484 # endif /* VBOX_INCLUDED_vmm_dbgf_h || DOXYGEN_RUNNING */ 481 485 482 486 /** … … 3564 3568 3565 3569 3570 # ifdef XAPIC_OFF_END /* Requires VBox/apic.h to be included before IEMInline.h. */ 3566 3571 /** 3567 3572 * Sets virtual-APIC write emulation as pending. … … 3588 3593 VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE); 3589 3594 } 3595 # endif /* XAPIC_OFF_END */ 3590 3596 3591 3597 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */ -
trunk/src/VBox/VMM/include/IEMInternal.h
r101111 r101163 742 742 AssertCompile(!(IEM_F_MODE_X86_64BIT & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK)); 743 743 744 /** Native instruction type for use with the native code generator. 745 * This is a byte (uint8_t) for x86 and amd64 and uint32_t for the other(s). */ 746 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 747 typedef uint8_t IEMNATIVEINSTR; 748 #else 749 typedef uint32_t IEMNATIVEINSTR; 750 #endif 751 /** Pointer to a native instruction unit. */ 752 typedef IEMNATIVEINSTR *PIEMNATIVEINSTR; 753 744 754 /** 745 755 * A call for the threaded call table. … … 826 836 struct 827 837 { 828 uint8_t *pbCode; 829 /** Amount of code that pbCode points to. */ 830 uint32_t cbAllocated; 838 /** The native instructions. */ 839 PIEMNATIVEINSTR paInstructions; 840 /** Number of instructions pointed to by paInstructions. */ 841 uint32_t cInstructions; 831 842 } Native; 832 843 /** Generic view for zeroing when freeing. */ … … 974 985 /** Statistics: Time spend pruning. */ 975 986 STAMPROFILE StatPrune; 987 988 /** The delayed free list (see iemTbAlloctorScheduleForFree). */ 989 PIEMTB pDelayedFreeHead; 976 990 977 991 /** Allocation chunks. */ … … 1368 1382 * This is allocated once with maxed-out sizes and re-used afterwards. */ 1369 1383 R3PTRTYPE(PIEMTB) pThrdCompileTbR3; 1370 /** Fixed TB used for native recompilation.1371 * This is allocated once and re-used afterwards, growing individual1372 * components as needed. */1373 R3PTRTYPE(PIEMTB) pNativeCompileTbR3;1374 1384 /** Pointer to the ring-3 TB cache for this EMT. */ 1375 1385 R3PTRTYPE(PIEMTBCACHE) pTbCacheR3; … … 1378 1388 * RIP to opcode bytes stored in the TB (AMD-V / VT-x). */ 1379 1389 uint64_t uCurTbStartPc; 1380 /** Number of TBs executed. */ 1381 uint64_t cTbExec; 1390 /** Number of threaded TBs executed. */ 1391 uint64_t cTbExecThreaded; 1392 /** Number of native TBs executed. */ 1393 uint64_t cTbExecNative; 1382 1394 /** Whether we need to check the opcode bytes for the current instruction. 1383 1395 * This is set by a previous instruction if it modified memory or similar. */ … … 1414 1426 /** Pointer to the ring-3 TB allocator for this EMT. */ 1415 1427 R3PTRTYPE(PIEMTBALLOCATOR) pTbAllocatorR3; 1416 /* Alignment. */ 1417 uint64_t auAlignment10[7]; 1428 /** Pointer to the ring-3 executable memory allocator for this EMT. */ 1429 R3PTRTYPE(struct IEMEXECMEMALLOCATOR *) pExecMemAllocatorR3; 1430 1431 /** Native recompiler state for ring-3. */ 1432 struct IEMRECOMPILERSTATE 1433 { 1434 /** Size of the buffer that pbNativeRecompileBufR3 points to in 1435 * IEMNATIVEINSTR units. */ 1436 uint32_t cInstrBufAlloc; 1437 uint32_t uPadding; /* We don't keep track of this here... */ 1438 /** Fixed temporary code buffer for native recompilation. */ 1439 R3PTRTYPE(PIEMNATIVEINSTR) pInstrBuf; 1440 1441 /** Actual number of labels in paLabels. */ 1442 uint32_t cLabels; 1443 /** Max number of entries allowed in paLabels before reallocating it. */ 1444 uint32_t cLabelsAlloc; 1445 /** Labels defined while recompiling (referenced by fixups). */ 1446 R3PTRTYPE(struct IEMNATIVELABEL *) paLabels; 1447 1448 /** Actual number of fixups paFixups. */ 1449 uint32_t cFixups; 1450 /** Max number of entries allowed in paFixups before reallocating it. */ 1451 uint32_t cFixupsAlloc; 1452 /** Buffer used by the recompiler for recording fixups when generating code. */ 1453 R3PTRTYPE(struct IEMNATIVEFIXUP *) paFixups; 1454 } Native; 1455 1456 // /* Alignment. */ 1457 // uint64_t auAlignment10[1]; 1418 1458 /** Statistics: Times TB execution was broken off before reaching the end. */ 1419 1459 STAMCOUNTER StatTbExecBreaks; … … 1430 1470 /** Threaded TB statistics: Number of calls per TB. */ 1431 1471 STAMPROFILE StatTbThreadedCalls; 1472 /** Native TB statistics: Native code size per TB. */ 1473 STAMPROFILE StatTbNativeCode; 1474 /** Native TB statistics: Profiling native recompilation. */ 1475 STAMPROFILE StatNativeRecompilation; 1432 1476 /** @} */ 1433 1477 … … 5290 5334 extern const PFNIEMOP g_apfnIemThreadedRecompilerVecMap3[1024]; 5291 5335 5292 DECLCALLBACK(int) iemTbInit(PVMCC pVM, uint32_t cInitialTbs, uint32_t cMaxTbs); 5293 void iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb); 5336 DECLCALLBACK(int) iemTbInit(PVMCC pVM, uint32_t cInitialTbs, uint32_t cMaxTbs, 5337 uint64_t cbInitialExec, uint64_t cbMaxExec, uint32_t cbChunkExec); 5338 void iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb, bool fSafeToFree); 5339 void iemTbAllocatorProcessDelayedFrees(PVMCPU pVCpu, PIEMTBALLOCATOR pTbAllocator); 5340 5294 5341 5295 5342 /** @todo FNIEMTHREADEDFUNC and friends may need more work... */ … … 5348 5395 bool iemThreadedCompileBeginEmitCallsComplications(PVMCPUCC pVCpu, PIEMTB pTb); 5349 5396 5397 /* Native recompiler public bits: */ 5398 PIEMTB iemNativeRecompile(PVMCPUCC pVCpu, PIEMTB pTb); 5399 int iemExecMemAllocatorInit(PVMCPU pVCpu, uint64_t cbMax, uint64_t cbInitial, uint32_t cbChunk); 5400 void iemExecMemAllocatorFree(PVMCPU pVCpu, void *pv, size_t cb); 5401 5350 5402 5351 5403 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.

