Changeset 103404 in vbox
- Timestamp:
- Feb 17, 2024 1:53:09 AM (12 months ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/vm.h
r101670 r103404 159 159 struct IEMCPU s; 160 160 #endif 161 uint8_t padding[ 32832];/* multiple of 64 */161 uint8_t padding[114752]; /* multiple of 64 */ 162 162 } iem; 163 163 -
trunk/include/VBox/vmm/vm.mac
r99385 r103404 58 58 59 59 alignb 64 60 .iem resb 3283260 .iem resb 114752 61 61 62 62 alignb 64 -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r103393 r103404 5656 5656 return off; 5657 5657 } 5658 5659 #ifdef VBOX_WITH_STATISTICS 5660 /** 5661 * Emits code to update the thread call statistics. 5662 */ 5663 DECL_INLINE_THROW(uint32_t) 5664 iemNativeEmitThreadCallStats(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTHRDEDCALLENTRY pCallEntry) 5665 { 5666 /* 5667 * Update threaded function stats. 5668 */ 5669 uint32_t const offVCpu = RT_UOFFSETOF_DYN(VMCPUCC, iem.s.acThreadedFuncStats[pCallEntry->enmFunction]); 5670 AssertCompile(sizeof(pReNative->pVCpu->iem.s.acThreadedFuncStats[pCallEntry->enmFunction]) == sizeof(uint32_t)); 5671 # if defined(RT_ARCH_ARM64) 5672 uint8_t const idxTmp1 = iemNativeRegAllocTmp(pReNative, &off); 5673 uint8_t const idxTmp2 = iemNativeRegAllocTmp(pReNative, &off); 5674 off = iemNativeEmitIncU32CounterInVCpu(pReNative, off, idxTmp1, idxTmp2, offVCpu); 5675 iemNativeRegFreeTmp(pReNative, idxTmp1); 5676 iemNativeRegFreeTmp(pReNative, idxTmp2); 5677 # else 5678 off = iemNativeEmitIncU32CounterInVCpu(pReNative, off, UINT8_MAX, UINT8_MAX, offVCpu); 5679 # endif 5680 return off; 5681 } 5682 #endif /* VBOX_WITH_STATISTICS */ 5658 5683 5659 5684 … … 13773 13798 13774 13799 /* 13775 * Debug info and assembly markup.13800 * Debug info, assembly markup and statistics. 13776 13801 */ 13777 13802 #if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || !defined(IEMNATIVE_WITH_BLTIN_CHECKMODE) … … 13797 13822 #if defined(VBOX_STRICT) 13798 13823 iemNativeRegAssertSanity(pReNative); 13824 #endif 13825 #ifdef VBOX_WITH_STATISTICS 13826 off = iemNativeEmitThreadCallStats(pReNative, off, pCallEntry); 13799 13827 #endif 13800 13828 -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
r103351 r103404 648 648 return '%s_%s%s' % ( sName, self.oParent.oMcBlock.iInFunction, self.sVariation, ); 649 649 650 def getThreadedFunctionStatisticsName(self): 651 sName = self.oParent.oMcBlock.sFunction; 652 if sName.startswith('iemOp_'): 653 sName = sName[len('iemOp_'):]; 654 655 sVarNm = self.sVariation; 656 if sVarNm: 657 if sVarNm.startswith('_'): 658 sVarNm = sVarNm[1:]; 659 if sVarNm.endswith('_Jmp'): 660 sVarNm = sVarNm[:-4]; 661 sName += '_Jmp'; 662 elif sVarNm.endswith('_NoJmp'): 663 sVarNm = sVarNm[:-6]; 664 sName += '_NoJmp'; 665 else: 666 sVarNm = 'DeferToCImpl'; 667 668 if self.oParent.oMcBlock.iInFunction == 0: 669 return '%s/%s' % ( sVarNm, sName ); 670 return '%s/%s_%s' % ( sVarNm, sName, self.oParent.oMcBlock.iInFunction, ); 671 650 672 def isWithFlagsCheckingAndClearingVariation(self): 651 673 """ … … 2428 2450 asLines += [ 2429 2451 'extern const PFNIEMTHREADEDFUNC g_apfnIemThreadedFunctions[kIemThreadedFunc_End];', 2452 'extern uint8_t const g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End];', 2430 2453 '#if defined(IN_RING3) || defined(LOG_ENABLED)', 2431 2454 'extern const char * const g_apszIemThreadedFunctions[kIemThreadedFunc_End];', 2432 2455 '#endif', 2433 'extern uint8_t const g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End];', 2456 '#if defined(IN_RING3)', 2457 'extern const char * const g_apszIemThreadedFunctionStats[kIemThreadedFunc_End];', 2458 '#endif', 2434 2459 ]; 2435 2460 … … 2552 2577 ' /*Invalid*/ NULL,', 2553 2578 ]; 2579 asArgCntTab = [ 2580 '/**', 2581 ' * Argument count table.', 2582 ' */', 2583 'uint8_t const g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End] =', 2584 '{', 2585 ' 0, /*Invalid*/', 2586 ]; 2554 2587 asNameTable = [ 2555 2588 '/**', … … 2560 2593 ' "Invalid",', 2561 2594 ]; 2562 as ArgCntTab= [2595 asStatTable = [ 2563 2596 '/**', 2564 ' * Argument counttable.',2597 ' * Function statistics name table.', 2565 2598 ' */', 2566 ' uint8_t const g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End] =',2599 'const char * const g_apszIemThreadedFunctionStats[kIemThreadedFunc_End] =', 2567 2600 '{', 2568 ' 0, /*Invalid*/',2601 ' NULL,', 2569 2602 ]; 2570 aasTables = (asFuncTable, as NameTable, asArgCntTab,);2603 aasTables = (asFuncTable, asArgCntTab, asNameTable, asStatTable,); 2571 2604 2572 2605 for asTable in aasTables: … … 2579 2612 for sFuncNm, cArgs, _ in self.katBltIns: 2580 2613 asFuncTable.append(' iemThreadedFunc_BltIn_%s,' % (sFuncNm,)); 2614 asArgCntTab.append(' %d, /*BltIn_%s*/' % (cArgs, sFuncNm,)); 2581 2615 asNameTable.append(' "BltIn_%s",' % (sFuncNm,)); 2582 as ArgCntTab.append(' %d, /*BltIn_%s*/' % (cArgs,sFuncNm,));2616 asStatTable.append(' "BltIn/%s",' % (sFuncNm,)); 2583 2617 2584 2618 iThreadedFunction = 1 + len(self.katBltIns); … … 2600 2634 asNameTable.append(' /*%4u*/ "%s",' % (iThreadedFunction, sName,)); 2601 2635 asArgCntTab.append(' /*%4u*/ %d, /*%s*/' % (iThreadedFunction, oVariation.cMinParams, sName,)); 2636 asStatTable.append(' "%s",' % (oVariation.getThreadedFunctionStatisticsName(),)); 2602 2637 2603 2638 for asTable in aasTables: … … 2612 2647 oOut.write( '\n' 2613 2648 + '\n' 2649 + '\n'); 2650 oOut.write('\n'.join(asArgCntTab)); 2651 oOut.write( '\n' 2614 2652 + '\n' 2615 2653 + '#if defined(IN_RING3) || defined(LOG_ENABLED)\n'); … … 2618 2656 + '#endif /* IN_RING3 || LOG_ENABLED */\n' 2619 2657 + '\n' 2620 + '\n'); 2621 oOut.write('\n'.join(asArgCntTab)); 2622 oOut.write('\n'); 2658 + '\n' 2659 + '#if defined(IN_RING3)\n'); 2660 oOut.write('\n'.join(asStatTable)); 2661 oOut.write( '\n' 2662 + '#endif /* IN_RING3 */\n'); 2623 2663 2624 2664 return True; -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp
r103376 r103404 2534 2534 g_apszIemThreadedFunctions[pCallEntry->enmFunction])); 2535 2535 #endif 2536 #ifdef VBOX_WITH_STATISTICS 2537 AssertCompile(RT_ELEMENTS(pVCpu->iem.s.acThreadedFuncStats) >= kIemThreadedFunc_End); 2538 pVCpu->iem.s.acThreadedFuncStats[pCallEntry->enmFunction] += 1; 2539 #endif 2536 2540 VBOXSTRICTRC const rcStrict = g_apfnIemThreadedFunctions[pCallEntry->enmFunction](pVCpu, 2537 2541 pCallEntry->auParams[0], -
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r103393 r103404 51 51 #include <iprt/string.h> 52 52 53 #if def VBOX_WITH_IEM_RECOMPILER53 #if defined(VBOX_WITH_STATISTICS) && defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8) 54 54 # include "IEMN8veRecompiler.h" 55 # include "IEMThreadedFunctions.h" 55 56 #endif 56 57 … … 549 550 # endif 550 551 552 # if !defined(VBOX_VMM_TARGET_ARMV8) && defined(VBOX_WITH_STATISTICS) 553 /* Threaded function statistics: */ 554 for (unsigned i = 1; i < (unsigned)kIemThreadedFunc_End; i++) 555 STAMR3RegisterF(pVM, &pVCpu->iem.s.acThreadedFuncStats[i], STAMTYPE_U32_RESET, STAMVISIBILITY_USED, 556 STAMUNIT_COUNT, NULL, "/IEM/CPU%u/ThrdFuncs/%s", idCpu, g_apszIemThreadedFunctionStats[i]); 557 # endif 558 551 559 #endif /* !defined(VBOX_VMM_TARGET_ARMV8) && defined(VBOX_WITH_NESTED_HWVIRT_VMX) - quick fix for stupid structure duplication non-sense */ 552 560 } -
trunk/src/VBox/VMM/include/IEMInternal.h
r103393 r103404 1863 1863 /** Instruction statistics for ring-3. */ 1864 1864 IEMINSTRSTATS StatsR3; 1865 # ifdef VBOX_WITH_IEM_RECOMPILER 1866 /** Statistics per threaded function call. 1867 * Updated by both the threaded and native recompilers. */ 1868 uint32_t acThreadedFuncStats[0x5000 /*20480*/]; 1869 # endif 1865 1870 #endif 1866 1871 } IEMCPU; -
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r102876 r103404 1036 1036 1037 1037 /** 1038 * Emits code for incrementing an unsigned 32-bit statistics counter in VMCPU. 1039 * 1040 * @note The two temp registers are not required for AMD64. ARM64 always 1041 * requires the first, and the 2nd is needed if the offset cannot be 1042 * encoded as an immediate. 1043 */ 1044 DECL_FORCE_INLINE(uint32_t) 1045 iemNativeEmitIncU32CounterInVCpuEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t idxTmp1, uint8_t idxTmp2, uint32_t offVCpu) 1046 { 1047 Assert(!(offVCpu & 3)); /* ASSUME correctly aligned member. */ 1048 #ifdef RT_ARCH_AMD64 1049 /* inc dword [pVCpu + offVCpu] */ 1050 pCodeBuf[off++] = 0xff; 1051 off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, 0, offVCpu); 1052 RT_NOREF(idxTmp1, idxTmp2); 1053 1054 #elif defined(RT_ARCH_ARM64) 1055 /* Determine how we're to access pVCpu first. */ 1056 uint32_t const cbData = sizeof(uint32_t); 1057 if (offVCpu < (unsigned)(_4K * cbData)) 1058 { 1059 /* Use the unsigned variant of ldr Wt, [<Xn|SP>, #off]. */ 1060 pCodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_Ld_Dword, idxTmp1, 1061 IEMNATIVE_REG_FIXED_PVMCPU, offVCpu / cbData); 1062 pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxTmp1, idxTmp1, 1); 1063 pCodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_St_Dword, idxTmp1, 1064 IEMNATIVE_REG_FIXED_PVMCPU, offVCpu / cbData); 1065 } 1066 else if (offVCpu - RT_UOFFSETOF(VMCPU, cpum.GstCtx) < (unsigned)(_4K * cbData)) 1067 { 1068 pCodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_Ld_Dword, idxTmp1, IEMNATIVE_REG_FIXED_PCPUMCTX, 1069 (offVCpu - RT_UOFFSETOF(VMCPU, cpum.GstCtx)) / cbData); 1070 pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxTmp1, idxTmp1, 1); 1071 pCodeBuf[off++] = Armv8A64MkInstrStLdRUOff(kArmv8A64InstrLdStType_St_Dword, idxTmp1, IEMNATIVE_REG_FIXED_PCPUMCTX, 1072 (offVCpu - RT_UOFFSETOF(VMCPU, cpum.GstCtx)) / cbData); 1073 } 1074 else 1075 { 1076 /* The offset is too large, so we must load it into a register and use 1077 ldr Wt, [<Xn|SP>, (<Wm>|<Xm>)]. We'll try use the 'LSL, #2' feature 1078 of the instruction if that'll reduce the constant to 16-bits. */ 1079 if (offVCpu / cbData < (unsigned)UINT16_MAX) 1080 { 1081 pCodeBuf[off++] = Armv8A64MkInstrMovZ(idxTmp2, offVCpu / cbData); 1082 pCodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(kArmv8A64InstrLdStType_Ld_Word, idxTmp1, IEMNATIVE_REG_FIXED_PVMCPU, 1083 idxTmp2, kArmv8A64InstrLdStExtend_Lsl, true /*fShifted(2)*/); 1084 pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxTmp1, idxTmp1, 1); 1085 pCodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(kArmv8A64InstrLdStType_St_Word, idxTmp1, IEMNATIVE_REG_FIXED_PVMCPU, 1086 idxTmp2, kArmv8A64InstrLdStExtend_Lsl, true /*fShifted(2)*/); 1087 } 1088 else 1089 { 1090 off = iemNativeEmitLoadGprImmEx(pCodeBuf, off, idxTmp2, offVCpu); 1091 pCodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(kArmv8A64InstrLdStType_Ld_Word, idxTmp1, IEMNATIVE_REG_FIXED_PVMCPU, idxTmp2); 1092 pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxTmp1, idxTmp1, 1); 1093 pCodeBuf[off++] = Armv8A64MkInstrStLdRegIdx(kArmv8A64InstrLdStType_St_Word, idxTmp1, IEMNATIVE_REG_FIXED_PVMCPU, idxTmp2); 1094 } 1095 } 1096 1097 #else 1098 # error "port me" 1099 #endif 1100 return off; 1101 } 1102 1103 1104 /** 1105 * Emits code for incrementing an unsigned 32-bit statistics counter in VMCPU. 1106 * 1107 * @note The two temp registers are not required for AMD64. ARM64 always 1108 * requires the first, and the 2nd is needed if the offset cannot be 1109 * encoded as an immediate. 1110 */ 1111 DECL_FORCE_INLINE(uint32_t) 1112 iemNativeEmitIncU32CounterInVCpu(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxTmp1, uint8_t idxTmp2, uint32_t offVCpu) 1113 { 1114 #ifdef RT_ARCH_AMD64 1115 off = iemNativeEmitIncU32CounterInVCpuEx(iemNativeInstrBufEnsure(pReNative, off, 6), off, idxTmp1, idxTmp2, offVCpu); 1116 #elif defined(RT_ARCH_ARM64) 1117 off = iemNativeEmitIncU32CounterInVCpuEx(iemNativeInstrBufEnsure(pReNative, off, 4+3), off, idxTmp1, idxTmp2, offVCpu); 1118 #else 1119 # error "port me" 1120 #endif 1121 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1122 return off; 1123 } 1124 1125 1126 /** 1038 1127 * Emits a gprdst = gprsrc load. 1039 1128 */
Note:
See TracChangeset
for help on using the changeset viewer.