91791f5f1949333fd6fd25add31e14243f52fc02
[platform/upstream/coreclr.git] / src / inc / profilepriv.h
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 // ProfilePriv.h
6 // 
7
8 //
9 // Structures, etc. used by the Profiling API and throughout the EE
10 // 
11
12 // ======================================================================================
13
14 #ifndef _ProfilePriv_h_
15 #define _ProfilePriv_h_
16
17
18 // Forward declarations
19 class EEToProfInterfaceImpl;
20 class Object;
21 struct ScanContext;
22
23 #if defined (PROFILING_SUPPORTED_DATA) || defined(PROFILING_SUPPORTED)
24 #ifndef PROFILING_SUPPORTED_DATA
25 #define PROFILING_SUPPORTED_DATA 1
26 #endif  // PROFILING_SUPPORTED_DATA
27
28 #include "corprof.h"
29
30 //---------------------------------------------------------------------------------------
31 // Enumerates the various init states of profiling.
32 // 
33 // *** NOTE: The order is important here, as some of the status checks (e.g.,
34 // CORProfilerPresentOrInitializing) use ">" with these enum values. ***
35
36 enum ProfilerStatus
37 {
38     kProfStatusNone                        = 0, // No profiler running.
39     kProfStatusDetaching                   = 1, // Prof was running, is now detaching, but still loaded
40     kProfStatusInitializingForStartupLoad  = 2, // Prof ready for (or in) its Initialize callback
41     kProfStatusInitializingForAttachLoad   = 3, // Prof ready for (or in) its InitializeForAttach callback
42     kProfStatusActive                      = 4, // Prof completed initialization and is actively running
43 };
44
45 class CurrentProfilerStatus
46 {
47 private:
48     // Why volatile?
49     // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
50     Volatile<ProfilerStatus> m_profStatus;
51
52 public:
53     void Init();
54     ProfilerStatus Get();
55     void Set(ProfilerStatus profStatus);
56 };
57
58 // ---------------------------------------------------------------------------------------
59 // Global struct that lets the EE see the load status of the profiler, and provides a
60 // pointer (pProfInterface) through which profiler calls can be made
61 //
62 // When you are adding new session, please refer to 
63 // code:ProfControlBlock::ResetPerSessionStatus#ProfileResetSessionStatus for more details.
64 struct ProfControlBlock
65 {
66     // **** IMPORTANT!! ****
67     // All uses of pProfInterface must be properly synchronized to avoid the profiler
68     // from detaching while the EE attempts to call into it.  The recommended way to do
69     // this is to use the (lockless) BEGIN_PIN_PROFILER / END_PIN_PROFILER macros.  See
70     // code:BEGIN_PIN_PROFILER for instructions.  For full details on how the
71     // synchronization works, see
72     // code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
73     VolatilePtr<EEToProfInterfaceImpl> pProfInterface;
74     // **** IMPORTANT!! ****
75     
76     DWORD dwEventMask;          // Original low event mask bits
77     DWORD dwEventMaskHigh;      // New high event mask bits
78     CurrentProfilerStatus curProfStatus;
79     BOOL fGCInProgress;
80     BOOL fBaseSystemClassesLoaded;
81
82 #ifdef PROF_TEST_ONLY_FORCE_ELT_DATA
83     // #TestOnlyELT This implements a test-only (and debug-only) hook that allows a test
84     // profiler to ensure enter/leave/tailcall is enabled on startup even though no
85     // profiler is loaded on startup. This allows an attach profiler to use ELT to build
86     // shadow stacks for the sole purpose of verifying OTHER areas of the profiling API
87     // (e.g., stack walking). When this BOOL is TRUE, the JIT will insert calls to the
88     // slow-path profiling API enter/leave/tailcall hooks, which will forward the call to
89     // a profiler if one is loaded (and do nothing otherwise).
90     // 
91     // See code:AreCallbackStateFlagsSet#P2CLRRestrictionsOverview for general information
92     // on how the test hooks lift restrictions normally in place for the Info functions.
93     BOOL fTestOnlyForceEnterLeave;
94 #endif
95
96 #ifdef PROF_TEST_ONLY_FORCE_OBJECT_ALLOCATED_DATA
97     // #TestOnlyObjectAllocated This implements a test-only (and debug-only) hook that allows
98     // a test profiler to ensure ObjectAllocated callback is enabled on startup even though no
99     // profiler is loaded on startup. This allows an attach profiler to use ObjectAllocated 
100     // callback for the sole purpose of verifying OTHER GC areas of the profiling API
101     // (e.g., constructing a object graph). When this BOOL is TRUE, the JIT will use special 
102     // version of new allocators that issue object allocation notifications, which will forward 
103     // the notifications to a profiler if one is loaded (and do nothing otherwise).
104     // 
105     // See code:AreCallbackStateFlagsSet#P2CLRRestrictionsOverview for general information
106     // on how the test hooks lift restrictions normally in place for the Info functions.
107     BOOL fTestOnlyForceObjectAllocated;
108 #endif 
109
110 #ifdef _DEBUG
111     // Test-only, debug-only code to allow attaching profilers to call ICorProfilerInfo inteface,  
112     // which would otherwise be disallowed for attaching profilers
113     BOOL                    fTestOnlyEnableICorProfilerInfo;
114 #endif // _DEBUG
115
116     // Whether we've turned off concurrent GC during attach
117     BOOL fConcurrentGCDisabledForAttach;
118
119     Volatile<BOOL> fProfControlBlockInitialized;
120
121     Volatile<BOOL> fProfilerRequestedRuntimeSuspend;
122     
123     void Init();
124     void ResetPerSessionStatus();    
125 };
126
127
128 GVAL_DECL(ProfControlBlock, g_profControlBlock);
129
130 // Provides definitions of the CORProfilerTrack* functions that test whether a profiler
131 // is active and responding to various callbacks
132 #include "profilepriv.inl"
133
134 //---------------------------------------------------------------
135 // Bit flags used to track profiler callback execution state, such as which
136 // ICorProfilerCallback method we're currently executing. These help us enforce the
137 // invariants of which calls a profiler is allowed to make at given times. These flags
138 // are stored in Thread::m_profilerCallbackState.
139 //
140 // For now, we ensure:
141 //     * Only asynchronous-safe calls are made asynchronously (i.e., are made from
142 //         outside of profiler callbacks).
143 //     * GC_TRIGGERS info methods are not called from GC_NOTRIGGER callbacks
144 //
145 // Later, we may choose to enforce even more refined call trees and add more flags.
146 #define COR_PRF_CALLBACKSTATE_INCALLBACK                 0x1
147 #define COR_PRF_CALLBACKSTATE_IN_TRIGGERS_SCOPE          0x2
148 #define COR_PRF_CALLBACKSTATE_FORCEGC_WAS_CALLED         0x4
149 #define COR_PRF_CALLBACKSTATE_REJIT_WAS_CALLED           0x8
150 //
151 //---------------------------------------------------------------
152
153 #endif // defined(PROFILING_SUPPORTED_DATA) || defined(PROFILING_SUPPORTED)
154
155 // This is the helper callback that the gc uses when walking the heap.
156 bool HeapWalkHelper(Object* pBO, void* pv);
157 void ScanRootsHelper(Object* pObj, Object** ppRoot, ScanContext *pSC, uint32_t dwUnused);
158 bool AllocByClassHelper(Object* pBO, void* pv);
159
160 #endif  // _ProfilePriv_h_
161