VirtualBox

Changeset 103404 in vbox


Ignore:
Timestamp:
Feb 17, 2024 1:53:09 AM (12 months ago)
Author:
vboxsync
Message:

VMM/IEM: Threaded function statistics. bugref:10376

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/vm.h

    r101670 r103404  
    159159        struct IEMCPU       s;
    160160#endif
    161         uint8_t             padding[32832];    /* multiple of 64 */
     161        uint8_t             padding[114752]; /* multiple of 64 */
    162162    } iem;
    163163
  • trunk/include/VBox/vmm/vm.mac

    r99385 r103404  
    5858
    5959    alignb 64
    60     .iem                    resb 32832
     60    .iem                    resb 114752
    6161
    6262    alignb 64
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r103393 r103404  
    56565656    return off;
    56575657}
     5658
     5659#ifdef VBOX_WITH_STATISTICS
     5660/**
     5661 * Emits code to update the thread call statistics.
     5662 */
     5663DECL_INLINE_THROW(uint32_t)
     5664iemNativeEmitThreadCallStats(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 */
    56585683
    56595684
     
    1377313798
    1377413799            /*
    13775              * Debug info and assembly markup.
     13800             * Debug info, assembly markup and statistics.
    1377613801             */
    1377713802#if defined(IEMNATIVE_WITH_TB_DEBUG_INFO) || !defined(IEMNATIVE_WITH_BLTIN_CHECKMODE)
     
    1379713822#if defined(VBOX_STRICT)
    1379813823            iemNativeRegAssertSanity(pReNative);
     13824#endif
     13825#ifdef VBOX_WITH_STATISTICS
     13826            off = iemNativeEmitThreadCallStats(pReNative, off, pCallEntry);
    1379913827#endif
    1380013828
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r103351 r103404  
    648648        return '%s_%s%s' % ( sName, self.oParent.oMcBlock.iInFunction, self.sVariation, );
    649649
     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
    650672    def isWithFlagsCheckingAndClearingVariation(self):
    651673        """
     
    24282450        asLines += [
    24292451            'extern const PFNIEMTHREADEDFUNC g_apfnIemThreadedFunctions[kIemThreadedFunc_End];',
     2452            'extern uint8_t const            g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End];',
    24302453            '#if defined(IN_RING3) || defined(LOG_ENABLED)',
    24312454            'extern const char * const       g_apszIemThreadedFunctions[kIemThreadedFunc_End];',
    24322455            '#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',
    24342459        ];
    24352460
     
    25522577            '    /*Invalid*/ NULL,',
    25532578        ];
     2579        asArgCntTab = [
     2580            '/**',
     2581            ' * Argument count table.',
     2582            ' */',
     2583            'uint8_t const g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End] =',
     2584            '{',
     2585            '    0, /*Invalid*/',
     2586        ];
    25542587        asNameTable = [
    25552588            '/**',
     
    25602593            '    "Invalid",',
    25612594        ];
    2562         asArgCntTab = [
     2595        asStatTable = [
    25632596            '/**',
    2564             ' * Argument count table.',
     2597            ' * Function statistics name table.',
    25652598            ' */',
    2566             'uint8_t const g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End] =',
     2599            'const char * const g_apszIemThreadedFunctionStats[kIemThreadedFunc_End] =',
    25672600            '{',
    2568             '    0, /*Invalid*/',
     2601            '    NULL,',
    25692602        ];
    2570         aasTables = (asFuncTable, asNameTable, asArgCntTab,);
     2603        aasTables = (asFuncTable, asArgCntTab, asNameTable, asStatTable,);
    25712604
    25722605        for asTable in aasTables:
     
    25792612        for sFuncNm, cArgs, _ in self.katBltIns:
    25802613            asFuncTable.append('    iemThreadedFunc_BltIn_%s,' % (sFuncNm,));
     2614            asArgCntTab.append('    %d, /*BltIn_%s*/' % (cArgs, sFuncNm,));
    25812615            asNameTable.append('    "BltIn_%s",' % (sFuncNm,));
    2582             asArgCntTab.append('    %d, /*BltIn_%s*/' % (cArgs, sFuncNm,));
     2616            asStatTable.append('    "BltIn/%s",' % (sFuncNm,));
    25832617
    25842618        iThreadedFunction = 1 + len(self.katBltIns);
     
    26002634                    asNameTable.append('    /*%4u*/ "%s",' % (iThreadedFunction, sName,));
    26012635                    asArgCntTab.append('    /*%4u*/ %d, /*%s*/' % (iThreadedFunction, oVariation.cMinParams, sName,));
     2636                    asStatTable.append('    "%s",' % (oVariation.getThreadedFunctionStatisticsName(),));
    26022637
    26032638        for asTable in aasTables:
     
    26122647        oOut.write(  '\n'
    26132648                   + '\n'
     2649                   + '\n');
     2650        oOut.write('\n'.join(asArgCntTab));
     2651        oOut.write(  '\n'
    26142652                   + '\n'
    26152653                   + '#if defined(IN_RING3) || defined(LOG_ENABLED)\n');
     
    26182656                   + '#endif /* IN_RING3 || LOG_ENABLED */\n'
    26192657                   + '\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');
    26232663
    26242664        return True;
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp

    r103376 r103404  
    25342534                  g_apszIemThreadedFunctions[pCallEntry->enmFunction]));
    25352535#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
    25362540            VBOXSTRICTRC const rcStrict = g_apfnIemThreadedFunctions[pCallEntry->enmFunction](pVCpu,
    25372541                                                                                              pCallEntry->auParams[0],
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r103393 r103404  
    5151#include <iprt/string.h>
    5252
    53 #ifdef VBOX_WITH_IEM_RECOMPILER
     53#if defined(VBOX_WITH_STATISTICS) && defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8)
    5454# include "IEMN8veRecompiler.h"
     55# include "IEMThreadedFunctions.h"
    5556#endif
    5657
     
    549550# endif
    550551
     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
    551559#endif /* !defined(VBOX_VMM_TARGET_ARMV8) && defined(VBOX_WITH_NESTED_HWVIRT_VMX) - quick fix for stupid structure duplication non-sense */
    552560    }
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r103393 r103404  
    18631863    /** Instruction statistics for ring-3. */
    18641864    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
    18651870#endif
    18661871} IEMCPU;
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r102876 r103404  
    10361036
    10371037/**
     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 */
     1044DECL_FORCE_INLINE(uint32_t)
     1045iemNativeEmitIncU32CounterInVCpuEx(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 */
     1111DECL_FORCE_INLINE(uint32_t)
     1112iemNativeEmitIncU32CounterInVCpu(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/**
    10381127 * Emits a gprdst = gprsrc load.
    10391128 */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette