1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | //----------------------------------------------------------------------------- |
5 | // JitPerf.h |
6 | // Internal interface for gathering JIT perfmormance stats. These stats are |
7 | // logged (or displayed) in two ways. If PERF_COUNTERS are enabled the |
8 | // perfmon etc. would display the jit stats. If ENABLE_PERF_LOG is enabled |
9 | // and PERF_OUTPUT env var is defined then the jit stats are displayed on the |
10 | // stdout. (The jit stats are outputted in a specific format to a file for |
11 | // automated perf tests.) |
12 | // |
13 | |
14 | //----------------------------------------------------------------------------- |
15 | |
16 | |
17 | #ifndef __JITPERF_H__ |
18 | #define __JITPERF_H__ |
19 | |
20 | #include "mscoree.h" |
21 | #include "clrinternal.h" |
22 | |
23 | // ENABLE_JIT_PERF tag used to activate JIT specific profiling. |
24 | #define ENABLE_JIT_PERF |
25 | |
26 | #if defined(ENABLE_JIT_PERF) |
27 | |
28 | extern __int64 g_JitCycles; |
29 | extern size_t g_NonJitCycles; |
30 | extern CRITSEC_COOKIE g_csJit; |
31 | extern __int64 g_tlsJitCycles; |
32 | extern int g_fJitPerfOn; |
33 | |
34 | extern size_t g_dwTlsx86CodeSize; |
35 | extern size_t g_TotalILCodeSize; |
36 | extern size_t g_Totalx86CodeSize; |
37 | extern size_t g_TotalMethodsJitted; |
38 | |
39 | // Public interface to initialize jit stats data structs |
40 | void InitJitPerf(void); |
41 | // Public interface to deallocate datastruct and output the stats. |
42 | void DoneJitPerfStats(void); |
43 | |
44 | // Start/StopNonJITPerf macros are used many times. Factor out the payload |
45 | // into helper method to reduce code size. |
46 | void StartNonJITPerfWorker(LARGE_INTEGER * pCycleStart); |
47 | void StopNonJITPerfWorker(LARGE_INTEGER * pCycleStart); |
48 | |
49 | // Use the callee's stack frame (so START & STOP functions can share variables) |
50 | #define START_JIT_PERF() \ |
51 | if (g_fJitPerfOn) { \ |
52 | ClrFlsSetValue (TlsIdx_JitPerf, (LPVOID)0); \ |
53 | g_dwTlsx86CodeSize = 0; \ |
54 | ClrFlsSetValue (TlsIdx_JitX86Perf, (LPVOID)g_dwTlsx86CodeSize); \ |
55 | } |
56 | |
57 | |
58 | #define STOP_JIT_PERF() \ |
59 | if (g_fJitPerfOn) { \ |
60 | size_t dwTlsNonJitCycles = (size_t)ClrFlsGetValue (TlsIdx_JitPerf); \ |
61 | size_t dwx86CodeSize = (size_t)ClrFlsGetValue (TlsIdx_JitX86Perf); \ |
62 | CRITSEC_Holder csh (g_csJit); \ |
63 | g_JitCycles += static_cast<size_t>(CycleStop.QuadPart - CycleStart.QuadPart); \ |
64 | g_NonJitCycles += dwTlsNonJitCycles; \ |
65 | g_TotalILCodeSize += methodInfo.ILCodeSize; \ |
66 | g_Totalx86CodeSize += dwx86CodeSize; \ |
67 | g_TotalMethodsJitted ++; \ |
68 | } |
69 | |
70 | #define START_NON_JIT_PERF() \ |
71 | LARGE_INTEGER CycleStart; \ |
72 | if(g_fJitPerfOn) { \ |
73 | StartNonJITPerfWorker(&CycleStart); \ |
74 | } |
75 | |
76 | #define STOP_NON_JIT_PERF() \ |
77 | if(g_fJitPerfOn) { \ |
78 | StopNonJITPerfWorker(&CycleStart); \ |
79 | } |
80 | |
81 | #define JIT_PERF_UPDATE_X86_CODE_SIZE(size) \ |
82 | if(g_fJitPerfOn) { \ |
83 | size_t dwx86CodeSize = (size_t)ClrFlsGetValue (TlsIdx_JitX86Perf); \ |
84 | dwx86CodeSize += (size); \ |
85 | ClrFlsSetValue (TlsIdx_JitX86Perf, (LPVOID)dwx86CodeSize); \ |
86 | } |
87 | |
88 | |
89 | #else //ENABLE_JIT_PERF |
90 | #define START_JIT_PERF() |
91 | #define STOP_JIT_PERF() |
92 | #define START_NON_JIT_PERF() |
93 | #define STOP_NON_JIT_PERF() |
94 | #define JIT_PERF_UPDATE_X86_CODE_SIZE(size) |
95 | #endif //ENABLE_JIT_PERF |
96 | |
97 | #endif //__JITPERF_H__ |
98 | |