Changeset 105855 in vbox
- Timestamp:
- Aug 23, 2024 11:12:23 PM (3 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
r105854 r105855 579 579 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 580 580 pReNative->Core.offPc += cbInstr; 581 Log4(("offPc=% xcbInstr=%#x off=%#x\n", pReNative->Core.offPc, cbInstr, off));581 Log4(("offPc=%#RX64 cbInstr=%#x off=%#x\n", pReNative->Core.offPc, cbInstr, off)); 582 582 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG 583 583 off = iemNativeEmitPcDebugAdd(pReNative, off, cbInstr, 64); … … 586 586 off = iemNativePcAdjustCheck(pReNative, off); 587 587 # endif 588 # if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || defined(VBOX_WITH_STATISTICS)589 588 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 590 pReNative->Core.cInstrPcUpdateSkipped++;591 # endif592 589 #endif 593 590 … … 628 625 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 629 626 pReNative->Core.offPc += cbInstr; 630 Log4(("offPc=% xcbInstr=%#x off=%#x\n", pReNative->Core.offPc, cbInstr, off));627 Log4(("offPc=%#RX64 cbInstr=%#x off=%#x\n", pReNative->Core.offPc, cbInstr, off)); 631 628 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG 632 629 off = iemNativeEmitPcDebugAdd(pReNative, off, cbInstr, 32); … … 635 632 off = iemNativePcAdjustCheck(pReNative, off); 636 633 # endif 637 # if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || defined(VBOX_WITH_STATISTICS)638 634 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 639 pReNative->Core.cInstrPcUpdateSkipped++;640 # endif641 635 #endif 642 636 … … 678 672 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 679 673 pReNative->Core.offPc += cbInstr; 680 Log4(("offPc=% xcbInstr=%#x off=%#x\n", pReNative->Core.offPc, cbInstr, off));674 Log4(("offPc=%#RX64 cbInstr=%#x off=%#x\n", pReNative->Core.offPc, cbInstr, off)); 681 675 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG 682 676 off = iemNativeEmitPcDebugAdd(pReNative, off, cbInstr, 16); … … 685 679 off = iemNativePcAdjustCheck(pReNative, off); 686 680 # endif 687 # if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || defined(VBOX_WITH_STATISTICS)688 681 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 689 pReNative->Core.cInstrPcUpdateSkipped++;690 # endif691 682 #endif 692 683 … … 776 767 { 777 768 Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT); 778 779 /* We speculatively modify PC and may raise #GP(0), so make sure the right values are in CPUMCTX. */780 /** @todo relax this one, we won't raise \#GP when a_fWithinPage is true. */781 off = iemNativeRegFlushPendingWrites(pReNative, off);782 783 769 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 784 Assert(pReNative->Core.offPc == 0);785 770 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 786 #endif 787 788 /* Allocate a temporary PC register. */ 789 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); 790 791 /* Perform the addition. */ 792 off = iemNativeEmitAddGprImm(pReNative, off, idxPcReg, (int64_t)offDisp + cbInstr); 793 794 if (RT_LIKELY(enmEffOpSize == IEMMODE_64BIT)) 795 { 796 /* Check that the address is canonical, raising #GP(0) + exit TB if it isn't. 797 We can skip this if the target is within the same page. */ 798 if (!a_fWithinPage) 799 off = iemNativeEmitCheckGprCanonicalMaybeRaiseGp0(pReNative, off, idxPcReg, idxInstr); 771 if (a_fWithinPage && enmEffOpSize == IEMMODE_64BIT) 772 { 773 pReNative->Core.offPc += (int64_t)offDisp + cbInstr; 774 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG 775 off = iemNativeEmitPcDebugAdd(pReNative, off, (int64_t)offDisp + cbInstr, enmEffOpSize == IEMMODE_64BIT ? 64 : 16); 776 # endif 800 777 } 801 778 else 802 { 803 /* Just truncate the result to 16-bit IP. */ 804 Assert(enmEffOpSize == IEMMODE_16BIT); 805 off = iemNativeEmitClear16UpGpr(pReNative, off, idxPcReg); 806 } 779 #endif 780 { 781 /* We speculatively modify PC and may raise #GP(0), so make sure the right values are in CPUMCTX. */ 782 off = iemNativeRegFlushPendingWrites(pReNative, off); 783 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 784 Assert(pReNative->Core.offPc == 0); 785 #endif 786 /* Allocate a temporary PC register. */ 787 uint8_t const idxPcReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, kIemNativeGstRegUse_ForUpdate); 788 789 /* Perform the addition. */ 790 off = iemNativeEmitAddGprImm(pReNative, off, idxPcReg, (int64_t)offDisp + cbInstr + pReNative->Core.offPc); 791 792 if (RT_LIKELY(enmEffOpSize == IEMMODE_64BIT)) 793 { 794 /* Check that the address is canonical, raising #GP(0) + exit TB if it isn't. 795 We can skip this if the target is within the same page. */ 796 if (!a_fWithinPage) 797 off = iemNativeEmitCheckGprCanonicalMaybeRaiseGp0(pReNative, off, idxPcReg, idxInstr); 798 } 799 else 800 { 801 /* Just truncate the result to 16-bit IP. */ 802 Assert(enmEffOpSize == IEMMODE_16BIT); 803 off = iemNativeEmitClear16UpGpr(pReNative, off, idxPcReg); 804 } 807 805 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG 808 off = iemNativeEmitPcDebugAdd(pReNative, off, (int64_t)offDisp + cbInstr, enmEffOpSize == IEMMODE_64BIT ? 64 : 16);809 off = iemNativeEmitPcDebugCheckWithReg(pReNative, off, idxPcReg);810 #endif 811 812 off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip));813 814 /* Free but don't flush the PC register. */815 iemNativeRegFreeTmp(pReNative, idxPcReg);816 806 off = iemNativeEmitPcDebugAdd(pReNative, off, (int64_t)offDisp + cbInstr, enmEffOpSize == IEMMODE_64BIT ? 64 : 16); 807 off = iemNativeEmitPcDebugCheckWithReg(pReNative, off, idxPcReg); 808 #endif 809 810 off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip)); 811 812 /* Free but don't flush the PC register. */ 813 iemNativeRegFreeTmp(pReNative, idxPcReg); 814 } 817 815 return off; 818 816 } … … 895 893 { 896 894 Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT); 895 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 896 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 897 #endif 897 898 898 899 /* We speculatively modify PC and may raise #GP(0), so make sure the right values are in CPUMCTX. */ 899 off = iemNativeRegFlushPendingWrites(pReNative, off); 900 900 if (!a_fFlat || enmEffOpSize == IEMMODE_16BIT) 901 { 902 off = iemNativeRegFlushPendingWrites(pReNative, off); 901 903 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 902 Assert(pReNative->Core.offPc == 0);903 STAM_COUNTER_INC(&pReNative->pVCpu->iem.s.StatNativePcUpdateTotal); 904 #endif 904 Assert(pReNative->Core.offPc == 0); 905 #endif 906 } 905 907 906 908 /* Allocate a temporary PC register. */ … … 908 910 909 911 /* Perform the addition. */ 910 off = iemNativeEmitAddGpr32Imm(pReNative, off, idxPcReg, offDisp + cbInstr); 912 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 913 off = iemNativeEmitAddGpr32Imm(pReNative, off, idxPcReg, offDisp + cbInstr + (int32_t)pReNative->Core.offPc); 914 #else 915 off = iemNativeEmitAddGpr32Imm(pReNative, off, idxPcReg, offDisp + cbInstr + (int32_t)pReNative->Core.offPc); 916 #endif 911 917 912 918 /* Truncate the result to 16-bit IP if the operand size is 16-bit. */ … … 918 924 off = iemNativeEmitCheckGpr32AgainstCsSegLimitMaybeRaiseGp0(pReNative, off, idxPcReg, idxInstr); 919 925 926 /* Commit it. */ 920 927 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG 921 928 off = iemNativeEmitPcDebugAdd(pReNative, off, offDisp + cbInstr, enmEffOpSize == IEMMODE_32BIT ? 32 : 16); … … 924 931 925 932 off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxPcReg, RT_UOFFSETOF(VMCPU, cpum.GstCtx.rip)); 933 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 934 pReNative->Core.offPc = 0; 935 #endif 926 936 927 937 /* Free but don't flush the PC register. */ … … 2727 2737 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 2728 2738 AssertMsgStmt(pReNative->Core.offPc == pOther->offPc, 2729 ("Core.offPc=%# x pOther->offPc=%#x\n", pReNative->Core.offPc, pOther->offPc),2739 ("Core.offPc=%#RX64 pOther->offPc=%#RX64\n", pReNative->Core.offPc, pOther->offPc), 2730 2740 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_COND_ENDIF_RECONCILIATION_FAILED)); 2731 2741 #endif … … 6301 6311 if ((bRmEx & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5) 6302 6312 { 6303 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING6304 /* Need to take the current PC offset into account for the displacement, no need to flush here6305 * as the PC is only accessed readonly and there is no branching or calling helpers involved. */6306 u32Disp += pReNative->Core.offPc;6307 #endif6308 6309 6313 uint8_t const idxRegRet = iemNativeVarRegisterAcquire(pReNative, idxVarRet, &off); 6310 6314 uint8_t const idxRegPc = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, 6311 6315 kIemNativeGstRegUse_ReadOnly); 6312 #ifdef RT_ARCH_AMD646313 6316 if (f64Bit) 6314 6317 { 6318 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6319 int64_t const offFinalDisp = (int64_t)(int32_t)u32Disp + cbInstr + (int64_t)pReNative->Core.offPc; 6320 #else 6315 6321 int64_t const offFinalDisp = (int64_t)(int32_t)u32Disp + cbInstr; 6322 #endif 6323 #ifdef RT_ARCH_AMD64 6316 6324 if ((int32_t)offFinalDisp == offFinalDisp) 6317 6325 off = iemNativeEmitLoadGprFromGprWithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, (int32_t)offFinalDisp); … … 6321 6329 off = iemNativeEmitAddGprImm8(pReNative, off, idxRegRet, cbInstr); 6322 6330 } 6331 #else 6332 off = iemNativeEmitLoadGprFromGprWithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, offFinalDisp); 6333 #endif 6323 6334 } 6324 6335 else 6325 off = iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, (int32_t)u32Disp + cbInstr); 6326 6327 #elif defined(RT_ARCH_ARM64) 6328 if (f64Bit) 6329 off = iemNativeEmitLoadGprFromGprWithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, 6330 (int64_t)(int32_t)u32Disp + cbInstr); 6331 else 6332 off = iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, 6333 (int32_t)u32Disp + cbInstr); 6334 6335 #else 6336 # error "Port me!" 6337 #endif 6336 { 6337 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 6338 int32_t const offFinalDisp = (int32_t)u32Disp + cbInstr + (int32_t)pReNative->Core.offPc; 6339 # else 6340 int32_t const offFinalDisp = (int32_t)u32Disp + cbInstr; 6341 # endif 6342 off = iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, offFinalDisp); 6343 } 6338 6344 iemNativeRegFreeTmp(pReNative, idxRegPc); 6339 6345 iemNativeVarRegisterRelease(pReNative, idxVarRet); -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r105854 r105855 2072 2072 pReNative->Core.offPc = 0; 2073 2073 # if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || defined(VBOX_WITH_STATISTICS) 2074 pReNative->Core. cInstrPcUpdateSkipped= 0;2074 pReNative->Core.idxInstrPlusOneOfLastPcUpdate = 0; 2075 2075 # endif 2076 2076 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG … … 2718 2718 * Debug Info: Record info about delayed RIP updates. 2719 2719 */ 2720 DECL_HIDDEN_THROW(void) iemNativeDbgInfoAddDelayedPcUpdate(PIEMRECOMPILERSTATE pReNative, uint 32_t offPc, uint32_t cInstrSkipped)2720 DECL_HIDDEN_THROW(void) iemNativeDbgInfoAddDelayedPcUpdate(PIEMRECOMPILERSTATE pReNative, uint64_t offPc, uint32_t cInstrSkipped) 2721 2721 { 2722 2722 PIEMTBDBGENTRY const pEntry = iemNativeDbgInfoAddNewEntry(pReNative, pReNative->pDbgInfo); 2723 2723 pEntry->DelayedPcUpdate.uType = kIemTbDbgEntryType_DelayedPcUpdate; 2724 pEntry->DelayedPcUpdate.offPc = offPc; 2724 pEntry->DelayedPcUpdate.offPc = offPc; /** @todo support larger values */ 2725 2725 pEntry->DelayedPcUpdate.cInstrSkipped = cInstrSkipped; 2726 2726 } … … 5765 5765 { 5766 5766 Assert(pReNative->Core.offPc); 5767 Log4(("offPc=%#x -> 0; off=%#x\n", pReNative->Core.offPc, off)); 5768 # ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 5767 # if !defined(IEMNATIVE_WITH_TB_DEBUG_INFO) && !defined(VBOX_WITH_STATISTICS) 5768 Log4(("iemNativeEmitPcWritebackSlow: offPc=%#RX64 -> 0; off=%#x\n", pReNative->Core.offPc, off)); 5769 # else 5770 uint8_t const idxOldInstrPlusOne = pReNative->Core.idxInstrPlusOneOfLastPcUpdate; 5771 uint8_t idxCurCall = pReNative->idxCurCall; 5772 uint8_t idxInstr = pReNative->pTbOrg->Thrd.paCalls[idxCurCall].idxInstr; /* unreliable*/ 5773 while (idxInstr == 0 && idxInstr + 1 < idxOldInstrPlusOne && idxCurCall > 0) 5774 idxInstr = pReNative->pTbOrg->Thrd.paCalls[--idxCurCall].idxInstr; 5775 uint8_t const cInstrsSkipped = idxInstr <= pReNative->Core.idxInstrPlusOneOfLastPcUpdate ? 0 5776 : idxInstr - pReNative->Core.idxInstrPlusOneOfLastPcUpdate; 5777 Log4(("iemNativeEmitPcWritebackSlow: offPc=%#RX64 -> 0; off=%#x; idxInstr=%u cInstrsSkipped=%u\n", 5778 pReNative->Core.offPc, off, idxInstr, cInstrsSkipped)); 5779 5780 pReNative->Core.idxInstrPlusOneOfLastPcUpdate = RT_MAX(idxInstr + 1, pReNative->Core.idxInstrPlusOneOfLastPcUpdate); 5781 STAM_COUNTER_ADD(&pReNative->pVCpu->iem.s.StatNativePcUpdateDelayed, cInstrsSkipped); 5782 5783 # ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 5769 5784 iemNativeDbgInfoAddNativeOffset(pReNative, off); 5770 iemNativeDbgInfoAddDelayedPcUpdate(pReNative, pReNative->Core.offPc, pReNative->Core.cInstrPcUpdateSkipped); 5785 iemNativeDbgInfoAddDelayedPcUpdate(pReNative, pReNative->Core.offPc, cInstrsSkipped); 5786 # endif 5771 5787 # endif 5772 5788 … … 5790 5806 # endif 5791 5807 5792 pReNative->Core.offPc = 0; 5793 # if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || defined(VBOX_WITH_STATISTICS) 5794 STAM_COUNTER_ADD(&pReNative->pVCpu->iem.s.StatNativePcUpdateDelayed, pReNative->Core.cInstrPcUpdateSkipped); 5795 pReNative->Core.cInstrPcUpdateSkipped = 0; 5796 # endif 5808 pReNative->Core.offPc = 0; 5797 5809 5798 5810 return off; … … 10136 10148 uint32_t cRecompiledCalls = 0; 10137 10149 #endif 10138 #if defined(IEMNATIVE_WITH_LIVENESS_ANALYSIS) || defined(IEM_WITH_INTRA_TB_JUMPS) || defined(VBOX_STRICT) || defined(LOG_ENABLED) 10150 #if defined(IEMNATIVE_WITH_LIVENESS_ANALYSIS) || defined(IEM_WITH_INTRA_TB_JUMPS) || defined(VBOX_STRICT) || defined(LOG_ENABLED) || defined(VBOX_WITH_STATISTICS) || defined(IEMNATIVE_WITH_DELAYED_PC_UPDATING) 10139 10151 uint32_t idxCurCall = 0; 10140 10152 #endif … … 10144 10156 { 10145 10157 PFNIEMNATIVERECOMPFUNC const pfnRecom = g_apfnIemNativeRecompileFunctions[pCallEntry->enmFunction]; 10146 #if def IEMNATIVE_WITH_LIVENESS_ANALYSIS10158 #if defined(IEMNATIVE_WITH_LIVENESS_ANALYSIS) || defined(VBOX_WITH_STATISTICS) || defined(IEMNATIVE_WITH_DELAYED_PC_UPDATING) 10147 10159 pReNative->idxCurCall = idxCurCall; 10148 10160 #endif … … 10258 10270 */ 10259 10271 pCallEntry++; 10260 #if defined(IEMNATIVE_WITH_LIVENESS_ANALYSIS) || defined(IEM_WITH_INTRA_TB_JUMPS) || defined(VBOX_STRICT) || defined(LOG_ENABLED) 10272 #if defined(IEMNATIVE_WITH_LIVENESS_ANALYSIS) || defined(IEM_WITH_INTRA_TB_JUMPS) || defined(VBOX_STRICT) || defined(LOG_ENABLED) || defined(VBOX_WITH_STATISTICS) || defined(IEMNATIVE_WITH_DELAYED_PC_UPDATING) 10261 10273 idxCurCall++; 10262 10274 #endif -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r105854 r105855 1240 1240 typedef struct IEMNATIVECORESTATE 1241 1241 { 1242 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING1243 /** The current instruction offset in bytes from when the guest program counter1244 * was updated last. Used for delaying the write to the guest context program counter1245 * as long as possible. */1246 uint32_t offPc;1247 # if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || defined(VBOX_WITH_STATISTICS)1248 /** Number of instructions where we could skip the updating. */1249 uint8_t cInstrPcUpdateSkipped;1250 # endif1251 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG1252 /** Set after we've loaded PC into uPcUpdatingDebug at the first update. */1253 bool fDebugPcInitialized;1254 uint8_t abPadding[2];1255 # else1256 uint8_t abPadding[3];1257 # endif1258 #endif1259 1242 /** Allocation bitmap for aHstRegs. */ 1260 1243 uint32_t bmHstRegs; … … 1268 1251 /** Bitmap marking the shadowed guest register as dirty and needing writeback when flushing. */ 1269 1252 uint64_t bmGstRegShadowDirty; 1253 #endif 1254 1255 #ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING 1256 /** The current instruction offset in bytes from when the guest program counter 1257 * was updated last. Used for delaying the write to the guest context program counter 1258 * as long as possible. */ 1259 int64_t offPc; 1260 # if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || defined(VBOX_WITH_STATISTICS) 1261 /** Statistics: The idxInstr+1 value at the last PC update. */ 1262 uint8_t idxInstrPlusOneOfLastPcUpdate; 1263 # endif 1264 # ifdef IEMNATIVE_WITH_DELAYED_PC_UPDATING_DEBUG 1265 /** Set after we've loaded PC into uPcUpdatingDebug at the first update. */ 1266 bool fDebugPcInitialized; 1267 # endif 1270 1268 #endif 1271 1269 … … 1669 1667 # endif 1670 1668 DECL_HIDDEN_THROW(void) iemNativeDbgInfoAddDelayedPcUpdate(PIEMRECOMPILERSTATE pReNative, 1671 uint 32_t offPc, uint32_t cInstrSkipped);1669 uint64_t offPc, uint32_t cInstrSkipped); 1672 1670 #endif /* IEMNATIVE_WITH_TB_DEBUG_INFO */ 1673 1671
Note:
See TracChangeset
for help on using the changeset viewer.