summaryrefslogtreecommitdiff
path: root/src/inc/jitperf.h
blob: 022cfd216994cdb2125d970e4d88eb65bd6a1425 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//-----------------------------------------------------------------------------
// JitPerf.h
// Internal interface for gathering JIT perfmormance stats. These stats are
// logged (or displayed) in two ways. If PERF_COUNTERS are enabled the 
// perfmon etc. would display the jit stats. If ENABLE_PERF_LOG is enabled
// and PERF_OUTPUT env var is defined then the jit stats are displayed on the 
// stdout. (The jit stats are outputted in a specific format to a file for 
// automated perf tests.)
//

//-----------------------------------------------------------------------------


#ifndef __JITPERF_H__
#define __JITPERF_H__

#include "mscoree.h"
#include "clrinternal.h"

// ENABLE_JIT_PERF tag used to activate JIT specific profiling.
#define ENABLE_JIT_PERF

#if defined(ENABLE_JIT_PERF)

extern __int64 g_JitCycles;
extern size_t g_NonJitCycles;
extern CRITSEC_COOKIE g_csJit;
extern __int64 g_tlsJitCycles;
extern int g_fJitPerfOn;

extern size_t g_dwTlsx86CodeSize;
extern size_t g_TotalILCodeSize;
extern size_t g_Totalx86CodeSize;
extern size_t g_TotalMethodsJitted;

// Public interface to initialize jit stats data structs
void InitJitPerf(void);
// Public interface to deallocate datastruct and output the stats.
void DoneJitPerfStats(void);

// Start/StopNonJITPerf macros are used many times. Factor out the payload
// into helper method to reduce code size.
void StartNonJITPerfWorker(LARGE_INTEGER * pCycleStart);
void StopNonJITPerfWorker(LARGE_INTEGER * pCycleStart);

// Use the callee's stack frame (so START & STOP functions can share variables)
#define START_JIT_PERF()                                                \
    if (g_fJitPerfOn) {                                                 \
        ClrFlsSetValue (TlsIdx_JitPerf, (LPVOID)0);                     \
        g_dwTlsx86CodeSize = 0;                                         \
        ClrFlsSetValue (TlsIdx_JitX86Perf, (LPVOID)g_dwTlsx86CodeSize); \
    } 


#define STOP_JIT_PERF()                                                 \
    if (g_fJitPerfOn) {                                                 \
        size_t dwTlsNonJitCycles = (size_t)ClrFlsGetValue (TlsIdx_JitPerf); \
        size_t dwx86CodeSize = (size_t)ClrFlsGetValue (TlsIdx_JitX86Perf); \
        CRITSEC_Holder csh (g_csJit);                                   \
        g_JitCycles += static_cast<size_t>(CycleStop.QuadPart - CycleStart.QuadPart);      \
        g_NonJitCycles += dwTlsNonJitCycles;                            \
        g_TotalILCodeSize += methodInfo.ILCodeSize;                     \
        g_Totalx86CodeSize += dwx86CodeSize;                            \
        g_TotalMethodsJitted ++;                                        \
    }

#define START_NON_JIT_PERF()                                            \
    LARGE_INTEGER CycleStart;                                           \
    if(g_fJitPerfOn) {                                                  \
        StartNonJITPerfWorker(&CycleStart);                             \
    }

#define STOP_NON_JIT_PERF()                                             \
    if(g_fJitPerfOn) {                                                  \
        StopNonJITPerfWorker(&CycleStart);                              \
    }

#define JIT_PERF_UPDATE_X86_CODE_SIZE(size)                             \
    if(g_fJitPerfOn) {                                                  \
        size_t dwx86CodeSize = (size_t)ClrFlsGetValue (TlsIdx_JitX86Perf); \
        dwx86CodeSize += (size);                                        \
        ClrFlsSetValue (TlsIdx_JitX86Perf, (LPVOID)dwx86CodeSize);      \
    }


#else //ENABLE_JIT_PERF
#define START_JIT_PERF()
#define STOP_JIT_PERF()
#define START_NON_JIT_PERF()
#define STOP_NON_JIT_PERF()
#define JIT_PERF_UPDATE_X86_CODE_SIZE(size)                 
#endif //ENABLE_JIT_PERF

#endif //__JITPERF_H__