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
28extern __int64 g_JitCycles;
29extern size_t g_NonJitCycles;
30extern CRITSEC_COOKIE g_csJit;
31extern __int64 g_tlsJitCycles;
32extern int g_fJitPerfOn;
33
34extern size_t g_dwTlsx86CodeSize;
35extern size_t g_TotalILCodeSize;
36extern size_t g_Totalx86CodeSize;
37extern size_t g_TotalMethodsJitted;
38
39// Public interface to initialize jit stats data structs
40void InitJitPerf(void);
41// Public interface to deallocate datastruct and output the stats.
42void DoneJitPerfStats(void);
43
44// Start/StopNonJITPerf macros are used many times. Factor out the payload
45// into helper method to reduce code size.
46void StartNonJITPerfWorker(LARGE_INTEGER * pCycleStart);
47void 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