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.
9 // Structures, etc. used by the Profiling API and throughout the EE
12 // ======================================================================================
14 #ifndef _ProfilePriv_h_
15 #define _ProfilePriv_h_
18 // Forward declarations
19 class EEToProfInterfaceImpl;
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
30 //---------------------------------------------------------------------------------------
31 // Enumerates the various init states of profiling.
33 // *** NOTE: The order is important here, as some of the status checks (e.g.,
34 // CORProfilerPresentOrInitializing) use ">" with these enum values. ***
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 kProfStatusPreInitialize = 5, // Prof is in LoadProfiler, but initialization has yet to occur
46 class CurrentProfilerStatus
50 // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
51 Volatile<ProfilerStatus> m_profStatus;
56 void Set(ProfilerStatus profStatus);
59 // ---------------------------------------------------------------------------------------
60 // Global struct that lets the EE see the load status of the profiler, and provides a
61 // pointer (pProfInterface) through which profiler calls can be made
63 // When you are adding new session, please refer to
64 // code:ProfControlBlock::ResetPerSessionStatus#ProfileResetSessionStatus for more details.
65 struct ProfControlBlock
67 // **** IMPORTANT!! ****
68 // All uses of pProfInterface must be properly synchronized to avoid the profiler
69 // from detaching while the EE attempts to call into it. The recommended way to do
70 // this is to use the (lockless) BEGIN_PIN_PROFILER / END_PIN_PROFILER macros. See
71 // code:BEGIN_PIN_PROFILER for instructions. For full details on how the
72 // synchronization works, see
73 // code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
74 VolatilePtr<EEToProfInterfaceImpl> pProfInterface;
75 // **** IMPORTANT!! ****
77 DWORD dwEventMask; // Original low event mask bits
78 DWORD dwEventMaskHigh; // New high event mask bits
79 CurrentProfilerStatus curProfStatus;
81 BOOL fBaseSystemClassesLoaded;
83 #ifdef PROF_TEST_ONLY_FORCE_ELT_DATA
84 // #TestOnlyELT This implements a test-only (and debug-only) hook that allows a test
85 // profiler to ensure enter/leave/tailcall is enabled on startup even though no
86 // profiler is loaded on startup. This allows an attach profiler to use ELT to build
87 // shadow stacks for the sole purpose of verifying OTHER areas of the profiling API
88 // (e.g., stack walking). When this BOOL is TRUE, the JIT will insert calls to the
89 // slow-path profiling API enter/leave/tailcall hooks, which will forward the call to
90 // a profiler if one is loaded (and do nothing otherwise).
92 // See code:AreCallbackStateFlagsSet#P2CLRRestrictionsOverview for general information
93 // on how the test hooks lift restrictions normally in place for the Info functions.
94 BOOL fTestOnlyForceEnterLeave;
97 #ifdef PROF_TEST_ONLY_FORCE_OBJECT_ALLOCATED_DATA
98 // #TestOnlyObjectAllocated This implements a test-only (and debug-only) hook that allows
99 // a test profiler to ensure ObjectAllocated callback is enabled on startup even though no
100 // profiler is loaded on startup. This allows an attach profiler to use ObjectAllocated
101 // callback for the sole purpose of verifying OTHER GC areas of the profiling API
102 // (e.g., constructing a object graph). When this BOOL is TRUE, the JIT will use special
103 // version of new allocators that issue object allocation notifications, which will forward
104 // the notifications to a profiler if one is loaded (and do nothing otherwise).
106 // See code:AreCallbackStateFlagsSet#P2CLRRestrictionsOverview for general information
107 // on how the test hooks lift restrictions normally in place for the Info functions.
108 BOOL fTestOnlyForceObjectAllocated;
112 // Test-only, debug-only code to allow attaching profilers to call ICorProfilerInfo inteface,
113 // which would otherwise be disallowed for attaching profilers
114 BOOL fTestOnlyEnableICorProfilerInfo;
117 // Whether we've turned off concurrent GC during attach
118 BOOL fConcurrentGCDisabledForAttach;
120 Volatile<BOOL> fProfControlBlockInitialized;
122 Volatile<BOOL> fProfilerRequestedRuntimeSuspend;
125 void ResetPerSessionStatus();
129 GVAL_DECL(ProfControlBlock, g_profControlBlock);
131 // Provides definitions of the CORProfilerTrack* functions that test whether a profiler
132 // is active and responding to various callbacks
133 #include "profilepriv.inl"
135 //---------------------------------------------------------------
136 // Bit flags used to track profiler callback execution state, such as which
137 // ICorProfilerCallback method we're currently executing. These help us enforce the
138 // invariants of which calls a profiler is allowed to make at given times. These flags
139 // are stored in Thread::m_profilerCallbackState.
141 // For now, we ensure:
142 // * Only asynchronous-safe calls are made asynchronously (i.e., are made from
143 // outside of profiler callbacks).
144 // * GC_TRIGGERS info methods are not called from GC_NOTRIGGER callbacks
146 // Later, we may choose to enforce even more refined call trees and add more flags.
147 #define COR_PRF_CALLBACKSTATE_INCALLBACK 0x1
148 #define COR_PRF_CALLBACKSTATE_IN_TRIGGERS_SCOPE 0x2
149 #define COR_PRF_CALLBACKSTATE_FORCEGC_WAS_CALLED 0x4
150 #define COR_PRF_CALLBACKSTATE_REJIT_WAS_CALLED 0x8
152 //---------------------------------------------------------------
154 #endif // defined(PROFILING_SUPPORTED_DATA) || defined(PROFILING_SUPPORTED)
156 // This is the helper callback that the gc uses when walking the heap.
157 bool HeapWalkHelper(Object* pBO, void* pv);
158 void ScanRootsHelper(Object* pObj, Object** ppRoot, ScanContext *pSC, uint32_t dwUnused);
159 bool AllocByClassHelper(Object* pBO, void* pv);
161 #endif // _ProfilePriv_h_