summaryrefslogtreecommitdiff
path: root/src/inc/corprof.idl
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/corprof.idl')
-rw-r--r--src/inc/corprof.idl3857
1 files changed, 3857 insertions, 0 deletions
diff --git a/src/inc/corprof.idl b/src/inc/corprof.idl
new file mode 100644
index 0000000000..4288897844
--- /dev/null
+++ b/src/inc/corprof.idl
@@ -0,0 +1,3857 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/**************************************************************************************
+ ** **
+ ** Corprof.idl - CLR Profiling interfaces. **
+ ** **
+ **************************************************************************************/
+
+/* -------------------------------------------------------------------------- *
+ * Imported types
+ * -------------------------------------------------------------------------- */
+
+#if !DEFINITIONS_FROM_NON_IMPORTABLE_PLACES
+
+cpp_quote("#define CorDB_CONTROL_Profiling \"Cor_Enable_Profiling\"")
+cpp_quote("#define CorDB_CONTROL_ProfilingL L\"Cor_Enable_Profiling\"")
+
+cpp_quote("#if 0")
+
+
+import "unknwn.idl";
+
+typedef LONG32 mdToken;
+typedef mdToken mdModule;
+typedef mdToken mdTypeDef;
+typedef mdToken mdMethodDef;
+typedef mdToken mdFieldDef;
+typedef ULONG CorElementType;
+
+// Forward declaration of enum in CorHdr.h
+enum CorElementType;
+
+// Forward declaration of structs in Cor.h
+
+typedef struct
+{
+ DWORD dwOSPlatformId; // Operating system platform.
+ DWORD dwOSMajorVersion; // OS Major version.
+ DWORD dwOSMinorVersion; // OS Minor version.
+} OSINFO;
+
+typedef struct
+{
+ USHORT usMajorVersion; // Major Version.
+ USHORT usMinorVersion; // Minor Version.
+ USHORT usBuildNumber; // Build Number.
+ USHORT usRevisionNumber; // Revision Number.
+ LPWSTR szLocale; // Locale.
+ ULONG cbLocale; // [IN/OUT] Size of the buffer in wide chars/Actual size.
+ DWORD *rProcessor; // Processor ID array.
+ ULONG ulProcessor; // [IN/OUT] Size of the Processor ID array/Actual # of entries filled in.
+ OSINFO *rOS; // OSINFO array.
+ ULONG ulOS; // [IN/OUT]Size of the OSINFO array/Actual # of entries filled in.
+} ASSEMBLYMETADATA;
+
+cpp_quote("#endif")
+
+typedef const BYTE *LPCBYTE;
+typedef BYTE *LPBYTE;
+
+#endif
+
+
+cpp_quote("#ifndef _COR_IL_MAP")
+cpp_quote("#define _COR_IL_MAP")
+
+#ifdef INTERNAL_DOCS
+// Note that this structure is also defined in CorDebug.idl - PROPAGATE CHANGES
+// BOTH WAYS, or this'll become a really insidious bug some day.
+#endif
+typedef struct _COR_IL_MAP
+{
+ ULONG32 oldOffset; // Old IL offset relative to beginning of function
+ ULONG32 newOffset; // New IL offset relative to beginning of function
+ BOOL fAccurate; //put here for compatibility with the Debugger structure.
+} COR_IL_MAP;
+
+cpp_quote("#endif //_COR_IL_MAP")
+
+cpp_quote("#ifndef _COR_DEBUG_IL_TO_NATIVE_MAP_")
+cpp_quote("#define _COR_DEBUG_IL_TO_NATIVE_MAP_")
+
+/* ICorProfilerInfo:: GetILToNativeMapping returns an array of
+ * COR_DEBUG_IL_TO_NATIVE_MAP structures. In order to convey that certain
+ * ranges of native instructions correspond to special regions of code (for
+ * example, the prolog), an entry in the array may have it's ilOffset field set
+ * to one of these values.
+ */
+typedef enum CorDebugIlToNativeMappingTypes
+{
+ NO_MAPPING = -1,
+ PROLOG = -2,
+ EPILOG = -3
+} CorDebugIlToNativeMappingTypes;
+
+typedef struct COR_DEBUG_IL_TO_NATIVE_MAP
+{
+ ULONG32 ilOffset;
+ ULONG32 nativeStartOffset;
+ ULONG32 nativeEndOffset;
+} COR_DEBUG_IL_TO_NATIVE_MAP;
+
+cpp_quote("#endif // _COR_DEBUG_IL_TO_NATIVE_MAP_")
+
+cpp_quote("#ifndef _COR_FIELD_OFFSET_")
+cpp_quote("#define _COR_FIELD_OFFSET_")
+
+typedef struct _COR_FIELD_OFFSET
+{
+ mdFieldDef ridOfField; // fieldDef token of the field
+ ULONG ulOffset; // offset (from the ObjectID pointer) of the field
+} COR_FIELD_OFFSET;
+
+cpp_quote("#endif // _COR_FIELD_OFFSET_")
+
+
+#ifndef DO_NO_IMPORTS
+import "wtypes.idl";
+import "unknwn.idl";
+#endif
+
+typedef UINT_PTR ProcessID;
+typedef UINT_PTR AssemblyID;
+typedef UINT_PTR AppDomainID;
+typedef UINT_PTR ModuleID;
+typedef UINT_PTR ClassID;
+typedef UINT_PTR ThreadID;
+typedef UINT_PTR ContextID;
+typedef UINT_PTR FunctionID;
+typedef UINT_PTR ObjectID;
+typedef UINT_PTR GCHandleID;
+typedef UINT_PTR COR_PRF_ELT_INFO;
+typedef UINT_PTR ReJITID;
+
+typedef union {FunctionID functionID; UINT_PTR clientID;} FunctionIDOrClientID;
+
+/*
+ * The FunctionIDMapper type definition is used by the
+ * ICorProfilerInfo::SetFunctionIDMapper method to specify
+ * a function that will be called to map FunctionIDs to alternative
+ * values that will be passed to the function entry and function exit
+ * callbacks supplied to the ICorProfilerInfo::SetEnterLeaveFunctionHooks
+ * method. The mapper can be set only once and it is recommended to do so
+ * in the Initialize callback.
+ *
+ * NOTE: There is a known bug in this API that must be worked around.
+ * The return value of FunctionIDMapper cannot be NULL (unless the boolean
+ * value in pbHookTheFunction is FALSE). All other values are treated as
+ * opaque data to be passed to the entry/exit callback functions. The use
+ * of a NULL return value will produce unpredictable results, including
+ * possibly halting the process.
+ *
+ * NOTE: Profilers should be tolerant of cases where multiple threads of
+ * a profiled app are calling the same method simultaneously. In such
+ * cases, the profiler may receive multiple FunctionIDMapper callbacks
+ * for the same functionId. The profiler should be certain to return
+ * the same values from this callback when it is called multiple times
+ * with the same functionId.
+ *
+ */
+typedef UINT_PTR __stdcall FunctionIDMapper(
+ FunctionID funcId,
+ BOOL *pbHookFunction);
+
+typedef UINT_PTR __stdcall FunctionIDMapper2(
+ FunctionID funcId,
+ void *clientData,
+ BOOL *pbHookFunction);
+
+/*
+ * Enum for specifying how much data to pass back with a stack snapshot
+ */
+typedef enum _COR_PRF_SNAPSHOT_INFO
+{
+ COR_PRF_SNAPSHOT_DEFAULT = 0x0,
+
+ // Return a register context for each frame
+ COR_PRF_SNAPSHOT_REGISTER_CONTEXT = 0x1,
+
+ // Use a quicker stack walk algorithm based on the EBP frame chain. This is available
+ // on x86 only.
+ COR_PRF_SNAPSHOT_X86_OPTIMIZED = 0x2,
+} COR_PRF_SNAPSHOT_INFO;
+
+/*
+ * Opaque handle that represents information about a given stack frame. It is only
+ * valid during the callback to which it is passed.
+ */
+typedef UINT_PTR COR_PRF_FRAME_INFO;
+
+/*
+ * Describes a range of function arguments stored contiguously in left-to-right
+ * order in memory.
+ */
+typedef struct _COR_PRF_FUNCTION_ARGUMENT_RANGE
+{
+ UINT_PTR startAddress; // start address of the range
+ ULONG length; // contiguous length of the range
+} COR_PRF_FUNCTION_ARGUMENT_RANGE;
+
+/*
+ * Describes the locations in memory of a function's arguments, in
+ * left-to-right order. Note that arguments stored in registers are
+ * spilled to memory to build these structures.
+ */
+typedef struct _COR_PRF_FUNCTION_ARGUMENT_INFO
+{
+ ULONG numRanges; // number of chunks of arguments
+ ULONG totalArgumentSize; // total size of arguments
+ COR_PRF_FUNCTION_ARGUMENT_RANGE ranges[1]; // chunks
+} COR_PRF_FUNCTION_ARGUMENT_INFO;
+
+/*
+ * Represents one contiguous chunk of native code
+ */
+typedef struct _COR_PRF_CODE_INFO
+{
+ UINT_PTR startAddress;
+ SIZE_T size;
+} COR_PRF_CODE_INFO;
+
+/*
+ * Enum for describing the type of static a field is. These may be bit-wise
+ * or'ed with each other if the field is multiple types.
+ */
+typedef enum
+{
+ COR_PRF_FIELD_NOT_A_STATIC = 0x0,
+ COR_PRF_FIELD_APP_DOMAIN_STATIC = 0x1,
+ COR_PRF_FIELD_THREAD_STATIC = 0x2,
+ COR_PRF_FIELD_CONTEXT_STATIC = 0x4,
+ COR_PRF_FIELD_RVA_STATIC = 0x8
+} COR_PRF_STATIC_TYPE;
+
+/*
+ * Represents a function uniquely by combining the FunctionID
+ * with a ReJITID.
+ */
+typedef struct _COR_PRF_FUNCTION
+{
+ FunctionID functionId;
+ ReJITID reJitId;
+} COR_PRF_FUNCTION;
+
+
+/*
+ * Structure populated by profiler when declaring additional assembly references
+ * that the CLR should consider when performing an assembly reference closure
+ * walk. See ICorProfilerCallback6::GetAssemblyReferences and
+ * ICorProfilerAssemblyReferenceProvider::AddAssemblyReference
+ */
+typedef struct _COR_PRF_ASSEMBLY_REFERENCE_INFO
+{
+ void *pbPublicKeyOrToken; // Public key or token of the assembly.
+ ULONG cbPublicKeyOrToken; // Count of bytes in the public key or token.
+ LPCWSTR szName; // Name of the assembly being referenced.
+ ASSEMBLYMETADATA * pMetaData; // Assembly MetaData, as defined in cor.h
+ void *pbHashValue; // Hash Blob.
+ ULONG cbHashValue; // Count of bytes in the Hash Blob.
+ DWORD dwAssemblyRefFlags; // Flags.
+} COR_PRF_ASSEMBLY_REFERENCE_INFO;
+
+
+/*
+ * Represents a IL methods uniquely by combining the module ID and method token.
+ */
+typedef struct _COR_PRF_METHOD
+{
+ ModuleID moduleId;
+ mdMethodDef methodId;
+} COR_PRF_METHOD;
+
+/*
+ * NOTE!!!
+ *
+ * The following applies to ALL FunctionEnter[2,3], FunctionLeave[2,3],
+ * FunctionTailcall[2,3] hooks below:
+ *
+ * It is VERY IMPORTANT to note that these function implementations must be
+ * __declspec(naked), since the EE is not saving any registers before calling
+ * any of them. YOU MUST SAVE ALL REGISTERS YOU USE, INCLUDING FPU REGISTERS
+ * IF THE FPU STACK IS NOT EMPTY AND YOU INTEND TO USE IT.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+
+ /*
+ * NOTE: DEPRECATED IN V2
+ *
+ * These functions are considered deprecated in V2 and higher. They will
+ * continue to work, but incur a performance penalty for usage. For equivalent
+ * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks with
+ * bits cleared for COR_PRF_ENABLE_FRAME_INFO, COR_PRF_ENABLE_FUNCTION_RETVAL
+ * and COR_PRF_ENABLE_FUNCTION_ARGS.
+ */
+typedef void __stdcall FunctionEnter(
+ FunctionID funcID);
+
+typedef void __stdcall FunctionLeave(
+ FunctionID funcID);
+
+typedef void __stdcall FunctionTailcall(
+ FunctionID funcID);
+
+/*
+ * NOTE: DEPRECATED IN V4
+ *
+ * These functions are considered deprecated in V4 and higher. They will
+ * continue to work, but incur a performance penalty for usage. For equivalent
+ * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks.
+ */
+
+typedef void __stdcall FunctionEnter2(
+ FunctionID funcId,
+ UINT_PTR clientData,
+ COR_PRF_FRAME_INFO func,
+ COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo);
+
+typedef void __stdcall FunctionLeave2(
+ FunctionID funcId,
+ UINT_PTR clientData,
+ COR_PRF_FRAME_INFO func,
+ COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange);
+
+typedef void __stdcall FunctionTailcall2(
+ FunctionID funcId,
+ UINT_PTR clientData,
+ COR_PRF_FRAME_INFO func);
+
+/*
+ * When you are not interested in inspecting arguments or return values, then
+ * use these to be notified as functions are called and return. Use
+ * SetEnterLeaveFunctionHooks3 to register your implementations of these
+ * functions.
+ *
+ * functionIDOrClientID: if the profiler returned a remapped value from
+ * FunctionIDMapper[2], then this is that remapped value; else it is the
+ * true FunctionID of the function.
+ */
+
+typedef void __stdcall FunctionEnter3(
+ FunctionIDOrClientID functionIDOrClientID);
+
+typedef void __stdcall FunctionLeave3(
+ FunctionIDOrClientID functionIDOrClientID);
+
+typedef void __stdcall FunctionTailcall3(
+ FunctionIDOrClientID functionIDOrClientID);
+
+/*
+ * When you are interested in inspecting arguments and return values, then
+ * use these to be notified as functions are called and return. Use
+ * SetEnterLeaveFunctionHooks3WithInfo to register your implementations of these
+ * functions.
+ *
+ * functionIDOrClientID: if the profiler returned a remapped value from
+ * FunctionIDMapper[2], then this is that remapped value; else it is the
+ * true FunctionID of the function.
+ *
+ * eltInfo is an opaque handle that represents information about a given stack frame.
+ * It is only valid during the callback to which it is passed.
+ */
+
+typedef void __stdcall FunctionEnter3WithInfo(
+ FunctionIDOrClientID functionIDOrClientID,
+ COR_PRF_ELT_INFO eltInfo);
+
+typedef void __stdcall FunctionLeave3WithInfo(
+ FunctionIDOrClientID functionIDOrClientID,
+ COR_PRF_ELT_INFO eltInfo);
+
+typedef void __stdcall FunctionTailcall3WithInfo(
+ FunctionIDOrClientID functionIDOrClientID,
+ COR_PRF_ELT_INFO eltInfo);
+
+/*
+ * Stack snapshot callback definition.
+ *
+ * This callback is called once per managed frame or run of unmanaged frames.
+ *
+ * funcID is the FunctionID of the managed function. If funcID == 0, the callback is
+ * for a run of unmanaged frames. The profiler may either ignore the frame, or use
+ * the register context to perform its own unmanaged stackwalk.
+ *
+ * ip is the native IP in the frame
+ *
+ * frameInfo is the COR_PRF_FRAME_INFO for this frame. It is only valid for
+ * use during this callback.
+ *
+ * context is a Win32 CONTEXT struct for the current platform (size given in
+ * contextSize). It will only be valid if the COR_PRF_SNAPSHOT_CONTEXT flag
+ * was passed to DoStackSnapshot.
+ *
+ * clientData is a void* passed straight through from DoStackSnapshot
+ *
+ * NOTE: One must limit the complexity of work done in StackSnapshotCallback.
+ * For example, particularly when using DoStackSnapshot in an asynchronous manner,
+ * the target thread may be holding locks. Executing code within StackSnapshotCallback
+ * that requires the same locks could lead to deadlock.
+ */
+typedef HRESULT __stdcall StackSnapshotCallback(
+ FunctionID funcId,
+ UINT_PTR ip,
+ COR_PRF_FRAME_INFO frameInfo,
+ ULONG32 contextSize,
+ BYTE context[],
+ void *clientData);
+
+typedef enum
+{
+ // These flags represent classes of callback events
+ COR_PRF_MONITOR_NONE = 0x00000000,
+
+ // MONITOR_FUNCTION_UNLOADS controls the
+ // FunctionUnloadStarted callback.
+ COR_PRF_MONITOR_FUNCTION_UNLOADS = 0x00000001,
+
+ // MONITOR_CLASS_LOADS controls the ClassLoad*
+ // and ClassUnload* callbacks.
+ // See the comments on those callbacks for important
+ // behavior changes in V2.
+ COR_PRF_MONITOR_CLASS_LOADS = 0x00000002,
+
+ // MONITOR_MODULE_LOADS controls the
+ // ModuleLoad*, ModuleUnload*, and ModuleAttachedToAssembly
+ // callbacks.
+ COR_PRF_MONITOR_MODULE_LOADS = 0x00000004,
+
+ // MONITOR_ASSEMBLY_LOADS controls the
+ // AssemblyLoad* and AssemblyUnload* callbacks
+ COR_PRF_MONITOR_ASSEMBLY_LOADS = 0x00000008,
+
+ // MONITOR_APPDOMAIN_LOADS controls the
+ // AppDomainCreation* and AppDomainShutdown* callbacks
+ COR_PRF_MONITOR_APPDOMAIN_LOADS = 0x00000010,
+
+ // MONITOR_JIT_COMPILATION controls the
+ // JITCompilation*, JITFunctionPitched, and JITInlining
+ // callbacks.
+ COR_PRF_MONITOR_JIT_COMPILATION = 0x00000020,
+
+
+ // MONITOR_EXCEPTIONS controls the ExceptionThrown,
+ // ExceptionSearch*, ExceptionOSHandler*, ExceptionUnwind*,
+ // and ExceptionCatcher* callbacks.
+ COR_PRF_MONITOR_EXCEPTIONS = 0x00000040,
+
+ // MONITOR_GC controls the GarbageCollectionStarted/Finished,
+ // MovedReferences, SurvivingReferences,
+ // ObjectReferences, ObjectsAllocatedByClass,
+ // RootReferences*, HandleCreated/Destroyed, and FinalizeableObjectQueued
+ // callbacks.
+ COR_PRF_MONITOR_GC = 0x00000080,
+
+ // MONITOR_OBJECT_ALLOCATED controls the
+ // ObjectAllocated callback.
+ COR_PRF_MONITOR_OBJECT_ALLOCATED = 0x00000100,
+
+ // MONITOR_THREADS controls the ThreadCreated,
+ // ThreadDestroyed, ThreadAssignedToOSThread,
+ // and ThreadNameChanged callbacks.
+ COR_PRF_MONITOR_THREADS = 0x00000200,
+
+ // MONITOR_REMOTING controls the Remoting*
+ // callbacks.
+ COR_PRF_MONITOR_REMOTING = 0x00000400,
+
+ // MONITOR_CODE_TRANSITIONS controls the
+ // UnmanagedToManagedTransition and
+ // ManagedToUnmanagedTransition callbacks.
+ COR_PRF_MONITOR_CODE_TRANSITIONS = 0x00000800,
+
+ // MONITOR_ENTERLEAVE controls the
+ // FunctionEnter*/Leave*/Tailcall* callbacks
+ COR_PRF_MONITOR_ENTERLEAVE = 0x00001000,
+
+ // MONITOR_CCW controls the COMClassicVTable*
+ // callbacks.
+ COR_PRF_MONITOR_CCW = 0x00002000,
+
+ // MONITOR_REMOTING_COOKIE controls whether
+ // a cookie will be passed to the Remoting* callbacks
+ COR_PRF_MONITOR_REMOTING_COOKIE = 0x00004000 | COR_PRF_MONITOR_REMOTING,
+
+ // MONITOR_REMOTING_ASYNC controls whether
+ // the Remoting* callbacks will monitor async events
+ COR_PRF_MONITOR_REMOTING_ASYNC = 0x00008000 | COR_PRF_MONITOR_REMOTING,
+
+ // MONITOR_SUSPENDS controls the RuntimeSuspend*,
+ // RuntimeResume*, RuntimeThreadSuspended, and
+ // RuntimeThreadResumed callbacks.
+ COR_PRF_MONITOR_SUSPENDS = 0x00010000,
+
+ // MONITOR_CACHE_SEARCHES controls the
+ // JITCachedFunctionSearch* callbacks.
+ // See the comments on those callbacks for important
+ // behavior changes in V2.
+ COR_PRF_MONITOR_CACHE_SEARCHES = 0x00020000,
+
+ // NOTE: ReJIT is now supported again. The profiler must set this flag on
+ // startup in order to use RequestReJIT or RequestRevert. If the profiler specifies
+ // this flag, then the profiler must also specify COR_PRF_DISABLE_ALL_NGEN_IMAGES
+ COR_PRF_ENABLE_REJIT = 0x00040000,
+
+ // V2 MIGRATION WARNING: DEPRECATED
+ // Inproc debugging is no longer supported. ENABLE_INPROC_DEBUGGING
+ // has no effect.
+ COR_PRF_ENABLE_INPROC_DEBUGGING = 0x00080000,
+
+ // V2 MIGRATION NOTE: DEPRECATED
+ // The runtime now always tracks IL-native maps; this flag is thus always
+ // considered to be set.
+ COR_PRF_ENABLE_JIT_MAPS = 0x00100000,
+
+ // DISABLE_INLINING tells the runtime to disable all inlining
+ COR_PRF_DISABLE_INLINING = 0x00200000,
+
+ // DISABLE_OPTIMIZATIONS tells the runtime to disable all code optimizations
+ COR_PRF_DISABLE_OPTIMIZATIONS = 0x00400000,
+
+ // ENABLE_OBJECT_ALLOCATED tells the runtime that the profiler may want
+ // object allocation notifications. This must be set during initialization if the profiler
+ // ever wants object notifications (using COR_PRF_MONITOR_OBJECT_ALLOCATED)
+ COR_PRF_ENABLE_OBJECT_ALLOCATED = 0x00800000,
+
+ // MONITOR_CLR_EXCEPTIONS controls the ExceptionCLRCatcher*
+ // callbacks.
+ COR_PRF_MONITOR_CLR_EXCEPTIONS = 0x01000000,
+
+ // All callback events are enabled with this flag
+ COR_PRF_MONITOR_ALL = 0x0107FFFF,
+
+ // ENABLE_FUNCTION_ARGS enables argument tracing through FunctionEnter2.
+ COR_PRF_ENABLE_FUNCTION_ARGS = 0X02000000,
+
+ // ENABLE_FUNCTION_RETVAL enables retval tracing through FunctionLeave2.
+ COR_PRF_ENABLE_FUNCTION_RETVAL = 0X04000000,
+
+ // ENABLE_FRAME_INFO enables retrieval of exact ClassIDs for generic functions using
+ // GetFunctionInfo2 with a COR_PRF_FRAME_INFO obtained from FunctionEnter2.
+ COR_PRF_ENABLE_FRAME_INFO = 0X08000000,
+
+ // ENABLE_STACK_SNAPSHOT enables the used of DoStackSnapshot calls.
+ COR_PRF_ENABLE_STACK_SNAPSHOT = 0X10000000,
+
+ // USE_PROFILE_IMAGES causes the native image search to look for profiler-enhanced
+ // images. If no profiler-enhanced image is found for a given assembly the
+ // runtime will fallback to JIT for that assembly.
+ COR_PRF_USE_PROFILE_IMAGES = 0x20000000,
+
+ // COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST will disable security
+ // transparency checks normally done during JIT compilation and class loading for
+ // full trust assemblies. This can make some instrumentation easier to perform.
+ COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST
+ = 0x40000000,
+
+ // Prevents all NGEN images (including profiler-enhanced images) from loading. If
+ // this and COR_PRF_USE_PROFILE_IMAGES are both specified,
+ // COR_PRF_DISABLE_ALL_NGEN_IMAGES wins.
+ COR_PRF_DISABLE_ALL_NGEN_IMAGES = 0x80000000,
+
+ // The mask for valid mask bits
+ COR_PRF_ALL = 0x8FFFFFFF,
+
+ // COR_PRF_REQUIRE_PROFILE_IMAGE represents all flags that require profiler-enhanced
+ // images.
+ COR_PRF_REQUIRE_PROFILE_IMAGE = COR_PRF_USE_PROFILE_IMAGES |
+ COR_PRF_MONITOR_CODE_TRANSITIONS |
+ COR_PRF_MONITOR_ENTERLEAVE,
+
+ COR_PRF_ALLOWABLE_AFTER_ATTACH = COR_PRF_MONITOR_THREADS |
+ COR_PRF_MONITOR_MODULE_LOADS |
+ COR_PRF_MONITOR_ASSEMBLY_LOADS |
+ COR_PRF_MONITOR_APPDOMAIN_LOADS |
+ COR_PRF_ENABLE_STACK_SNAPSHOT |
+ COR_PRF_MONITOR_GC |
+ COR_PRF_MONITOR_SUSPENDS |
+ COR_PRF_MONITOR_CLASS_LOADS |
+ COR_PRF_MONITOR_EXCEPTIONS |
+ COR_PRF_MONITOR_JIT_COMPILATION,
+
+ // 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.
+ COR_PRF_MONITOR_IMMUTABLE = COR_PRF_MONITOR_CODE_TRANSITIONS |
+ COR_PRF_MONITOR_REMOTING |
+ COR_PRF_MONITOR_REMOTING_COOKIE |
+ COR_PRF_MONITOR_REMOTING_ASYNC |
+ COR_PRF_ENABLE_REJIT |
+ COR_PRF_ENABLE_INPROC_DEBUGGING |
+ COR_PRF_ENABLE_JIT_MAPS |
+ COR_PRF_DISABLE_OPTIMIZATIONS |
+ COR_PRF_DISABLE_INLINING |
+ COR_PRF_ENABLE_OBJECT_ALLOCATED |
+ COR_PRF_ENABLE_FUNCTION_ARGS |
+ COR_PRF_ENABLE_FUNCTION_RETVAL |
+ COR_PRF_ENABLE_FRAME_INFO |
+ COR_PRF_USE_PROFILE_IMAGES |
+ COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST |
+ COR_PRF_DISABLE_ALL_NGEN_IMAGES
+} COR_PRF_MONITOR;
+
+/*
+ * Additional flags the profiler can specify via SetEventMask2 when loading
+ */
+typedef enum
+{
+ COR_PRF_HIGH_MONITOR_NONE = 0x00000000,
+
+ COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES = 0x00000001,
+
+ COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x00000002,
+
+ COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0,
+
+ COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED,
+
+ // 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.
+ COR_PRF_HIGH_MONITOR_IMMUTABLE = 0,
+
+} COR_PRF_HIGH_MONITOR;
+
+/*
+ * COR_PRF_MISC contains miscellaneous constant ID's used for special
+ * purposes.
+ */
+typedef enum
+{
+ // PROFILER_PARENT_UNKNOWN is the AssemblyID used by GetModuleInfo
+ // when a module has not yet been attached to an assembly.
+ PROFILER_PARENT_UNKNOWN = 0xFFFFFFFD,
+
+ // PROFILER_GLOBAL_CLASS is a ClassID used for globals that belong to no class
+ PROFILER_GLOBAL_CLASS = 0xFFFFFFFE,
+
+ // PROFILER_GLOBAL_MODULE is a ModuleID used for globals that belong
+ // to no module in particular
+ PROFILER_GLOBAL_MODULE = 0xFFFFFFFF
+} COR_PRF_MISC;
+
+/*
+ * COR_PRF_JIT_CACHE contains values used to express the result of a
+ * cached function search. Note that FOUND is 0, and thus this is not truly
+ * a boolean.
+ */
+typedef enum
+{
+ COR_PRF_CACHED_FUNCTION_FOUND,
+ COR_PRF_CACHED_FUNCTION_NOT_FOUND
+} COR_PRF_JIT_CACHE;
+
+/*
+ * COR_PRF_TRANSITION_REASON contains values used to describe
+ * the reason for a ManagedToUnmanaged or UnmanagedToManagedTransition
+ * callback.
+ */
+typedef enum
+{
+ COR_PRF_TRANSITION_CALL,
+ COR_PRF_TRANSITION_RETURN
+} COR_PRF_TRANSITION_REASON;
+
+/*
+ * COR_PRF_SUSPEND_REASON contains values used to describe the
+ * reason for suspending the runtime. See the RuntimeSuspension*
+ * callbacks for detailed descriptions of each.
+ */
+typedef enum
+{
+ COR_PRF_SUSPEND_OTHER = 0,
+ COR_PRF_SUSPEND_FOR_GC = 1,
+ COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN = 2,
+ COR_PRF_SUSPEND_FOR_CODE_PITCHING = 3,
+ COR_PRF_SUSPEND_FOR_SHUTDOWN = 4,
+ COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER = 6,
+ COR_PRF_SUSPEND_FOR_GC_PREP = 7,
+ COR_PRF_SUSPEND_FOR_REJIT = 8,
+} COR_PRF_SUSPEND_REASON;
+
+/*
+ * COR_PRF_RUNTIME_TYPE contains values used to indicate the
+ * type of runtime.
+ */
+typedef enum
+{
+ COR_PRF_DESKTOP_CLR = 0x1,
+ COR_PRF_CORE_CLR = 0x2,
+} COR_PRF_RUNTIME_TYPE;
+
+
+/* -------------------------------------------------------------------------- *
+ * Forward declarations
+ * -------------------------------------------------------------------------- */
+
+interface ICorProfilerCallback;
+interface ICorProfilerCallback2;
+interface ICorProfilerCallback3;
+interface ICorProfilerCallback4;
+interface ICorProfilerInfo;
+interface ICorProfilerInfo2;
+interface ICorProfilerInfo3;
+interface ICorProfilerInfo4;
+interface ICorProfilerObjectEnum;
+interface ICorProfilerFunctionEnum;
+interface ICorProfilerModuleEnum;
+interface ICorProfilerThreadEnum;
+interface ICorProfilerMethodEnum;
+interface IMethodMalloc;
+interface ICorProfilerFunctionControl;
+interface ICorProfilerAssemblyReferenceProvider;
+/* -------------------------------------------------------------------------- *
+ * User Callback interface
+ * -------------------------------------------------------------------------- */
+
+/*
+ * The ICorProfilerCallback interface is used by the CLR to notify a
+ * code profiler when events have occurred that the code profiler has registered
+ * an in interest in receiving. This is the primary callback interface through
+ * which the CLR communicates with the code profiler. A code profiler
+ * must register this callback interface in the Win32 registry. This object has
+ * several methods that receive notification from the runtime when an event is
+ * about to occur in an executing runtime process.
+ *
+ * The methods implemented on this interface return S_OK on success, or E_FAIL
+ * on failure.
+ */
+
+[
+ object,
+ uuid(176FBED1-A55C-4796-98CA-A9DA0EF883E7),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback : IUnknown
+{
+
+ /*
+ *
+ * STARTUP/SHUTDOWN EVENTS
+ *
+ */
+
+ /*
+ * The CLR calls Initialize to setup the code profiler
+ * whenever a new CLR application is started. The call provides
+ * an IUnknown interface pointer that should be QI'd for an ICorProfilerInfo
+ * interface pointer.
+ *
+ * NOTE: this is the only opportunity to enable callbacks that are a part
+ * of COR_PRF_MONITOR_IMMUTABLE, since they can no longer be changed after
+ * returning from this function. This is done through SetEventMask on the
+ * ICorProfilerInfo object.
+ */
+ HRESULT Initialize(
+ [in] IUnknown *pICorProfilerInfoUnk);
+
+ /*
+ * The CLR calls Shutdown to notify the code profiler that
+ * the application is exiting. This is the profiler's last opportunity to
+ * safely call functions on the ICorProfilerInfo interface. After returning
+ * from this function the runtime will proceed to unravel its internal data
+ * structures and any calls to ICorProfilerInfo are undefined in their
+ * behaviour.
+ *
+ * NOTE: Certain IMMUTABLE events may still occur after Shutdown.
+ *
+ * NOTE: Shutdown will only fire where the managed application that is being
+ * profiled was started running managed code (i.e., the initial frame on the
+ * process' stack is managed). If the application being profiled started
+ * life as unmanaged code, which later 'jumped into' managed code (thereby
+ * creating an instance of the CLR), then Shutdown will not fire. In these
+ * cases, the profiler should include a DllMain routine in their library that
+ * uses Win32's DLL_PROCESS_DETACH call to free any resources and perform tidy-up
+ * processing of its data (flush traces to disk, etc)
+ *
+ * NOTE: The profiler must in general cope with unexpected shutdowns, such as
+ * when the process is "killed" by Win32's TerminateProcess.
+ *
+ * NOTE: Sometimes the CLR will violently kill certain managed threads
+ * (background threads) without delivering orderly destruction messages for them.
+ */
+ HRESULT Shutdown();
+
+
+ /*
+ *
+ * APPLICATION DOMAIN EVENTS
+ *
+ */
+
+ /*
+ * Called when an application domain creation has begun and ended.
+ * The ID is not valid for any information request until the Finished
+ * event is called.
+ *
+ * Some parts of app domain loading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of app domain creation succeeded.
+ */
+ HRESULT AppDomainCreationStarted(
+ [in] AppDomainID appDomainId);
+
+ HRESULT AppDomainCreationFinished(
+ [in] AppDomainID appDomainId,
+ [in] HRESULT hrStatus);
+
+ /*
+ * Called before and after an app domain is unloaded from a process.
+ * The ID is no longer valid after the Started event returns.
+ *
+ * Some parts of app domain unloading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of app domain unloading succeeded.
+ */
+ HRESULT AppDomainShutdownStarted(
+ [in] AppDomainID appDomainId);
+
+ HRESULT AppDomainShutdownFinished(
+ [in] AppDomainID appDomainId,
+ [in] HRESULT hrStatus);
+
+ /*
+ *
+ * ASSEMBLY EVENTS
+ *
+ */
+
+ /*
+ * Called when an Assembly load has begun and ended. The ID is not valid
+ * for any information request until the Finished event is called.
+ *
+ * Some parts of assembly loading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of assembly loading succeeded.
+ */
+ HRESULT AssemblyLoadStarted(
+ [in] AssemblyID assemblyId);
+
+ HRESULT AssemblyLoadFinished(
+ [in] AssemblyID assemblyId,
+ [in] HRESULT hrStatus);
+
+ /*
+ * Called before and after an assembly is unloaded.
+ * The ID is no longer valid after the Started event returns.
+ *
+ * Some parts of assembly unloading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of assembly unloading succeeded.
+ */
+ HRESULT AssemblyUnloadStarted(
+ [in] AssemblyID assemblyId);
+
+ HRESULT AssemblyUnloadFinished(
+ [in] AssemblyID assemblyId,
+ [in] HRESULT hrStatus);
+
+
+ /*
+ *
+ * MODULE EVENTS
+ *
+ */
+
+ /*
+ * Called when a module load has begun and ended. The ID is not valid
+ * for any information request until the Finished event is called.
+ *
+ * Some parts of module loading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of module loading succeeded.
+ *
+ * Note that when a module load is reported as finished this indicates
+ * that the load has completed but it has not yet returned to the caller.
+ * This is the opportunity for the profiler to note that other notifications regarding
+ * this module may start coming afterwards however internal safeguards
+ * protecting the runtime from recursive loading are still present and so it is
+ * a bad time to begin inquiries on this module. The notification is informational
+ * only.
+ *
+ * Note: ModuleLoadFinished is a reasonable time to interrogate MetaData via API's
+ * like GetModuleMetadata, however APIs that create (e.g. ClassID's and FunctionID's)
+ * are not safe to use here. Profiler writers are advised to stay in the universe of
+ * tokens.
+ *
+ */
+ HRESULT ModuleLoadStarted(
+ [in] ModuleID moduleId);
+
+ HRESULT ModuleLoadFinished(
+ [in] ModuleID moduleId,
+ [in] HRESULT hrStatus);
+
+ /*
+ * Called before and after a module is unloaded.
+ * The ID is no longer valid after the Started event returns.
+ *
+ * Some parts of module unloading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of module unloading succeeded.
+ */
+ HRESULT ModuleUnloadStarted(
+ [in] ModuleID moduleId);
+
+ HRESULT ModuleUnloadFinished(
+ [in] ModuleID moduleId,
+ [in] HRESULT hrStatus);
+
+ /*
+ * A module can get loaded through legacy means (ie: IAT or LoadLibrary) or
+ * through a metadata reference. The CLR loader therefore has many code
+ * paths for determining what assembly a module lives in. It is therefore
+ * possible that after a ModuleLoadFinished event, the module does not
+ * know what assembly it is in and getting the parent AssemblyID is not possible.
+ * This event is fired when the module is officially attached to its parent
+ * assembly. Calling GetModuleInfo after this function is called will return the
+ * proper parent assembly.
+ */
+ HRESULT ModuleAttachedToAssembly(
+ [in] ModuleID moduleId,
+ [in] AssemblyID AssemblyId);
+
+
+ /*
+ *
+ * CLASS EVENTS
+ *
+ */
+
+ /*
+ * Called when a class load has begun and ended. The ID is not valid
+ * for any information request until the Finished event is called.
+ *
+ * Some parts of class loading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of class loading succeeded.
+ *
+ * Note that when a class load is reported as finished this indicates
+ * that the load has completed but it has not yet returned to the caller.
+ * This is the opportunity for the profiler to note that other notifications regarding
+ * this class may start coming afterwards however internal safeguards
+ * protecting the runtime from recursive loading are still present and so it is
+ * a bad time to begin inquiries on this class. The notification is informational
+ * only.
+ *
+ */
+ HRESULT ClassLoadStarted(
+ [in] ClassID classId);
+
+ HRESULT ClassLoadFinished(
+ [in] ClassID classId,
+ [in] HRESULT hrStatus);
+
+ /*
+ * Called before and after a class is unloaded.
+ * The ID is no longer valid after the Started event returns.
+ *
+ * Some parts of class unloading may take place lazily at some time
+ * after the Finished callback. Therefore, while a failure HRESULT in
+ * hrStatus definitely indicates a failure, a success HRESULT only indicates
+ * that the first part of class unloading succeeded.
+ */
+ HRESULT ClassUnloadStarted(
+ [in] ClassID classId);
+
+ HRESULT ClassUnloadFinished(
+ [in] ClassID classId,
+ [in] HRESULT hrStatus);
+
+ /*
+ *
+ * JIT EVENTS
+ *
+ */
+
+ /*
+ * The CLR calls FunctionUnloadStarted to notify the code
+ * profiler that a function is being unloaded. After returning from this
+ * call, the FunctionID is no longer valid.
+ */
+ HRESULT FunctionUnloadStarted(
+ [in] FunctionID functionId);
+
+
+ /*
+ * The CLR calls JITCompilationStarted to notify the code
+ * profiler that the JIT compiler is starting to compile a function.
+ *
+ * The fIsSafeToBlock argument tells the profiler whether or not blocking
+ * will affect the operation of the runtime. If true, blocking may cause
+ * the runtime to wait for the calling thread to return from this callback.
+ * Although this will not harm the runtime, it will skew the profiling
+ * results.
+ *
+ * NOTE: It is possible to receive more than one JITCompilationStarted/
+ * JITCompilationFinished pair for each method. This is because of how
+ * the runtime handles class constructors: method A starts to be JIT'd,
+ * then realizes that the class ctor for class B needs to be run, so
+ * JIT's it and runs it, and while it's running makes a call to original
+ * method A, which causes it to be JIT'd again, and causes the original
+ * (incomplete) JIT'ing of A to be aborted. However, both attempts to
+ * JIT A are reported with JIT compilation events. If the profiler is
+ * going to replace IL code for this method with SetILFunctionBody, then
+ * it must do so for both JITCompilationStarted events, but may use the
+ * same IL block for both.
+ *
+ * NOTE: A profiler should be tolerant of the sequence of JIT callbacks
+ * received in cases where two threads are simultaneously calling a
+ * method. For example, thread A receives JITCompilationStarted.
+ * But before thread A receives JITCompilationFinished, thread B
+ * receives FunctionEnter with the functionId from thread A's
+ * JITCompilationStarted callback. It may appear that functionId should
+ * not yet be valid because JITCompilationFinished had not yet been
+ * received. But it is indeed valid in such a case.
+ */
+ HRESULT JITCompilationStarted(
+ [in] FunctionID functionId,
+ [in] BOOL fIsSafeToBlock);
+
+ /*
+ * The CLR calls JITCompilationFinished to notify the code
+ * profiler that the JIT compiler has finished compiling a function.
+ *
+ * The fIsSafeToBlock argument tells the profiler whether or not blocking
+ * will affect the operation of the runtime. If true, blocking may cause
+ * the runtime to wait for the calling thread to return from this callback.
+ * Although this will not harm the runtime, it will skew the profiling
+ * results.
+ *
+ * The FunctionID is now valid in ICorProfilerInfo APIs.
+ *
+ * The hrStatus provides the success or failure of the operation
+ */
+ HRESULT JITCompilationFinished(
+ [in] FunctionID functionId,
+ [in] HRESULT hrStatus,
+ [in] BOOL fIsSafeToBlock);
+
+ /*
+ * V2 MIGRATION WARNING: DOES NOT ALWAYS OCCUR
+ * The JITCachedFunctionSearchStarted/Finished callbacks
+ * will now occur only for some functions in regular NGEN images;
+ * only profiler-optimized NGEN images will generate callbacks for
+ * all functions in the image. Profilers which do not use these callbacks
+ * to force a function to be JIT-compiled should move to using a lazy
+ * strategy for gathering function information.
+ *
+ * This notifies the profiler when a search for a prejitted function is
+ * starting.
+ *
+ * functionId: the function for which the search is being performed.
+ * bUseCachedFunction: if true, the EE uses the cached function (if applicable)
+ * if false, the EE jits the function instead of
+ * using a pre-jitted version.
+ *
+ * NOTE: Profilers should be tolerant of cases where multiple threads of
+ * a profiled app are calling the same method simultaneously. For example,
+ * thread A may receive JITCachedFunctionSearchStarted (and the
+ * profiler sets *pbUseCachedFunction=FALSE to force a JIT), thread A
+ * then receives JITCompilationStarted/JITCompilationFinished, then
+ * thread B receives another JITCachedFunctionSearchStarted for the same
+ * method. It might appear odd to receive this final callback, since the
+ * profiler already stated its intention to JIT the method. But this is
+ * occurring because the CLR in thread B decided to send this callback
+ * before thread A responded to JITCachedFunctionSearchStarted
+ * with *pbUseCachedFunction=FALSE, and the thread B callback
+ * hadn't actually been sent until now due how the threads
+ * happened to be scheduled. In such cases where the profiler
+ * receives duplicate JITCachedFunctionSearchStarted callbacks for
+ * the same functionId, the profiler should be certain to set
+ * *pbUseCachedFunction to the same value from this callback
+ * when it is called multiple times with the same functionId.
+ */
+ HRESULT JITCachedFunctionSearchStarted(
+ [in] FunctionID functionId,
+ [out] BOOL *pbUseCachedFunction);
+
+ /*
+ * V2 MIGRATION WARNING: DOES NOT ALWAYS OCCUR
+ * The JITCachedFunctionSearchStarted/Finished callbacks
+ * will now occur only for some functions in regular NGEN images;
+ * only profiler-optimized NGEN images will generate callbacks for
+ * all functions in the image. Profilers which do not use these callbacks
+ * to force a function to be JIT-compiled should move to using a lazy
+ * strategy for gathering function information.
+ *
+ * This notifies the profiler when a search for a cached function has been
+ * performed.
+ *
+ * functionId: the function for which the search has been performed.
+ * result: the result of the search. There are two possible results:
+ * COR_PRF_CACHED_FUNCTION_FOUND
+ * COR_PRF_CACHED_FUNCTION_NOT_FOUND
+ *
+ */
+ HRESULT JITCachedFunctionSearchFinished(
+ [in] FunctionID functionId,
+ [in] COR_PRF_JIT_CACHE result);
+
+ /*
+ * The CLR calls JITFunctionPitched to notify the profiler
+ * that a jitted function was removed from memory. If the pitched
+ * function is called in the future, the profiler will receive new
+ * JIT compilation events as it is re-jitted.
+ *
+ * Currently the CLR JIT does not pitch functions, so this callback
+ * will not be received.
+ *
+ * NOTE: the FunctionID is not valid until it is re-jitted. When it is
+ * re-jitted, it will use the same FunctionID value.
+ */
+ HRESULT JITFunctionPitched(
+ [in] FunctionID functionId);
+
+ /*
+ * The CLR calls JITInlining to notify the profiler that the jitter
+ * is about to inline calleeId into callerId. Set pfShouldInline to FALSE
+ * to prevent the callee from being inlined into the caller, and set to
+ * TRUE to allow the inline to occur.
+ *
+ * NOTE: Inlined functions do not provide Enter/Leave events, so if you desire
+ * an accurate callgraph, you should set FALSE. Be aware that
+ * setting FALSE will affect performance, since inlining typically
+ * increases speed and reduces separate jitting events for the inlined
+ * method.
+ *
+ * NOTE: It is also possible to globally disable inlining by setting the
+ * COR_PRF_DISABLE_INLINING flag.
+ */
+ HRESULT JITInlining(
+ [in] FunctionID callerId,
+ [in] FunctionID calleeId,
+ [out] BOOL *pfShouldInline);
+
+ /*
+ *
+ * THREAD EVENTS
+ *
+ */
+
+ /*
+ * The CLR calls ThreadCreated to notify the code profiler
+ * that a thread has been created. The ThreadID is valid immediately.
+ */
+ HRESULT ThreadCreated(
+ [in] ThreadID threadId);
+
+ /*
+ * The CLR calls ThreadDestroyed to notify the code profiler
+ * that a thread has been destroyed. The ThreadID is no longer valid
+ * at the time of this call.
+ */
+ HRESULT ThreadDestroyed(
+ [in] ThreadID threadId);
+
+ /*
+ * The CLR calls ThreadAssignedToOSThread to tell the profiler
+ * that a managed thread is being implemented via a particualr OS thread.
+ * This callback exists so that the profiler can maintain an accurate
+ * OS to Managed thread mapping across fibres.
+ */
+ HRESULT ThreadAssignedToOSThread(
+ [in] ThreadID managedThreadId,
+ [in] DWORD osThreadId);
+
+ /*
+ *
+ * REMOTING EVENTS
+ *
+ */
+
+ //
+ // Client-side events
+ //
+
+ /*
+ * NOTE: each of the following pairs of callbacks will occur on the same
+ * thread
+ * RemotingClientInvocationStarted & RemotingClientSendingMessage
+ * RemotingClientReceivingReply & RemotingClientInvocationFinished
+ * RemotingServerInvocationReturned & RemotingServerSendingReply
+ *
+ * There are a few issues with the remoting callbacks that should be outlined.
+ * First, remoting function execution is not reflected by the profiler API, so
+ * the notifications for functions that are called from the client and executed
+ * to the server are not properly received. The actual invocation happens via a
+ * proxy object. That creates the illusion to the profiler that certain
+ * functions get jit-compiled but they never get used. Second, the profiler does
+ * not receive accurate notifications for asynchronous remoting events.
+ */
+
+ /*
+ * The CLR calls RemotingClientInvocationStarted to notify the profiler that
+ * a remoting call has begun. This event is the same for synchronous and
+ * asynchronous calls.
+ */
+ HRESULT RemotingClientInvocationStarted();
+
+ /*
+ * The CLR calls RemotingClientSendingMessage to notify the profiler that
+ * a remoting call is requiring the the caller to send an invocation request through
+ * a remoting channel.
+ *
+ * pCookie - if remoting GUID cookies are active, this value will correspond with the
+ * the value provided in RemotingServerReceivingMessage, if the channel
+ * succeeds in transmitting the message, and if GUID cookies are active on
+ * the server-side process. This allows easy pairing of remoting calls,
+ * and the creation of a logical call stack.
+ * fIsAsync - is true if the call is asynchronous.
+ */
+ HRESULT RemotingClientSendingMessage(
+ [in] GUID *pCookie,
+ [in] BOOL fIsAsync);
+
+ /*
+ * The CLR calls RemotingClientReceivingReply to notify the profiler that
+ * the server-side portion of a remoting call has completed and that the client is
+ * now receiving and about to process the reply.
+ *
+ * pCookie - if remoting GUID cookies are active, this value will correspond with the
+ * the value provided in RemotingServerSendingReply, if the channel
+ * succeeds in transmitting the message, and if GUID cookies are active on
+ * the server-side process. This allows easy pairing of remoting calls.
+ * fIsAsync - is true if the call is asynchronous.
+ */
+ HRESULT RemotingClientReceivingReply(
+ [in] GUID *pCookie,
+ [in] BOOL fIsAsync);
+
+ /*
+ * The CLR calls RemotingClientInvocationFinished to notify the profiler that
+ * a remoting invocation has run to completion on the client side. If the call was
+ * synchronous, this means that it has also run to completion on the server side. If
+ * the call was asynchronous, a reply may still be expected when the call is handled.
+ * If the call is asynchronous, and a reply is expected, then the reply will occur in
+ * the form of a call to RemotingClientReceivingReply and an additional call to
+ * RemotingClientInvocationFinished to indicate the required secondary processing of
+ * an asynchronous call.
+ */
+ HRESULT RemotingClientInvocationFinished();
+
+ //
+ // Server-side events
+ //
+
+ /*
+ * The CLR calls RemotingServerReceivingMessage to notify the profiler that
+ * the process has received a remote method invocation (or activation) request. If
+ * the message request is asynchronous, then the request may be serviced by any
+ * arbitrary thread.
+ *
+ * pCookie - if remoting GUID cookies are active, this value will correspond with the
+ * the value provided in RemotingClientSendingMessage, if the channel
+ * succeeds in transmitting the message, and if GUID cookies are active on
+ * the client-side process. This allows easy pairing of remoting calls.
+ * fIsAsync - is true if the call is asynchronous.
+ */
+ HRESULT RemotingServerReceivingMessage(
+ [in] GUID *pCookie,
+ [in] BOOL fIsAsync);
+
+ /*
+ * The CLR calls RemotingServerInvocationStarted to notify the profiler that
+ * the process is invoking a method due to a remote method invocation request.
+ */
+ HRESULT RemotingServerInvocationStarted();
+
+ /*
+ * The CLR calls RemotingServerInvocationReturned to notify the profiler that
+ * the process has finished invoking a method due to a remote method invocation request.
+ */
+ HRESULT RemotingServerInvocationReturned();
+
+ /*
+ * The CLR calls RemotingServerSendingReply to notify the profiler that
+ * the process has finished processing a remote method invocation request and is
+ * about to transmit the reply through a channel.
+ *
+ * pCookie - if remoting GUID cookies are active, this value will correspond with the
+ * the value provided in RemotingClientReceivingReply, if the channel
+ * succeeds in transmitting the message, and if GUID cookies are active on
+ * the client-side process. This allows easy pairing of remoting calls.
+ * fIsAsync - is true if the call is asynchronous.
+ */
+ HRESULT RemotingServerSendingReply(
+ [in] GUID *pCookie,
+ [in] BOOL fIsAsync);
+
+ /*
+ *
+ * TRANSITION EVENTS
+ *
+ */
+
+ /*
+ * The CLR calls UnmanagedToManagedTransition to notify the
+ * code profiler that a transition from unmanaged code to managed code has
+ * occurred. functionId is always the ID of the callee, and reason
+ * indicates whether the transition was due to a call into managed code from
+ * unmanaged, or a return from an unmanaged function called by a managed one.
+ *
+ * Note that if the reason is COR_PRF_TRANSITION_RETURN and the functionId is
+ * non-NULL, then the functionId is that of the unmanaged function, and will
+ * never have been jitted. Unmanaged functions still have some basic
+ * information associated with them, such as a name, and some metadata.
+ *
+ * Note that if the reason is COR_PRF_TRANSITION_RETURN and the callee was
+ * a PInvoke call indirect, then the runtime does not know the destination
+ * of the call and functionId will be NULL.
+ *
+ * Note that if the reason is COR_PRF_TRANSITION_CALL then it may be possible
+ * that the callee has not yet been JIT-compiled.
+ */
+ HRESULT UnmanagedToManagedTransition(
+ [in] FunctionID functionId,
+ [in] COR_PRF_TRANSITION_REASON reason);
+
+
+ /*
+ * The CLR calls ManagedToUnmanagedTransition to notify the
+ * code profiler that a transition from managed code to unmanaged code has
+ * occurred. functionId is always the ID of the callee, and reason
+ * indicates whether the transition was due to a call into unmanaged code from
+ * managed, or a return from an managed function called by an unmanaged one.
+ *
+ * Note that if the reason is COR_PRF_TRANSITION_CALL, then the functionId
+ * is that of the unmanaged function, and will never have been jitted.
+ * Unmanaged functions still have some basic information associated with
+ * them, such as a name, and some metadata.
+ *
+ * Note that if the reason is COR_PRF_TRANSITION_CALL and the callee is
+ * a PInvoke call indirect, then the runtime does not know the destination
+ * of the call and functionId will be NULL.
+ */
+ HRESULT ManagedToUnmanagedTransition(
+ [in] FunctionID functionId,
+ [in] COR_PRF_TRANSITION_REASON reason);
+
+
+ /*
+ *
+ * RUNTIME SUSPENSION EVENTS
+ *
+ */
+
+ /*
+ * The CLR calls RuntimeSuspendStarted to notify the code profiler
+ * that the runtime is about to suspend all of the runtime threads.
+ * All runtime threads that are in unmanaged code are permitted to continue
+ * running until they try to re-enter the runtime, at which point they will
+ * also suspend until the runtime resumes. This also applies to new threads
+ * that enter the runtime. All threads within the runtime are either
+ * suspended immediately if they are in interruptible code, or asked to
+ * suspend when they do reach interruptible code.
+ *
+ * suspendReason make be any of the following values:
+ * COR_PRF_SUSPEND_FOR_GC
+ * the runtime is suspending to service a GC request. The GC-related
+ * callbacks will occur between the RuntimeSuspendFinished and
+ * RuntimeResumeStarted events.
+ * COR_PRF_SUSPEND_FOR_CODE_PITCHING
+ * the runtime is suspending so that code pitching may occur. This
+ * only occurs when the EJit is active with code pitching enabled.
+ * Code pitching callbacks will occur between the
+ * RuntimeSuspendFinished and RuntimeResumeStarted events.
+ * COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN
+ * the runtime is suspending so that an AppDomain can be shut down.
+ * While the runtime is suspended, the runtime will determine which
+ * threads are in the AppDomain that is being shut down, set them to
+ * abort when they resume, and then resumes the runtime. There are
+ * no AppDomain-specific callbacks during this suspension.
+ * COR_PRF_SUSPEND_FOR_SHUTDOWN
+ * the runtime is shutting down, and it must suspend all threads to
+ * complete the operation.
+ * COR_PRF_SUSPEND_FOR_GC_PREP
+ * the runtime is preparing for a GC.
+ * COR_PRF_SUSPEND_FOR_INPROC_DEBUGGER
+ * the runtime is suspending for in-process debugging.
+ * COR_PRF_SUSPEND_OTHER
+ * the runtime is suspending for a reason other than those above.
+ */
+ HRESULT RuntimeSuspendStarted(
+ [in] COR_PRF_SUSPEND_REASON suspendReason);
+
+ /*
+ * The CLR calls RuntimeSuspendFinished to notify the code profiler
+ * that the runtime has suspended all threads needed for a runtime
+ * suspension. Note that not all runtime threads are required to be
+ * suspended, as described in the comment for RuntimeSuspendStarted.
+ *
+ * NOTE: It is guaranteed that this event will occur on the same ThreadID
+ * as RuntimeSuspendStarted occurred on.
+ */
+ HRESULT RuntimeSuspendFinished();
+
+ /*
+ * The CLR calls RuntimeSuspendAborted to notify the code profiler
+ * that the runtime is aborting the runtime suspension that was occurring.
+ * This may occur if two threads simultaneously attempt to suspend the
+ * runtime.
+ *
+ * NOTE: It is guaranteed that this event will occur on the same ThreadID
+ * as the RuntimeSuspendStarted occurred on, and that only one of
+ * RuntimeSuspendFinished and RuntimeSuspendAborted may occur on a single
+ * thread following a RuntimeSuspendStarted event.
+ */
+ HRESULT RuntimeSuspendAborted();
+
+ /*
+ * The CLR calls RuntimeResumeStarted to notify the code profiler
+ * that the runtime is about to resume all of the runtime threads.
+ */
+ HRESULT RuntimeResumeStarted();
+
+ /*
+ * The CLR calls RuntimeResumeFinished to notify the code profiler
+ * that the runtime has finished resuming all of it's threads and is now
+ * back in normal operation.
+ *
+ * NOTE: It is *NOT* guaranteed that this event will occur on the same
+ * ThreadID as the RuntimeSuspendStarted occurred on, but is guaranteed
+ * to occur on the same ThreadID as the RuntimeResumeStarted occurred on.
+ */
+ HRESULT RuntimeResumeFinished();
+
+ /*
+ * The CLR calls RuntimeThreadSuspended to notify the code profiler
+ * that a particular thread has been suspended.
+ *
+ * This notification may occur any time between the RuntimeSuspendStarted
+ * and the associated RuntimeResumeStarted. Notifications that occur
+ * between RuntimeSuspendFinished and RuntimeResumeStarted are for
+ * threads that had been running in unmanaged code and were suspended
+ * upon entry to the runtime.
+ */
+ HRESULT RuntimeThreadSuspended(
+ [in] ThreadID threadId);
+
+ /*
+ * The CLR calls RuntimeThreadResumed to notify the code profiler
+ * that a particular thread has been resumed after being suspended due to
+ * a runtime suspension.
+ */
+ HRESULT RuntimeThreadResumed(
+ [in] ThreadID threadId);
+
+ /*
+ *
+ * GC EVENTS
+ *
+ * NOTE: All of these callbacks (except ObjectAllocated) are made while the
+ * runtime is suspended, so none of the ObjectID values can change until
+ * the runtime resumes and another GC occurs.
+ *
+ * NOTE: The profiler will receive GC-related events (except ObjectAllocated)
+ * when the profiler has been suspended for COR_PRF_SUSPEND_FOR_GC *except*
+ * for one special case. When the runtime is shutting down, there is a
+ * stage where it is suspended for COR_PRF_SUSPEND_FOR_SHUTDOWN reason and
+ * is never resumed. But after this suspension a garbage collection may
+ * occur without a COR_PRF_SUSPEND_FOR_GC suspension notification, and
+ * the profiler will thus receive GC-related callbacks.
+ *
+ * NOTE: All of these callbacks (except ObjectAllocated) may be called more than
+ * once during the same GC. These calls should be considered multiple parts of
+ * one long report; the profiler should simply aggregate the information provided
+ * in all of them.
+ */
+
+ /*
+ * The CLR calls MovedReferences with information about
+ * object references that moved as a result of garbage collection.
+ *
+ * cMovedObjectIDRanges is a count of the number of ObjectID ranges that
+ * were moved.
+ * oldObjectIDRangeStart is an array of elements, each of which is the start
+ * value of a range of ObjectID values before being moved.
+ * newObjectIDRangeStart is an array of elements, each of which is the start
+ * value of a range of ObjectID values after being moved.
+ * cObjectIDRangeLength is an array of elements, each of which states the
+ * size of the moved ObjectID value range.
+ *
+ * The last three arguments of this function are parallel arrays.
+ *
+ * In other words, if an ObjectID value lies within the range
+ * oldObjectIDRangeStart[i] <= ObjectID < oldObjectIDRangeStart[i] + cObjectIDRangeLength[i]
+ * for 0 <= i < cMovedObjectIDRanges, then the ObjectID value has changed to
+ * ObjectID - oldObjectIDRangeStart[i] + newObjectIDRangeStart[i]
+ *
+ * NOTE: None of the objectIDs returned by MovedReferences are valid during the callback
+ * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
+ * should not attempt to inspect objects during a MovedReferences call. At
+ * GarbageCollectionFinished, all objects have been moved to their new locations, and
+ * inspection may be done.
+ *
+ * THIS CALLBACK IS OBSOLETE. It reports ranges for objects >4GB as ULONG_MAX
+ * on 64-bit platforms. Use ICorProfilerCallback4::MovedReferences2 instead.
+ */
+ HRESULT MovedReferences(
+ [in] ULONG cMovedObjectIDRanges,
+ [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
+ [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
+ [in, size_is(cMovedObjectIDRanges)] ULONG cObjectIDRangeLength[] );
+
+ /*
+ * The CLR calls ObjectAllocated to notify the code profiler
+ * an object was allocated on the heap. This notification does not fire
+ * for allocations from the stack, nor from unmanaged memory.
+ *
+ * It is possible to receive a classId that corresponds to a regular class
+ * that has not been loaded yet. The profiler will receive a class load
+ * callback for that class immediately after the object creation callback.
+ */
+ HRESULT ObjectAllocated(
+ [in] ObjectID objectId,
+ [in] ClassID classId);
+
+ /*
+ * The CLR calls ObjectsAllocatedByClass to notify the code
+ * profiler about the number of objects of a particular class that were
+ * allocated since the previous garbage collection. The classes and the
+ * counts are passed in parallel arrays. (Classes for which no instances
+ * have been allocated since the previous GC are omitted entirely.)
+ *
+ * NOTE: This callback will not report objects allocated in the large
+ * object heap.
+ *
+ * NOTE: The numbers here are only estimates. Use ObjectAllocated for
+ * exact counts.
+ */
+ HRESULT ObjectsAllocatedByClass(
+ [in] ULONG cClassCount,
+ [in, size_is(cClassCount)] ClassID classIds[] ,
+ [in, size_is(cClassCount)] ULONG cObjects[] );
+
+ /*
+ * The CLR calls ObjectReferences to provide information
+ * about objects in memory referenced by a given object. This function
+ * is called for each object remaining in the GC heap after a collection
+ * has completed. If the profiler returns an error from this callback,
+ * the profiling services will discontinue invoking this callback until the
+ * next GC. This callback can be used in conjunction with the
+ * RootReferences callback to create a complete object reference graph for
+ * the runtime.
+ *
+ * NOTE: The CLR will ensure that each object reference is reported only
+ * once by this function.
+ *
+ * NOTE: None of the objectIDs returned by ObjectReferences are valid during the callback
+ * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
+ * should not attempt to inspect objects during an ObjectReferences call. At
+ * GarbageCollectionFinished, all objects have been moved to their new locations, and
+ * inspection may be done.
+ */
+ HRESULT ObjectReferences(
+ [in] ObjectID objectId,
+ [in] ClassID classId,
+ [in] ULONG cObjectRefs,
+ [in, size_is(cObjectRefs)] ObjectID objectRefIds[] );
+
+ /*
+ * The CLR calls RootReferences with information about root
+ * references after a garbage collection has occurred. Static object
+ * references and references to objects on a stack are co-mingled in the
+ * arrays.
+ *
+ * NOTE: It is possible to get NULL ObjectIDs in the RootReferences callback.
+ * For example, all object references declared on the stack are treated as
+ * roots by the GC, and will always be reported.
+ *
+ * NOTE: None of the objectIDs returned by RootReferences are valid during the callback
+ * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
+ * should not attempt to inspect objects during a RootReferences call. At
+ * GarbageCollectionFinished, all objects have been moved to their new locations, and
+ * inspection may be done.
+ */
+ HRESULT RootReferences(
+ [in] ULONG cRootRefs,
+ [in, size_is(cRootRefs)] ObjectID rootRefIds[] );
+
+
+ /*
+ *
+ * EXCEPTION EVENTS
+ *
+ */
+
+ //
+ // Exception creation
+ //
+
+ /*
+ * The CLR calls ExceptionThrown to notify the code
+ * profiler that an exception has been thrown.
+ *
+ * NOTE: This function is only called if the exception reaches
+ * managed code.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+ HRESULT ExceptionThrown(
+ [in] ObjectID thrownObjectId);
+
+ //
+ // Search phase
+ //
+
+ /*
+ * The CLR calls ExceptionSearchFunctionEnter to notify the profiler
+ * that the search phase of exception handling has entered a function.
+ */
+ HRESULT ExceptionSearchFunctionEnter(
+ [in] FunctionID functionId);
+
+ /*
+ * The CLR calls ExceptionSearchFunctionLeave to notify the profiler
+ * that the search phase of exception handling has left a function.
+ */
+ HRESULT ExceptionSearchFunctionLeave();
+
+ /*
+ * The CLR will call ExceptionSearchFilterEnter just before excecuting
+ * a user filter. The functionID is that of the function containing the filter.
+ */
+ HRESULT ExceptionSearchFilterEnter(
+ [in] FunctionID functionId);
+
+ /*
+ * The CLR will call ExceptionSearchFilterLeave immediately after
+ * executing a user filter.
+ */
+ HRESULT ExceptionSearchFilterLeave();
+
+ /*
+ * The CLR will call ExceptionSearchCatcherFound when the search
+ * phase of exception handling has located a handler for the exception that
+ * was thrown.
+ */
+ HRESULT ExceptionSearchCatcherFound(
+ [in] FunctionID functionId);
+
+ /*
+ * DEPRECATED. It is the job of the unmanaged profiler to detect OS
+ * handling of exceptions.
+ */
+ HRESULT ExceptionOSHandlerEnter(
+ [in] UINT_PTR __unused);
+
+ /*
+ * DEPRECATED. It is the job of the unmanaged profiler to detect OS
+ * handling of exceptions.
+ */
+ HRESULT ExceptionOSHandlerLeave(
+ [in] UINT_PTR __unused);
+
+ //
+ // Unwind phase
+ //
+
+ /*
+ * The CLR calls ExceptionUnwindFunctionEnter to notify the profiler
+ * that the unwind phase of exception handling has entered a function.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+ HRESULT ExceptionUnwindFunctionEnter(
+ [in] FunctionID functionId);
+
+ /*
+ * The CLR calls ExceptionUnwindFunctionLeave to notify the profiler
+ * that the unwind phase of exception handling has left a function. The
+ * function instance and it's stack data has now been removed from the stack.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+ HRESULT ExceptionUnwindFunctionLeave();
+
+ /*
+ * The CLR calls ExceptionUnwindFinallyEnter to notify the profiler
+ * that the unwind phase of exception is entering a finally clause contained
+ * in the specified function.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+ HRESULT ExceptionUnwindFinallyEnter(
+ [in] FunctionID functionId);
+
+ /*
+ * The CLR calls ExceptionUnwindFinallyLeave to notify the profiler
+ * that the unwind phase of exception is leaving a finally clause.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+ HRESULT ExceptionUnwindFinallyLeave();
+
+ /*
+ * The CLR calls this function just before passing control to
+ * the appropriate catch block. Note that this is called only if the
+ * catch point is in JIT'ed code. An exception that is caught in
+ * unmanaged code, or in the internal code of the CLR will
+ * not generate this notification. The ObjectID is passed again since
+ * a GC could have moved the object since the ExceptionThrown
+ * notification.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+ HRESULT ExceptionCatcherEnter(
+ [in] FunctionID functionId,
+ [in] ObjectID objectId);
+
+ /*
+ * The CLR calls ExceptionCatcherLeave when the runtime leaves
+ * the catcher's code.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ */
+ HRESULT ExceptionCatcherLeave();
+
+ /*
+ * CLR<->COM interop vtable creation/destruction.
+ */
+
+ /*
+ * The CLR calls this function when an CLR<->COM interop vtable
+ * for a particular IID and for a particular class has been created.
+ * This provides the ClassID of the class for which this vtable has been
+ * created, the IID it implements, the start of the vtable and how many
+ * slots are in it.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ *
+ * NOTE: It is possible to receive a NULL GUID if the interface is
+ * internal only.
+ */
+ HRESULT COMClassicVTableCreated(
+ [in] ClassID wrappedClassId,
+ [in] REFGUID implementedIID,
+ [in] void *pVTable,
+ [in] ULONG cSlots);
+
+ /*
+ * The CLR calls this function when a CLR<->COM interop vtable is
+ * being destroyed. Provided are the ClassID, IID and vtable pointer for
+ * the destroyed vtable.
+ *
+ * NOTE: The profiler should not block here, since the stack may not be in a
+ * GC-friendly state and so preemptive GC cannot be enabled. If the
+ * profiler blocks here and a GC is attempted, the runtime will block
+ * until this callback returns. Also, the profiler may NOT call into
+ * managed code or in any way cause a managed memory allocation.
+ *
+ * NOTE: It is possible to receive a NULL GUID if the interface is
+ * internal only.
+ *
+ * NOTE: This callback is likely never to occur, since the destruction of
+ * vtables occurs very close to Shutdown.
+ */
+ HRESULT COMClassicVTableDestroyed(
+ [in] ClassID wrappedClassId,
+ [in] REFGUID implementedIID,
+ [in] void *pVTable);
+
+ /*
+ * DEPRECATED. These callbacks are no longer delivered.
+ */
+ HRESULT ExceptionCLRCatcherFound();
+
+ HRESULT ExceptionCLRCatcherExecute();
+}
+
+/*
+ * COR_PRF_GC_ROOT_KIND describes the kind of GC root exposed by
+ * the RootReferences2 callback.
+ */
+
+typedef enum
+{
+ COR_PRF_GC_ROOT_STACK = 1, // Variables on the stack
+ COR_PRF_GC_ROOT_FINALIZER = 2, // Entry in the finalizer queue
+ COR_PRF_GC_ROOT_HANDLE = 3, // GC Handle
+ COR_PRF_GC_ROOT_OTHER = 0 //Misc. roots
+} COR_PRF_GC_ROOT_KIND;
+
+
+/*
+ * COR_PRF_GC_ROOT_FLAGS describes properties of a GC root
+ * exposed by the RootReferences callback.
+ */
+
+typedef enum
+{
+ COR_PRF_GC_ROOT_PINNING = 0x1, // Prevents GC from moving the object
+ COR_PRF_GC_ROOT_WEAKREF = 0x2, // Does not prevent collection
+ COR_PRF_GC_ROOT_INTERIOR = 0x4, // Refers to a field of the object rather than the object itself
+ COR_PRF_GC_ROOT_REFCOUNTED = 0x8, // Whether it prevents collection depends on a refcount - if not,
+ // COR_PRF_GC_ROOT_WEAKREF will be set also
+} COR_PRF_GC_ROOT_FLAGS;
+
+
+/*
+ * COR_PRF_FINALIZER_FLAGS is used by FinalizableObjectQueued to describe
+ * the finalizer for the object.
+ */
+
+typedef enum
+{
+ COR_PRF_FINALIZER_CRITICAL = 0x1 // Critical finalizer
+} COR_PRF_FINALIZER_FLAGS;
+
+
+/*
+ * COR_PRF_GC_GENERATION contains the numbers used to represent each GC generation
+ * in the GetGenerationBounds and GetObjectGeneration functions.
+ */
+
+typedef enum
+{
+ COR_PRF_GC_GEN_0 = 0,
+ COR_PRF_GC_GEN_1 = 1,
+ COR_PRF_GC_GEN_2 = 2,
+ COR_PRF_GC_LARGE_OBJECT_HEAP = 3
+} COR_PRF_GC_GENERATION;
+
+
+/*
+ * COR_PRF_GC_GENERATION_RANGE describes a range of memory in the GetGenerationBounds and GetObjectGeneration functions.
+ * Note that the rangeLength member is only guaranteed to be accurate if GetGenerationBounds or GetObjectGeneration are
+ * called from a GarbageCollectionStarted or GarbageCollectionFinished notification
+ */
+typedef struct COR_PRF_GC_GENERATION_RANGE
+{
+ COR_PRF_GC_GENERATION generation; // what generation the range of memory belongs to
+ ObjectID rangeStart; // the start of the range
+ UINT_PTR rangeLength; // the used length of the range
+ UINT_PTR rangeLengthReserved; // the amount of memory reserved for the range (including rangeLength)
+
+} COR_PRF_GC_GENERATION_RANGE;
+
+
+
+/*
+ * COR_PRF_CLAUSE_TYPE defines the various clause codes for the EX clauses
+ */
+typedef enum
+{
+ COR_PRF_CLAUSE_NONE = 0, // not a real clause (only used in error cases)
+ COR_PRF_CLAUSE_FILTER = 1,
+ COR_PRF_CLAUSE_CATCH = 2,
+ COR_PRF_CLAUSE_FINALLY = 3,
+} COR_PRF_CLAUSE_TYPE;
+
+/*
+ * COR_PRF_EX_CLAUSE_INFO identifies a specific exception clause instance and its associated frame.
+ * When an exception notification is received, GetNotifiedExceptionClauseInfo() may be used to get the
+ * native address and frame information for the exception clause (catch/finally/filter) that is
+ * about to be run (ExceptionCatchEnter, ExceptionUnwindFinallyEnter, ExceptionFilterEnter) or has just
+ * been run (ExceptionCatchLeave, ExceptionUnwindFinallyLeave, ExceptionFilterLeave).
+ */
+typedef struct COR_PRF_EX_CLAUSE_INFO
+{
+ COR_PRF_CLAUSE_TYPE clauseType; // the type of clause we just entered or left
+ UINT_PTR programCounter; // the native entry point of the clause handler (e.g. EIP)
+ UINT_PTR framePointer; // the logical frame pointer (e.g. EBP) for that clause handler
+ UINT_PTR shadowStackPointer; // the shadow stack pointer (IA64 only, BSP)
+} COR_PRF_EX_CLAUSE_INFO;
+
+/*
+ * COR_PRF_GC_REASON describes the reason for a given GC.
+ */
+typedef enum
+{
+ COR_PRF_GC_INDUCED = 1, // Induced by GC.Collect
+ COR_PRF_GC_OTHER = 0 // Anything else
+} COR_PRF_GC_REASON;
+
+/*
+ * Bits from COR_PRF_MODULE_FLAGS are returned to the profiler in GetModuleInfo2's
+ * pdwModuleFlags output parameter. Some combinations of 2 or more flags are possible,
+ * though not all combinations are possible.
+ */
+typedef enum
+{
+ // The module was loaded from disk
+ COR_PRF_MODULE_DISK = 0x00000001,
+
+ // The module had been generated via NGEN
+ COR_PRF_MODULE_NGEN = 0x00000002,
+
+ // The module was created via methods in the Reflection.Emit namespace
+ COR_PRF_MODULE_DYNAMIC = 0x00000004,
+
+ // The module's lifetime is managed by the garbage collector.
+ COR_PRF_MODULE_COLLECTIBLE = 0x00000008,
+
+ // The module contains no metadata and is used strictly as a resource. The managed
+ // equivalent of this bit is the System.Reflection.Module.IsResource() method.
+ COR_PRF_MODULE_RESOURCE = 0x00000010,
+
+ // The module's layout in memory is flat, as opposed to mapped. For modules that have
+ // this bit set, profilers that directly read information out of the PE header will
+ // need to be careful when interpreting RVAs present in the PE header.
+ COR_PRF_MODULE_FLAT_LAYOUT = 0x00000020,
+
+ // The Windows Runtime content type flag is set in the metadata for this module's
+ // assembly
+ COR_PRF_MODULE_WINDOWS_RUNTIME = 0x00000040,
+} COR_PRF_MODULE_FLAGS;
+/*
+ * The ICorProfilerCallback2 interface is used by the CLR to notify a
+ * code profiler when events have occurred that the code profiler has registered
+ * an in interest in receiving. These are new callbacks implemented in V2.0
+ * of the runtime.
+ *
+ * The methods implemented on this interface return S_OK on success, or E_FAIL
+ * on failure.
+ */
+
+[
+ object,
+ uuid(8A8CC829-CCF2-49fe-BBAE-0F022228071A),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback2 : ICorProfilerCallback
+{
+
+ /*
+ *
+ * THREAD EVENTS
+ *
+ */
+
+ /*
+ * The CLR calls ThreadNameChanged to notify the code profiler
+ * that a thread's name has changed.
+ *
+ * name is not NULL terminated.
+ *
+ */
+ HRESULT ThreadNameChanged(
+ [in] ThreadID threadId,
+ [in] ULONG cchName,
+ [in, annotation("_In_reads_opt_(cchName)")] WCHAR name[]);
+
+ /*
+ *
+ * GARBAGE COLLECTION EVENTS
+ *
+ */
+
+ /*
+ * The CLR calls GarbageCollectionStarted before beginning a
+ * garbage collection. All GC callbacks pertaining to this
+ * collection will occur between the GarbageCollectionStarted
+ * callback and the corresponding GarbageCollectionFinished
+ * callback. Corresponding GarbageCollectionStarted and
+ * GarbageCollectionFinished callbacks need not occur on the same thread.
+ *
+ * cGenerations indicates the total number of entries in
+ * the generationCollected array
+ * generationCollected is an array of booleans, indexed
+ * by COR_PRF_GC_GENERATIONS, indicating which
+ * generations are being collected in this collection
+ * reason indicates whether this GC was induced
+ * by the application calling GC.Collect().
+ *
+ * NOTE: It is safe to inspect objects in their original locations
+ * during this callback. The GC will begin moving objects after
+ * the profiler returns from this callback. Therefore, after
+ * returning, the profiler should consider all ObjectIDs to be invalid
+ * until it receives a GarbageCollectionFinished callback.
+ */
+ HRESULT GarbageCollectionStarted(
+ [in] int cGenerations,
+ [in, size_is(cGenerations)] BOOL generationCollected[],
+ [in] COR_PRF_GC_REASON reason);
+
+ /*
+ * The CLR calls SurvivingReferences with information about
+ * object references that survived a garbage collection.
+ *
+ * Generally, the CLR calls SurvivingReferences for non-compacting garbage collections.
+ * For compacting garbage collections, MovedReferences is called instead.
+ *
+ * The exception to this rule is that the CLR always calls SurvivingReferences for objects
+ * in the large object heap, which is not compacted.
+ *
+ * Multiple calls to SurvivingReferences may be received during a particular
+ * garbage collection, due to limited internal buffering, multiple threads reporting
+ * in the case of server gc, and other reasons.
+ * In the case of multiple calls, the information is cumulative - all of the references
+ * reported in any SurvivingReferences call survive this collection.
+ *
+ * cSurvivingObjectIDRanges is a count of the number of ObjectID ranges that
+ * survived.
+ * objectIDRangeStart is an array of elements, each of which is the start
+ * value of a range of ObjectID values that survived the collection.
+ * cObjectIDRangeLength is an array of elements, each of which states the
+ * size of the surviving ObjectID value range.
+ *
+ * The last two arguments of this function are parallel arrays.
+ *
+ * In other words, if an ObjectID value lies within the range
+ * objectIDRangeStart[i] <= ObjectID < objectIDRangeStart[i] + cObjectIDRangeLength[i]
+ * for 0 <= i < cMovedObjectIDRanges, then the ObjectID has survived the collection
+ *
+ * THIS CALLBACK IS OBSOLETE. It reports ranges for objects >4GB as ULONG_MAX
+ * on 64-bit platforms. Use ICorProfilerCallback4::SurvivingReferences2 instead.
+ */
+ HRESULT SurvivingReferences(
+ [in] ULONG cSurvivingObjectIDRanges,
+ [in, size_is(cSurvivingObjectIDRanges)] ObjectID objectIDRangeStart[] ,
+ [in, size_is(cSurvivingObjectIDRanges)] ULONG cObjectIDRangeLength[] );
+ /*
+ * The CLR calls GarbageCollectionFinished after a garbage
+ * collection has completed and all GC callbacks have been
+ * issued for it.
+ *
+ * NOTE: It is now safe to inspect objects in their
+ * final locations.
+ */
+ HRESULT GarbageCollectionFinished();
+
+ /*
+ * The CLR calls FinalizeableObjectQueued to notify the code profiler
+ * that an object with a finalizer (destructor in C# parlance) has
+ * just been queued to the finalizer thread for execution of its
+ * Finalize method.
+ *
+ * finalizerFlags describes aspects of the finalizer, and takes its
+ * value from COR_PRF_FINALIZER_FLAGS.
+ *
+ */
+
+ HRESULT FinalizeableObjectQueued(
+ [in] DWORD finalizerFlags,
+ [in] ObjectID objectID);
+
+ /*
+ * The CLR calls RootReferences2 with information about root
+ * references after a garbage collection has occurred.
+ * For each root reference in rootRefIds, there is information in
+ * rootClassifications to classify it. Depending on the classification,
+ * rootsIds may contain additional information. The information in
+ * rootKinds and rootFlags contains information about the location and
+ * properties of the reference.
+ *
+ * If the profiler implements ICorProfilerCallback2, both
+ * ICorProfilerCallback::RootReferences and ICorProfilerCallback2::RootReferences2
+ * are called. As the information passed to RootReferences2 is a superset
+ * of the one passed to RootReferences, profilers will normally implement
+ * one or the other, but not both.
+ *
+ * If the root kind is STACK, the ID is the FunctionID of the
+ * function containing the variable. If the FunctionID is 0, the function
+ * is an unnamed function internal to the CLR.
+ *
+ * If the root kind is HANDLE, the ID is the GCHandleID.
+ *
+ * For the other root kinds, the ID is an opaque value and should
+ * be ignored.
+ *
+ * It's possible for entries in rootRefIds to be 0 - this just
+ * implies the corresponding root reference was null and thus did not
+ * refer to an object on the managed heap.
+ *
+ * NOTE: None of the objectIDs returned by RootReferences2 are valid during the callback
+ * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
+ * should not attempt to inspect objects during a RootReferences2 call. At
+ * GarbageCollectionFinished, all objects have been moved to their new locations, and
+ * inspection may be done.
+ */
+
+ HRESULT RootReferences2(
+ [in] ULONG cRootRefs,
+ [in, size_is(cRootRefs)] ObjectID rootRefIds[],
+ [in, size_is(cRootRefs)] COR_PRF_GC_ROOT_KIND rootKinds[],
+ [in, size_is(cRootRefs)] COR_PRF_GC_ROOT_FLAGS rootFlags[],
+ [in, size_is(cRootRefs)] UINT_PTR rootIds[]);
+
+ /*
+ * The CLR calls HandleCreated when a gc handle has been created.
+ *
+ */
+
+ HRESULT HandleCreated(
+ [in] GCHandleID handleId,
+ [in] ObjectID initialObjectId);
+
+ /*
+ * The CLR calls HandleDestroyed when a gc handle has been destroyed.
+ *
+ */
+
+ HRESULT HandleDestroyed(
+ [in] GCHandleID handleId);
+}
+
+[
+ object,
+ uuid(4FD2ED52-7731-4b8d-9469-03D2CC3086C5),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback3 : ICorProfilerCallback2
+{
+ HRESULT InitializeForAttach(
+ [in] IUnknown * pCorProfilerInfoUnk,
+ [in] void * pvClientData,
+ [in] UINT cbClientData);
+
+ HRESULT ProfilerAttachComplete();
+
+ HRESULT ProfilerDetachSucceeded();
+};
+
+[
+ object,
+ uuid(7B63B2E3-107D-4d48-B2F6-F61E229470D2),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback4 : ICorProfilerCallback3
+{
+ /*
+ * Similar to JITCompilationStarted, except called when rejitting a method
+ */
+ HRESULT ReJITCompilationStarted(
+ [in] FunctionID functionId,
+ [in] ReJITID rejitId,
+ [in] BOOL fIsSafeToBlock);
+
+ /*
+ * This is called exactly once per method (which may represent more than
+ * one function id), to allow the code profiler to set alternate code
+ * generation flags or a new method body.
+ */
+ HRESULT GetReJITParameters(
+ [in] ModuleID moduleId,
+ [in] mdMethodDef methodId,
+ [in] ICorProfilerFunctionControl *pFunctionControl);
+
+ /*
+ * Similar to JITCompilationFinished, except called when rejitting a method
+ */
+ HRESULT ReJITCompilationFinished(
+ [in] FunctionID functionId,
+ [in] ReJITID rejitId,
+ [in] HRESULT hrStatus,
+ [in] BOOL fIsSafeToBlock);
+
+ /*
+ * This is called to report an error encountered while processing a ReJIT request.
+ * This may either be called from within the RequestReJIT call itself, or called after
+ * RequestReJIT returns, if the error was encountered later on.
+ */
+ HRESULT ReJITError(
+ [in] ModuleID moduleId,
+ [in] mdMethodDef methodId,
+ [in] FunctionID functionId,
+ [in] HRESULT hrStatus);
+
+ /*
+ * The CLR calls MovedReferences with information about
+ * object references that moved as a result of garbage collection.
+ *
+ * cMovedObjectIDRanges is a count of the number of ObjectID ranges that
+ * were moved.
+ * oldObjectIDRangeStart is an array of elements, each of which is the start
+ * value of a range of ObjectID values before being moved.
+ * newObjectIDRangeStart is an array of elements, each of which is the start
+ * value of a range of ObjectID values after being moved.
+ * cObjectIDRangeLength is an array of elements, each of which states the
+ * size of the moved ObjectID value range.
+ *
+ * The last three arguments of this function are parallel arrays.
+ *
+ * In other words, if an ObjectID value lies within the range
+ * oldObjectIDRangeStart[i] <= ObjectID < oldObjectIDRangeStart[i] + cObjectIDRangeLength[i]
+ * for 0 <= i < cMovedObjectIDRanges, then the ObjectID value has changed to
+ * ObjectID - oldObjectIDRangeStart[i] + newObjectIDRangeStart[i]
+ *
+ * NOTE: None of the objectIDs returned by MovedReferences are valid during the callback
+ * itself, as the GC may be in the middle of moving objects from old to new. Thus profilers
+ * should not attempt to inspect objects during a MovedReferences call. At
+ * GarbageCollectionFinished, all objects have been moved to their new locations, and
+ * inspection may be done.
+ *
+ * If the profiler implements ICorProfilerCallback4, ICorProfilerCallback4::MovedReferences2
+ * is called first and ICorProfilerCallback::MovedReferences is called second but only if
+ * ICorProfilerCallback4::MovedReferences2 returned success. Profilers can return failure
+ * from ICorProfilerCallback4::MovedReferences2 to save some chattiness.
+ */
+ HRESULT MovedReferences2(
+ [in] ULONG cMovedObjectIDRanges,
+ [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
+ [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
+ [in, size_is(cMovedObjectIDRanges)] SIZE_T cObjectIDRangeLength[] );
+
+ /*
+ * The CLR calls SurvivingReferences with information about
+ * object references that survived a garbage collection.
+ *
+ * Generally, the CLR calls SurvivingReferences for non-compacting garbage collections.
+ * For compacting garbage collections, MovedReferences is called instead.
+ *
+ * The exception to this rule is that the CLR always calls SurvivingReferences for objects
+ * in the large object heap, which is not compacted.
+ *
+ * Multiple calls to SurvivingReferences may be received during a particular
+ * garbage collection, due to limited internal buffering, multiple threads reporting
+ * in the case of server gc, and other reasons.
+ * In the case of multiple calls, the information is cumulative - all of the references
+ * reported in any SurvivingReferences call survive this collection.
+ *
+ * cSurvivingObjectIDRanges is a count of the number of ObjectID ranges that
+ * survived.
+ * objectIDRangeStart is an array of elements, each of which is the start
+ * value of a range of ObjectID values that survived the collection.
+ * cObjectIDRangeLength is an array of elements, each of which states the
+ * size of the surviving ObjectID value range.
+ *
+ * The last two arguments of this function are parallel arrays.
+ *
+ * In other words, if an ObjectID value lies within the range
+ * objectIDRangeStart[i] <= ObjectID < objectIDRangeStart[i] + cObjectIDRangeLength[i]
+ * for 0 <= i < cMovedObjectIDRanges, then the ObjectID has survived the collection
+ *
+ * If the profiler implements ICorProfilerCallback4, ICorProfilerCallback4::SurvivingReferences2
+ * is called first and ICorProfilerCallback2::SurvivingReferences is called second but only if
+ * ICorProfilerCallback4::SurvivingReferences2 returned success. Profilers can return failure
+ * from ICorProfilerCallback4::SurvivingReferences2 to save some chattiness.
+ */
+ HRESULT SurvivingReferences2(
+ [in] ULONG cSurvivingObjectIDRanges,
+ [in, size_is(cSurvivingObjectIDRanges)] ObjectID objectIDRangeStart[] ,
+ [in, size_is(cSurvivingObjectIDRanges)] SIZE_T cObjectIDRangeLength[] );
+
+};
+
+
+[
+ object,
+ uuid(8DFBA405-8C9F-45F8-BFFA-83B14CEF78B5),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback5 : ICorProfilerCallback4
+{
+ /*
+ * The CLR calls ConditionalWeakTableElementReferences with information
+ * about dependent handles after a garbage collection has occurred.
+ *
+ * For each root ID in rootIds, keyRefIds will contain the ObjectID for
+ * the primary element in the dependent handle pair, and valueRefIds will
+ * contain the ObjectID for the secondary element (keyRefIds[i] keeps
+ * valueRefIds[i] alive).
+ *
+ * NOTE: None of the objectIDs returned by ConditionalWeakTableElementReferences
+ * are valid during the callback itself, as the GC may be in the middle
+ * of moving objects from old to new. Thus profilers should not attempt
+ * to inspect objects during a ConditionalWeakTableElementReferences call.
+ * At GarbageCollectionFinished, all objects have been moved to their new
+ * locations, and inspection may be done.
+ */
+ HRESULT ConditionalWeakTableElementReferences(
+ [in] ULONG cRootRefs,
+ [in, size_is(cRootRefs)] ObjectID keyRefIds[],
+ [in, size_is(cRootRefs)] ObjectID valueRefIds[],
+ [in, size_is(cRootRefs)] GCHandleID rootIds[]);
+};
+
+
+[
+ object,
+ uuid(FC13DF4B-4448-4F4F-950C-BA8D19D00C36),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback6 : ICorProfilerCallback5
+{
+ // 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
+ // to modify the metadata of the Assembly to add AssemblyRefs (later, in ModuleLoadFinished). In
+ // such a case, the profiler should implement this callback as well, to inform the CLR that assembly references
+ // will be added once the module has loaded. This is useful to ensure that assembly sharing decisions
+ // made by the CLR during this early stage remain valid even though the profiler plans to modify the metadata
+ // assembly references later on. This can be used to avoid some instances where profiler metadata
+ // modifications can cause the SECURITY_E_INCOMPATIBLE_SHARE error to be thrown.
+ //
+ // The profiler uses the ICorProfilerAssemblyReferenceProvider provided to add assembly references
+ // to the CLR assembly reference closure walker. The ICorProfilerAssemblyReferenceProvider
+ // should only be used from within this callback. The profiler will still need to explicitly add assembly
+ // references via IMetaDataAssemblyEmit, from within the ModuleLoadFinished callback for the referencing assembly,
+ // even though the profiler implements this GetAssemblyReferences callback. This callback does not result in
+ // modified metadata; only in a modified assembly reference closure walk.
+ //
+ // The profiler should be prepared to receive duplicate calls to this callback for the same assembly,
+ // and should respond identically for each such duplicate call (by making the same set of
+ // ICorProfilerAssemblyReferenceProvider::AddAssemblyReference calls).
+ HRESULT GetAssemblyReferences(
+ [in, string] const WCHAR * wszAssemblyPath,
+ [in] ICorProfilerAssemblyReferenceProvider * pAsmRefProvider);
+};
+
+
+[
+ object,
+ uuid(F76A2DBA-1D52-4539-866C-2AA518F9EFC3),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback7 : ICorProfilerCallback6
+{
+ // This event is triggered whenever the symbol stream associated with an
+ // in-memory module is updated. Even when symbols are provided up-front in
+ // a call to the managed API Assembly.Load(byte[], byte[], ...) the runtime
+ // may not actually associate the symbolic data with the module until after
+ // the ModuleLoadFinished callback has occured. This event provides a later
+ // opportunity to collect symbols for such modules.
+ //
+ // This event is controlled by the COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED
+ // event mask flag.
+ //
+ // Note: This event is not currently raised for symbols implicitly created or
+ // modified via Reflection.Emit APIs.
+ HRESULT ModuleInMemorySymbolsUpdated(ModuleID moduleId);
+}
+
+
+/*
+ * COR_PRF_CODEGEN_FLAGS controls various flags and hooks for a specific
+ * method. A combination of COR_PRF_CODEGEN_FLAGS is provided by the
+ * profiler in its call to ICorProfilerFunctionControl::SetCodegenFlags()
+ * when rejitting a method.
+ */
+typedef enum
+{
+ COR_PRF_CODEGEN_DISABLE_INLINING = 0x0001,
+ COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS = 0x0002,
+} COR_PRF_CODEGEN_FLAGS;
+
+
+/*
+ * The CLR implements the ICorProfilerInfo interface. This interface is
+ * used by a code profiler to communicate with the CLR to control event
+ * monitoring and request information. The CLR passes an
+ * ICorProfilerInfo interface to each code profiler during initialization.
+ *
+ * A code profiler can call methods on the ICorProfilerInfo interface to get
+ * information about managed code being executed under the control of the CLR
+ *
+ * The ICorProfilerInfo interface implemented by the CLR uses the free
+ * threaded model.
+ *
+ * The methods implemented on this interface return S_OK on success, or E_FAIL
+ * on failure.
+ *
+ */
+
+[
+ object,
+ uuid(28B5557D-3F3F-48b4-90B2-5F9EEA2F6C48),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo : IUnknown
+{
+ /*
+ * The code profiler calls GetClassFromObject to obtain the ClassID of an
+ * object given its ObjectID.
+ */
+ HRESULT GetClassFromObject(
+ [in] ObjectID objectId,
+ [out] ClassID *pClassId);
+
+ /*
+ * V2 MIGRATION WARNING - DOES NOT WORK FOR GENERIC TYPES
+ *
+ * This function will be removed in a future release, so
+ * use GetClassFromTokenAndTypeArgs for all types.
+ */
+ HRESULT GetClassFromToken(
+ [in] ModuleID moduleId,
+ [in] mdTypeDef typeDef,
+ [out] ClassID *pClassId);
+
+ /*
+ * V2 MIGRATION WARNING - WILL NOT WORK WITH .NET FRAMEWORK
+ * FUNCTIONS
+ *
+ * This function will be removed in a future release; use GetCodeInfo2
+ * in all cases.
+ */
+ HRESULT GetCodeInfo(
+ [in] FunctionID functionId,
+ [out] LPCBYTE *pStart,
+ [out] ULONG *pcSize);
+
+ /*
+ * RECOMMENDATION: USE GetEventMask2 INSTEAD. WHILE THIS METHOD CONTINUES TO
+ * TO WORK, GetEventMask2 PROVIDES MORE FUNCTIONALITY.
+ *
+ * The code profiler calls GetEventMask to obtain the current event
+ * categories for which it is to receive event notifications from the COM+
+ * Runtime.
+ */
+ HRESULT GetEventMask(
+ [out] DWORD *pdwEvents);
+
+ /*
+ * The code profiler calls GetFunctionFromIP to map an instruction pointer
+ * in managed code to a FunctionID.
+ */
+ HRESULT GetFunctionFromIP(
+ [in] LPCBYTE ip,
+ [out] FunctionID *pFunctionId);
+
+ /*
+ * V2 MIGRATION WARNING - WILL NOT WORK FOR GENERIC FUNCTIONS OR
+ * FUNCTIONS ON GENERIC TYPES
+ *
+ * This function will be removed in a future release, so use
+ * GetFunctionFromTokenAndTypeArgs for all functions.
+ */
+ HRESULT GetFunctionFromToken(
+ [in] ModuleID moduleId,
+ [in] mdToken token,
+ [out] FunctionID *pFunctionId);
+
+ /*
+ * The code profiler calls GetHandleFromThread to map a ThreadID to a Win32
+ * thread handle. The profiler must call DuplicateHandle on the handle
+ * before using it.
+ */
+ HRESULT GetHandleFromThread(
+ [in] ThreadID threadId,
+ [out] HANDLE *phThread);
+
+ /*
+ * The code profiler calls GetObjectSize to obtain the size of an object.
+ * Note that types like arrays and strings may have a different size for each object.
+ *
+ * THIS API IS OBSOLETE. It does not work for objects >4GB on 64-bit platforms.
+ * Use ICorProfilerInfo4::GetObjectSize2 instead.
+ */
+ HRESULT GetObjectSize(
+ [in] ObjectID objectId,
+ [out] ULONG *pcSize);
+
+ /*
+ * This will return S_OK if the ClassID provided is an array class, and will
+ * fill out the information for any non-null out params. S_FALSE will be
+ * returned if the ClassID is not an array.
+ *
+ * classId : the ClassID to return information about
+ * pBaseElemType : the array's base element type
+ * pBaseClassId : the base ClassID if the element type == ELEMENT_TYPE_CLASS
+ * pcRank : the number of dimensions of the array
+ */
+ HRESULT IsArrayClass(
+ [in] ClassID classId,
+ [out] CorElementType *pBaseElemType,
+ [out] ClassID *pBaseClassId,
+ [out] ULONG *pcRank);
+
+ /*
+ * The code profiler calls GetThreadInfo to obtain the current Win32 thread ID for
+ * the specified thread.
+ */
+ HRESULT GetThreadInfo(
+ [in] ThreadID threadId,
+ [out] DWORD *pdwWin32ThreadId);
+
+ /*
+ * The code profiler calls GetCurrentThreadID to get the managed thread ID
+ * for the current thread.
+ *
+ * NOTE: GetCurrentThreadID may return CORPROF_E_NOT_MANAGED_THREAD if the
+ * current thread is an internal runtime thread, and the returned value of
+ * pThreadId will be NULL.
+ */
+ HRESULT GetCurrentThreadID(
+ [out] ThreadID *pThreadId);
+
+ /*
+ * V2 MIGRATION NOTE - More information is available for generic types
+ * from GetClassIDInfo2.
+ *
+ * Returns the parent module a class is defined in, along with the
+ * metadata token for the class. One can call GetModuleMetaData
+ * to obtain the metadata interface for a given module. The token
+ * can then be used to access the metadata for this class.
+ */
+ HRESULT GetClassIDInfo(
+ [in] ClassID classId,
+ [out] ModuleID *pModuleId,
+ [out] mdTypeDef *pTypeDefToken);
+
+ /*
+ * Return the parent class for a given function. Also return the metadata
+ * token which can be used to read the metadata.
+ *
+ * V2 MIGRATION WARNING - LESS INFORMATION FOR GENERIC CLASSES
+ * The ClassID of a function on a generic class may not be obtainable without
+ * more context about the use of the function. In this case, *pClassId will be 0;
+ * try using GetFunctionInfo2 with a COR_PRF_FRAME_INFO to give more context.
+ */
+ HRESULT GetFunctionInfo(
+ [in] FunctionID functionId,
+ [out] ClassID *pClassId,
+ [out] ModuleID *pModuleId,
+ [out] mdToken *pToken);
+
+ /*
+ * RECOMMENDATION: USE SetEventMask2 INSTEAD. WHILE THIS METHOD CONTINUES TO
+ * TO WORK, SetEventMask2 PROVIDES MORE FUNCTIONALITY.
+ *
+ * The code profiler calls SetEventMask to set the event categories for
+ * which it is set to receive notification from the CLR.
+ */
+ HRESULT SetEventMask(
+ [in] DWORD dwEvents);
+
+ /*
+ * The code profiler calls SetFunctionHooks to specify handlers
+ * for FunctionEnter, FunctionLeave, and FunctionTailcall.
+ *
+ * Note that only one set of callbacks may be active at a time. Thus,
+ * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
+ * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
+ * wins. SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
+ * when both are set.
+ *
+ * Each function pointer may be null to disable that callback.
+ *
+ * SetEnterLeaveFunctionHooks may only be called from the
+ * profiler's Initialize() callback.
+ */
+ HRESULT SetEnterLeaveFunctionHooks(
+ [in] FunctionEnter *pFuncEnter,
+ [in] FunctionLeave *pFuncLeave,
+ [in] FunctionTailcall *pFuncTailcall);
+
+ /*
+ * This is used for mapping FunctionIDs to alternative values that will be
+ * passed to the callbacks
+ */
+ HRESULT SetFunctionIDMapper(
+ [in] FunctionIDMapper *pFunc);
+
+ /*
+ * For a given function, retrieve the token value and an instance of the
+ * meta data interface which can be used against this token.
+ */
+ HRESULT GetTokenAndMetaDataFromFunction(
+ [in] FunctionID functionId,
+ [in] REFIID riid,
+ [out] IUnknown **ppImport,
+ [out] mdToken *pToken);
+
+ /*
+ * Retrieve information about a given module.
+ *
+ * When the module is loaded from disk, the name returned will be the filename;
+ * otherwise, the name will be the name from the metadata Module table (i.e.,
+ * the same as the managed System.Reflection.Module.ScopeName).
+ *
+ * NOTE: While this function may be called as soon as the moduleId is alive,
+ * the AssemblyID of the containing assembly will not be available until the
+ * ModuleAttachedToAssembly callback.
+ *
+ * NOTE: More information is available by using ICorProfilerInfo3::GetModuleInfo2 instead.
+ */
+ HRESULT GetModuleInfo(
+ [in] ModuleID moduleId,
+ [out] LPCBYTE *ppBaseLoadAddress,
+ [in] ULONG cchName,
+ [out] ULONG *pcchName,
+ [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
+ WCHAR szName[] ,
+ [out] AssemblyID *pAssemblyId);
+
+ /*
+ * Get a metadata interface instance which maps to the given module.
+ * One may ask for the metadata to be opened in read+write mode, but
+ * this will result in slower metadata execution of the program, because
+ * changes made to the metadata cannot be optimized as they were from
+ * the compiler.
+ *
+ * NOTE: Some modules (such as resource modules) have no metadata. In
+ * those cases, GetModuleMetaData will return S_FALSE, and a NULL
+ * IUnknown.
+ *
+ * NOTE: the only values valid for dwOpenFlags are ofRead and ofWrite.
+ */
+ HRESULT GetModuleMetaData(
+ [in] ModuleID moduleId,
+ [in] DWORD dwOpenFlags,
+ [in] REFIID riid,
+ [out] IUnknown **ppOut);
+
+ /*
+ * Retrieve a pointer to the body of a method starting at it's header.
+ * A method is scoped by the module it lives in. Because this function
+ * is designed to give a tool access to IL before it has been loaded
+ * by the Runtime, it uses the metadata token of the method to find
+ * the instance desired.
+ *
+ * GetILFunctionBody can return CORPROF_E_FUNCTION_NOT_IL if the methodId
+ * points to a method without any IL (such as an abstract method, or a
+ * P/Invoke method).
+ */
+ HRESULT GetILFunctionBody(
+ [in] ModuleID moduleId,
+ [in] mdMethodDef methodId,
+ [out] LPCBYTE *ppMethodHeader,
+ [out] ULONG *pcbMethodSize);
+
+ /*
+ * IL method bodies must be located as RVA's to the loaded module, which
+ * means they come after the module within 4 gb. In order to make it
+ * easier for a tool to swap out the body of a method, this allocator
+ * will ensure memory is allocated within that range.
+ */
+ HRESULT GetILFunctionBodyAllocator(
+ [in] ModuleID moduleId,
+ [out] IMethodMalloc **ppMalloc);
+
+ /*
+ * Replaces the method body for a function in a module. This will replace
+ * the RVA of the method in the metadata to point to this new method body,
+ * and adjust any internal data structures as required. This function can
+ * only be called on those methods which have never been compiled by a JITTER.
+ * Please use the GetILFunctionAllocator to allocate space for the new method to
+ * ensure the buffer is compatible.
+ */
+ HRESULT SetILFunctionBody(
+ [in] ModuleID moduleId,
+ [in] mdMethodDef methodid,
+ [in] LPCBYTE pbNewILMethodHeader);
+
+ /*
+ * Retrieve app domain information given its id.
+ */
+ HRESULT GetAppDomainInfo(
+ [in] AppDomainID appDomainId,
+ [in] ULONG cchName,
+ [out] ULONG *pcchName,
+ [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
+ WCHAR szName[] ,
+ [out] ProcessID *pProcessId);
+
+ /*
+ * Retrieve information about an assembly given its ID.
+ */
+ HRESULT GetAssemblyInfo(
+ [in] AssemblyID assemblyId,
+ [in] ULONG cchName,
+ [out] ULONG *pcchName,
+ [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
+ WCHAR szName[] ,
+ [out] AppDomainID *pAppDomainId,
+ [out] ModuleID *pModuleId);
+
+
+ /*
+ * V2 MIGRATION WARNING: DEPRECATED. Returns E_NOTIMPL always.
+ *
+ * See ICorProfilerInfo4::RequestReJIT instead
+ *
+ */
+ HRESULT SetFunctionReJIT(
+ [in] FunctionID functionId);
+
+ /*
+ * ForceGC forces a GC to occur within the runtime.
+ *
+ * NOTE: This method needs to be called from a thread that does not have any
+ * profiler callbacks on its stack. The most convenient way to implement this is
+ * to create a separate thread within the profiler and have it call ForceGC when
+ * signalled.
+ */
+ HRESULT ForceGC();
+
+ /*
+ *
+ * V2 MIGRATION NOTE - Calling SetILInstrumentedCodeMap on any one
+ * of the multiple FunctionIDs that represent a generic function in a given
+ * AppDomain will affect all instantiations of that function in the AppDomain.
+ *
+ * fStartJit should be set to true the first time this function is called for
+ * a given FunctionID, and false thereafter.
+ *
+ * The format of the map is as follows:
+ * The debugger will assume that each oldOffset refers to an IL offset
+ * within the original, unmodified IL code. newOffset refers to the corresponding
+ * IL offset within the new, instrumented code.
+ *
+ * The map should be sorted in increasing order. For stepping to work properly:
+ * - Instrumented IL should not be reordered (so both old & new are sorted)
+ * - original IL should not be removed
+ * - the map should include entries to map all of the sequence points from the pdb.
+ *
+ * The map does not interpolate missing entries. So given the following map:
+ * (0 old, 0 new)
+ * (5 old, 10 new)
+ * (9 old, 20 new)
+ * - An old offset of 0,1,2,3,4 will be mapped to a new offset of 0
+ * - An old offset of 5,6,7, or 8 will be mapped to new offset 10.
+ * - An old offset of 9 or higher will be mapped to new offset 20.
+ * - A new offset of 0, 1,...8,9 will be mapped to old offset 0
+ * - A new offset of 10,11,...18,19 will be mapped to old offset 5.
+ * - A new offset of 20 or higher will be mapped to old offset 9.
+ *
+ */
+ HRESULT SetILInstrumentedCodeMap(
+ [in] FunctionID functionId,
+ [in] BOOL fStartJit,
+ [in] ULONG cILMapEntries,
+ [in, size_is(cILMapEntries)] COR_IL_MAP rgILMapEntries[] );
+
+ /*
+ * DEPRECATED.
+ */
+ HRESULT GetInprocInspectionInterface(
+ [out] IUnknown **ppicd);
+
+ /*
+ * DEPRECATED.
+ */
+ HRESULT GetInprocInspectionIThisThread(
+ [out] IUnknown **ppicd);
+
+ /*
+ * This will return the ContextID currently associated with the calling
+ * runtime thread. This will set pContextId to NULL if the calling thread
+ * is not a runtime thread.
+ */
+ HRESULT GetThreadContext(
+ [in] ThreadID threadId,
+ [out] ContextID *pContextId);
+
+ /*
+ * DEPRECATED.
+ */
+ HRESULT BeginInprocDebugging(
+ [in] BOOL fThisThreadOnly,
+ [out] DWORD *pdwProfilerContext);
+
+ /*
+ * DEPRECATED.
+ */
+ HRESULT EndInprocDebugging(
+ [in] DWORD dwProfilerContext);
+
+ /*
+ * GetILToNativeMapping returns a map from IL offsets to native
+ * offsets for this code. An array of COR_PROF_IL_TO_NATIVE_MAP
+ * structs will be returned, and some of the ilOffsets in this array
+ * may be the values specified in CorDebugIlToNativeMappingTypes.
+ */
+ HRESULT GetILToNativeMapping(
+ [in] FunctionID functionId,
+ [in] ULONG32 cMap,
+ [out] ULONG32 *pcMap,
+ [out, size_is(cMap), length_is(*pcMap)]
+ COR_DEBUG_IL_TO_NATIVE_MAP map[]);
+}
+
+/*
+ * The CLR implements the ICorProfilerInfo2 interface. This interface is
+ * used by a code profiler to communicate with the CLR to control event
+ * monitoring and request information. The CLR passes an
+ * ICorProfilerInfo2 interface to each code profiler during initialization.
+ *
+ * A code profiler can call methods on the ICorProfilerInfo2 interface to get
+ * information about managed code being executed under the control of the CLR
+ *
+ * The ICorProfilerInfo2 interface implemented by the CLR uses the free
+ * threaded model.
+ *
+ * The methods implemented on this interface return S_OK on success, or E_FAIL
+ * on failure.
+ *
+ */
+
+[
+ object,
+ uuid(CC0935CD-A518-487d-B0BB-A93214E65478),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo2 : ICorProfilerInfo
+{
+ /*
+ * The code profiler calls DoStackSnapshot to do sparse one-off stack snapshots.
+ *
+ * Passing NULL for thread yields a snapshot of the current thread. If a ThreadID
+ * of a different thread is passed, the runtime will suspend that thread, perform
+ * the snapshot, and resume.
+ *
+ * infoFlags come from the COR_PRF_SNAPSHOT_INFO enum.
+ *
+ * context is a platform-dependent CONTEXT structure, representing the complete
+ * register context that the profiling API will use to seed the stack walk. If this
+ * is non-NULL, it must point to JITd or NGENd code, or else DoStackSnapshot
+ * will return CORPROF_E_STACKSNAPSHOT_UNMANAGED_CTX. Contexts are
+ * only provided by profilers that hijack threads to force them to walk their
+ * own stacks; profilers should not attempt to provide a context when walking
+ * another thread's stack. If context is NULL, the stack walk will begin at the
+ * last available managed frame for the target thread.
+ *
+ * See the definition of StackSnapshotCallback for more information.
+ */
+ HRESULT DoStackSnapshot(
+ [in] ThreadID thread,
+ [in] StackSnapshotCallback *callback,
+ [in] ULONG32 infoFlags,
+ [in] void *clientData,
+ [in, size_is(contextSize)] BYTE context[],
+ [in] ULONG32 contextSize);
+
+ /*
+ * The code profiler calls SetFunctionHooks2 to specify handlers
+ * for FunctionEnter2, FunctionLeave2, and FunctionTailcall2
+ * callbacks.
+ *
+ * Note that only one set of callbacks may be active at a time. Thus,
+ * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
+ * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
+ * wins. SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
+ * when both are set.
+ *
+ * Each pointer may be null to disable that particular callback.
+ *
+ * SetEnterLeaveFunctionHooks2 may only be called from the
+ * profiler's Initialize() callback.
+ */
+ HRESULT SetEnterLeaveFunctionHooks2(
+ [in] FunctionEnter2 *pFuncEnter,
+ [in] FunctionLeave2 *pFuncLeave,
+ [in] FunctionTailcall2 *pFuncTailcall);
+
+ /*
+ * GetFunctionInfo2 returns the parent class of a function, plus the
+ * function's metadata token and the ClassIDs of its type arguments
+ * (if any).
+ *
+ * When a COR_PRF_FRAME_INFO obtained from a FunctionEnter2
+ * callback is passed, the ClassID and all type arguments will be exact.
+ *
+ * When a COR_PRF_FRAME_INFO from any other source is passed, or
+ * when 0 is passed as the frameInfo argument, exact ClassID and type
+ * arguments cannot always be determined. The value returned in pClassId
+ * may be NULL and some type args will come back as System.Object.
+ *
+ */
+ HRESULT GetFunctionInfo2(
+ [in] FunctionID funcId,
+ [in] COR_PRF_FRAME_INFO frameInfo,
+ [out] ClassID *pClassId,
+ [out] ModuleID *pModuleId,
+ [out] mdToken *pToken,
+ [in] ULONG32 cTypeArgs,
+ [out] ULONG32 *pcTypeArgs,
+ [out] ClassID typeArgs[]);
+
+ /*
+ * GetStringLayout returns detailed information about how string objects are stored.
+ *
+ * *pBufferLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
+ * stores the length of the string's buffer
+ *
+ * *pStringLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
+ * stores the length of the string itself
+ *
+ * *pBufferOffset is the offset (from the ObjectID pointer) to the actual buffer
+ * of wide characters
+ *
+ * Strings may or may not be null-terminated.
+ */
+ HRESULT GetStringLayout(
+ [out] ULONG *pBufferLengthOffset,
+ [out] ULONG *pStringLengthOffset,
+ [out] ULONG *pBufferOffset);
+
+ /*
+ * GetClassLayout returns detailed information how a specific class is stored.
+ * It only returns the fields defined by the class itself; if the parent class
+ * defined fields as well, the profiler must call GetClassLayout on the parent class
+ * to obtain those fields.
+ *
+ * It will fail with E_INVALIDARG for string and array classes.
+ */
+ HRESULT GetClassLayout(
+ [in] ClassID classID,
+ [in, out] COR_FIELD_OFFSET rFieldOffset[],
+ [in] ULONG cFieldOffset,
+ [out] ULONG *pcFieldOffset,
+ [out] ULONG *pulClassSize);
+
+ /*
+ * Returns the parent module a class is defined in, along with the
+ * metadata token for the class, the ClassID of its parent class, and the
+ * ClassIDs of its type arguments (if any).
+ *
+ * One can call GetModuleMetaData to obtain the metadata interface for
+ * a given module. The token can then be used to access the metadata for this
+ * class.
+ */
+ HRESULT GetClassIDInfo2(
+ [in] ClassID classId,
+ [out] ModuleID *pModuleId,
+ [out] mdTypeDef *pTypeDefToken,
+ [out] ClassID *pParentClassId,
+ [in] ULONG32 cNumTypeArgs,
+ [out] ULONG32 *pcNumTypeArgs,
+ [out] ClassID typeArgs[]);
+
+ /*
+ * GetCodeInfo2 returns the extents of native code associated with the
+ * given FunctionID. These extents are returned sorted in order of increasing
+ * IL offset.
+ */
+ HRESULT GetCodeInfo2(
+ [in] FunctionID functionID,
+ [in] ULONG32 cCodeInfos,
+ [out] ULONG32 *pcCodeInfos,
+ [out, size_is(cCodeInfos), length_is(*pcCodeInfos)]
+ COR_PRF_CODE_INFO codeInfos[]);
+
+ /*
+ * GetClassFromTokenAndTypeArgs returns the ClassID of a type given its metadata
+ * token (typedef) and the ClassIDs of its type arguments (if any).
+ *
+ * cTypeArgs must be equal to the number of type parameters for the given type
+ * (0 for non-generic types)
+ * typeArgs may be NULL if cTypeArgs == 0
+ *
+ * Calling this function with a TypeRef token can have unpredictable results; callers
+ * should resolve the TypeRef to a TypeDef and use that.
+ *
+ * If the type is not already loaded, calling this function will cause it to be.
+ * Loading is a dangerous operation in many contexts. For example, calling
+ * this function during loading of modules or other types could lead to an infinite
+ * loop as the runtime attempts to circularly load things.
+ *
+ * In general, use of this function is discouraged. If profilers are interested in
+ * events for a particular type, they should store the ModuleID and TypeDef of that type,
+ * and use GetClassIDInfo2 to check whether a given ClassID is the desired type.
+ */
+ HRESULT GetClassFromTokenAndTypeArgs(
+ [in] ModuleID moduleID,
+ [in] mdTypeDef typeDef,
+ [in] ULONG32 cTypeArgs,
+ [in, size_is(cTypeArgs)] ClassID typeArgs[],
+ [out] ClassID* pClassID);
+
+ /*
+ * GetFunctionFromTokenAndTypeArgs returns the FunctionID of a function given
+ * its metadata token (methoddef), containing class, and type args (if any).
+ *
+ * classID may be 0 if the containing class is not generic
+ * typeArgs may be NULL if cTypeArgs == 0
+ *
+ * Calling this function with a MethodRef token can have unpredictable results; callers
+ * should resolve the MethodRef to a MethodDef and use that.
+ *
+ * If the function is not already loaded, calling this function will cause it to be.
+ * Loading is a dangerous operation in many contexts. For example, calling
+ * this function during loading of modules or types could lead to an infinite
+ * loop as the runtime attempts to circularly load things.
+ *
+ * In general, use of this function is discouraged. If profilers are interested in
+ * events for a particular function, they should store the ModuleID and MethodDef of that function,
+ * and use GetFunctionInfo2 to check whether a given FunctionID is the desired function.
+ */
+ HRESULT GetFunctionFromTokenAndTypeArgs(
+ [in] ModuleID moduleID,
+ [in] mdMethodDef funcDef,
+ [in] ClassID classId,
+ [in] ULONG32 cTypeArgs,
+ [in, size_is(cTypeArgs)] ClassID typeArgs[],
+ [out] FunctionID* pFunctionID);
+
+ /*
+ * Returns an enumerator over all frozen objects in the given module.
+ */
+ HRESULT EnumModuleFrozenObjects(
+ [in] ModuleID moduleID,
+ [out] ICorProfilerObjectEnum** ppEnum);
+
+
+
+ /*
+ * GetArrayObjectInfo returns detailed information about an array object.
+ * objectId is a valid array object.
+ * cDimensions is the rank (# of dimensions).
+ * On success:
+ * pDimensionSizes, pDimensionLowerBounds are parallel arrays describing the size and lower bound for each dimension.
+ * (*ppData) is a pointer to the raw buffer for the array, which is laid out according to the C++
+ * convention
+ */
+ HRESULT GetArrayObjectInfo(
+ [in] ObjectID objectId,
+ [in] ULONG32 cDimensions,
+ [out, size_is(cDimensions)] ULONG32 pDimensionSizes[],
+ [out, size_is(cDimensions)] int pDimensionLowerBounds[],
+ [out] BYTE **ppData);
+
+ /*
+ * GetBoxClassLayout returns information about how a particular value type is laid out
+ * when boxed.
+ *
+ * *pBufferOffset is the offset (from the ObjectID pointer) to where the value type
+ * is stored within the box. The value type's class layout may then be used to
+ * interpret it.
+ */
+ HRESULT GetBoxClassLayout(
+ [in] ClassID classId,
+ [out] ULONG32 *pBufferOffset);
+
+
+ /*
+ * GetThreadAppDomain returns the AppDomainID currently associated with\
+ * the given ThreadID
+ */
+ HRESULT GetThreadAppDomain(
+ [in] ThreadID threadId,
+ [out] AppDomainID *pAppDomainId);
+
+
+ /*
+ * GetRVAStaticAddress gets the address of the home for the given
+ * RVA static. It must be called from a managed thread. Otherwise,
+ * it will return CORPROF_E_NOT_MANAGED_THREAD.
+ */
+ HRESULT GetRVAStaticAddress(
+ [in] ClassID classId,
+ [in] mdFieldDef fieldToken,
+ [out] void **ppAddress);
+
+ /*
+ * GetAppDomainStaticAddress gets the address of the home for the given
+ * AppDomain static in the given AppDomain.
+ *
+ * This function may return CORPROF_E_DATAINCOMPLETE if the given static
+ * has not been assigned a home in the given AppDomain.
+ */
+ HRESULT GetAppDomainStaticAddress(
+ [in] ClassID classId,
+ [in] mdFieldDef fieldToken,
+ [in] AppDomainID appDomainId,
+ [out] void **ppAddress);
+
+ /*
+ * GetThreadStaticAddress gets the address of the home for the given
+ * Thread static in the given Thread. threadId must be the current thread
+ * ID or NULL, which means using curernt thread ID.
+ *
+ * This function may return CORPROF_E_DATAINCOMPLETE if the given static
+ * has not been assigned a home in the given Thread.
+ */
+ HRESULT GetThreadStaticAddress(
+ [in] ClassID classId,
+ [in] mdFieldDef fieldToken,
+ [in] ThreadID threadId,
+ [out] void **ppAddress);
+
+ /*
+ * GetContextStaticAddress gets the address of the home for the given
+ * Context static in the given context. It must be called from a managed
+ * thread. Otherwise, it will return CORPROF_E_NOT_MANAGED_THREAD.
+ *
+ * This function may return CORPROF_E_DATAINCOMPLETE if the given static
+ * has not been assigned a home in the given Context.
+ */
+ HRESULT GetContextStaticAddress(
+ [in] ClassID classId,
+ [in] mdFieldDef fieldToken,
+ [in] ContextID contextId,
+ [out] void **ppAddress);
+
+ /*
+ * GetStaticFieldInfo gets COR_PRF_STATIC_TYPE for a specific
+ * field in a class. This information can be used to decide which
+ * function to call to get the address of the static.
+ *
+ * NOTE: One should still check the metadata for a static to ensure
+ * it is actually going to have an address. Statics that are literals
+ * (aka constants) exist only in the metadata and do not have an address.
+ *
+ */
+ HRESULT GetStaticFieldInfo(
+ [in] ClassID classId,
+ [in] mdFieldDef fieldToken,
+ [out] COR_PRF_STATIC_TYPE *pFieldInfo);
+
+ /*
+ * GetGenerationBounds returns the memory regions that make up a given
+ * GC generation in memory. It may be called from any profiler callback as long
+ * as a GC is not in progress. (To be exact, it may be called from any callback
+ * except for those that occur between GarbageCollectionStarted and GarbageCollectionFinished.)
+ *
+ * Most shifting of generations takes place during garbage collections; between
+ * collections generations may grow, but generally do not move around. Therefore
+ * the most interesting places to call this function are in GarbageCollectionStarted
+ * and Finished.
+ *
+ * During program startup, some objects are allocated by the CLR itself, generally
+ * in generations 3 and 0. So by the time managed code starts executing, these
+ * generations will already contain objects. Generations 1 and 2 will be normally
+ * empty, except for dummy objects generated by the garbage collector (of size 12
+ * bytes in 32-bit implementations of the CLR, larger in 64-bit implementaions).
+ * You may also see generation 2 ranges that are inside modules generated by ngen.
+ * These are "frozen objects" generated at ngen time rather than allocated by the
+ * garbage collector.
+ *
+ * cObjectRanges is a count of the number of elements allocated by the caller for
+ * the ranges array
+ * pcObjectRanges is an out param for the number of ranges in the given generation
+ * ranges is an array of elements of type COR_PRF_GC_GENERATION_RANGE, each of which
+ * describes a range of memory used by the garbage collector
+ */
+
+ HRESULT GetGenerationBounds(
+ [in] ULONG cObjectRanges,
+ [out] ULONG *pcObjectRanges,
+ [out, size_is(cObjectRanges), length_is(*pcObjectRanges)] COR_PRF_GC_GENERATION_RANGE ranges[]);
+
+ /*
+ * GetObjectGeneration returns which generation the given object is currently in, along
+ * with the start and length of the segment containing the object. It may be called
+ * at any time as long as a GC is not in progress.
+ */
+
+ HRESULT GetObjectGeneration(
+ [in] ObjectID objectId,
+ [out] COR_PRF_GC_GENERATION_RANGE *range);
+
+
+ /*
+ * When an exception notification is received, GetNotifiedExceptionClauseInfo() may be used
+ * to get the native address and frame information for the exception clause (catch/finally/filter)
+ * that is about to be run (ExceptionCatchEnter, ExceptionUnwindFinallyEnter, ExceptionFilterEnter)
+ * or has just been run (ExceptionCatchLeave, ExceptionUnwindFinallyLeave, ExceptionFilterLeave).
+ *
+ * This call may be made at any time after one of the Enter calls above until either the matching
+ * Leave call is received or until a nested exception throws out of the current clause in which case
+ * there will be no Leave notification for that clause. Note it is not possible for a throw to escape
+ * a Filter so there is always a Leave in that case.
+ *
+ * Return values:
+ * S_OK indicates success
+ * S_FALSE indicates that no exception clause is active
+ * CORPROF_E_NOT_MANAGED_THREAD indicates an unmanaged thread.
+ */
+
+ HRESULT GetNotifiedExceptionClauseInfo(
+ [out] COR_PRF_EX_CLAUSE_INFO *pinfo);
+}
+
+/*
+ * The CLR implements the ICorProfilerInfo3 interface. This interface is
+ * used by a code profiler to communicate with the CLR to control event
+ * monitoring and request information. The CLR passes an
+ * ICorProfilerInfo3 interface to each code profiler during initialization.
+ *
+ * A code profiler can call methods on the ICorProfilerInfo3 interface to get
+ * information about managed code being executed under the control of the CLR
+ *
+ * The ICorProfilerInfo3 interface implemented by the CLR uses the free
+ * threaded model.
+ *
+ * The methods implemented on this interface return S_OK on success, or E_FAIL
+ * on failure.
+ *
+ */
+
+[
+ object,
+ uuid(B555ED4F-452A-4E54-8B39-B5360BAD32A0),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo3 : ICorProfilerInfo2
+{
+ /*
+ * Returns an enumerator for all previously jitted functions. May overlap with
+ * functions previously reported via CompilationStarted callbacks.
+ * NOTE: The returned enumeration will only include '0' for the value of the
+ * COR_PRF_FUNCTION::reJitId field. If you require valid COR_PRF_FUNCTION::reJitId values, use
+ * ICorProfilerInfo4::EnumJITedFunctions2.
+ */
+ HRESULT EnumJITedFunctions([out] ICorProfilerFunctionEnum** ppEnum);
+
+ HRESULT RequestProfilerDetach([in] DWORD dwExpectedCompletionMilliseconds);
+
+ HRESULT SetFunctionIDMapper2(
+ [in] FunctionIDMapper2 *pFunc,
+ [in] void *clientData);
+
+ /*
+ * GetStringLayout2 returns detailed information about how string objects are stored.
+ *
+ * *pStringLengthOffset is the offset (from the ObjectID pointer) to a DWORD that
+ * stores the length of the string itself
+ *
+ * *pBufferOffset is the offset (from the ObjectID pointer) to the actual buffer
+ * of wide characters
+ *
+ * Strings may or may not be null-terminated.
+ */
+ HRESULT GetStringLayout2(
+ [out] ULONG *pStringLengthOffset,
+ [out] ULONG *pBufferOffset);
+
+ /*
+ * The code profiler calls SetFunctionHooks3 to specify handlers
+ * for FunctionEnter3, FunctionLeave3, and FunctionTailcall3, and calls
+ * SetFunctionHooks3WithInfo to specify handlers for FunctionEnter3WithInfo,
+ * FunctionLeave3WithInfo, and FunctionTailcall3WithInfo.
+ *
+ * Note that only one set of callbacks may be active at a time. Thus,
+ * if a profiler calls SetEnterLeaveFunctionHooks, SetEnterLeaveFunctionHooks2
+ * and SetEnterLeaveFunctionHooks3(WithInfo), then SetEnterLeaveFunctionHooks3(WithInfo)
+ * wins. SetEnterLeaveFunctionHooks2 takes precedence over SetEnterLeaveFunctionHooks
+ * when both are set.
+ *
+ * Each function pointer may be null to disable that callback.
+ *
+ * SetEnterLeaveFunctionHooks3(WithInfo) may only be called from the
+ * profiler's Initialize() callback.
+ */
+ HRESULT SetEnterLeaveFunctionHooks3(
+ [in] FunctionEnter3 *pFuncEnter3,
+ [in] FunctionLeave3 *pFuncLeave3,
+ [in] FunctionTailcall3 *pFuncTailcall3);
+
+
+ HRESULT SetEnterLeaveFunctionHooks3WithInfo(
+ [in] FunctionEnter3WithInfo *pFuncEnter3WithInfo,
+ [in] FunctionLeave3WithInfo *pFuncLeave3WithInfo,
+ [in] FunctionTailcall3WithInfo *pFuncTailcall3WithInfo);
+
+ /*
+ * The profiler can call GetFunctionEnter3Info to gather frame info and argument info
+ * in FunctionEnter3WithInfo callback. The profiler needs to allocate sufficient space
+ * for COR_PRF_FUNCTION_ARGUMENT_INFO of the function it's inspecting and indicate the
+ * size in a ULONG pointed by pcbArgumentInfo.
+ */
+ HRESULT GetFunctionEnter3Info(
+ [in] FunctionID functionId,
+ [in] COR_PRF_ELT_INFO eltInfo,
+ [out] COR_PRF_FRAME_INFO *pFrameInfo,
+ [in, out] ULONG *pcbArgumentInfo,
+ [out, size_is(*pcbArgumentInfo)] COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo);
+
+ /*
+ * The profiler can call GetFunctionLeave3Info to gather frame info and return value
+ * in FunctionLeave3WithInfo callback.
+ */
+ HRESULT GetFunctionLeave3Info(
+ [in] FunctionID functionId,
+ [in] COR_PRF_ELT_INFO eltInfo,
+ [out] COR_PRF_FRAME_INFO *pFrameInfo,
+ [out] COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange);
+
+ /*
+ * The profiler can call GetFunctionTailcall3Info to gather frame info in
+ * FunctionTailcall3WithInfo callback.
+ */
+ HRESULT GetFunctionTailcall3Info(
+ [in] FunctionID functionId,
+ [in] COR_PRF_ELT_INFO eltInfo,
+ [out] COR_PRF_FRAME_INFO *pFrameInfo);
+
+ HRESULT EnumModules([out] ICorProfilerModuleEnum** ppEnum);
+
+ /*
+ * The profiler can call GetRuntimeInformation to query CLR version information.
+ * Passing NULL to any parameter is acceptable except pcchVersionString cannot
+ * be NULL if szVersionString is not NULL.
+ */
+ HRESULT GetRuntimeInformation([out] USHORT *pClrInstanceId,
+ [out] COR_PRF_RUNTIME_TYPE *pRuntimeType,
+ [out] USHORT *pMajorVersion,
+ [out] USHORT *pMinorVersion,
+ [out] USHORT *pBuildNumber,
+ [out] USHORT *pQFEVersion,
+ [in] ULONG cchVersionString,
+ [out] ULONG *pcchVersionString,
+ [out, annotation("_Out_writes_to_(cchVersionString, *pcchVersionString)")]
+ WCHAR szVersionString[]);
+
+ /*
+ * GetThreadStaticAddress2 gets the address of the home for the given
+ * Thread static in the given Thread.
+ *
+ * This function may return CORPROF_E_DATAINCOMPLETE if the given static
+ * has not been assigned a home in the given Thread.
+ */
+ HRESULT GetThreadStaticAddress2(
+ [in] ClassID classId,
+ [in] mdFieldDef fieldToken,
+ [in] AppDomainID appDomainId,
+ [in] ThreadID threadId,
+ [out] void **ppAddress);
+
+ /*
+ * GetAppDomainsContainingModule returns the AppDomainIDs in which the
+ * given module has been loaded
+ */
+ HRESULT GetAppDomainsContainingModule(
+ [in] ModuleID moduleId,
+ [in] ULONG32 cAppDomainIds,
+ [out] ULONG32 *pcAppDomainIds,
+ [out, size_is(cAppDomainIds), length_is(*pcAppDomainIds)] AppDomainID appDomainIds[]);
+
+
+ /*
+ * Retrieve information about a given module.
+ *
+ * When the module is loaded from disk, the name returned will be the filename;
+ * otherwise, the name will be the name from the metadata Module table (i.e.,
+ * the same as the managed System.Reflection.Module.ScopeName).
+ *
+ * *pdwModuleFlags will be filled in with a bitmask of values from COR_PRF_MODULE_FLAGS
+ * that specify some properties of the module.
+ *
+ * NOTE: While this function may be called as soon as the moduleId is alive,
+ * the AssemblyID of the containing assembly will not be available until the
+ * ModuleAttachedToAssembly callback.
+ *
+ */
+ HRESULT GetModuleInfo2(
+ [in] ModuleID moduleId,
+ [out] LPCBYTE *ppBaseLoadAddress,
+ [in] ULONG cchName,
+ [out] ULONG *pcchName,
+ [out, annotation("_Out_writes_to_(cchName, *pcchName)")]
+ WCHAR szName[],
+ [out] AssemblyID *pAssemblyId,
+ [out] DWORD *pdwModuleFlags);
+
+
+}
+
+
+/*
+ * This interface lets you iterate over the frozen objects from ngen images.
+ */
+
+[
+ object,
+ uuid(2C6269BD-2D13-4321-AE12-6686365FD6AF),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerObjectEnum : IUnknown
+{
+ HRESULT Skip(
+ [in] ULONG celt);
+
+ HRESULT Reset();
+
+ HRESULT Clone(
+ [out] ICorProfilerObjectEnum **ppEnum);
+
+ HRESULT GetCount(
+ [out] ULONG *pcelt);
+
+ HRESULT Next(
+ [in] ULONG celt,
+ [out, size_is(celt), length_is(*pceltFetched)] ObjectID objects[],
+ [out] ULONG *pceltFetched);
+}
+
+
+/*
+ * This interface lets you iterate over functions in the runtime.
+ */
+
+[
+ object,
+ uuid(FF71301A-B994-429D-A10B-B345A65280EF),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerFunctionEnum : IUnknown
+{
+ HRESULT Skip([in] ULONG celt);
+
+ HRESULT Reset();
+
+ HRESULT Clone([out] ICorProfilerFunctionEnum **ppEnum);
+
+ HRESULT GetCount([out] ULONG *pcelt);
+
+ HRESULT Next([in] ULONG celt,
+ [out, size_is(celt), length_is(*pceltFetched)]
+ COR_PRF_FUNCTION ids[],
+ [out] ULONG * pceltFetched);
+};
+
+/*
+ * This interface lets you iterate over modules in the runtime.
+ */
+
+[
+ object,
+ uuid(b0266d75-2081-4493-af7f-028ba34db891),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerModuleEnum : IUnknown
+{
+ HRESULT Skip([in] ULONG celt);
+
+ HRESULT Reset();
+
+ HRESULT Clone([out] ICorProfilerModuleEnum **ppEnum);
+
+ HRESULT GetCount([out] ULONG *pcelt);
+
+ HRESULT Next([in] ULONG celt,
+ [out, size_is(celt), length_is(*pceltFetched)]
+ ModuleID ids[],
+ [out] ULONG * pceltFetched);
+};
+
+/*
+ * NOTE: DEPRECATED, now you can use your any allocator.
+ *
+ * This is simple allocator that only allows you to allocate memory.
+ * You may not free it. This was used in conjunction with
+ * ICorProfilerInfo::SetILFunctionBody.
+ */
+[
+ object,
+ uuid(A0EFB28B-6EE2-4d7b-B983-A75EF7BEEDB8),
+ pointer_default(unique),
+ local
+]
+interface IMethodMalloc : IUnknown
+{
+ /*
+ * Tries to allocate memory above the start address of the module from
+ * which it was created. It is important to note that this method may
+ * fail to allocate the memory specified above the start address, and
+ * may as a result return NULL.
+ */
+ PVOID Alloc(
+ [in] ULONG cb);
+}
+
+/*
+ * The CLR implements the ICorProfilerFunctionControl interface. This interface
+ * is used by a code profiler to communicate with the CLR to control how the
+ * JIT should generate code when rejitting a specific method.
+ *
+ * The ICorProfilerFunctionControl interface implemented by the CLR uses the
+ * free threaded model.
+ */
+
+[
+ object,
+ uuid(F0963021-E1EA-4732-8581-E01B0BD3C0C6),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerFunctionControl : IUnknown
+{
+ /*
+ * Set one or more flags from COR_PRF_CODEGEN_FLAGS to control code
+ * generation just for this method.
+ */
+ HRESULT SetCodegenFlags(
+ [in] DWORD flags);
+
+ /*
+ * Override the method body.
+ */
+ HRESULT SetILFunctionBody(
+ [in] ULONG cbNewILMethodHeader,
+ [in, size_is(cbNewILMethodHeader)] LPCBYTE pbNewILMethodHeader);
+
+ /*
+ * This is not currently implemented, and will return E_NOTIMPL
+ */
+ HRESULT SetILInstrumentedCodeMap(
+ [in] ULONG cILMapEntries,
+ [in, size_is(cILMapEntries)] COR_IL_MAP rgILMapEntries[]);
+
+}
+
+/*
+ * The CLR implements the ICorProfilerInfo4 interface. This interface is
+ * used by a code profiler to communicate with the CLR to control event
+ * monitoring and request information. The CLR passes an
+ * ICorProfilerInfo4 interface to each code profiler during initialization.
+ *
+ * A code profiler can call methods on the ICorProfilerInfo4 interface to get
+ * information about managed code being executed under the control of the CLR
+ *
+ * The ICorProfilerInfo4 interface implemented by the CLR uses the free
+ * threaded model.
+ *
+ * The methods implemented on this interface return S_OK on success, or E_FAIL
+ * on failure.
+ *
+ */
+
+[
+ object,
+ uuid(0d8fdcaa-6257-47bf-b1bf-94dac88466ee),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo4 : ICorProfilerInfo3
+{
+ HRESULT EnumThreads([out] ICorProfilerThreadEnum **ppEnum);
+ HRESULT InitializeCurrentThread();
+
+ /*
+ * Call RequestReJIT to have the runtime re-JIT a particular set of methods.
+ * A code profiler can then adjust the code generated when the method is
+ * re-JITed through the ICorProfilerFunctionControl interface. This does
+ * not impact currently executing methods, only future invocations.
+ *
+ * A return code of S_OK indicates that all of the requested methods were
+ * attempted to be rejitted. However, the profiler must implement
+ * ICorProfilerCallback4::ReJITError to determine which of the methods were
+ * successfully re-JITed.
+ *
+ * A failure return value (E_*) indicates some failure that prevents any
+ * re-JITs.
+ */
+ HRESULT RequestReJIT(
+ [in] ULONG cFunctions,
+ [in, size_is(cFunctions)] ModuleID moduleIds[],
+ [in, size_is(cFunctions)] mdMethodDef methodIds[]);
+
+ /*
+ * RequestRevert will instruct the runtime to revert to using/calling the
+ * original method (original IL and flags) rather than whatever was
+ * ReJITed. This does not change any currently active methods, only future
+ * invocations.
+ *
+ */
+ HRESULT RequestRevert(
+ [in] ULONG cFunctions,
+ [in, size_is(cFunctions)] ModuleID moduleIds[],
+ [in, size_is(cFunctions)] mdMethodDef methodIds[],
+ [out, size_is(cFunctions)] HRESULT status[]);
+
+ /*
+ * Same as GetCodeInfo2, except instead of always returning the code info
+ * associated with the original IL/function, you can request the code info
+ * for a particular re-JITed version of a function.
+ */
+ HRESULT GetCodeInfo3(
+ [in] FunctionID functionID,
+ [in] ReJITID reJitId,
+ [in] ULONG32 cCodeInfos,
+ [out] ULONG32 * pcCodeInfos,
+ [out, size_is(cCodeInfos), length_is(*pcCodeInfos)]
+ COR_PRF_CODE_INFO codeInfos[]);
+
+ /*
+ * Same as GetFunctionFromIP, but also returns which re-JITed version is
+ * associated with the IP address.
+ */
+ HRESULT GetFunctionFromIP2(
+ [in] LPCBYTE ip,
+ [out] FunctionID * pFunctionId,
+ [out] ReJITID * pReJitId);
+
+ /*
+ * GetReJITIDs can be used to find all of the re-JITed versions of the
+ * given function.
+ */
+ HRESULT GetReJITIDs(
+ [in] FunctionID functionId,
+ [in] ULONG cReJitIds,
+ [out] ULONG * pcReJitIds,
+ [out, size_is(cReJitIds), length_is(*pcReJitIds)]
+ ReJITID reJitIds[]);
+
+ /*
+ * Same as GetILToNativeMapping, but allows the code profiler to specify
+ * which re-JITed version it applies to.
+ */
+ HRESULT GetILToNativeMapping2(
+ [in] FunctionID functionId,
+ [in] ReJITID reJitId,
+ [in] ULONG32 cMap,
+ [out] ULONG32 * pcMap,
+ [out, size_is(cMap),length_is(*pcMap)]
+ COR_DEBUG_IL_TO_NATIVE_MAP map[]);
+
+ /*
+ * Returns an enumerator for all previously jitted functions. May overlap with
+ * functions previously reported via CompilationStarted callbacks. The returned
+ * enumeration will include values for the COR_PRF_FUNCTION::reJitId field
+ */
+ HRESULT EnumJITedFunctions2([out] ICorProfilerFunctionEnum** ppEnum);
+
+ /*
+ * The code profiler calls GetObjectSize to obtain the size of an object.
+ * Note that types like arrays and strings may have a different size for each object.
+ */
+ HRESULT GetObjectSize2(
+ [in] ObjectID objectId,
+ [out] SIZE_T *pcSize);
+
+}
+
+[
+ object,
+ uuid(07602928-CE38-4B83-81E7-74ADAF781214),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo5 : ICorProfilerInfo4
+{
+ /*
+ * The code profiler calls GetEventMask2 to obtain the current event
+ * categories for which it is to receive event notifications from the CLR
+ *
+ * *pdwEventsLow is a bitwise combination of values from COR_PRF_MONITOR
+ * *pdwEventsHigh is a bitwise combination of values from COR_PRF_HIGH_MONITOR
+ */
+ HRESULT GetEventMask2(
+ [out] DWORD *pdwEventsLow,
+ [out] DWORD *pdwEventsHigh);
+
+ /*
+ * The code profiler calls SetEventMask2 to set the event categories for
+ * which it is set to receive notification from the CLR.
+ *
+ * dwEventsLow is a bitwise combination of values from COR_PRF_MONITOR
+ * dwEventsHigh is a bitwise combination of values from COR_PRF_HIGH_MONITOR
+ */
+ HRESULT SetEventMask2(
+ [in] DWORD dwEventsLow,
+ [in] DWORD dwEventsHigh);
+};
+
+
+[
+ object,
+ uuid(F30A070D-BFFB-46A7-B1D8-8781EF7B698A),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo6 : ICorProfilerInfo5
+{
+ /*
+ * Returns an enumerator for all methods that
+ * - belong to a given NGen module (inlinersModuleId) and
+ * - inlined a body of a given method (inlineeModuleId / inlineeMethodId).
+ *
+ * If incompleteData is set to TRUE after function is called, it means that the methods enumerator
+ * doesn't contain all methods inlining a given method.
+ * It can happen when one or more direct or indirect dependencies of inliners module haven't been loaded yet.
+ * If profiler needs accurate data it should retry later when more modules are loaded (preferable on each module load).
+ *
+ * It can be used to lift limitation on inlining for ReJIT.
+ */
+ HRESULT EnumNgenModuleMethodsInliningThisMethod(
+ [in] ModuleID inlinersModuleId,
+ [in] ModuleID inlineeModuleId,
+ [in] mdMethodDef inlineeMethodId,
+ [out] BOOL *incompleteData,
+ [out] ICorProfilerMethodEnum** ppEnum);
+};
+
+[
+ object,
+ uuid(9AEECC0D-63E0-4187-8C00-E312F503F663),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo7 : ICorProfilerInfo6
+{
+ /*
+ * Applies the newly emitted Metadata.
+ *
+ * This method can be used to apply the newly defined metadata by IMetadataEmit::Define* methods
+ * to the module.
+ *
+ * If metadata changes are made after ModuleLoadFinished callback,
+ * it is required to call this method before using the new metadata
+ */
+ HRESULT ApplyMetaData(
+ [in] ModuleID moduleId);
+
+ /* Returns the length of an in-memory symbol stream
+ *
+ * If the module has in-memory symbols the length of the stream will
+ * be placed in pCountSymbolBytes. If the module doesn't have in-memory
+ * symbols, *pCountSymbolBytes = 0
+ *
+ * Returns S_OK if the length could be determined (even if it is 0)
+ *
+ * Note: The current implementation does not support reflection.emit.
+ * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case.
+ */
+ HRESULT GetInMemorySymbolsLength(
+ [in] ModuleID moduleId,
+ [out] DWORD* pCountSymbolBytes);
+
+ /* Reads bytes from an in-memory symbol stream
+ *
+ * This function attempts to read countSymbolBytes of data starting at offset
+ * symbolsReadOffset within the in-memory stream. The data will be copied into
+ * pSymbolBytes which is expected to have countSymbolBytes of space available.
+ * pCountSymbolsBytesRead contains the actual number of bytes read which
+ * may be less than countSymbolBytes if the end of the stream is reached.
+ *
+ * Returns S_OK if a non-zero number of bytes were read.
+ *
+ * Note: The current implementation does not support reflection.emit.
+ * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case.
+ */
+ HRESULT ReadInMemorySymbols(
+ [in] ModuleID moduleId,
+ [in] DWORD symbolsReadOffset,
+ [out] BYTE* pSymbolBytes,
+ [in] DWORD countSymbolBytes,
+ [out] DWORD* pCountSymbolBytesRead);
+
+};
+
+/*
+* This interface lets you iterate over methods in the runtime.
+*/
+
+[
+ object,
+ uuid(FCCEE788-0088-454B-A811-C99F298D1942),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerMethodEnum : IUnknown
+{
+ HRESULT Skip([in] ULONG celt);
+
+ HRESULT Reset();
+
+ HRESULT Clone([out] ICorProfilerMethodEnum **ppEnum);
+
+ HRESULT GetCount([out] ULONG *pcelt);
+
+ HRESULT Next([in] ULONG celt,
+ [out, size_is(celt), length_is(*pceltFetched)]
+ COR_PRF_METHOD elements[],
+ [out] ULONG * pceltFetched);
+}
+
+/*
+ * This interface lets you iterate over threads in the runtime.
+ */
+
+[
+ object,
+ uuid(571194f7-25ed-419f-aa8b-7016b3159701),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerThreadEnum : IUnknown
+{
+ HRESULT Skip([in] ULONG celt);
+
+ HRESULT Reset();
+
+ HRESULT Clone([out] ICorProfilerThreadEnum **ppEnum);
+
+ HRESULT GetCount([out] ULONG *pcelt);
+
+ HRESULT Next([in] ULONG celt,
+ [out, size_is(celt), length_is(*pceltFetched)]
+ ThreadID ids[],
+ [out] ULONG * pceltFetched);
+}
+
+
+/*
+ * This interface is given to the profiler in the GetAssemblyReferences() callback, to
+ * allow the profiler to inform the CLR of assembly references that the profiler plans to
+ * add later on during ModuleLoadFinished. This improves the accuracy of the CLR assembly
+ * reference closure walker, and its algorithms for determining whether assemblies may be shared
+ *
+ * This interface is valid for use only within the GetAssemblyReferences callback that passed
+ * this interface to the profiler
+ */
+[
+ object,
+ uuid(66A78C24-2EEF-4F65-B45F-DD1D8038BF3C),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerAssemblyReferenceProvider : IUnknown
+{
+ // The profiler calls this for each target assembly it plans to reference from the
+ // assembly specified in the wszAssemblyPath argument of the GetAssemblyReferences callback.
+ HRESULT AddAssemblyReference(const COR_PRF_ASSEMBLY_REFERENCE_INFO * pAssemblyRefInfo);
+};