Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mason <davmason@microsoft.com>2021-06-15 21:54:02 +0300
committerGitHub <noreply@github.com>2021-06-15 21:54:02 +0300
commitab71c1f4031d449ed3d60ccaaecb629bb73b648a (patch)
tree891426baadbc67a3718edc12632887ef5cc83d00 /src/coreclr/inc
parent63c8ab2e7acedca0547bc9d59ba8b7d34faf3ddb (diff)
Add the concept of "notification profilers" to the runtime (#53122)
Diffstat (limited to 'src/coreclr/inc')
-rw-r--r--src/coreclr/inc/CrstTypes.def2
-rw-r--r--src/coreclr/inc/clrconfigvalues.h4
-rw-r--r--src/coreclr/inc/corprof.idl47
-rw-r--r--src/coreclr/inc/profilepriv.h306
-rw-r--r--src/coreclr/inc/profilepriv.inl1837
-rw-r--r--src/coreclr/inc/sarray.inl2
6 files changed, 1994 insertions, 204 deletions
diff --git a/src/coreclr/inc/CrstTypes.def b/src/coreclr/inc/CrstTypes.def
index 185a590d938..c48872a0b94 100644
--- a/src/coreclr/inc/CrstTypes.def
+++ b/src/coreclr/inc/CrstTypes.def
@@ -433,7 +433,7 @@ Crst SingleUseLock
End
Crst UnwindInfoTableLock
- AcquiredAfter StubUnwindInfoHeapSegments SingleUseLock
+ AcquiredAfter StubUnwindInfoHeapSegments SingleUseLock
AcquiredBefore StressLog
End
diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h
index 5dc7e5d34b2..3f21e41dfa3 100644
--- a/src/coreclr/inc/clrconfigvalues.h
+++ b/src/coreclr/inc/clrconfigvalues.h
@@ -504,6 +504,10 @@ RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CORECLR_PROFILER_PATH_32, W("CORECLR_PROFI
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CORECLR_PROFILER_PATH_64, W("CORECLR_PROFILER_PATH_64"), "CoreCLR only: Specifies the path to the DLL of profiler to load into currently running 64 process", CLRConfig::LookupOptions::DontPrependPrefix)
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CORECLR_PROFILER_PATH_ARM32, W("CORECLR_PROFILER_PATH_ARM32"), "CoreCLR only: Specifies the path to the DLL of profiler to load into currently running ARM32 process", CLRConfig::LookupOptions::DontPrependPrefix)
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CORECLR_PROFILER_PATH_ARM64, W("CORECLR_PROFILER_PATH_ARM64"), "CoreCLR only: Specifies the path to the DLL of profiler to load into currently running ARM64 process", CLRConfig::LookupOptions::DontPrependPrefix)
+RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_CORECLR_ENABLE_NOTIFICATION_PROFILERS, W("CORECLR_ENABLE_NOTIFICATION_PROFILERS"), 0, "Set to 0 to disable loading notification profilers.", CLRConfig::LookupOptions::DontPrependPrefix)
+RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CORECLR_NOTIFICATION_PROFILERS_64, W("CORECLR_NOTIFICATION_PROFILERS_64"), "A semi-colon separated list of notification profilers to load in the form \"path={guid}\"", CLRConfig::LookupOptions::DontPrependPrefix)
+RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CORECLR_NOTIFICATION_PROFILERS_32, W("CORECLR_NOTIFICATION_PROFILERS_32"), "A semi-colon separated list of notification profilers to load in the form \"path={guid}\"", CLRConfig::LookupOptions::DontPrependPrefix)
+RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CORECLR_NOTIFICATION_PROFILERS, W("CORECLR_NOTIFICATION_PROFILERS"), "A semi-colon separated list of notification profilers to load in the form \"path={guid}\"", CLRConfig::LookupOptions::DontPrependPrefix)
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_ProfAPI_ProfilerCompatibilitySetting, W("ProfAPI_ProfilerCompatibilitySetting"), "Specifies the profiler loading policy (the default is not to load a V2 profiler in V4)", CLRConfig::LookupOptions::TrimWhiteSpaceFromStringValue)
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ProfAPI_DetachMinSleepMs, W("ProfAPI_DetachMinSleepMs"), 0, "The minimum time, in milliseconds, the CLR will wait before checking whether a profiler that is in the process of detaching is ready to be unloaded.")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ProfAPI_DetachMaxSleepMs, W("ProfAPI_DetachMaxSleepMs"), 0, "The maximum time, in milliseconds, the CLR will wait before checking whether a profiler that is in the process of detaching is ready to be unloaded.")
diff --git a/src/coreclr/inc/corprof.idl b/src/coreclr/inc/corprof.idl
index 74fb8099281..8fc965a84f6 100644
--- a/src/coreclr/inc/corprof.idl
+++ b/src/coreclr/inc/corprof.idl
@@ -475,6 +475,7 @@ typedef enum
// and ThreadNameChanged callbacks.
COR_PRF_MONITOR_THREADS = 0x00000200,
+ // CORECLR DEPRECATION WARNING: Remoting no longer exists in coreclr
// MONITOR_REMOTING controls the Remoting*
// callbacks.
COR_PRF_MONITOR_REMOTING = 0x00000400,
@@ -492,10 +493,12 @@ typedef enum
// callbacks.
COR_PRF_MONITOR_CCW = 0x00002000,
+ // CORECLR DEPRECATION WARNING: Remoting no longer exists in coreclr
// MONITOR_REMOTING_COOKIE controls whether
// a cookie will be passed to the Remoting* callbacks
COR_PRF_MONITOR_REMOTING_COOKIE = 0x00004000 | COR_PRF_MONITOR_REMOTING,
+ // CORECLR DEPRECATION WARNING: Remoting no longer exists in coreclr
// MONITOR_REMOTING_ASYNC controls whether
// the Remoting* callbacks will monitor async events
COR_PRF_MONITOR_REMOTING_ASYNC = 0x00008000 | COR_PRF_MONITOR_REMOTING,
@@ -594,6 +597,28 @@ typedef enum
COR_PRF_MONITOR_JIT_COMPILATION |
COR_PRF_ENABLE_REJIT,
+ COR_PRF_ALLOWABLE_NOTIFICATION_PROFILER
+ = COR_PRF_MONITOR_FUNCTION_UNLOADS |
+ COR_PRF_MONITOR_CLASS_LOADS |
+ COR_PRF_MONITOR_MODULE_LOADS |
+ COR_PRF_MONITOR_ASSEMBLY_LOADS |
+ COR_PRF_MONITOR_APPDOMAIN_LOADS |
+ COR_PRF_MONITOR_JIT_COMPILATION |
+ COR_PRF_MONITOR_EXCEPTIONS |
+ COR_PRF_MONITOR_OBJECT_ALLOCATED |
+ COR_PRF_MONITOR_THREADS |
+ COR_PRF_MONITOR_CODE_TRANSITIONS |
+ COR_PRF_MONITOR_CCW |
+ COR_PRF_MONITOR_SUSPENDS |
+ COR_PRF_MONITOR_CACHE_SEARCHES |
+ COR_PRF_DISABLE_INLINING |
+ COR_PRF_DISABLE_OPTIMIZATIONS |
+ COR_PRF_ENABLE_OBJECT_ALLOCATED |
+ COR_PRF_MONITOR_CLR_EXCEPTIONS |
+ COR_PRF_ENABLE_STACK_SNAPSHOT |
+ COR_PRF_USE_PROFILE_IMAGES |
+ COR_PRF_DISABLE_ALL_NGEN_IMAGES,
+
// MONITOR_IMMUTABLE represents all flags that may only be set during initialization.
// Trying to change any of these flags elsewhere will result in a
// failed HRESULT.
@@ -621,6 +646,7 @@ typedef enum
{
COR_PRF_HIGH_MONITOR_NONE = 0x00000000,
+ // CORECLR DEPRECATION WARNING: This flag is no longer checked by the runtime
COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES = 0x00000001,
COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x00000002,
@@ -648,6 +674,15 @@ typedef enum
COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED |
COR_PRF_HIGH_MONITOR_EVENT_PIPE,
+ COR_PRF_HIGH_ALLOWABLE_NOTIFICATION_PROFILER
+ = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED |
+ COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS |
+ COR_PRF_HIGH_DISABLE_TIERED_COMPILATION |
+ COR_PRF_HIGH_BASIC_GC |
+ COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS |
+ COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED |
+ COR_PRF_HIGH_MONITOR_EVENT_PIPE,
+
// MONITOR_IMMUTABLE represents all flags that may only be set during initialization.
// Trying to change any of these flags elsewhere will result in a
// failed HRESULT.
@@ -2433,6 +2468,7 @@ interface ICorProfilerCallback5 : ICorProfilerCallback4
]
interface ICorProfilerCallback6 : ICorProfilerCallback5
{
+ // CORECLR DEPRECATION WARNING: This callback does not occur on coreclr.
// Controlled by the COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES event mask flag.
// Notifies the profiler of a very early stage in the loading of an Assembly, where the CLR
// performs an assembly reference closure walk. This is useful ONLY if the profiler will need
@@ -2555,6 +2591,17 @@ interface ICorProfilerCallback10 : ICorProfilerCallback9
HRESULT EventPipeProviderCreated([in] EVENTPIPE_PROVIDER provider);
}
+[
+ object,
+ uuid(42350846-AAED-47F7-B128-FD0C98881CDE),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback11 : ICorProfilerCallback10
+{
+ HRESULT LoadAsNotficationOnly(BOOL *pbNotificationOnly);
+}
+
/*
* COR_PRF_CODEGEN_FLAGS controls various flags and hooks for a specific
* method. A combination of COR_PRF_CODEGEN_FLAGS is provided by the
diff --git a/src/coreclr/inc/profilepriv.h b/src/coreclr/inc/profilepriv.h
index bd5533f12c6..75d1c3dbcc2 100644
--- a/src/coreclr/inc/profilepriv.h
+++ b/src/coreclr/inc/profilepriv.h
@@ -16,8 +16,15 @@
// Forward declarations
class EEToProfInterfaceImpl;
+class ProfToEEInterfaceImpl;
class Object;
struct ScanContext;
+enum EtwGCRootFlags: int32_t;
+enum EtwGCRootKind: int32_t;
+struct IAssemblyBindingClosure;
+struct AssemblyReferenceClosureWalkContextForProfAPI;
+
+#include "eventpipeadaptertypes.h"
#if defined (PROFILING_SUPPORTED_DATA) || defined(PROFILING_SUPPORTED)
#ifndef PROFILING_SUPPORTED_DATA
@@ -25,6 +32,9 @@ struct ScanContext;
#endif // PROFILING_SUPPORTED_DATA
#include "corprof.h"
+#include "slist.h"
+
+#define MAX_NOTIFICATION_PROFILERS 32
//---------------------------------------------------------------------------------------
// Enumerates the various init states of profiling.
@@ -55,33 +65,183 @@ public:
void Set(ProfilerStatus profStatus);
};
-// ---------------------------------------------------------------------------------------
-// Global struct that lets the EE see the load status of the profiler, and provides a
-// pointer (pProfInterface) through which profiler calls can be made
-//
-// When you are adding new session, please refer to
-// code:ProfControlBlock::ResetPerSessionStatus#ProfileResetSessionStatus for more details.
-struct ProfControlBlock
+class EventMask
{
+ friend class ProfControlBlock;
+private:
+ const UINT64 EventMaskLowMask = 0x00000000FFFFFFFF;
+ const UINT64 EventMaskHighShiftAmount = 32;
+ const UINT64 EventMaskHighMask = 0xFFFFFFFF00000000;
+
+ Volatile<UINT64> m_eventMask;
+
+public:
+ EventMask() :
+ m_eventMask(0)
+ {
+
+ }
+
+ EventMask& operator=(const EventMask& other);
+
+ BOOL IsEventMaskSet(DWORD eventMask);
+ DWORD GetEventMask();
+ void SetEventMask(DWORD eventMask);
+ BOOL IsEventMaskHighSet(DWORD eventMaskHigh);
+ DWORD GetEventMaskHigh();
+ void SetEventMaskHigh(DWORD eventMaskHigh);
+};
+
+class ProfilerInfo
+{
+public:
// **** IMPORTANT!! ****
// All uses of pProfInterface must be properly synchronized to avoid the profiler
// from detaching while the EE attempts to call into it. The recommended way to do
- // this is to use the (lockless) BEGIN_PIN_PROFILER / END_PIN_PROFILER macros. See
- // code:BEGIN_PIN_PROFILER for instructions. For full details on how the
+ // this is to use the (lockless) BEGIN_PROFILER_CALLBACK / END_PROFILER_CALLBACK macros. See
+ // code:BEGIN_PROFILER_CALLBACK for instructions. For full details on how the
// synchronization works, see
// code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
VolatilePtr<EEToProfInterfaceImpl> pProfInterface;
// **** IMPORTANT!! ****
- DWORD dwEventMask; // Original low event mask bits
- DWORD dwEventMaskHigh; // New high event mask bits
CurrentProfilerStatus curProfStatus;
+
+ EventMask eventMask;
+
+ //---------------------------------------------------------------
+ // m_dwProfilerEvacuationCounter keeps track of how many profiler
+ // callback calls remain on the stack
+ //---------------------------------------------------------------
+ // Why volatile?
+ // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization.
+ Volatile<DWORD> dwProfilerEvacuationCounter;
+
+ Volatile<BOOL> inUse;
+
+ // Reset those variables that is only for the current attach session
+ void ResetPerSessionStatus();
+ void Init();
+};
+
+enum class ProfilerCallbackType
+{
+ Active,
+ ActiveOrInitializing
+};
+
+// We need a way to track which profilers are in active calls, to synchronize with detach.
+// If we detached a profiler while it was actively in a callback there would be issues.
+// However, we don't want to pin all profilers, because then a chatty profiler could
+// cause another profiler to not be able to detach. We can't just check the event masks
+// before and after the call because it is legal for a profiler to change its event mask,
+// and then it would be possible for a profiler to permanently prevent itself from detaching.
+//
+// WHEN IS EvacuationCounterHolder REQUIRED?
+// Answer: any time you access a ProfilerInfo *. There is a specific sequence that must be followed:
+// - Do a dirty read of the Profiler interface
+// - Increment an evacuation counter by using EvacuationCounterHolder as a RAII guard class
+// - Now do a clean read of the ProfilerInfo's status - this will be changed during detach and
+// is always read with a memory barrier
+//
+// The DoProfilerCallback/IterateProfilers functions automate this process for you, you should use
+// them unless you are absoultely sure you know what you're doing
+class EvacuationCounterHolder
+{
+private:
+ ProfilerInfo *m_pProfilerInfo;
+
+public:
+ EvacuationCounterHolder(ProfilerInfo *pProfilerInfo) :
+ m_pProfilerInfo(pProfilerInfo)
+ {
+ _ASSERTE(m_pProfilerInfo != NULL);
+ InterlockedIncrement((LONG *)(m_pProfilerInfo->dwProfilerEvacuationCounter.GetPointer()));
+ }
+
+ ~EvacuationCounterHolder()
+ {
+ InterlockedDecrement((LONG *)(m_pProfilerInfo->dwProfilerEvacuationCounter.GetPointer()));
+ }
+};
+
+struct StoredProfilerNode
+{
+ CLSID guid;
+ SString path;
+ SLink m_Link;
+};
+
+typedef SList<StoredProfilerNode, true> STOREDPROFILERLIST;
+// ---------------------------------------------------------------------------------------
+// Global struct that lets the EE see the load status of the profiler, and provides a
+// pointer (pProfInterface) through which profiler calls can be made
+//
+// When you are adding new session, please refer to
+// code:ProfControlBlock::ResetPerSessionStatus#ProfileResetSessionStatus for more details.
+class ProfControlBlock
+{
+private:
+ // IsProfilerPresent(pProfilerInfo) returns whether or not a CLR Profiler is actively loaded
+ // (meaning it's initialized and ready to receive callbacks).
+ FORCEINLINE BOOL IsProfilerPresent(ProfilerInfo *pProfilerInfo)
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return pProfilerInfo->curProfStatus.Get() >= kProfStatusActive;
+ }
+
+ FORCEINLINE BOOL IsProfilerPresentOrInitializing(ProfilerInfo *pProfilerInfo)
+ {
+ return pProfilerInfo->curProfStatus.Get() > kProfStatusDetaching;
+ }
+
+ template<typename Func, typename... Args>
+ FORCEINLINE VOID DoOneProfilerIteration(ProfilerInfo *pProfilerInfo, ProfilerCallbackType callbackType, Func callback, Args... args)
+ {
+ // This is the dirty read
+ if (pProfilerInfo->pProfInterface.Load() != NULL)
+ {
+#ifdef FEATURE_PROFAPI_ATTACH_DETACH
+ // Now indicate we are accessing the profiler
+ EvacuationCounterHolder evacuationCounter(pProfilerInfo);
+#endif // FEATURE_PROFAPI_ATTACH_DETACH
+
+ if ((callbackType == ProfilerCallbackType::Active && IsProfilerPresent(pProfilerInfo))
+ || (callbackType == ProfilerCallbackType::ActiveOrInitializing && IsProfilerPresentOrInitializing(pProfilerInfo)))
+ {
+ callback(pProfilerInfo, args...);
+ }
+ }
+ }
+
+ template<typename Func, typename... Args>
+ FORCEINLINE VOID IterateProfilers(ProfilerCallbackType callbackType, Func callback, Args... args)
+ {
+ DoOneProfilerIteration(&mainProfilerInfo, callbackType, callback, args...);
+
+ if (notificationProfilerCount > 0)
+ {
+ for (SIZE_T i = 0; i < MAX_NOTIFICATION_PROFILERS; ++i)
+ {
+ ProfilerInfo *current = &(notificationOnlyProfilers[i]);
+ DoOneProfilerIteration(current, callbackType, callback, args...);
+ }
+ }
+ }
+
+public:
BOOL fGCInProgress;
BOOL fBaseSystemClassesLoaded;
- BOOL fIsStoredProfilerRegistered;
- CLSID clsStoredProfilerGuid;
- SString sStoredProfilerPath;
+ STOREDPROFILERLIST storedProfilers;
+
+ ProfilerInfo mainProfilerInfo;
+
+ ProfilerInfo notificationOnlyProfilers[MAX_NOTIFICATION_PROFILERS];
+ Volatile<LONG> notificationProfilerCount;
+
+ EventMask globalEventMask;
#ifdef PROF_TEST_ONLY_FORCE_ELT_DATA
// #TestOnlyELT This implements a test-only (and debug-only) hook that allows a test
@@ -118,14 +278,128 @@ struct ProfControlBlock
#endif // _DEBUG
// Whether we've turned off concurrent GC during attach
- BOOL fConcurrentGCDisabledForAttach;
+ Volatile<BOOL> fConcurrentGCDisabledForAttach;
Volatile<BOOL> fProfControlBlockInitialized;
Volatile<BOOL> fProfilerRequestedRuntimeSuspend;
void Init();
- void ResetPerSessionStatus();
+ BOOL IsMainProfiler(EEToProfInterfaceImpl *pEEToProf);
+ BOOL IsMainProfiler(ProfToEEInterfaceImpl *pProfToEE);
+ ProfilerInfo *GetProfilerInfo(ProfToEEInterfaceImpl *pProfToEE);
+
+ template<typename ConditionFunc, typename CallbackFunc, typename Data = void, typename... Args>
+ FORCEINLINE HRESULT DoProfilerCallback(ProfilerCallbackType callbackType, ConditionFunc condition, Data *additionalData, CallbackFunc callback, Args... args)
+ {
+ HRESULT hr = S_OK;
+ IterateProfilers(callbackType,
+ [](ProfilerInfo *pProfilerInfo, ConditionFunc condition, Data *additionalData, CallbackFunc callback, HRESULT *pHR, Args... args)
+ {
+ if (condition(pProfilerInfo))
+ {
+ HRESULT innerHR = callback(additionalData, pProfilerInfo->pProfInterface, args...);
+ if (FAILED(innerHR))
+ {
+ *pHR = innerHR;
+ }
+ }
+ },
+ condition, additionalData, callback, &hr, args...);
+ return hr;
+ }
+
+#ifndef DACCESS_COMPILE
+ ProfilerInfo *FindNextFreeProfilerInfoSlot();
+ void DeRegisterProfilerInfo(ProfilerInfo *pProfilerInfo);
+ void UpdateGlobalEventMask();
+#endif // DACCESS_COMPILE
+
+ BOOL IsCallback3Supported();
+ BOOL IsCallback5Supported();
+ BOOL IsDisableTransparencySet();
+ BOOL RequiresGenericsContextForEnterLeave();
+ UINT_PTR EEFunctionIDMapper(FunctionID funcId, BOOL * pbHookFunction);
+
+ void ThreadCreated(ThreadID threadID);
+ void ThreadDestroyed(ThreadID threadID);
+ void ThreadAssignedToOSThread(ThreadID managedThreadId, DWORD osThreadId);
+ void ThreadNameChanged(ThreadID managedThreadId, ULONG cchName, WCHAR name[]);
+ void Shutdown();
+ void FunctionUnloadStarted(FunctionID functionId);
+ void JITCompilationFinished(FunctionID functionId, HRESULT hrStatus, BOOL fIsSafeToBlock);
+ void JITCompilationStarted(FunctionID functionId, BOOL fIsSafeToBlock);
+ void DynamicMethodJITCompilationStarted(FunctionID functionId, BOOL fIsSafeToBlock, LPCBYTE pILHeader, ULONG cbILHeader);
+ void DynamicMethodJITCompilationFinished(FunctionID functionId, HRESULT hrStatus, BOOL fIsSafeToBlock);
+ void DynamicMethodUnloaded(FunctionID functionId);
+ void JITCachedFunctionSearchStarted(FunctionID functionId, BOOL *pbUseCachedFunction);
+ void JITCachedFunctionSearchFinished(FunctionID functionId, COR_PRF_JIT_CACHE result);
+ HRESULT JITInlining(FunctionID callerId, FunctionID calleeId, BOOL *pfShouldInline);
+ void ReJITCompilationStarted(FunctionID functionId, ReJITID reJitId, BOOL fIsSafeToBlock);
+ HRESULT GetReJITParameters(ModuleID moduleId, mdMethodDef methodId, ICorProfilerFunctionControl *pFunctionControl);
+ void ReJITCompilationFinished(FunctionID functionId, ReJITID reJitId, HRESULT hrStatus, BOOL fIsSafeToBlock);
+ void ReJITError(ModuleID moduleId, mdMethodDef methodId, FunctionID functionId, HRESULT hrStatus);
+ void ModuleLoadStarted(ModuleID moduleId);
+ void ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus);
+ void ModuleUnloadStarted(ModuleID moduleId);
+ void ModuleUnloadFinished(ModuleID moduleId, HRESULT hrStatus);
+ void ModuleAttachedToAssembly(ModuleID moduleId, AssemblyID AssemblyId);
+ void ModuleInMemorySymbolsUpdated(ModuleID moduleId);
+ void ClassLoadStarted(ClassID classId);
+ void ClassLoadFinished(ClassID classId, HRESULT hrStatus);
+ void ClassUnloadStarted(ClassID classId);
+ void ClassUnloadFinished(ClassID classId, HRESULT hrStatus);
+ void AppDomainCreationStarted(AppDomainID appDomainId);
+ void AppDomainCreationFinished(AppDomainID appDomainId, HRESULT hrStatus);
+ void AppDomainShutdownStarted(AppDomainID appDomainId);
+ void AppDomainShutdownFinished(AppDomainID appDomainId, HRESULT hrStatus);
+ void AssemblyLoadStarted(AssemblyID assemblyId);
+ void AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus);
+ void AssemblyUnloadStarted(AssemblyID assemblyId);
+ void AssemblyUnloadFinished(AssemblyID assemblyId, HRESULT hrStatus);
+ void UnmanagedToManagedTransition(FunctionID functionId, COR_PRF_TRANSITION_REASON reason);
+ void ManagedToUnmanagedTransition(FunctionID functionId, COR_PRF_TRANSITION_REASON reason);
+ void ExceptionThrown(ObjectID thrownObjectId);
+ void ExceptionSearchFunctionEnter(FunctionID functionId);
+ void ExceptionSearchFunctionLeave();
+ void ExceptionSearchFilterEnter(FunctionID funcId);
+ void ExceptionSearchFilterLeave();
+ void ExceptionSearchCatcherFound(FunctionID functionId);
+ void ExceptionOSHandlerEnter(FunctionID funcId);
+ void ExceptionOSHandlerLeave(FunctionID funcId);
+ void ExceptionUnwindFunctionEnter(FunctionID functionId);
+ void ExceptionUnwindFunctionLeave();
+ void ExceptionUnwindFinallyEnter(FunctionID functionId);
+ void ExceptionUnwindFinallyLeave();
+ void ExceptionCatcherEnter(FunctionID functionId, ObjectID objectId);
+ void ExceptionCatcherLeave();
+ void COMClassicVTableCreated(ClassID wrappedClassId, REFGUID implementedIID, void *pVTable, ULONG cSlots);
+ void RuntimeSuspendStarted(COR_PRF_SUSPEND_REASON suspendReason);
+ void RuntimeSuspendFinished();
+ void RuntimeSuspendAborted();
+ void RuntimeResumeStarted();
+ void RuntimeResumeFinished();
+ void RuntimeThreadSuspended(ThreadID suspendedThreadId);
+ void RuntimeThreadResumed(ThreadID resumedThreadId);
+ void ObjectAllocated(ObjectID objectId, ClassID classId);
+ void FinalizeableObjectQueued(BOOL isCritical, ObjectID objectID);
+ void MovedReference(BYTE *pbMemBlockStart, BYTE *pbMemBlockEnd, ptrdiff_t cbRelocDistance, void *pHeapId, BOOL fCompacting);
+ void EndMovedReferences(void *pHeapId);
+ void RootReference2(BYTE *objectId, EtwGCRootKind dwEtwRootKind, EtwGCRootFlags dwEtwRootFlags, void *rootID, void *pHeapId);
+ void EndRootReferences2(void *pHeapId);
+ void ConditionalWeakTableElementReference(BYTE *primaryObjectId, BYTE *secondaryObjectId, void *rootID, void *pHeapId);
+ void EndConditionalWeakTableElementReferences(void *pHeapId);
+ void AllocByClass(ObjectID objId, ClassID classId, void *pHeapId);
+ void EndAllocByClass(void *pHeapId);
+ HRESULT ObjectReference(ObjectID objId, ClassID classId, ULONG cNumRefs, ObjectID *arrObjRef);
+ void HandleCreated(UINT_PTR handleId, ObjectID initialObjectId);
+ void HandleDestroyed(UINT_PTR handleId);
+ void GarbageCollectionStarted(int cGenerations, BOOL generationCollected[], COR_PRF_GC_REASON reason);
+ void GarbageCollectionFinished();
+ void GetAssemblyReferences(LPCWSTR wszAssemblyPath, IAssemblyBindingClosure *pClosure, AssemblyReferenceClosureWalkContextForProfAPI *pContext);
+ void EventPipeEventDelivered(EventPipeProvider *provider, DWORD eventId, DWORD eventVersion, ULONG cbMetadataBlob, LPCBYTE metadataBlob, ULONG cbEventData,
+ LPCBYTE eventData, LPCGUID pActivityId, LPCGUID pRelatedActivityId, Thread *pEventThread, ULONG numStackFrames, UINT_PTR stackFrames[]);
+ void EventPipeProviderCreated(EventPipeProvider *provider);
};
diff --git a/src/coreclr/inc/profilepriv.inl b/src/coreclr/inc/profilepriv.inl
index 41e0bf3da96..08ba58f5623 100644
--- a/src/coreclr/inc/profilepriv.inl
+++ b/src/coreclr/inc/profilepriv.inl
@@ -17,7 +17,6 @@
#include "eetoprofinterfaceimpl.h"
#ifdef PROFILING_SUPPORTED
#include "profilinghelper.h"
-BOOL CORProfilerBypassSecurityChecks();
#endif // PROFILING_SUPPORTED
//---------------------------------------------------------------------------------------
@@ -36,6 +35,76 @@ inline ProfilerStatus CurrentProfilerStatus::Get()
return m_profStatus;
}
+inline EventMask& EventMask::operator=(const EventMask& other)
+{
+ m_eventMask = other.m_eventMask;
+ return *this;
+}
+
+inline BOOL EventMask::IsEventMaskSet(DWORD eventMask)
+{
+ return (GetEventMask() & eventMask) != 0;
+}
+
+inline DWORD EventMask::GetEventMask()
+{
+ return (DWORD)(m_eventMask & EventMaskLowMask);
+}
+
+inline void EventMask::SetEventMask(DWORD eventMask)
+{
+ m_eventMask = (m_eventMask & EventMaskHighMask) | (UINT64)eventMask;
+}
+
+inline BOOL EventMask::IsEventMaskHighSet(DWORD eventMaskHigh)
+{
+ return (GetEventMaskHigh() & eventMaskHigh) != 0;
+}
+
+inline DWORD EventMask::GetEventMaskHigh()
+{
+ return (DWORD)((m_eventMask & EventMaskHighMask) >> EventMaskHighShiftAmount);
+}
+
+inline void EventMask::SetEventMaskHigh(DWORD eventMaskHigh)
+{
+ m_eventMask = (m_eventMask & EventMaskLowMask) | ((UINT64)eventMaskHigh << EventMaskHighShiftAmount);
+}
+
+// Reset those variables that is only for the current attach session
+inline void ProfilerInfo::ResetPerSessionStatus()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ pProfInterface = NULL;
+ eventMask.SetEventMask(COR_PRF_MONITOR_NONE);
+ eventMask.SetEventMaskHigh(COR_PRF_HIGH_MONITOR_NONE);
+}
+
+inline void ProfilerInfo::Init()
+{
+ curProfStatus.Init();
+ dwProfilerEvacuationCounter = 0;
+ ResetPerSessionStatus();
+ inUse = FALSE;
+}
+
+template<typename ConditionFunc>
+inline BOOL AnyProfilerPassesCondition(ConditionFunc condition)
+{
+ BOOL anyPassed = FALSE;
+ (&g_profControlBlock)->DoProfilerCallback(ProfilerCallbackType::ActiveOrInitializing,
+ condition,
+ &anyPassed,
+ [](BOOL *pAnyPassed, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ *pAnyPassed = TRUE;
+ return S_OK;
+ });
+
+ return anyPassed;
+}
+
//---------------------------------------------------------------------------------------
// ProfControlBlock
//---------------------------------------------------------------------------------------
@@ -50,7 +119,15 @@ inline void ProfControlBlock::Init()
}
CONTRACTL_END;
- curProfStatus.Init();
+ mainProfilerInfo.Init();
+
+ for (SIZE_T i = 0; i < MAX_NOTIFICATION_PROFILERS; ++i)
+ {
+ notificationOnlyProfilers[i].Init();
+ }
+
+ globalEventMask.SetEventMask(COR_PRF_MONITOR_NONE);
+ globalEventMask.SetEventMaskHigh(COR_PRF_HIGH_MONITOR_NONE);
fGCInProgress = FALSE;
fBaseSystemClassesLoaded = FALSE;
@@ -68,21 +145,1518 @@ inline void ProfControlBlock::Init()
fConcurrentGCDisabledForAttach = FALSE;
- ResetPerSessionStatus();
+ mainProfilerInfo.ResetPerSessionStatus();
fProfControlBlockInitialized = TRUE;
fProfilerRequestedRuntimeSuspend = FALSE;
}
-// Reset those variables that is only for the current attach session
-inline void ProfControlBlock::ResetPerSessionStatus()
+
+inline BOOL ProfControlBlock::IsMainProfiler(EEToProfInterfaceImpl *pEEToProf)
+{
+ EEToProfInterfaceImpl *pProfInterface = mainProfilerInfo.pProfInterface.Load();
+ return pProfInterface == pEEToProf;
+}
+
+inline BOOL ProfControlBlock::IsMainProfiler(ProfToEEInterfaceImpl *pProfToEE)
+{
+ EEToProfInterfaceImpl *pProfInterface = mainProfilerInfo.pProfInterface.Load();
+ return pProfInterface != NULL && pProfInterface->m_pProfToEE == pProfToEE;
+}
+
+inline ProfilerInfo *ProfControlBlock::GetProfilerInfo(ProfToEEInterfaceImpl *pProfToEE)
+{
+ ProfilerInfo *pProfilerInfo = NULL;
+ IterateProfilers(ProfilerCallbackType::Active,
+ [](ProfilerInfo *pProfilerInfo, ProfToEEInterfaceImpl *pProfToEE, ProfilerInfo **ppFoundProfilerInfo)
+ {
+ if (pProfilerInfo->pProfInterface->m_pProfToEE == pProfToEE)
+ {
+ *ppFoundProfilerInfo = pProfilerInfo;
+ }
+ },
+ pProfToEE,
+ &pProfilerInfo);
+
+ return pProfilerInfo;
+}
+
+#ifndef DACCESS_COMPILE
+inline ProfilerInfo *ProfControlBlock::FindNextFreeProfilerInfoSlot()
+{
+ for (SIZE_T i = 0; i < MAX_NOTIFICATION_PROFILERS; ++i)
+ {
+ if (InterlockedCompareExchange((LONG *)notificationOnlyProfilers[i].inUse.GetPointer(), TRUE, FALSE) == FALSE)
+ {
+ InterlockedIncrement(notificationProfilerCount.GetPointer());
+ return &(notificationOnlyProfilers[i]);
+ }
+ }
+
+ return NULL;
+}
+
+inline void ProfControlBlock::DeRegisterProfilerInfo(ProfilerInfo *pProfilerInfo)
+{
+ pProfilerInfo->inUse = FALSE;
+ InterlockedDecrement(notificationProfilerCount.GetPointer());
+}
+
+inline void ProfControlBlock::UpdateGlobalEventMask()
+{
+ while (true)
+ {
+ UINT64 originalEventMask = globalEventMask.m_eventMask;
+ UINT64 qwEventMask = 0;
+
+ IterateProfilers(ProfilerCallbackType::ActiveOrInitializing,
+ [](ProfilerInfo *pProfilerInfo, UINT64 *pEventMask)
+ {
+ *pEventMask |= pProfilerInfo->eventMask.m_eventMask;
+ },
+ &qwEventMask);
+
+ // We are relying on the memory barrier introduced by InterlockedCompareExchange64 to observer any
+ // change to the global event mask.
+ if ((UINT64)InterlockedCompareExchange64((LONG64 *)&(globalEventMask.m_eventMask), (LONG64)qwEventMask, (LONG64)originalEventMask) == originalEventMask)
+ {
+ break;
+ }
+ }
+}
+#endif // DACCESS_COMPILE
+
+inline BOOL ProfControlBlock::IsCallback3Supported()
+{
+ return AnyProfilerPassesCondition([](ProfilerInfo *pProfilerInfo) { return pProfilerInfo->pProfInterface->IsCallback3Supported(); });
+}
+
+inline BOOL ProfControlBlock::IsCallback5Supported()
+{
+ return AnyProfilerPassesCondition([](ProfilerInfo *pProfilerInfo) { return pProfilerInfo->pProfInterface->IsCallback5Supported(); });
+}
+
+inline BOOL ProfControlBlock::IsDisableTransparencySet()
+{
+ return AnyProfilerPassesCondition([](ProfilerInfo *pProfilerInfo) { return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST); });
+}
+
+inline BOOL ProfControlBlock::RequiresGenericsContextForEnterLeave()
+{
+ return AnyProfilerPassesCondition([](ProfilerInfo *pProfilerInfo) { return pProfilerInfo->pProfInterface->RequiresGenericsContextForEnterLeave(); });
+}
+
+inline bool DoesProfilerWantEEFunctionIDMapper(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return ((pProfilerInfo->pProfInterface->GetFunctionIDMapper() != NULL) ||
+ (pProfilerInfo->pProfInterface->GetFunctionIDMapper2() != NULL));
+}
+
+inline UINT_PTR ProfControlBlock::EEFunctionIDMapper(FunctionID funcId, BOOL *pbHookFunction)
{
LIMITED_METHOD_CONTRACT;
+ UINT_PTR ptr = NULL;
+ DoOneProfilerIteration(&mainProfilerInfo,
+ ProfilerCallbackType::Active,
+ [](ProfilerInfo *pProfilerInfo, FunctionID funcId, BOOL *pbHookFunction, UINT_PTR *pPtr)
+ {
+ if (DoesProfilerWantEEFunctionIDMapper(pProfilerInfo))
+ {
+ *pPtr = pProfilerInfo->pProfInterface->EEFunctionIDMapper(funcId, pbHookFunction);
+ }
+ },
+ funcId, pbHookFunction, &ptr);
+
+ return ptr;
+}
- pProfInterface = NULL;
- dwEventMask = COR_PRF_MONITOR_NONE;
- dwEventMaskHigh = COR_PRF_HIGH_MONITOR_NONE;
+inline BOOL IsProfilerTrackingThreads(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_THREADS);
+}
+
+inline void ProfControlBlock::ThreadCreated(ThreadID threadID)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingThreads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ThreadID threadID)
+ {
+ return profInterface->ThreadCreated(threadID);
+ },
+ threadID);
+}
+
+inline void ProfControlBlock::ThreadDestroyed(ThreadID threadID)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingThreads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ThreadID threadID)
+ {
+ return profInterface->ThreadDestroyed(threadID);
+ },
+ threadID);
+}
+
+inline void ProfControlBlock::ThreadAssignedToOSThread(ThreadID managedThreadId, DWORD osThreadId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingThreads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ThreadID managedThreadId, DWORD osThreadId)
+ {
+ return profInterface->ThreadAssignedToOSThread(managedThreadId, osThreadId);
+ },
+ managedThreadId, osThreadId);
+}
+
+inline void ProfControlBlock::ThreadNameChanged(ThreadID managedThreadId, ULONG cchName, WCHAR name[])
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingThreads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ThreadID managedThreadId, ULONG cchName, WCHAR name[])
+ {
+ return profInterface->ThreadNameChanged(managedThreadId, cchName, name);
+ },
+ managedThreadId, cchName, name);
+}
+
+inline void ProfControlBlock::Shutdown()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ [](ProfilerInfo *pProfilerInfo) { return true; },
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->Shutdown();
+ });
+}
+
+inline BOOL IsProfilerTrackingJITInfo(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_JIT_COMPILATION);
+}
+
+inline void ProfControlBlock::JITCompilationFinished(FunctionID functionId, HRESULT hrStatus, BOOL fIsSafeToBlock)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingJITInfo,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, HRESULT hrStatus, BOOL fIsSafeToBlock)
+ {
+ return profInterface->JITCompilationFinished(functionId, hrStatus, fIsSafeToBlock);
+ },
+ functionId, hrStatus, fIsSafeToBlock);
+}
+
+inline void ProfControlBlock::JITCompilationStarted(FunctionID functionId, BOOL fIsSafeToBlock)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingJITInfo,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, BOOL fIsSafeToBlock)
+ {
+ return profInterface->JITCompilationStarted(functionId, fIsSafeToBlock);
+ },
+ functionId, fIsSafeToBlock);
+}
+
+inline void ProfControlBlock::DynamicMethodJITCompilationStarted(FunctionID functionId, BOOL fIsSafeToBlock, LPCBYTE pILHeader, ULONG cbILHeader)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingJITInfo,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, BOOL fIsSafeToBlock, LPCBYTE pILHeader, ULONG cbILHeader)
+ {
+ return profInterface->DynamicMethodJITCompilationStarted(functionId, fIsSafeToBlock, pILHeader, cbILHeader);
+ },
+ functionId, fIsSafeToBlock, pILHeader, cbILHeader);
+}
+
+inline void ProfControlBlock::DynamicMethodJITCompilationFinished(FunctionID functionId, HRESULT hrStatus, BOOL fIsSafeToBlock)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingJITInfo,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, HRESULT hrStatus, BOOL fIsSafeToBlock)
+ {
+ return profInterface->DynamicMethodJITCompilationFinished(functionId, hrStatus, fIsSafeToBlock);
+ },
+ functionId, hrStatus, fIsSafeToBlock);
+}
+
+inline BOOL IsProfilerMonitoringDynamicFunctionUnloads(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS);
+}
+
+inline void ProfControlBlock::DynamicMethodUnloaded(FunctionID functionId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerMonitoringDynamicFunctionUnloads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId)
+ {
+ return profInterface->DynamicMethodUnloaded(functionId);
+ },
+ functionId);
+}
+
+inline BOOL IsProfilerTrackingCacheSearches(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_CACHE_SEARCHES);
+}
+
+inline void ProfControlBlock::JITCachedFunctionSearchStarted(FunctionID functionId, BOOL *pbUseCachedFunction)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ BOOL allTrue = TRUE;
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingCacheSearches,
+ &allTrue,
+ [](BOOL *pAllTrue, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, BOOL *pbUseCachedFunction)
+ {
+ HRESULT hr = profInterface->JITCachedFunctionSearchStarted(functionId, pbUseCachedFunction);
+ *pAllTrue &= *pbUseCachedFunction;
+ return hr;
+ },
+ functionId, pbUseCachedFunction);
+
+ // If any reject it, consider it rejected.
+ *pbUseCachedFunction = allTrue;
+}
+
+inline void ProfControlBlock::JITCachedFunctionSearchFinished(FunctionID functionId, COR_PRF_JIT_CACHE result)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingCacheSearches,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, COR_PRF_JIT_CACHE result)
+ {
+ return profInterface->JITCachedFunctionSearchFinished(functionId, result);
+ },
+ functionId, result);
+}
+
+inline HRESULT ProfControlBlock::JITInlining(FunctionID callerId, FunctionID calleeId, BOOL *pfShouldInline)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ BOOL allTrue = TRUE;
+ HRESULT hr = DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingJITInfo,
+ &allTrue,
+ [](BOOL *pAllTrue, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID callerId, FunctionID calleeId, BOOL *pfShouldInline)
+ {
+ HRESULT hr = profInterface->JITInlining(callerId, calleeId, pfShouldInline);
+ *pAllTrue &= *pfShouldInline;
+ return hr;
+ },
+ callerId, calleeId, pfShouldInline);
+
+ // If any reject it, consider it rejected.
+ *pfShouldInline = allTrue;
+ return hr;
+}
+
+inline BOOL IsRejitEnabled(ProfilerInfo *pProfilerInfo)
+{
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_ENABLE_REJIT);
+}
+
+inline void ProfControlBlock::ReJITCompilationStarted(FunctionID functionId, ReJITID reJitId, BOOL fIsSafeToBlock)
+{
+ LIMITED_METHOD_CONTRACT;
+ DoOneProfilerIteration(&mainProfilerInfo,
+ ProfilerCallbackType::Active,
+ [](ProfilerInfo *pProfilerInfo, FunctionID functionId, ReJITID reJitId, BOOL fIsSafeToBlock)
+ {
+ if (IsRejitEnabled(pProfilerInfo))
+ {
+ pProfilerInfo->pProfInterface->ReJITCompilationStarted(functionId, reJitId, fIsSafeToBlock);
+ }
+ },
+ functionId, reJitId, fIsSafeToBlock);
+}
+
+inline HRESULT ProfControlBlock::GetReJITParameters(ModuleID moduleId, mdMethodDef methodId, ICorProfilerFunctionControl *pFunctionControl)
+{
+ LIMITED_METHOD_CONTRACT;
+ HRESULT hr = S_OK;
+ DoOneProfilerIteration(&mainProfilerInfo,
+ ProfilerCallbackType::Active,
+ [](ProfilerInfo *pProfilerInfo, ModuleID moduleId, mdMethodDef methodId, ICorProfilerFunctionControl *pFunctionControl, HRESULT *pHr)
+ {
+ if (IsRejitEnabled(pProfilerInfo))
+ {
+ *pHr = pProfilerInfo->pProfInterface->GetReJITParameters(moduleId, methodId, pFunctionControl);
+ }
+ },
+ moduleId, methodId, pFunctionControl, &hr);
+ return hr;
+}
+
+inline void ProfControlBlock::ReJITCompilationFinished(FunctionID functionId, ReJITID reJitId, HRESULT hrStatus, BOOL fIsSafeToBlock)
+{
+ LIMITED_METHOD_CONTRACT;
+ DoOneProfilerIteration(&mainProfilerInfo,
+ ProfilerCallbackType::Active,
+ [](ProfilerInfo *pProfilerInfo, FunctionID functionId, ReJITID reJitId, HRESULT hrStatus, BOOL fIsSafeToBlock)
+ {
+ if (IsRejitEnabled(pProfilerInfo))
+ {
+ pProfilerInfo->pProfInterface->ReJITCompilationFinished(functionId, reJitId, hrStatus, fIsSafeToBlock);
+ }
+ },
+ functionId, reJitId, hrStatus, fIsSafeToBlock);
+}
+
+inline void ProfControlBlock::ReJITError(ModuleID moduleId, mdMethodDef methodId, FunctionID functionId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+ DoOneProfilerIteration(&mainProfilerInfo,
+ ProfilerCallbackType::Active,
+ [](ProfilerInfo *pProfilerInfo, ModuleID moduleId, mdMethodDef methodId, FunctionID functionId, HRESULT hrStatus)
+ {
+ if (IsRejitEnabled(pProfilerInfo))
+ {
+ pProfilerInfo->pProfInterface->ReJITError(moduleId, methodId, functionId, hrStatus);
+ }
+ },
+ moduleId, methodId, functionId, hrStatus);
+}
+
+inline BOOL IsProfilerTrackingModuleLoads(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_MODULE_LOADS);
+}
+
+inline void ProfControlBlock::ModuleLoadStarted(ModuleID moduleId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingModuleLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ModuleID moduleId)
+ {
+ return profInterface->ModuleLoadStarted(moduleId);
+ },
+ moduleId);
+}
+
+inline void ProfControlBlock::ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingModuleLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ModuleID moduleId, HRESULT hrStatus)
+ {
+ return profInterface->ModuleLoadFinished(moduleId, hrStatus);
+ },
+ moduleId, hrStatus);
+}
+
+inline void ProfControlBlock::ModuleUnloadStarted(ModuleID moduleId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingModuleLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ModuleID moduleId)
+ {
+ return profInterface->ModuleUnloadStarted(moduleId);
+ },
+ moduleId);
+}
+
+inline void ProfControlBlock::ModuleUnloadFinished(ModuleID moduleId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingModuleLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ModuleID moduleId, HRESULT hrStatus)
+ {
+ return profInterface->ModuleUnloadFinished(moduleId, hrStatus);
+ },
+ moduleId, hrStatus);
+}
+
+inline void ProfControlBlock::ModuleAttachedToAssembly(ModuleID moduleId, AssemblyID AssemblyId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingModuleLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ModuleID moduleId, AssemblyID AssemblyId)
+ {
+ return profInterface->ModuleAttachedToAssembly(moduleId, AssemblyId);
+ },
+ moduleId, AssemblyId);
+}
+
+inline BOOL IsProfilerTrackingInMemorySymbolsUpdatesEnabled(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskHighSet(COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED);
+}
+
+inline void ProfControlBlock::ModuleInMemorySymbolsUpdated(ModuleID moduleId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingInMemorySymbolsUpdatesEnabled,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ModuleID moduleId)
+ {
+ return profInterface->ModuleInMemorySymbolsUpdated(moduleId);
+ },
+ moduleId);
+}
+
+inline BOOL IsProfilerTrackingClasses(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_CLASS_LOADS);
+}
+
+inline void ProfControlBlock::ClassLoadStarted(ClassID classId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingClasses,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ClassID classId)
+ {
+ return profInterface->ClassLoadStarted(classId);
+ },
+ classId);
+}
+
+inline void ProfControlBlock::ClassLoadFinished(ClassID classId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingClasses,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ClassID classId, HRESULT hrStatus)
+ {
+ return profInterface->ClassLoadFinished(classId, hrStatus);
+ },
+ classId, hrStatus);
+}
+
+inline void ProfControlBlock::ClassUnloadStarted(ClassID classId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingClasses,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ClassID classId)
+ {
+ return profInterface->ClassUnloadStarted(classId);
+ },
+ classId);
+}
+
+inline void ProfControlBlock::ClassUnloadFinished(ClassID classId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingClasses,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ClassID classId, HRESULT hrStatus)
+ {
+ return profInterface->ClassUnloadFinished(classId, hrStatus);
+ },
+ classId, hrStatus);
+}
+
+inline BOOL IsProfilerTrackingAppDomainLoads(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_APPDOMAIN_LOADS);
+}
+
+inline void ProfControlBlock::AppDomainCreationStarted(AppDomainID appDomainId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAppDomainLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AppDomainID appDomainId)
+ {
+ return profInterface->AppDomainCreationStarted(appDomainId);
+ },
+ appDomainId);
+}
+
+inline void ProfControlBlock::AppDomainCreationFinished(AppDomainID appDomainId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAppDomainLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AppDomainID appDomainId, HRESULT hrStatus)
+ {
+ return profInterface->AppDomainCreationFinished(appDomainId, hrStatus);
+ },
+ appDomainId, hrStatus);
+}
+
+inline void ProfControlBlock::AppDomainShutdownStarted(AppDomainID appDomainId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAppDomainLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AppDomainID appDomainId)
+ {
+ return profInterface->AppDomainShutdownStarted(appDomainId);
+ },
+ appDomainId);
+}
+
+inline void ProfControlBlock::AppDomainShutdownFinished(AppDomainID appDomainId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAppDomainLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AppDomainID appDomainId, HRESULT hrStatus)
+ {
+ return profInterface->AppDomainShutdownFinished(appDomainId, hrStatus);
+ },
+ appDomainId, hrStatus);
+}
+
+inline BOOL IsProfilerTrackingAssemblyLoads(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_ASSEMBLY_LOADS);
+}
+
+inline void ProfControlBlock::AssemblyLoadStarted(AssemblyID assemblyId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAssemblyLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AssemblyID assemblyId)
+ {
+ return profInterface->AssemblyLoadStarted(assemblyId);
+ },
+ assemblyId);
+}
+
+inline void ProfControlBlock::AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAssemblyLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AssemblyID assemblyId, HRESULT hrStatus)
+ {
+ return profInterface->AssemblyLoadFinished(assemblyId, hrStatus);
+ },
+ assemblyId, hrStatus);
+}
+
+inline void ProfControlBlock::AssemblyUnloadStarted(AssemblyID assemblyId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAssemblyLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AssemblyID assemblyId)
+ {
+ return profInterface->AssemblyUnloadStarted(assemblyId);
+ },
+ assemblyId);
+}
+
+inline void ProfControlBlock::AssemblyUnloadFinished(AssemblyID assemblyId, HRESULT hrStatus)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAssemblyLoads,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, AssemblyID assemblyId, HRESULT hrStatus)
+ {
+ return profInterface->AssemblyUnloadFinished(assemblyId, hrStatus);
+ },
+ assemblyId, hrStatus);
+}
+
+inline BOOL IsProfilerTrackingTransitions(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_CODE_TRANSITIONS);
+}
+
+inline void ProfControlBlock::UnmanagedToManagedTransition(FunctionID functionId, COR_PRF_TRANSITION_REASON reason)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingTransitions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, COR_PRF_TRANSITION_REASON reason)
+ {
+ return profInterface->UnmanagedToManagedTransition(functionId, reason);
+ },
+ functionId, reason);
+}
+
+inline void ProfControlBlock::ManagedToUnmanagedTransition(FunctionID functionId, COR_PRF_TRANSITION_REASON reason)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingTransitions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, COR_PRF_TRANSITION_REASON reason)
+ {
+ return profInterface->ManagedToUnmanagedTransition(functionId, reason);
+ },
+ functionId, reason);
+}
+
+inline BOOL IsProfilerTrackingExceptions(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_EXCEPTIONS);
+}
+
+inline void ProfControlBlock::ExceptionThrown(ObjectID thrownObjectId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ObjectID thrownObjectId)
+ {
+ return profInterface->ExceptionThrown(thrownObjectId);
+ },
+ thrownObjectId);
+}
+
+inline void ProfControlBlock::ExceptionSearchFunctionEnter(FunctionID functionId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId)
+ {
+ return profInterface->ExceptionSearchFunctionEnter(functionId);
+ },
+ functionId);
+}
+
+inline void ProfControlBlock::ExceptionSearchFunctionLeave()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->ExceptionSearchFunctionLeave();
+ });
+}
+
+inline void ProfControlBlock::ExceptionSearchFilterEnter(FunctionID funcId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID funcId)
+ {
+ return profInterface->ExceptionSearchFilterEnter(funcId);
+ },
+ funcId);
+}
+
+inline void ProfControlBlock::ExceptionSearchFilterLeave()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->ExceptionSearchFilterLeave();
+ });
+}
+
+inline void ProfControlBlock::ExceptionSearchCatcherFound(FunctionID functionId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId)
+ {
+ return profInterface->ExceptionSearchCatcherFound(functionId);
+ },
+ functionId);
+}
+
+inline void ProfControlBlock::ExceptionOSHandlerEnter(FunctionID funcId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID funcId)
+ {
+ return profInterface->ExceptionOSHandlerEnter(funcId);
+ },
+ funcId);
+}
+
+inline void ProfControlBlock::ExceptionOSHandlerLeave(FunctionID funcId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID funcId)
+ {
+ return profInterface->ExceptionOSHandlerLeave(funcId);
+ },
+ funcId);
+}
+
+inline void ProfControlBlock::ExceptionUnwindFunctionEnter(FunctionID functionId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId)
+ {
+ return profInterface->ExceptionUnwindFunctionEnter(functionId);
+ },
+ functionId);
+}
+
+inline void ProfControlBlock::ExceptionUnwindFunctionLeave()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->ExceptionUnwindFunctionLeave();
+ });
+}
+
+inline void ProfControlBlock::ExceptionUnwindFinallyEnter(FunctionID functionId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId)
+ {
+ return profInterface->ExceptionUnwindFinallyEnter(functionId);
+ },
+ functionId);
+}
+
+inline void ProfControlBlock::ExceptionUnwindFinallyLeave()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->ExceptionUnwindFinallyLeave();
+ });
+}
+
+inline void ProfControlBlock::ExceptionCatcherEnter(FunctionID functionId, ObjectID objectId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, FunctionID functionId, ObjectID objectId)
+ {
+ return profInterface->ExceptionCatcherEnter(functionId, objectId);
+ },
+ functionId, objectId);
+}
+
+inline void ProfControlBlock::ExceptionCatcherLeave()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingExceptions,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->ExceptionCatcherLeave();
+ });
+}
+
+inline BOOL IsProfilerTrackingCCW(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_CCW);
+}
+
+inline void ProfControlBlock::COMClassicVTableCreated(ClassID wrappedClassId, REFGUID implementedIID, void *pVTable, ULONG cSlots)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingCCW,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ClassID wrappedClassId, REFGUID implementedIID, void *pVTable, ULONG cSlots)
+ {
+ return profInterface->COMClassicVTableCreated(wrappedClassId, implementedIID, pVTable, cSlots);
+ },
+ wrappedClassId, implementedIID, pVTable, cSlots);
+}
+
+inline BOOL IsProfilerTrackingSuspends(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_SUSPENDS);
+}
+
+inline void ProfControlBlock::RuntimeSuspendStarted(COR_PRF_SUSPEND_REASON suspendReason)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingSuspends,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, COR_PRF_SUSPEND_REASON suspendReason)
+ {
+ return profInterface->RuntimeSuspendStarted(suspendReason);
+ },
+ suspendReason);
+}
+
+inline void ProfControlBlock::RuntimeSuspendFinished()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingSuspends,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->RuntimeSuspendFinished();
+ });
+}
+
+inline void ProfControlBlock::RuntimeSuspendAborted()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingSuspends,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->RuntimeSuspendAborted();
+ });
+}
+
+inline void ProfControlBlock::RuntimeResumeStarted()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingSuspends,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->RuntimeResumeStarted();
+ });
+}
+
+inline void ProfControlBlock::RuntimeResumeFinished()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingSuspends,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->RuntimeResumeFinished();
+ });
+}
+
+inline void ProfControlBlock::RuntimeThreadSuspended(ThreadID suspendedThreadId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingSuspends,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ThreadID suspendedThreadId)
+ {
+ return profInterface->RuntimeThreadSuspended(suspendedThreadId);
+ },
+ suspendedThreadId);
+}
+
+inline void ProfControlBlock::RuntimeThreadResumed(ThreadID resumedThreadId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingSuspends,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ThreadID resumedThreadId)
+ {
+ return profInterface->RuntimeThreadResumed(resumedThreadId);
+ },
+ resumedThreadId);
+}
+
+inline BOOL IsProfilerTrackingAllocations(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return (pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_ENABLE_OBJECT_ALLOCATED)
+ || pProfilerInfo->eventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED));
+}
+
+inline void ProfControlBlock::ObjectAllocated(ObjectID objectId, ClassID classId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingAllocations,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ObjectID objectId, ClassID classId)
+ {
+ return profInterface->ObjectAllocated(objectId, classId);
+ },
+ objectId, classId);
+}
+
+
+inline BOOL IsProfilerTrackingGC(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskSet(COR_PRF_MONITOR_GC);
+}
+
+inline void ProfControlBlock::FinalizeableObjectQueued(BOOL isCritical, ObjectID objectID)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, BOOL isCritical, ObjectID objectID)
+ {
+ return profInterface->FinalizeableObjectQueued(isCritical, objectID);
+ },
+ isCritical, objectID);
+}
+
+inline void ProfControlBlock::MovedReference(BYTE *pbMemBlockStart, BYTE *pbMemBlockEnd, ptrdiff_t cbRelocDistance, void *pHeapId, BOOL fCompacting)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, BYTE *pbMemBlockStart, BYTE *pbMemBlockEnd, ptrdiff_t cbRelocDistance, void *pHeapId, BOOL fCompacting)
+ {
+ return profInterface->MovedReference(pbMemBlockStart, pbMemBlockEnd, cbRelocDistance, pHeapId, fCompacting);
+ },
+ pbMemBlockStart, pbMemBlockEnd, cbRelocDistance, pHeapId, fCompacting);
+}
+
+inline void ProfControlBlock::EndMovedReferences(void *pHeapId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, void *pHeapId)
+ {
+ return profInterface->EndMovedReferences(pHeapId);
+ },
+ pHeapId);
+}
+
+inline void ProfControlBlock::RootReference2(BYTE *objectId, EtwGCRootKind dwEtwRootKind, EtwGCRootFlags dwEtwRootFlags, void *rootID, void *pHeapId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, BYTE *objectId, EtwGCRootKind dwEtwRootKind, EtwGCRootFlags dwEtwRootFlags, void *rootID, void *pHeapId)
+ {
+ return profInterface->RootReference2(objectId, dwEtwRootKind, dwEtwRootFlags, rootID, pHeapId);
+ },
+ objectId, dwEtwRootKind, dwEtwRootFlags, rootID, pHeapId);
+}
+
+inline void ProfControlBlock::EndRootReferences2(void *pHeapId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, void *pHeapId)
+ {
+ return profInterface->EndRootReferences2(pHeapId);
+ },
+ pHeapId);
+}
+
+inline void ProfControlBlock::ConditionalWeakTableElementReference(BYTE *primaryObjectId, BYTE *secondaryObjectId, void *rootID, void *pHeapId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, BYTE *primaryObjectId, BYTE *secondaryObjectId, void *rootID, void *pHeapId)
+ {
+ if (!profInterface->IsCallback5Supported())
+ {
+ return S_OK;
+ }
+
+ return profInterface->ConditionalWeakTableElementReference(primaryObjectId, secondaryObjectId, rootID, pHeapId);
+ },
+ primaryObjectId, secondaryObjectId, rootID, pHeapId);
+}
+
+inline void ProfControlBlock::EndConditionalWeakTableElementReferences(void *pHeapId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, void *pHeapId)
+ {
+ if (!profInterface->IsCallback5Supported())
+ {
+ return S_OK;
+ }
+
+ return profInterface->EndConditionalWeakTableElementReferences(pHeapId);
+ },
+ pHeapId);
+}
+
+inline void ProfControlBlock::AllocByClass(ObjectID objId, ClassID classId, void *pHeapId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ObjectID objId, ClassID classId, void *pHeapId)
+ {
+ return profInterface->AllocByClass(objId, classId, pHeapId);
+ },
+ objId, classId, pHeapId);
+}
+
+inline void ProfControlBlock::EndAllocByClass(void *pHeapId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, void *pHeapId)
+ {
+ return profInterface->EndAllocByClass(pHeapId);
+ },
+ pHeapId);
+}
+
+inline HRESULT ProfControlBlock::ObjectReference(ObjectID objId, ClassID classId, ULONG cNumRefs, ObjectID *arrObjRef)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, ObjectID objId, ClassID classId, ULONG cNumRefs, ObjectID *arrObjRef)
+ {
+ return profInterface->ObjectReference(objId, classId, cNumRefs, arrObjRef);
+ },
+ objId, classId, cNumRefs, arrObjRef);
+}
+
+inline void ProfControlBlock::HandleCreated(UINT_PTR handleId, ObjectID initialObjectId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, UINT_PTR handleId, ObjectID initialObjectId)
+ {
+ return profInterface->HandleCreated(handleId, initialObjectId);
+ },
+ handleId, initialObjectId);
+}
+
+inline void ProfControlBlock::HandleDestroyed(UINT_PTR handleId)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, UINT_PTR handleId)
+ {
+ return profInterface->HandleDestroyed(handleId);
+ },
+ handleId);
+}
+
+
+inline BOOL IsProfilerTrackingBasicGC(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskHighSet(COR_PRF_HIGH_BASIC_GC);
+}
+
+inline BOOL IsProfilerTrackingMovedObjects(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS);
+}
+
+inline BOOL IsProfilerTrackingGCOrBasicGC(ProfilerInfo *pProfilerInfo)
+{
+ return IsProfilerTrackingGC(pProfilerInfo) || IsProfilerTrackingBasicGC(pProfilerInfo);
+}
+
+inline BOOL IsProfilerTrackingGCOrMovedObjects(ProfilerInfo *pProfilerInfo)
+{
+ return IsProfilerTrackingGC(pProfilerInfo) || IsProfilerTrackingMovedObjects(pProfilerInfo);
+}
+
+inline void ProfControlBlock::GarbageCollectionStarted(int cGenerations, BOOL generationCollected[], COR_PRF_GC_REASON reason)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGCOrBasicGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, int cGenerations, BOOL generationCollected[], COR_PRF_GC_REASON reason)
+ {
+ return profInterface->GarbageCollectionStarted(cGenerations, generationCollected, reason);
+ },
+ cGenerations, generationCollected, reason);
+}
+
+inline void ProfControlBlock::GarbageCollectionFinished()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerTrackingGCOrBasicGC,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface)
+ {
+ return profInterface->GarbageCollectionFinished();
+ });
+}
+
+
+inline BOOL IsProfilerMonitoringEventPipe(ProfilerInfo *pProfilerInfo)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return pProfilerInfo->eventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_EVENT_PIPE);
+}
+
+
+inline void ProfControlBlock::EventPipeEventDelivered(EventPipeProvider *provider,
+ DWORD eventId,
+ DWORD eventVersion,
+ ULONG cbMetadataBlob,
+ LPCBYTE metadataBlob,
+ ULONG cbEventData,
+ LPCBYTE eventData,
+ LPCGUID pActivityId,
+ LPCGUID pRelatedActivityId,
+ Thread *pEventThread,
+ ULONG numStackFrames,
+ UINT_PTR stackFrames[])
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerMonitoringEventPipe,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, EventPipeProvider *provider,
+ DWORD eventId,
+ DWORD eventVersion,
+ ULONG cbMetadataBlob,
+ LPCBYTE metadataBlob,
+ ULONG cbEventData,
+ LPCBYTE eventData,
+ LPCGUID pActivityId,
+ LPCGUID pRelatedActivityId,
+ Thread *pEventThread,
+ ULONG numStackFrames,
+ UINT_PTR stackFrames[])
+ {
+ return profInterface->EventPipeEventDelivered(provider,
+ eventId,
+ eventVersion,
+ cbMetadataBlob,
+ metadataBlob,
+ cbEventData,
+ eventData,
+ pActivityId,
+ pRelatedActivityId,
+ pEventThread,
+ numStackFrames,
+ stackFrames);
+ },
+ provider,
+ eventId,
+ eventVersion,
+ cbMetadataBlob,
+ metadataBlob,
+ cbEventData,
+ eventData,
+ pActivityId,
+ pRelatedActivityId,
+ pEventThread,
+ numStackFrames,
+ stackFrames);
+}
+
+inline void ProfControlBlock::EventPipeProviderCreated(EventPipeProvider *provider)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ DoProfilerCallback(ProfilerCallbackType::Active,
+ IsProfilerMonitoringEventPipe,
+ (void *)NULL,
+ [](void *additionalData, VolatilePtr<EEToProfInterfaceImpl> profInterface, EventPipeProvider *provider)
+ {
+ return profInterface->EventPipeProviderCreated(provider);
+ },
+ provider);
}
//---------------------------------------------------------------------------------------
@@ -90,14 +1664,18 @@ inline void ProfControlBlock::ResetPerSessionStatus()
// and what features it enabled callbacks for.
//---------------------------------------------------------------------------------------
-
-// CORProfilerPresent() returns whether or not a CLR Profiler is actively loaded
-// (meaning it's initialized and ready to receive callbacks).
inline BOOL CORProfilerPresent()
{
LIMITED_METHOD_DAC_CONTRACT;
- return ((&g_profControlBlock)->curProfStatus.Get() == kProfStatusActive);
+ return AnyProfilerPassesCondition([](ProfilerInfo *pProfilerInfo) { return pProfilerInfo->curProfStatus.Get() >= kProfStatusActive; });
+}
+
+inline BOOL CORMainProfilerPresent()
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return (&g_profControlBlock)->mainProfilerInfo.curProfStatus.Get() >= kProfStatusActive;
}
// These return whether a CLR Profiler is actively loaded AND has requested the
@@ -113,10 +1691,10 @@ inline BOOL CORProfilerFunctionIDMapperEnabled()
}
CONTRACTL_END;
- return (CORProfilerPresent() &&
+ return (CORMainProfilerPresent() &&
(
- ((&g_profControlBlock)->pProfInterface->GetFunctionIDMapper() != NULL) ||
- ((&g_profControlBlock)->pProfInterface->GetFunctionIDMapper2() != NULL)
+ ((&g_profControlBlock)->mainProfilerInfo.pProfInterface->GetFunctionIDMapper() != NULL) ||
+ ((&g_profControlBlock)->mainProfilerInfo.pProfInterface->GetFunctionIDMapper2() != NULL)
));
}
@@ -131,7 +1709,7 @@ inline BOOL CORProfilerTrackJITInfo()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_JIT_COMPILATION));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_JIT_COMPILATION));
}
inline BOOL CORProfilerTrackCacheSearches()
@@ -145,7 +1723,7 @@ inline BOOL CORProfilerTrackCacheSearches()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_CACHE_SEARCHES));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_CACHE_SEARCHES));
}
inline BOOL CORProfilerTrackModuleLoads()
@@ -159,7 +1737,7 @@ inline BOOL CORProfilerTrackModuleLoads()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_MODULE_LOADS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_MODULE_LOADS));
}
inline BOOL CORProfilerTrackAssemblyLoads()
@@ -173,7 +1751,7 @@ inline BOOL CORProfilerTrackAssemblyLoads()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_ASSEMBLY_LOADS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_ASSEMBLY_LOADS));
}
inline BOOL CORProfilerTrackAppDomainLoads()
@@ -187,7 +1765,7 @@ inline BOOL CORProfilerTrackAppDomainLoads()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_APPDOMAIN_LOADS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_APPDOMAIN_LOADS));
}
inline BOOL CORProfilerTrackThreads()
@@ -201,7 +1779,7 @@ inline BOOL CORProfilerTrackThreads()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_THREADS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_THREADS));
}
inline BOOL CORProfilerTrackClasses()
@@ -215,7 +1793,7 @@ inline BOOL CORProfilerTrackClasses()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_CLASS_LOADS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_CLASS_LOADS));
}
inline BOOL CORProfilerTrackGC()
@@ -229,7 +1807,7 @@ inline BOOL CORProfilerTrackGC()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_GC));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_GC));
}
inline BOOL CORProfilerTrackAllocationsEnabled()
@@ -248,7 +1826,7 @@ inline BOOL CORProfilerTrackAllocationsEnabled()
(&g_profControlBlock)->fTestOnlyForceObjectAllocated ||
#endif
(CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_ENABLE_OBJECT_ALLOCATED))
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_ENABLE_OBJECT_ALLOCATED))
);
}
@@ -264,7 +1842,7 @@ inline BOOL CORProfilerTrackAllocations()
return
(CORProfilerTrackAllocationsEnabled() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_OBJECT_ALLOCATED));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_OBJECT_ALLOCATED));
}
inline BOOL CORProfilerTrackLargeAllocations()
@@ -279,7 +1857,7 @@ inline BOOL CORProfilerTrackLargeAllocations()
return
(CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED));
}
inline BOOL CORProfilerEnableRejit()
@@ -292,8 +1870,8 @@ inline BOOL CORProfilerEnableRejit()
}
CONTRACTL_END;
- return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_ENABLE_REJIT));
+ return (CORMainProfilerPresent() &&
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_ENABLE_REJIT));
}
inline BOOL CORProfilerTrackExceptions()
@@ -307,7 +1885,7 @@ inline BOOL CORProfilerTrackExceptions()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_EXCEPTIONS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_EXCEPTIONS));
}
inline BOOL CORProfilerTrackTransitions()
@@ -321,7 +1899,7 @@ inline BOOL CORProfilerTrackTransitions()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_CODE_TRANSITIONS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_CODE_TRANSITIONS));
}
inline BOOL CORProfilerTrackEnterLeave()
@@ -340,7 +1918,7 @@ inline BOOL CORProfilerTrackEnterLeave()
#endif // PROF_TEST_ONLY_FORCE_ELT
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_ENTERLEAVE));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_ENTERLEAVE));
}
inline BOOL CORProfilerTrackCCW()
@@ -354,53 +1932,7 @@ inline BOOL CORProfilerTrackCCW()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_CCW));
-}
-
-inline BOOL CORProfilerTrackRemoting()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CANNOT_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_REMOTING));
-}
-
-inline BOOL CORProfilerTrackRemotingCookie()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CANNOT_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- return
- (CORProfilerPresent() &&
- (((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_REMOTING_COOKIE)
- == COR_PRF_MONITOR_REMOTING_COOKIE));
-}
-
-inline BOOL CORProfilerTrackRemotingAsync()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CANNOT_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- return
- (CORProfilerPresent() &&
- (((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_REMOTING_ASYNC)
- == COR_PRF_MONITOR_REMOTING_ASYNC));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_CCW));
}
inline BOOL CORProfilerTrackSuspends()
@@ -414,7 +1946,7 @@ inline BOOL CORProfilerTrackSuspends()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_SUSPENDS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_MONITOR_SUSPENDS));
}
inline BOOL CORProfilerDisableInlining()
@@ -428,21 +1960,7 @@ inline BOOL CORProfilerDisableInlining()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_DISABLE_INLINING));
-}
-
-inline BOOL CORProfilerJITMapEnabled()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CANNOT_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_ENABLE_JIT_MAPS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_DISABLE_INLINING));
}
inline BOOL CORProfilerDisableOptimizations()
@@ -457,7 +1975,7 @@ inline BOOL CORProfilerDisableOptimizations()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_DISABLE_OPTIMIZATIONS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_DISABLE_OPTIMIZATIONS));
}
inline BOOL CORProfilerUseProfileImages()
@@ -475,14 +1993,8 @@ inline BOOL CORProfilerUseProfileImages()
return TRUE;
#endif // PROF_TEST_ONLY_FORCE_ELT
- if (!CORProfilerPresent())
- return FALSE;
-
- if (((&g_profControlBlock)->dwEventMask &
- COR_PRF_REQUIRE_PROFILE_IMAGE) == 0)
- return FALSE;
-
- return TRUE;
+ return (CORProfilerPresent() &&
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_REQUIRE_PROFILE_IMAGE));
}
inline BOOL CORProfilerDisableAllNGenImages()
@@ -490,14 +2002,14 @@ inline BOOL CORProfilerDisableAllNGenImages()
LIMITED_METHOD_DAC_CONTRACT;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_DISABLE_ALL_NGEN_IMAGES));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_DISABLE_ALL_NGEN_IMAGES));
}
inline BOOL CORProfilerTrackConditionalWeakTableElements()
{
LIMITED_METHOD_DAC_CONTRACT;
- return CORProfilerTrackGC() && (&g_profControlBlock)->pProfInterface->IsCallback5Supported();
+ return CORProfilerTrackGC() && (&g_profControlBlock)->IsCallback5Supported();
}
// CORProfilerPresentOrInitializing() returns nonzero iff a CLR Profiler is actively
@@ -508,8 +2020,8 @@ inline BOOL CORProfilerTrackConditionalWeakTableElements()
// that may still be initializing, and this function is appropriate for that code.
inline BOOL CORProfilerPresentOrInitializing()
{
- LIMITED_METHOD_DAC_CONTRACT;
- return ((&g_profControlBlock)->curProfStatus.Get() > kProfStatusDetaching);
+ LIMITED_METHOD_CONTRACT;
+ return AnyProfilerPassesCondition([](ProfilerInfo *pProfilerInfo) { return pProfilerInfo->curProfStatus.Get() > kProfStatusDetaching; });
}
// These return whether a CLR Profiler has requested the specified functionality.
@@ -531,7 +2043,7 @@ inline BOOL CORProfilerELT3SlowPathEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & (COR_PRF_ENABLE_FUNCTION_ARGS | COR_PRF_ENABLE_FUNCTION_RETVAL | COR_PRF_ENABLE_FRAME_INFO)));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet((COR_PRF_ENABLE_FUNCTION_ARGS | COR_PRF_ENABLE_FUNCTION_RETVAL | COR_PRF_ENABLE_FRAME_INFO)));
}
inline BOOL CORProfilerELT3SlowPathEnterEnabled()
@@ -545,7 +2057,7 @@ inline BOOL CORProfilerELT3SlowPathEnterEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & (COR_PRF_ENABLE_FUNCTION_ARGS | COR_PRF_ENABLE_FRAME_INFO)));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet((COR_PRF_ENABLE_FUNCTION_ARGS | COR_PRF_ENABLE_FRAME_INFO)));
}
inline BOOL CORProfilerELT3SlowPathLeaveEnabled()
@@ -559,7 +2071,7 @@ inline BOOL CORProfilerELT3SlowPathLeaveEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & (COR_PRF_ENABLE_FUNCTION_RETVAL | COR_PRF_ENABLE_FRAME_INFO)));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet((COR_PRF_ENABLE_FUNCTION_RETVAL | COR_PRF_ENABLE_FRAME_INFO)));
}
inline BOOL CORProfilerELT3SlowPathTailcallEnabled()
@@ -573,7 +2085,7 @@ inline BOOL CORProfilerELT3SlowPathTailcallEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & (COR_PRF_ENABLE_FRAME_INFO)));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet((COR_PRF_ENABLE_FRAME_INFO)));
}
inline BOOL CORProfilerELT2FastPathEnterEnabled()
@@ -587,7 +2099,7 @@ inline BOOL CORProfilerELT2FastPathEnterEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- (!((&g_profControlBlock)->dwEventMask & (COR_PRF_ENABLE_STACK_SNAPSHOT | COR_PRF_ENABLE_FUNCTION_ARGS | COR_PRF_ENABLE_FRAME_INFO))));
+ !((&g_profControlBlock)->globalEventMask.IsEventMaskSet((COR_PRF_ENABLE_STACK_SNAPSHOT | COR_PRF_ENABLE_FUNCTION_ARGS | COR_PRF_ENABLE_FRAME_INFO))));
}
inline BOOL CORProfilerELT2FastPathLeaveEnabled()
@@ -601,7 +2113,7 @@ inline BOOL CORProfilerELT2FastPathLeaveEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- (!((&g_profControlBlock)->dwEventMask & (COR_PRF_ENABLE_STACK_SNAPSHOT | COR_PRF_ENABLE_FUNCTION_RETVAL | COR_PRF_ENABLE_FRAME_INFO))));
+ !((&g_profControlBlock)->globalEventMask.IsEventMaskSet((COR_PRF_ENABLE_STACK_SNAPSHOT | COR_PRF_ENABLE_FUNCTION_RETVAL | COR_PRF_ENABLE_FRAME_INFO))));
}
inline BOOL CORProfilerELT2FastPathTailcallEnabled()
@@ -615,7 +2127,7 @@ inline BOOL CORProfilerELT2FastPathTailcallEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- (!((&g_profControlBlock)->dwEventMask & (COR_PRF_ENABLE_STACK_SNAPSHOT | COR_PRF_ENABLE_FRAME_INFO))));
+ !((&g_profControlBlock)->globalEventMask.IsEventMaskSet((COR_PRF_ENABLE_STACK_SNAPSHOT | COR_PRF_ENABLE_FRAME_INFO))));
}
inline BOOL CORProfilerFunctionArgsEnabled()
@@ -629,7 +2141,7 @@ inline BOOL CORProfilerFunctionArgsEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_ENABLE_FUNCTION_ARGS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_ENABLE_FUNCTION_ARGS));
}
inline BOOL CORProfilerFunctionReturnValueEnabled()
@@ -643,7 +2155,7 @@ inline BOOL CORProfilerFunctionReturnValueEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_ENABLE_FUNCTION_RETVAL));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_ENABLE_FUNCTION_RETVAL));
}
inline BOOL CORProfilerFrameInfoEnabled()
@@ -657,7 +2169,7 @@ inline BOOL CORProfilerFrameInfoEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_ENABLE_FRAME_INFO));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_ENABLE_FRAME_INFO));
}
inline BOOL CORProfilerStackSnapshotEnabled()
@@ -671,21 +2183,7 @@ inline BOOL CORProfilerStackSnapshotEnabled()
CONTRACTL_END;
return (CORProfilerPresentOrInitializing() &&
- ((&g_profControlBlock)->dwEventMask & COR_PRF_ENABLE_STACK_SNAPSHOT));
-}
-
-inline BOOL CORProfilerAddsAssemblyReferences()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CANNOT_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskSet(COR_PRF_ENABLE_STACK_SNAPSHOT));
}
inline BOOL CORProfilerInMemorySymbolsUpdatesEnabled()
@@ -699,10 +2197,10 @@ inline BOOL CORProfilerInMemorySymbolsUpdatesEnabled()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskHighSet(COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED));
}
-inline BOOL CORProfilerIsMonitoringDynamicFunctionUnloads()
+inline BOOL CORProfilerTrackDynamicFunctionUnloads()
{
CONTRACTL
{
@@ -713,7 +2211,7 @@ inline BOOL CORProfilerIsMonitoringDynamicFunctionUnloads()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS));
}
inline BOOL CORProfilerDisableTieredCompilation()
@@ -728,7 +2226,7 @@ inline BOOL CORProfilerDisableTieredCompilation()
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_DISABLE_TIERED_COMPILATION));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskHighSet(COR_PRF_HIGH_DISABLE_TIERED_COMPILATION));
}
inline BOOL CORProfilerTrackBasicGC()
@@ -742,7 +2240,7 @@ inline BOOL CORProfilerTrackBasicGC()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_BASIC_GC));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskHighSet(COR_PRF_HIGH_BASIC_GC));
}
inline BOOL CORProfilerTrackGCMovedObjects()
@@ -756,10 +2254,10 @@ inline BOOL CORProfilerTrackGCMovedObjects()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS));
}
-inline BOOL CORProfilerIsMonitoringEventPipe()
+inline BOOL CORProfilerTrackEventPipe()
{
CONTRACTL
{
@@ -770,55 +2268,38 @@ inline BOOL CORProfilerIsMonitoringEventPipe()
CONTRACTL_END;
return (CORProfilerPresent() &&
- ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_MONITOR_EVENT_PIPE));
+ (&g_profControlBlock)->globalEventMask.IsEventMaskHighSet(COR_PRF_HIGH_MONITOR_EVENT_PIPE));
}
#if defined(PROFILING_SUPPORTED) && !defined(CROSSGEN_COMPILE)
-#if defined(FEATURE_PROFAPI_ATTACH_DETACH)
-
//---------------------------------------------------------------------------------------
-// When EE calls into the profiler, an EvacuationCounterHolder object is instantiated on
-// the stack to increment the evacuation counter inside the EE Thread. Upon returning to
-// EE, this EvacuationCounterHolder object when being destroyed decreases the evacuation
-// counter by one.
-//
-// Do not use this object directly. Use BEGIN_PIN_PROFILER / END_PIN_PROFILER defined
-// below.
-//
-// See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization.
-//
-typedef Wrapper<Thread *, ProfilingAPIUtility::IncEvacuationCounter, ProfilingAPIUtility::DecEvacuationCounter,
- (UINT_PTR)0, CompareDefault<Thread *>> EvacuationCounterHolder;
-
-
-//---------------------------------------------------------------------------------------
-// These macros must be placed around any access to g_profControlBlock.pProfInterface by
+// These macros must be placed around any callbacks to g_profControlBlock by
// the EE. Example:
// {
-// BEGIN_PIN_PROFILER(CORProfilerTrackAppDomainLoads());
-// g_profControlBlock.pProfInterface->AppDomainCreationStarted(MyAppDomainID);
-// END_PIN_PROFILER();
+// BEGIN_PROFILER_CALLBACK(CORProfilerTrackAppDomainLoads;
+// g_profControlBlock.AppDomainCreationStarted(MyAppDomainID);
+// END_PROFILER_CALLBACK();
// }
-// The parameter to the BEGIN_PIN_PROFILER is the condition you want to check for, to
+// The parameter to the BEGIN_PROFILER_CALLBACK is the condition you want to check for, to
// determine whether the profiler is loaded and requesting the callback you're about to
// issue. Typically, this will be a call to one of the inline functions in
// profilepriv.inl. If the condition is true, the macro will increment an evacuation
// counter that effectively pins the profiler, recheck the condition, and (if still
-// true), execute whatever code you place inside the BEGIN/END_PIN_PROFILER block. If
+// true), execute whatever code you place inside the BEGIN/END_PROFILER_CALLBACK block. If
// your condition is more complex than a simple profiler status check, then place the
// profiler status check as parameter to the macro, and add a separate if inside the
// block. Example:
//
// {
-// BEGIN_PIN_PROFILER(CORProfilerTrackTransitions());
+// BEGIN_PROFILER_CALLBACK(CorProfilerTrackTransitions);
// if (!pNSL->pMD->IsQCall())
// {
-// g_profControlBlock.pProfInterface->
+// g_profControlBlock.
// ManagedToUnmanagedTransition((FunctionID) pNSL->pMD,
// COR_PRF_TRANSITION_CALL);
// }
-// END_PIN_PROFILER();
+// END_PROFILER_CALLBACK();
// }
//
// This ensures that the extra condition check (in this case "if
@@ -827,35 +2308,19 @@ typedef Wrapper<Thread *, ProfilingAPIUtility::IncEvacuationCounter, ProfilingAP
//
// See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
// for more details about how the synchronization works.
-#define BEGIN_PIN_PROFILER(condition) \
+#define BEGIN_PROFILER_CALLBACK(condition) \
/* Do a cheap check of the condition (dirty-read) */ \
if (condition) \
{ \
- EvacuationCounterHolder __evacuationCounter(GetThreadNULLOk()); \
- /* Now that the evacuation counter is incremented, the condition re-check */ \
- /* below is a clean read. There's no MemoryBarrier() here, but that's ok */ \
- /* as writes to the profiler status force a FlushStoreBuffers(). */ \
- if (condition) \
- {
-#define END_PIN_PROFILER() } }
-
-#else // FEATURE_PROFAPI_ATTACH_DETACH
-
-// For builds that include profiling but not attach / detach (e.g., Silverlight 2), the
-// *PIN_PROFILER macros should just check the condition without using the evacuation
-// counters.
-
-#define BEGIN_PIN_PROFILER(condition) if (condition) {
-#define END_PIN_PROFILER() }
-#endif // FEATURE_PROFAPI_ATTACH_DETACH
+#define END_PROFILER_CALLBACK() }
#else // PROFILING_SUPPORTED && !CROSSGEN_COMPILE
// Profiling feature not supported
-#define BEGIN_PIN_PROFILER(condition) if (false) {
-#define END_PIN_PROFILER() }
+#define BEGIN_PROFILER_CALLBACK(condition) if (false) {
+#define END_PROFILER_CALLBACK() }
#endif // PROFILING_SUPPORTED && !CROSSGEN_COMPILE
diff --git a/src/coreclr/inc/sarray.inl b/src/coreclr/inc/sarray.inl
index b375b6a633b..7d6a5b6a37d 100644
--- a/src/coreclr/inc/sarray.inl
+++ b/src/coreclr/inc/sarray.inl
@@ -247,7 +247,7 @@ inline void SArray<ELEMENT, BITWISE_COPY>::Delete(const Iterator &i, COUNT_T cou
}
template <typename ELEMENT, BOOL BITWISE_COPY>
-inline void SArray<ELEMENT, BITWISE_COPY>:: Replace(const Iterator &i, COUNT_T deleteCount, COUNT_T insertCount)
+inline void SArray<ELEMENT, BITWISE_COPY>::Replace(const Iterator &i, COUNT_T deleteCount, COUNT_T insertCount)
{
WRAPPER_NO_CONTRACT;
DestructBuffer(i, deleteCount);