home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / corprof.idl < prev    next >
Encoding:
Text File  |  2000-06-23  |  60.8 KB  |  1,543 lines

  1. /**************************************************************************************
  2.  **                                                                                  **
  3.  ** Corprof.idl - COM+ Runtime Profiling interfaces.                                 **
  4.  **                                                                                  **
  5.  ** Copyright (c) 1996-2000 Microsoft Corporation.  All Rights Reserved.             **
  6.  **                                                                                  **
  7.  **************************************************************************************/
  8.  
  9. /* -------------------------------------------------------------------------- *
  10.  * Imported types
  11.  * -------------------------------------------------------------------------- */
  12.  
  13. #if !DUMMY_DEFINITIONS_BECAUSE_I_CANT_FIGURE_OUT_HOW_TO_IMPORT_THESE
  14.  
  15.  
  16. /* -------------------------------------------------------------------------- *
  17.  * These are registry key & value names where profilers register themselves
  18.  * Note that '\\\\' -- midl--> '\\' -- C++ compiler --> '\'
  19.  * -------------------------------------------------------------------------- */
  20. cpp_quote("#define PROFILER_REGKEY_ROOT            L\"software\\\\microsoft\\\\COMplus\\\\Profilers\"")
  21. cpp_quote("#define PROFILER_REGVALUE_HELPSTRING    L\"HelpString\"")
  22. cpp_quote("#define PROFILER_REGVALUE_PROFID        L\"ProfilerID\"")
  23.  
  24. cpp_quote("#define CorDB_CONTROL_Profiling         \"Cor_Enable_Profiling\"")
  25. cpp_quote("#define CorDB_CONTROL_ProfilingL       L\"Cor_Enable_Profiling\"")
  26.  
  27. cpp_quote("#if 0")
  28.  
  29. /*
  30.  * !!! need to figure out the correct way to import these defintions
  31.  */
  32.  
  33. #ifdef _WIN64
  34. import "unknwn.idl";
  35. #else
  36. #include "basetsd.h"
  37. #endif
  38.  
  39. typedef LONG32  mdToken;
  40. typedef mdToken mdModule;
  41. typedef mdToken mdTypeDef;
  42. typedef mdToken mdSourceFile;
  43. typedef mdToken mdMemberRef;
  44. typedef mdToken mdMethodDef;
  45. typedef mdToken mdFieldDef;
  46. typedef ULONG CorElementType;
  47.  
  48. typedef SIZE_T LPDEBUG_EVENT;
  49.  
  50. typedef SIZE_T LPSTARTUPINFOW;
  51. typedef SIZE_T LPPROCESS_INFORMATION;
  52.  
  53. cpp_quote("#endif")
  54.  
  55. #endif
  56.  
  57. cpp_quote("#ifndef _COR_IL_MAP")
  58. cpp_quote("#define _COR_IL_MAP")
  59.  
  60. // Note that this structure is also defined in CorDebug.idl - PROPOGATE CHANGES
  61. // BOTH WAYS, or this'll become a really insidious bug some day.
  62. typedef struct _COR_IL_MAP
  63. {
  64.     ULONG32 oldOffset;        // Old IL offset relative to beginning of function
  65.     ULONG32 newOffset;        // New IL offset relative to beginning of function
  66. } COR_IL_MAP;
  67.  
  68. cpp_quote("#endif //_COR_IL_MAP")
  69.  
  70. #ifndef DO_NO_IMPORTS
  71. import "wtypes.idl";
  72. import "unknwn.idl";
  73. #endif
  74.  
  75. typedef const BYTE *LPCBYTE;
  76. typedef BYTE *LPBYTE;
  77.  
  78. typedef UINT_PTR ProcessID;
  79. typedef UINT_PTR AssemblyID;
  80. typedef UINT_PTR AppDomainID;
  81. typedef UINT_PTR ModuleID;
  82. typedef UINT_PTR ClassID;
  83. typedef UINT_PTR ThreadID;
  84. typedef UINT_PTR ContextID;
  85. typedef UINT_PTR FunctionID;
  86. typedef UINT_PTR ObjectID;
  87. typedef UINT_PTR MonitorID;
  88.  
  89. typedef UINT_PTR __stdcall FunctionIDMapper(FunctionID funcId, BOOL *pbHookFunction);
  90.  
  91. /*
  92.  * NOTE!!!
  93.  *
  94.  * It is VERY IMPORTANT to note that these function implementations must be
  95.  * __declspec(naked), since the EE is not saving any registers before calling
  96.  * any of them.  YOU MUST SAVE ALL REGISTERS YOU USE, INCLUDING FPU REGISTERS
  97.  * IF THE FPU STACK IS NOT EMPTY AND YOU INTEND TO USE IT.
  98.  *
  99.  * NOTE: The profiler cannot block here, since the stack may not be in a
  100.  *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  101.  *       profiler blocks here and a GC is attempted, the runtime will block
  102.  *       until this callback returns.  Also, the profiler may NOT call into
  103.  *       managed code or in any way cause a managed memory allocation.
  104.  */
  105. typedef void FunctionEnter(FunctionID funcID);
  106. typedef void FunctionLeave(FunctionID funcID);
  107. typedef void FunctionTailcall(FunctionID funcID);
  108.  
  109. typedef enum
  110. {
  111.     COR_PRF_MONITOR_NONE                = 0x00000000,
  112.     COR_PRF_MONITOR_FUNCTION_UNLOADS    = 0x00000001,
  113.     COR_PRF_MONITOR_CLASS_LOADS         = 0x00000002,
  114.     COR_PRF_MONITOR_MODULE_LOADS        = 0x00000004,
  115.     COR_PRF_MONITOR_ASSEMBLY_LOADS      = 0x00000008,
  116.     COR_PRF_MONITOR_APPDOMAIN_LOADS     = 0x00000010,
  117.     COR_PRF_MONITOR_CALLS               = 0x00000020,
  118.     COR_PRF_MONITOR_JIT_COMPILATION     = 0x00000040,
  119.     COR_PRF_MONITOR_EXCEPTIONS          = 0x00000080,
  120.     COR_PRF_MONITOR_GC                  = 0x00000100,
  121.     COR_PRF_MONITOR_OBJECT_ALLOCATED    = 0x00000200,
  122.     COR_PRF_MONITOR_THREADS             = 0x00000400,
  123.     COR_PRF_MONITOR_REMOTING            = 0x00000800,
  124.     COR_PRF_MONITOR_SECURITY_CHECKS     = 0x00001000,
  125.     COR_PRF_MONITOR_CODE_TRANSITIONS    = 0x00002000,
  126.     COR_PRF_MONITOR_SYNCHRONIZATIONS    = 0x00004000,
  127.     COR_PRF_MONITOR_ALLOW_REJIT         = 0x00008000,
  128.     COR_PRF_MONITOR_ENTERLEAVE          = 0x00010000,
  129.     COR_PRF_MONITOR_CCW                 = 0x00020000,
  130.     COR_PRF_MONITOR_REMOTING_COOKIE     = 0x00040000 | COR_PRF_MONITOR_REMOTING,
  131.     COR_PRF_MONITOR_REMOTING_ASYNC      = 0x00080000 | COR_PRF_MONITOR_REMOTING,
  132.     COR_PRF_MONITOR_SUSPENDS            = 0x00100000,
  133.     COR_PRF_DISABLE_INLINING            = 0x00200000,
  134.     COR_PRF_MONITOR_CACHE_SEARCHES      = 0x00400000,
  135.     COR_PRF_MONITOR_RESERVED2           = 0x20000000,
  136.     COR_PRF_MONITOR_ALL                 = 0x0FFFFFFF,
  137.  
  138.     COR_PRF_MONITOR_IMMUTABLE           = COR_PRF_MONITOR_CODE_TRANSITIONS |
  139.                                           COR_PRF_MONITOR_REMOTING |
  140.                                           COR_PRF_MONITOR_REMOTING_COOKIE |
  141.                                           COR_PRF_MONITOR_REMOTING_ASYNC |
  142.                                           COR_PRF_MONITOR_ALLOW_REJIT
  143. } COR_PRF_MONITOR;
  144.  
  145. typedef enum
  146. {
  147.     PROFILER_PARENT_UNKNOWN             = 0xFFFFFFFD,
  148.     PROFILER_GLOBAL_CLASS               = 0xFFFFFFFE,
  149.     PROFILER_GLOBAL_MODULE              = 0xFFFFFFFF
  150. } COR_PRF_MISC;
  151.  
  152. typedef enum
  153. {
  154.     COR_PRF_CACHED_FUNCTION_FOUND,
  155.     COR_PRF_CACHED_FUNCTION_NOT_FOUND
  156. } COR_PRF_JIT_CACHE;
  157.  
  158. typedef enum
  159. {
  160.     COR_PRF_TRANSITION_CALL,
  161.     COR_PRF_TRANSITION_RETURN
  162. } COR_PRF_TRANSITION_REASON;
  163.  
  164. typedef enum
  165. {
  166.     COR_PRF_SUSPEND_OTHER                   = 0,
  167.     COR_PRF_SUSPEND_FOR_GC                  = 1,
  168.     COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN  = 2,
  169.     COR_PRF_SUSPEND_FOR_CODE_PITCHING       = 3,
  170.     COR_PRF_SUSPEND_FOR_SHUTDOWN            = 4
  171. } COR_PRF_SUSPEND_REASON;
  172.  
  173. /* -------------------------------------------------------------------------- *
  174.  * Forward declarations
  175.  * -------------------------------------------------------------------------- */
  176.  
  177. interface ICorProfilerCallback;
  178. interface ICorProfilerInfo;
  179. interface IMethodMalloc;
  180.  
  181. /* -------------------------------------------------------------------------- *
  182.  * User Callback interface
  183.  * -------------------------------------------------------------------------- */
  184.  
  185. /*
  186.  * The ICorProfilerCallback interface is used by the COM+ Runtime to notify a
  187.  * code profiler when events have occurred that the code profiler has registered
  188.  * an in interest in receiving. This is the primary callback interface through
  189.  * which the COM+ Runtime communicates with the code profiler. A code profiler
  190.  * must register this callback interface in the Win32 registry. This object has
  191.  * several methods that receive notification from the runtime when an event is
  192.  * about to occur in an executing runtime process.
  193.  *
  194.  * The methods implemented on this interface return S_OK on success, or E_FAIL
  195.  * on failure.
  196.  */
  197.  
  198. [
  199.     object,
  200.     uuid(22B85E59-2A47-4554-8248-FFCBEDDED9C5),
  201.     pointer_default(unique),
  202.     local
  203. interface ICorProfilerCallback : IUnknown
  204. {
  205.  
  206.     /*
  207.      *
  208.      * STARTUP/SHUTDOWN EVENTS
  209.      *
  210.      */
  211.  
  212.     /*
  213.      * The COM+ Runtime calls Initialize to setup the code profiler
  214.      * whenever a new COM+ Runtime application is started. The call provides
  215.      * an IUnknown interface pointer that should be QI'd for an ICorProfilerInfo
  216.      * interface pointer, and a pointer to a DWORD that should be filled out
  217.      * with all of the values from the COR_PRF_MONITOR enum that the profiler
  218.      * wishes to receive events for.
  219.      *
  220.      * NOTE: this is the only opportunity to enable callbacks that are a part
  221.      * of COR_PRF_MONITOR_IMMUTABLE, since they can no longer be changed after
  222.      * returning from this function.
  223.      */
  224.     HRESULT Initialize(
  225.                 [in] IUnknown     *pICorProfilerInfoUnk,
  226.                 [out] DWORD        *pdwRequestedEvents);
  227.  
  228.     /*
  229.      * The COM+ Runtime calls Shutdown to notify the code profiler that
  230.      * the application is exiting.  This is the profiler's last opportunity to
  231.      * safely call functions on the ICorProfilerInfo interface.  After returning
  232.      * from this function the runtime will proceed to unravel its internal data
  233.      * structures and any calls to ICorProfilerInfo are undefined in their
  234.      * behaviour.
  235.      *
  236.      * NOTE: to maintain overall API speed, the profiler omits many argument
  237.      * checks.  This means that the profiler is responsible for making sure
  238.      * that the arguments it provides to any ICorProfilerInfo API are valid.
  239.      */
  240.     HRESULT Shutdown();
  241.  
  242.  
  243.     /*
  244.      *
  245.      * APPLICATION DOMAIN EVENTS
  246.      *
  247.      */
  248.  
  249.     /*
  250.      * Called when an application domain creation has begun and ended.
  251.      * The id is not valid for any information request until after the app
  252.      * domain has been fully created.  One may only cache the id provided in
  253.      * AppDomainCreationStarted for later use.
  254.      * The hrStatus provides the success or failure of the operation
  255.      */
  256.     HRESULT AppDomainCreationStarted(
  257.                 [in] AppDomainID appDomainId);
  258.  
  259.     HRESULT AppDomainCreationFinished(
  260.                 [in] AppDomainID appDomainId,
  261.                 [in] HRESULT     hrStatus);
  262.  
  263.     /*
  264.      * Called before and after an app domain is unloaded from a process.
  265.      * Once an AppDomain unload has started, its ID is no longer valid in the
  266.      * system and cannot be used in calls to any ICorProfilerInfo APIs.
  267.      * The hrStatus provides the success or failure of the operation
  268.      */
  269.     HRESULT AppDomainShutdownStarted(
  270.                 [in] AppDomainID appDomainId);
  271.  
  272.     HRESULT AppDomainShutdownFinished(
  273.                 [in] AppDomainID appDomainId,
  274.                 [in] HRESULT     hrStatus);
  275.  
  276.     /*
  277.      *
  278.      * ASSEMBLY EVENTS
  279.      *
  280.      */
  281.  
  282.     /*
  283.      * Called when an Assembly load has begun and ended. The id is not valid
  284.      * for any information request until after the assembly has been fully
  285.      * loaded.  One may only cache the id provided in AssemblyLoadStarted for
  286.      * later use.
  287.      * The hrStatus provides the success or failure of the operation
  288.      */
  289.     HRESULT AssemblyLoadStarted(
  290.                 [in] AssemblyID assemblyId);
  291.  
  292.     HRESULT AssemblyLoadFinished(
  293.                 [in] AssemblyID assemblyId,
  294.                 [in] HRESULT    hrStatus);
  295.  
  296.     /*
  297.      * Called before and after an assembly is unloaded.  AssemblyUnloadStarted
  298.      * is the last point at which the AssemblyID is valid for calls to the
  299.      * ICorProfilerInfo interface.
  300.      * The hrStatus provides the success or failure of the operation
  301.      */
  302.     HRESULT AssemblyUnloadStarted(
  303.                 [in] AssemblyID assemblyId);
  304.  
  305.     HRESULT AssemblyUnloadFinished(
  306.                 [in] AssemblyID assemblyId,
  307.                 [in] HRESULT    hrStatus);
  308.  
  309.  
  310.     /*
  311.      *
  312.      * MODULE EVENTS
  313.      *
  314.      */
  315.  
  316.     /*
  317.      * The COM+ Runtime calls ModuleLoadStarted to notify the code
  318.      * profiler that a module is about to be loaded.  Because this module has not
  319.      * yet been loaded, other module information methods are not valid to
  320.      * call in this callback.  Wait until ModuleLoadFinished() is
  321.      * received to do things like acquire the metadata.
  322.      */
  323.     HRESULT ModuleLoadStarted(
  324.                 [in] ModuleID moduleId);
  325.  
  326.     /*
  327.      * The COM+ Runtime calls ModuleLoadFinished to notify the code
  328.      * profiler that a module has been loaded. The hrStatus provides the
  329.      * success or failure of the operation
  330.      */
  331.     HRESULT ModuleLoadFinished(
  332.                 [in] ModuleID moduleId,
  333.                 [in] HRESULT  hrStatus);
  334.  
  335.     /*
  336.      * Called before a module is being unloaded.  Use this events to collect
  337.      * final statics that require the ModuleID to be valid.  After returning
  338.      * from ModuleUnloadStarted, the ModuleID is no longer valid.
  339.      * The hrStatus provides the success or failure of the operation
  340.      */
  341.     HRESULT ModuleUnloadStarted(
  342.                 [in] ModuleID moduleId);
  343.  
  344.     HRESULT ModuleUnloadFinished(
  345.                 [in] ModuleID moduleId,
  346.                 [in] HRESULT  hrStatus);
  347.  
  348.     /*
  349.      * A module can get loaded through legacy means (ie: IAT or LoadLibrary) or
  350.      * through a metadata reference.  The COM+ Runtime loader therefore has many code
  351.      * paths for determining what assembly a module lives in.  It is therefore
  352.      * possible that after a ModuleLoadFinished event, the module does not
  353.      * know what assembly it is in and getting the parent AssemblyID is not possible.
  354.      * This event is fired when the module is officially attached to its parent
  355.      * assembly.  Calling GetModuleInfo after this point will return the proper parent
  356.      * assembly.
  357.      */
  358.     HRESULT ModuleAttachedToAssembly(
  359.                 [in] ModuleID   moduleId,
  360.                 [in] AssemblyID AssemblyId);
  361.  
  362.  
  363.     /*
  364.      *
  365.      *  CLASS EVENTS
  366.      *
  367.      */
  368.  
  369.     /*
  370.      * The COM+ Runtime calls ClassLoadStarted to notify the code profiler
  371.      * that a class is being loaded.  The ClassID is not valid for calls to
  372.      * the ICorProfilerInfo interface until the profiler receives a
  373.      * ClassLoadFinished event for the same ClassID.
  374.      */
  375.     HRESULT ClassLoadStarted(
  376.                 [in] ClassID classId);
  377.  
  378.     /*
  379.      * The COM+ Runtime calls ClassLoadFinished to notify the code
  380.      * profiler that a class has been loaded.  The ClassID is now valid for
  381.      * calls to the ICorProfilerInfo interface.
  382.      * The hrStatus provides the success or failure of the operation
  383.      */
  384.     HRESULT ClassLoadFinished(
  385.                 [in] ClassID classId,
  386.                 [in] HRESULT hrStatus);
  387.  
  388.     /*
  389.      * The given class is about to be unloaded.  Use this event to gather final
  390.      * status and clean up anything that requires the ClassID to be valid.
  391.      * After returning from this callback the ClassID is no longer valid.
  392.      * The hrStatus provides the success or failure of the operation
  393.      */
  394.     HRESULT ClassUnloadStarted(
  395.                 [in] ClassID classId);
  396.  
  397.     HRESULT ClassUnloadFinished(
  398.                 [in] ClassID classId,
  399.                 [in] HRESULT hrStatus);
  400.  
  401.     /*
  402.      *
  403.      * JIT EVENTS
  404.      *
  405.      */
  406.  
  407.     /*
  408.      * The COM+ Runtime calls FunctionUnloadStarted to notify the code
  409.      * profiler that a function is being unloaded.  After returning from this
  410.      * call, the FunctionID is no longer valid.
  411.      */
  412.     HRESULT FunctionUnloadStarted(
  413.                 [in] FunctionID functionId);
  414.  
  415.  
  416.     /*
  417.      * The COM+ Runtime calls JITCompilationStarted to notify the code
  418.      * profiler that the JIT compiler is starting to compile a function.
  419.      *
  420.      * The fIsSafeToBlock argument tells the profiler whether or not blocking
  421.      * will affect the operation of the runtime.  If true, blocking may cause
  422.      * the runtime to wait for the calling thread to return from this callback.
  423.      * Although this will not harm the runtime, it will skew the profiling
  424.      * results.
  425.      */
  426.     HRESULT JITCompilationStarted(
  427.                 [in] FunctionID functionId,
  428.                 [in] BOOL       fIsSafeToBlock);
  429.  
  430.     /*
  431.      * The COM+ Runtime calls JITCompilationFinished to notify the code
  432.      * profiler that the JIT compiler has finished compiling a function.
  433.      *
  434.      * The fIsSafeToBlock argument tells the profiler whether or not blocking
  435.      * will affect the operation of the runtime.  If true, blocking may cause
  436.      * the runtime to wait for the calling thread to return from this callback.
  437.      * Although this will not harm the runtime, it will skew the profiling
  438.      * results.
  439.      *
  440.      * The FunctionID is now valid in ICorProfilerInfo APIs.
  441.      *
  442.      * The hrStatus provides the success or failure of the operation
  443.      */
  444.     HRESULT JITCompilationFinished(
  445.                 [in] FunctionID functionId,
  446.                 [in] HRESULT    hrStatus,
  447.                 [in] BOOL       fIsSafeToBlock);
  448.  
  449.     /*
  450.      * This notifies the profiler when a search for a prejitted function is
  451.      * starting.
  452.      *
  453.      *    functionId: the function for which the search is being performed.
  454.      *    bUseCachedFunction: if true, the EE uses the cached function (if applicable)
  455.      *                        if false, the EE jits the function instead of
  456.      *                        using a pre-jitted version.
  457.      */
  458.     HRESULT JITCachedFunctionSearchStarted(
  459.                 [in] FunctionID functionId,
  460.                 [out] BOOL      *pbUseCachedFunction);
  461.  
  462.     /*
  463.      * This notifies the profiler when a search for a cached function has been
  464.      * performed.
  465.      *
  466.      *    functionId: the function for which the search has been performed.
  467.      *    result: the result of the search.  There are two possible results:
  468.      *        COR_PRF_CACHED_FUNCTION_FOUND
  469.      *        COR_PRF_CACHED_FUNCTION_NOT_FOUND
  470.      *
  471.      * NOTE: the FunctionID is not valid for calls to any ICorProfilerInfo APIs
  472.      * until the profiler has received the corresponding JITCompilationFinished.
  473.      *        
  474.      */
  475.     HRESULT JITCachedFunctionSearchFinished(
  476.                 [in] FunctionID        functionId,
  477.                 [in] COR_PRF_JIT_CACHE result);
  478.  
  479.     /*
  480.      * The COM+ Runtime calls JITFunctionPitched to notify the profiler
  481.      * that a jitted function was removed from memory.  If the pitched
  482.      * function is called in the future, the profiler will receive new
  483.      * JIT compilation events as it is re-jitted.
  484.      *
  485.      * NOTE: the FunctionID is not valid until it is re-jitted.  When it is
  486.      * re-jitted, it will use the same FunctionID value.
  487.      */
  488.     HRESULT JITFunctionPitched(
  489.                 [in] FunctionID functionId);
  490.  
  491.     /*
  492.      * The COM+ Runtime calls JITInlining to notify the profiler that the jitter
  493.      * is about to inline calleeId into callerId.  Set pfShouldInline to FALSE
  494.      * to prevent the callee from being inlined into the caller, and set to
  495.      * TRUE to allow the inline to occur.
  496.      *
  497.      * NOTE: Inlined functions do not provide Enter/Leave events, so if you desire
  498.      *       an accurate callgraph, you should set FALSE.  Be aware that
  499.      *       setting FALSE will affect performance, since inlining typically
  500.      *       increases speed and reduces separate jitting events for the inlined
  501.      *       method.
  502.      */
  503.     HRESULT JITInlining(
  504.                 [in] FunctionID callerId,
  505.                 [in] FunctionID calleeId,
  506.                 [out] BOOL      *pfShouldInline);
  507.  
  508.     /*
  509.      *
  510.      * THREAD EVENTS
  511.      *
  512.      */
  513.  
  514.     /*
  515.      * The COM+ Runtime calls ThreadAcquiringMonitor to notify the code
  516.      * profiler that a thread is attempting to acquire a monitor on an object.
  517.      * CURRENT STATUS:  E_NOTIMPL
  518.      */
  519.     HRESULT ThreadAcquiringMonitor(
  520.                 [in] ThreadID  threadId,
  521.                 [in] MonitorID monitorId,
  522.                 [in] ObjectID  objectId,
  523.                 [in] ClassID   classId);
  524.  
  525.     /*
  526.      * The COM+ Runtime calls ThreadAcquiredMonitor to notify the code
  527.      * profiler that a thread has acquired a monitor on an object.
  528.      * CURRENT STATUS:  E_NOTIMPL
  529.      */
  530.     HRESULT ThreadAcquiredMonitor(
  531.                 [in] ThreadID  threadId,
  532.                 [in] MonitorID monitorId,
  533.                 [in] ObjectID  objectId,
  534.                 [in] ClassID   classId);
  535.  
  536.     /*
  537.      * The COM+ Runtime calls ThreadBlockedMonitor to notify the code
  538.      * profiler that a thread has blocked while attempting to acquire a monitor
  539.      * on an object.
  540.      * CURRENT STATUS:  E_NOTIMPL
  541.      */
  542.     HRESULT ThreadBlockedMonitor(
  543.                 [in] ThreadID  threadId,
  544.                 [in] MonitorID monitorId,
  545.                 [in] ObjectID  objectId,
  546.                 [in] ClassID   classId);
  547.  
  548.     /*
  549.      * The COM+ Runtime calls ThreadCreated to notify the code profiler
  550.      * that a thread has been created.  The ThreadID is valid immediately.
  551.      */
  552.     HRESULT ThreadCreated(
  553.                 [in] ThreadID threadId);
  554.  
  555.     /*
  556.      * The COM+ Runtime calls ThreadDestroyed to notify the code profiler
  557.      * that a thread has been destroyed.  The ThreadID is no longer valid.
  558.      */
  559.     HRESULT ThreadDestroyed(
  560.                 [in] ThreadID threadId);
  561.  
  562.     /*
  563.      * The COM+ Runtime calls ThreadAssignedToOSThread to tell the profiler
  564.      * that a managed thread is being implemented via a particualr OS thread.
  565.      * This callback exists so that the profiler can maintain an accurate
  566.      * OS to Managed thread mapping across fibres.
  567.      */
  568.     HRESULT ThreadAssignedToOSThread(
  569.                 [in] ThreadID managedThreadId,
  570.                 [in] DWORD    osThreadId);
  571.  
  572.     /*
  573.      * The COM+ Runtime calls ThreadReleasedMonitor to notify the code
  574.      * profiler that a thread has released a monitor on an object.
  575.      * CURRENT STATUS:  E_NOTIMPL
  576.      */
  577.     HRESULT ThreadReleasedMonitor(
  578.                 [in] ThreadID  threadId,
  579.                 [in] MonitorID monitorId,
  580.                 [in] ObjectID  objectId,
  581.                 [in] ClassID   classId);
  582.  
  583.     /*
  584.      *
  585.      * REMOTING EVENTS
  586.      *
  587.      */
  588.  
  589.     //
  590.     // Client-side events
  591.     //
  592.  
  593.     /*
  594.      * NOTE: each of the following pairs of callbacks will occur on the same
  595.      *       thread
  596.      *   RemotingClientInvocationStarted  & RemotingClientSendingMessage
  597.      *   RemotingClientReceivingReply     & RemotingClientInvocationFinished
  598.      *   RemotingServerInvocationReturned & RemotingServerSendingReply
  599.  
  600.     /*
  601.      * The COM+ Runtime calls RemotingClientInvocationStarted to notify the profiler that
  602.      * a remoting call has begun.  This event is the same for synchronous and
  603.      * asynchronous calls.
  604.      */
  605.     HRESULT RemotingClientInvocationStarted();
  606.  
  607.     /*
  608.      * The COM+ Runtime calls RemotingClientSendingMessage to notify the profiler that
  609.      * a remoting call is requiring the the caller to send an invocation request through
  610.      * a remoting channel.
  611.      *
  612.      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
  613.      *            the value provided in RemotingServerReceivingMessage, if the channel
  614.      *            succeeds in transmitting the message, and if GUID cookies are active on
  615.      *            the server-side process.  This allows easy pairing of remoting calls,
  616.      *            and the creation of a logical call stack.
  617.      * fIsAsync - is true if the call is asynchronous.
  618.      */
  619.     HRESULT RemotingClientSendingMessage(
  620.                 [in] GUID *pCookie,
  621.                 [in] BOOL fIsAsync);
  622.  
  623.     /*
  624.      * The COM+ Runtime calls RemotingClientReceivingReply to notify the profiler that
  625.      * the server-side portion of a remoting call has completed and that the client is
  626.      * now receiving and about to process the reply.
  627.      *
  628.      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
  629.      *            the value provided in RemotingServerSendingReply, if the channel
  630.      *            succeeds in transmitting the message, and if GUID cookies are active on
  631.      *            the server-side process.  This allows easy pairing of remoting calls.
  632.      * fIsAsync - is true if the call is asynchronous.
  633.      */
  634.     HRESULT RemotingClientReceivingReply(
  635.                 [in] GUID *pCookie,
  636.                 [in] BOOL fIsAsync);
  637.  
  638.     /*
  639.      * The COM+ Runtime calls RemotingClientInvocationFinished to notify the profiler that
  640.      * a remoting invocation has run to completion on the client side.  If the call was
  641.      * synchronous, this means that it has also run to completion on the server side.  If
  642.      * the call was asynchronous, a reply may still be expected when the call is handled.
  643.      * If the call is asynchronous, and a reply is expected, then the reply will occur in
  644.      * the form of a call to RemotingClientReceivingReply and an additional call to
  645.      * RemotingClientInvocationFinished to indicate the required secondary processing of
  646.      * an asynchronous call.
  647.      */
  648.     HRESULT RemotingClientInvocationFinished();
  649.  
  650.     //
  651.     // Server-side events
  652.     //
  653.  
  654.     /*
  655.      * The COM+ Runtime calls RemotingServerReceivingMessage to notify the profiler that
  656.      * the process has received a remote method invocation (or activation) request.  If
  657.      * the message request is asynchronous, then the request may be serviced by any
  658.      * arbitrary thread.
  659.      *
  660.      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
  661.      *            the value provided in RemotingClientSendingMessage, if the channel
  662.      *            succeeds in transmitting the message, and if GUID cookies are active on
  663.      *            the client-side process.  This allows easy pairing of remoting calls.
  664.      * fIsAsync - is true if the call is asynchronous.
  665.      */
  666.     HRESULT RemotingServerReceivingMessage(
  667.                 [in] GUID *pCookie,
  668.                 [in] BOOL fIsAsync);
  669.  
  670.     /*
  671.      * The COM+ Runtime calls RemotingServerInvocationStarted to notify the profiler that
  672.      * the process is invoking a method due to a remote method invocation request.
  673.      */
  674.     HRESULT RemotingServerInvocationStarted();
  675.  
  676.     /*
  677.      * The COM+ Runtime calls RemotingServerInvocationReturned to notify the profiler that
  678.      * the process has finished invoking a method due to a remote method invocation request.
  679.      */
  680.     HRESULT RemotingServerInvocationReturned();
  681.  
  682.     /*
  683.      * The COM+ Runtime calls RemotingServerSendingReply to notify the profiler that
  684.      * the process has finished processing a remote method invocation request and is
  685.      * about to transmit the reply through a channel.
  686.      *
  687.      * pCookie  - if remoting GUID cookies are active, this value will correspond with the
  688.      *            the value provided in RemotingClientReceivingReply, if the channel
  689.      *            succeeds in transmitting the message, and if GUID cookies are active on
  690.      *            the client-side process.  This allows easy pairing of remoting calls.
  691.      * fIsAsync - is true if the call is asynchronous.
  692.      */
  693.     HRESULT RemotingServerSendingReply(
  694.                 [in] GUID *pCookie,
  695.                 [in] BOOL fIsAsync);
  696.  
  697.     /*
  698.      *
  699.      * TRANSITION EVENTS
  700.      *
  701.      */
  702.  
  703.     /*
  704.      * The COM+ Runtime calls UnmanagedToManagedTransition to notify the
  705.      * code profiler that a transition from unmanaged code to managed code has
  706.      * occurred. functionId is always the ID of the callee, and reason
  707.      * indicates whether the transition was due to a call into managed code from
  708.      * unmanaged, or a return from an unmanaged function called by a managed one.
  709.      *
  710.      * Note that if the reason is COR_PRF_TRANSITION_RETURN, then the functionId
  711.      * is that of the unmanaged function, and will never have been jitted.
  712.      * Unmanaged functions still have some basic information associated with
  713.      * them, such as a name, and some metadata.
  714.      *
  715.      * Note that if the reason is COR_PRF_TRANSITION_RETURN and the callee was
  716.      * a PInvoke call indirect, then the runtime does not know the destination
  717.      * of the call and functionId will be NULL.
  718.      *
  719.      * Note that if the reason is COR_PRF_TRANSITION_CALL then it may be possible
  720.      * that the callee has not yet been JIT-compiled.
  721.      */
  722.     HRESULT UnmanagedToManagedTransition(
  723.                 [in] FunctionID                functionId,
  724.                 [in] COR_PRF_TRANSITION_REASON reason);
  725.  
  726.  
  727.     /*
  728.      * The COM+ Runtime calls ManagedToUnmanagedTransition to notify the
  729.      * code profiler that a transition from managed code to unmanaged code has
  730.      * occurred. functionId is always the ID of the callee, and reason
  731.      * indicates whether the transition was due to a call into unmanaged code from
  732.      * managed, or a return from an managed function called by an unmanaged one.
  733.      *
  734.      * Note that if the reason is COR_PRF_TRANSITION_CALL, then the functionId
  735.      * is that of the unmanaged function, and will never have been jitted.
  736.      * Unmanaged functions still have some basic information associated with
  737.      * them, such as a name, and some metadata.
  738.      *
  739.      * Note that if the reason is COR_PRF_TRANSITION_CALL and the callee is
  740.      * a PInvoke call indirect, then the runtime does not know the destination
  741.      * of the call and functionId will be NULL.
  742.      */
  743.     HRESULT ManagedToUnmanagedTransition(
  744.                 [in] FunctionID                functionId,
  745.                 [in] COR_PRF_TRANSITION_REASON reason);
  746.  
  747.  
  748.     /*
  749.      *
  750.      * RUNTIME SUSPENSION EVENTS
  751.      *
  752.      */
  753.  
  754.     /*
  755.      * The COM+ Runtime calls RuntimeSuspendStarted to notify the code profiler
  756.      * that the runtime is about to suspend all of the runtime threads.
  757.      * All runtime threads that are in unmanaged code are permitted to continue
  758.      * running until they try to re-enter the runtime, at which point they will
  759.      * also suspend until the runtime resumes.  This also applies to new threads
  760.      * that enter the runtime.  All threads within the runtime are either
  761.      * suspended immediately if they are in interruptible code, or asked to
  762.      * suspend when they do reach interruptible code.
  763.      *
  764.      * suspendReason make be any of the following values:
  765.      *  COR_PRF_SUSPEND_FOR_GC
  766.      *      the runtime is suspending to service a GC request.  The GC-related
  767.      *      callbacks will occur between the RuntimeSuspendFinished and
  768.      *      RuntimeResumeStarted events.
  769.      *  COR_PRF_SUSPEND_FOR_CODE_PITCHING
  770.      *      the runtime is suspending so that code pitching may occur.  This
  771.      *      only occurs when the EJit is active with code pitching enabled.
  772.      *      Code pitching callbacks will occur between the
  773.      *      RuntimeSuspendFinished and RuntimeResumeStarted events.
  774.      *  COR_PRF_SUSPEND_FOR_APPDOMAIN_SHUTDOWN
  775.      *      the runtime is suspending so that an AppDomain can be shut down.
  776.      *      While the runtime is suspended, the runtime will determine which
  777.      *      threads are in the AppDomain that is being shut down, set them to
  778.      *      abort when they resume, and then resumes the runtime.  There are
  779.      *      no AppDomain-specific callbacks during this suspension.
  780.      *  COR_PRF_SUSPEND_FOR_SHUTDOWN
  781.      *      the runtime is shutting down, and it must suspend all threads to
  782.      *      complete the operation.
  783.      *  COR_PRF_SUSPEND_OTHER
  784.      *      the runtime is suspending for a reason other than those above.
  785.      */
  786.     HRESULT RuntimeSuspendStarted(
  787.             [in] COR_PRF_SUSPEND_REASON suspendReason);
  788.  
  789.     /*
  790.      * The COM+ Runtime calls SyncForSuspendFinished to notify the code profiler
  791.      * that the runtime has suspended all threads needed for a runtime
  792.      * suspension.  Note that not all runtime threads are required to be
  793.      * suspended, as described in the comment for SyncForSuspendStarted.
  794.      *
  795.      * NOTE: It is guaranteed that this event will occur on the same ThreadID
  796.      * as RuntimeSuspendStarted occurred on.
  797.      */
  798.     HRESULT RuntimeSuspendFinished();
  799.  
  800.     /*
  801.      * The COM+ Runtime calls RuntimeSuspendAborted to notify the code profiler
  802.      * that the runtime is aborting the runtime suspension that was occurring.
  803.      * This may occur if two threads simultaneously attempt to suspend the
  804.      * runtime.
  805.      *
  806.      * NOTE: It is guaranteed that this event will occur on the same ThreadID
  807.      * as the RuntimeSuspendStarted occurred on, and that only one of
  808.      * RuntimeSuspendFinished and RuntimeSuspendAborted may occur on a single
  809.      * thread following a RuntimeSuspendStarted event.
  810.      */
  811.     HRESULT RuntimeSuspendAborted();
  812.  
  813.     /*
  814.      * The COM+ Runtime calls RuntimeResumeStarted to notify the code profiler
  815.      * that the runtime is about to resume all of the runtime threads.
  816.      *
  817.      * NOTE: It is guaranteed that this event will occur on the same ThreadID
  818.      * as the RuntimeSuspendStarted occurred on.
  819.      */
  820.     HRESULT RuntimeResumeStarted();
  821.  
  822.     /*
  823.      * The COM+ Runtime calls RuntimeResumeFinished to notify the code profiler
  824.      * that the runtime has finished resuming all of it's threads and is now
  825.      * back in normal operation.
  826.      *
  827.      * NOTE: It is guaranteed that this event will occur on the same ThreadID
  828.      * as the RuntimeSuspendStarted occurred on.
  829.      */
  830.     HRESULT RuntimeResumeFinished();
  831.  
  832.     /*
  833.      * The COM+ Runtime calls ThreadSuspended to notify the code profiler
  834.      * that a particular thread has been suspended.  All threads within managed
  835.      * code must be suspended.  If a thread is in unmanaged code, it will be
  836.      * allowed to continue, but will suspend upon re-entering the runtime
  837.      * and will fire this event.  Thus, this notification could occur after
  838.      * a suspension has completed, but before the runtime resumes.
  839.      */
  840.     HRESULT RuntimeThreadSuspended(
  841.                     [in] ThreadID threadId);
  842.  
  843.     /*
  844.      * The COM+ Runtime calls ThreadResumed to notify the code profiler
  845.      * that a particular thread has been resumed after being suspended due to
  846.      * a runtime suspension.
  847.      */
  848.     HRESULT RuntimeThreadResumed(
  849.                     [in] ThreadID threadId);
  850.  
  851.     /*
  852.      *
  853.      * GC EVENTS
  854.      *
  855.      */
  856.  
  857.     /*
  858.      * The COM+ Runtime calls MovedReferences with information about
  859.      * object references that moved as a result of garbage collection.
  860.      *
  861.      * cMovedObjectIDRanges is a count of the number of ObjectID ranges that
  862.      *      were moved.
  863.      * oldObjectIDRangeStart is an array of elements, each of which is the start
  864.      *      value of a range of ObjectID values before being moved.
  865.      * newObjectIDRangeStart is an array of elements, each of which is the start
  866.      *      value of a range of ObjectID values after being moved.
  867.      * cObjectIDRangeLength is an array of elements, each of which states the
  868.      *      size of the moved ObjectID value range.
  869.      *
  870.      * The last three arguments of this function are parallel arrays.
  871.      *
  872.      * In other words, if an ObjectID value lies within the range
  873.      *      oldObjectIDRangeStart[i] <= ObjectID < oldObjectIDRangeStart[i] + cObjectIDRangeLength[i] 
  874.      * for 0 <= i < cMovedObjectIDRanges, then the ObjectID value has changed to
  875.      *      ObjectID - oldObjectIDRangeStart[i] + newObjectIDRangeStart[i] 
  876.      *
  877.      * NOTE: All of these callbacks are made while the runtime is suspended, so
  878.      *       none of the ObjectID values can change until the runtime resumes
  879.      *       and another GC occurs.
  880.      */
  881.     HRESULT MovedReferences(
  882.                 [in]                                ULONG    cMovedObjectIDRanges,
  883.                 [in, size_is(cMovedObjectIDRanges)] ObjectID oldObjectIDRangeStart[] ,
  884.                 [in, size_is(cMovedObjectIDRanges)] ObjectID newObjectIDRangeStart[] ,
  885.                 [in, size_is(cMovedObjectIDRanges)] ULONG    cObjectIDRangeLength[] );
  886.  
  887.     /*
  888.      * The COM+ Runtime calls ObjectAllocated to notify the code profiler
  889.      * an object was allocated on the heap.
  890.      * CURRENT STATUS:  E_NOTIMPL
  891.      */
  892.     HRESULT ObjectAllocated(
  893.                 [in] ObjectID objectId,
  894.                 [in] ClassID classId);
  895.  
  896.     /*
  897.      * The COM+ Runtime calls ObjectsAllocatedByClass to notify the code
  898.      * profiler about the number of objects of a particular class that were
  899.      * allocated since the previous garbage collection. The classes and the
  900.      * counts are passed in parallel arrays.
  901.      */
  902.     HRESULT ObjectsAllocatedByClass(
  903.                 [in]                       ULONG   cClassCount,
  904.                 [in, size_is(cClassCount)] ClassID classIds[] ,
  905.                 [in, size_is(cClassCount)] ULONG   cObjects[] );
  906.  
  907.     /*
  908.      * The COM+ Runtime calls ObjectReferences to provide information
  909.      * about objects in memory referenced by a given object.  This function
  910.      * is called for each object remaining in the GC heap after a collection
  911.      * has completed.  If the profiler returns an error from this callback,
  912.      * the profiling services will discontinue invoking this callback until the
  913.      * next GC.  This callback can be used in conjunction with the
  914.      * RootReferences callback to create a complete object reference graph for
  915.      * the runtime.
  916.      */
  917.     HRESULT ObjectReferences(
  918.                 [in]                       ObjectID objectId,
  919.                 [in]                       ClassID  classId,
  920.                 [in]                       ULONG    cObjectRefs,
  921.                 [in, size_is(cObjectRefs)] ObjectID objectRefIds[] );
  922.  
  923.     /*
  924.      * The COM+ Runtime calls RootReferences with information about root
  925.      * references after a garbage collection has occurred. Static object
  926.      * references and references to objects on a stack are co-mingled in the
  927.      * arrays.
  928.      */
  929.     HRESULT RootReferences(
  930.                 [in]                     ULONG    cRootRefs,
  931.                 [in, size_is(cRootRefs)] ObjectID rootRefIds[] );
  932.  
  933.  
  934.     /*
  935.      *
  936.      * SECURITY EVENTS
  937.      *
  938.      */
  939.  
  940.  
  941.     /*
  942.      * The COM+ Runtime calls SecurityCheck to notify the code profiler
  943.      * that a security check occurred.
  944.      * CURRENT STATUS:  E_NOTIMPL
  945.      */
  946.     HRESULT SecurityCheck(
  947.                 [in] ThreadID threadId);
  948.  
  949.  
  950.     /*
  951.      *
  952.      * EXCEPTION EVENTS
  953.      *
  954.      */
  955.  
  956.     //
  957.     // Exception creation
  958.     //
  959.  
  960.     /*
  961.      * The COM+ Runtime calls ExceptionThrown to notify the code
  962.      * profiler that an exception has been thrown.
  963.      * NOTE: This function is only called if the COM+ Runtime exception handler
  964.      *       is called to process an exception.
  965.      */
  966.     HRESULT ExceptionThrown(
  967.                 [in] ObjectID thrownObjectId);
  968.  
  969.     //
  970.     // Search phase
  971.     //
  972.  
  973.     /*
  974.      * The COM+ Runtime calls ExceptionSearchFunctionEnter to notify the profiler
  975.      * that the search phase of exception handling has entered a function.
  976.      */
  977.     HRESULT ExceptionSearchFunctionEnter(
  978.                 [in] FunctionID functionId);
  979.  
  980.     /*
  981.      * The COM+ Runtime calls ExceptionSearchFunctionLeave to notify the profiler
  982.      * that the search phase of exception handling has left a function.
  983.      */
  984.     HRESULT ExceptionSearchFunctionLeave();
  985.  
  986.     /*
  987.      * The COM+ Runtime will call ExceptionSearchFilterEnter just before excecuting
  988.      * a user filter.  The functionID is that of the function containing the filter.
  989.      */
  990.     HRESULT ExceptionSearchFilterEnter(
  991.                 [in] FunctionID functionId);
  992.  
  993.     /*
  994.      * The COM+ Runtime will call ExceptionSearchFilterLeave immediately after
  995.      * executing a user filter.
  996.      */
  997.     HRESULT ExceptionSearchFilterLeave();
  998.  
  999.     /*
  1000.      * The COM+ Runtime will call ExceptionSearchCatcherFound when the search
  1001.      * phase of exception handling has located a handler for the exception that
  1002.      * was thrown.
  1003.      */
  1004.     HRESULT ExceptionSearchCatcherFound(
  1005.                 [in] FunctionID functionId);
  1006.  
  1007.     /*
  1008.      * The COM+ Runtime calls ExceptionHandlerEnter when the runtime's
  1009.      * [Win32 SEH] exception handler is entered AND there is at least one 
  1010.      * JIT'ed function guarded by that instance of the handler.  This function
  1011.      * will not be called if there is no managed code guarded by the instance
  1012.      * of the handler, nor if there is only internal runtime code guarded by
  1013.      * the instance of the handler.
  1014.      * This notification is provided to allow profilers to detect unmanaged-to-
  1015.      * managed transitions in stack searches and unwinds.
  1016.      * The functionID is that of the first function encountered on the search
  1017.      * or unwind.
  1018.      *
  1019.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1020.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1021.      *       profiler blocks here and a GC is attempted, the runtime will block
  1022.      *       until this callback returns.  Also, the profiler may NOT call into
  1023.      *       managed code or in any way cause a managed memory allocation.
  1024.      *       @TODO: Also, this callback may currently be innacurate - this will
  1025.      *       be addressed at a later date.
  1026.      */
  1027.     HRESULT ExceptionOSHandlerEnter(
  1028.                 [in] FunctionID functionId);
  1029.  
  1030.     /*
  1031.      * This function is similar to ExceptionHandlerEnter, except that
  1032.      * it is called just before the runtime's exception handler returns.
  1033.      * The functionID is that of the last function encountered on the search
  1034.      * or unwind.
  1035.      *
  1036.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1037.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1038.      *       profiler blocks here and a GC is attempted, the runtime will block
  1039.      *       until this callback returns.  Also, the profiler may NOT call into
  1040.      *       managed code or in any way cause a managed memory allocation.
  1041.      *       @TODO: Also, this callback may currently be innacurate - this will
  1042.      *       be addressed at a later date.
  1043.      */
  1044.     HRESULT ExceptionOSHandlerLeave(
  1045.                 [in] FunctionID functionId);
  1046.  
  1047.     //
  1048.     // Unwind phase
  1049.     //
  1050.  
  1051.     /*
  1052.      * The COM+ Runtime calls ExceptionUnwindFunctionEnter to notify the profiler
  1053.      * that the unwind phase of exception handling has entered a function.
  1054.      *
  1055.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1056.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1057.      *       profiler blocks here and a GC is attempted, the runtime will block
  1058.      *       until this callback returns.  Also, the profiler may NOT call into
  1059.      *       managed code or in any way cause a managed memory allocation.
  1060.      */
  1061.     HRESULT ExceptionUnwindFunctionEnter(
  1062.                 [in] FunctionID functionId);
  1063.  
  1064.     /*
  1065.      * The COM+ Runtime calls ExceptionUnwindFunctionLeave to notify the profiler
  1066.      * that the unwind phase of exception handling has left a function.  The
  1067.      * function instance and it's stack data has now been removed from the stack.
  1068.      *
  1069.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1070.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1071.      *       profiler blocks here and a GC is attempted, the runtime will block
  1072.      *       until this callback returns.  Also, the profiler may NOT call into
  1073.      *       managed code or in any way cause a managed memory allocation.
  1074.      */
  1075.     HRESULT ExceptionUnwindFunctionLeave();
  1076.  
  1077.     /*
  1078.      * The COM+ Runtime calls ExceptionUnwindFinallyEnter to notify the profiler
  1079.      * that the unwind phase of exception is entering a finally clause contained
  1080.      * in the specified function.
  1081.      *
  1082.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1083.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1084.      *       profiler blocks here and a GC is attempted, the runtime will block
  1085.      *       until this callback returns.  Also, the profiler may NOT call into
  1086.      *       managed code or in any way cause a managed memory allocation.
  1087.      */
  1088.     HRESULT ExceptionUnwindFinallyEnter(
  1089.                 [in] FunctionID functionId);
  1090.  
  1091.     /*
  1092.      * The COM+ Runtime calls ExceptionUnwindFinallyLeave to notify the profiler
  1093.      * that the unwind phase of exception is leaving a finally clause.
  1094.      *
  1095.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1096.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1097.      *       profiler blocks here and a GC is attempted, the runtime will block
  1098.      *       until this callback returns.  Also, the profiler may NOT call into
  1099.      *       managed code or in any way cause a managed memory allocation.
  1100.      */
  1101.     HRESULT ExceptionUnwindFinallyLeave();
  1102.  
  1103.     /*
  1104.      * The COM+ Runtime calls this function just before passing control to 
  1105.      * the appropriate catch block.  Note that this is called only if the 
  1106.      * catch point is in JIT'ed code.  An exception that is caught in 
  1107.      * unmanaged code, or in the internal code of the COM+ runtime will
  1108.      * not generate this notification.  The ObjectID is passed again since
  1109.      * a GC could have moved the object since the ExceptionThrown
  1110.      * notification.
  1111.      *
  1112.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1113.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1114.      *       profiler blocks here and a GC is attempted, the runtime will block
  1115.      *       until this callback returns.  Also, the profiler may NOT call into
  1116.      *       managed code or in any way cause a managed memory allocation.
  1117.      */
  1118.     HRESULT ExceptionCatcherEnter(
  1119.                 [in] FunctionID functionId,
  1120.                 [in] ObjectID   objectId);
  1121.  
  1122.     /*
  1123.      * The COM+ Runtime calls ExceptionCatcherLeave when the runtime leaves
  1124.      * the catcher's code.
  1125.      *
  1126.      * NOTE: The profiler cannot block here, since the stack may not be in a
  1127.      *       GC-friendly state and so preemptive GC cannot be enabled.  If the
  1128.      *       profiler blocks here and a GC is attempted, the runtime will block
  1129.      *       until this callback returns.  Also, the profiler may NOT call into
  1130.      *       managed code or in any way cause a managed memory allocation.
  1131.      */
  1132.     HRESULT ExceptionCatcherLeave();
  1133.  
  1134.     /*
  1135.      *  CCW creation/destruction.
  1136.      */
  1137.  
  1138.     /*
  1139.      * The COM+ Runtime calls this function when a CCW is created.
  1140.      * @TODO incorrectly implemented, fix needed.
  1141.      */
  1142.     HRESULT COMClassicWrapperCreated(
  1143.                [in] ClassID wrappedClassId,
  1144.                [in] REFGUID implementedIID,
  1145.                [in] void    *pUnk,
  1146.                [in] ULONG   cSlots);
  1147.  
  1148.     /*
  1149.      * The COM+ Runtime calls this function when a CCW is destroyed.
  1150.      * @TODO incorrectly implemented, fix needed.
  1151.      */
  1152.     HRESULT COMClassicWrapperDestroyed(
  1153.                [in] ClassID wrappedClassId,
  1154.                [in] REFGUID implementedIID,
  1155.                [in] void    *pUnk);
  1156. }
  1157.  
  1158. /*
  1159.  * The COM+ Runtime implements the ICorProfilerInfo interface. This interface is
  1160.  * used by a code profiler to communicate with the COM+ Runtime to control event
  1161.  * monitoring and request information. The COM+ Runtime passes an
  1162.  * ICorProfilerInfo interface to each code profiler during initialization.
  1163.  *
  1164.  * A code profiler can call methods on the ICorProfilerInfo interface to get
  1165.  * information about managed code being executed under the control of the COM+
  1166.  * Runtime.
  1167.  *
  1168.  * The ICorProfilerInfo interface implemented by the COM+ Runtime uses the free
  1169.  * threaded model. Events are dispatched from within the COM+ Runtime or on a
  1170.  * thread that is making the code profiler method call. Interface methods
  1171.  * implemented by the COM+ Runtime can be called from any thread (that has been
  1172.  * CoInitialized) at any time.
  1173.  *
  1174.  * The methods implemented on this interface return S_OK on success, or E_FAIL
  1175.  * on failure.
  1176.  *
  1177.  * For parameters returned from these methods that are [out] buffer parameters
  1178.  * filled with pointers to buffers (and not NULL pointers), these objects were
  1179.  * allocated by the runtime using CoTaskMemAlloc. The code profiler must free
  1180.  * these objects using calls to CoTaskMemFree.
  1181.  */
  1182.  
  1183. [
  1184.     object,
  1185.     uuid(B1CD9EB3-1F6F-11d3-8F74-00A0C9B4D50C),
  1186.     pointer_default(unique),
  1187.     local
  1188. interface ICorProfilerInfo : IUnknown
  1189. {
  1190.     /*
  1191.      * The code profiler calls GetClassFromObject to obtain the ClassID of an
  1192.      * object given its ObjectID.
  1193.      */
  1194.     HRESULT GetClassFromObject(
  1195.                 [in]  ObjectID objectId,
  1196.                 [out] ClassID *pClassId);
  1197.  
  1198.     /*
  1199.      * The code profiler calls GetClassFromToken to obtain the ClassID of a
  1200.      * class given its metadata.
  1201.      */
  1202.     HRESULT GetClassFromToken(
  1203.                 [in]  ModuleID  moduleId,
  1204.                 [in]  mdTypeDef typeDef,
  1205.                 [out] ClassID   *pClassId);
  1206.  
  1207.     /*
  1208.      * The code profiler calls GetCodeInfo to obtain information about a
  1209.      * JIT-compiled function.
  1210.      *
  1211.      * An error will be returned if GetCodeInfo is called with a FunctionID
  1212.      * for a function that has not been JIT-compiled.
  1213.      */
  1214.     HRESULT GetCodeInfo(
  1215.                 [in]  FunctionID functionId,
  1216.                 [out] LPCBYTE    *pStart,
  1217.                 [out] ULONG      *pcSize);
  1218.  
  1219.     /*
  1220.      * The code profiler calls GetEventMask to obtain the current event
  1221.      * categories for which it is to receive event notifications from the COM+
  1222.      * Runtime.
  1223.      */
  1224.     HRESULT GetEventMask(
  1225.                 [out] DWORD *pdwEvents);
  1226.  
  1227.     /*
  1228.      * The code profiler calls GetFunctionFromIP to map an instruction pointer
  1229.      * in managed code to a FunctionID.
  1230.      */
  1231.     HRESULT GetFunctionFromIP(
  1232.                 [in]  BYTE*      ip,
  1233.                 [out] FunctionID *pFunctionId);
  1234.  
  1235.     /*
  1236.      * The code profiler calls GetFunctionFromToken to obtain the FunctionID of
  1237.      * a function given its metadata.
  1238.      */
  1239.     HRESULT GetFunctionFromToken(
  1240.                 [in]  ModuleID   moduleId,
  1241.                 [in]  mdToken    token,
  1242.                 [out] FunctionID *pFunctionId);
  1243.  
  1244.     /*
  1245.      * The code profiler calls GetHandleFromThread to map a ThreadID to a Win32
  1246.      * thread handle.
  1247.      */
  1248.     HRESULT GetHandleFromThread(
  1249.                 [in]  ThreadID threadId,
  1250.                 [out] HANDLE  *phThread);
  1251.  
  1252.     /*
  1253.      * The code profiler calls GetObjectSize to obtain the size of an object.
  1254.      */
  1255.     HRESULT GetObjectSize(
  1256.                 [in]  ObjectID objectId,
  1257.                 [out] ULONG32  *pcSize);
  1258.  
  1259.     /*
  1260.      * The code profiler calls GetClassInfo to obtain the size of static data in
  1261.      * a class.
  1262.      * CURRENT STATUS:  E_NOTIMPL
  1263.      */
  1264.     HRESULT GetStaticClassSize(
  1265.                 [in]  ClassID classId,
  1266.                 [out] ULONG   *pcStaticSize);
  1267.  
  1268.     /*
  1269.      * The code profiler calls GetThreadInfo to obtain the Win32 thread ID for
  1270.      * the specified thread.
  1271.      */
  1272.     HRESULT GetThreadInfo(
  1273.                 [in]  ThreadID threadId,
  1274.                 [out] DWORD    *pdwWin32ThreadId);
  1275.  
  1276.     /*
  1277.      * The code profiler calls GetCurrentThreadID to get the managed thread ID
  1278.      * for the current thread.
  1279.      */
  1280.     HRESULT GetCurrentThreadID(
  1281.                 [out] ThreadID *pThreadId);
  1282.  
  1283.     /*
  1284.      * Returns the parent module a class is defined in, along with the
  1285.      * metadata token for the class.  One can hook the ModuleLoadStarted
  1286.      * event to obtain the metadata interface for a given module.  The token
  1287.      * can then be used to access the metadata for this class.
  1288.      */
  1289.     HRESULT GetClassIDInfo(
  1290.                 [in]  ClassID   classId,
  1291.                 [out] ModuleID  *pModuleId,
  1292.                 [out] mdTypeDef *pTypeDefToken);
  1293.  
  1294.     /*
  1295.      * Return the parent class for a given function.  Also return the metadata
  1296.      * token which can be used to read the metadata.
  1297.      */
  1298.     HRESULT GetFunctionInfo(
  1299.                 [in]  FunctionID functionId,
  1300.                 [out] ClassID    *pClassId,
  1301.                 [out] ModuleID   *pModuleId,
  1302.                 [out] mdToken    *pToken);
  1303.  
  1304.     /*
  1305.      * The code profiler calls SetEventMask to sets the event categories for
  1306.      * which it is set to receive notification from the COM+ Runtime.
  1307.      */
  1308.     HRESULT SetEventMask(
  1309.                 [in] DWORD dwEvents);
  1310.  
  1311.     /*
  1312.      * The code profiler calls SetFunctionHooks to specify its own callback
  1313.      * replacements for ICorProfilerCallback::FunctionEntry,
  1314.      * ICorProfilerCallback::FunctionExit and
  1315.      * ICorProfilerCallback::FunctionTailcall
  1316.      */
  1317.     HRESULT SetEnterLeaveFunctionHooks(
  1318.                 [in] FunctionEnter    *pFuncEnter,
  1319.                 [in] FunctionLeave    *pFuncLeave,
  1320.                 [in] FunctionTailcall *pFuncTailcall);
  1321.  
  1322.     /*
  1323.      * This is used for mapping FunctionIDs to alternative values that will be
  1324.      * passed to the callbacks
  1325.      */
  1326.     HRESULT SetFunctionIDMapper(
  1327.                 [in] FunctionIDMapper *pFunc);
  1328.  
  1329.     /*
  1330.      * The code profiler calls SetILMapFlag to request the COM+ Runtime to
  1331.      * maintain information about IL mapping. This information is used to map an
  1332.      * instruction pointer to an internal point within a function. 
  1333.      *
  1334.      * Note. The debugger uses the same IL mapping information.
  1335.      * CURRENT STATUS:  E_NOTIMPL
  1336.      */
  1337.     HRESULT SetILMapFlag();
  1338.     
  1339.     
  1340.     /*
  1341.      * For a given function, retrieve the token value and an instance of the
  1342.      * meta data interface which can be used against this token.
  1343.      */
  1344.     HRESULT GetTokenAndMetaDataFromFunction(
  1345.                 [in]  FunctionID functionId,
  1346.                 [in]  REFIID     riid,
  1347.                 [out] IUnknown   **ppImport,
  1348.                 [out] mdToken    *pToken);
  1349.  
  1350.     /*
  1351.      * Retrieve information about a given module.
  1352.      */
  1353.     HRESULT GetModuleInfo(
  1354.                 [in]  ModuleID   moduleId,
  1355.                 [out] LPCBYTE    *ppBaseLoadAddress,
  1356.                 [in]  ULONG32    cchName, 
  1357.                 [out] ULONG32    *pcchName,
  1358.                 [out, size_is(cchName), length_is(*pcchName)] 
  1359.                       WCHAR      szName[] ,
  1360.                 [out] mdModule   *pModuleToken,
  1361.                 [out] AssemblyID *pAssemblyId);
  1362.  
  1363.     /*
  1364.      * Get a metadata interface instance which maps to the given module.
  1365.      * One may ask for the metadata to be opened in read+write mode, but
  1366.      * this will result in slower metadata execution of the program, because
  1367.      * changes made to the metadata cannot be optimized as they were from
  1368.      * the compiler.
  1369.      */
  1370.     HRESULT GetModuleMetaData(
  1371.                 [in]  ModuleID moduleId,
  1372.                 [in]  DWORD    dwOpenFlags,
  1373.                 [in]  REFIID   riid,
  1374.                 [out] IUnknown **ppOut);
  1375.  
  1376.     /*
  1377.      * Retrieve a pointer to the body of a method starting at it's header.
  1378.      * A method is coped by the module it lives in.  Because this function
  1379.      * is designed to give a tool access to IL before it has been loaded
  1380.      * by the Runtime, it uses the metadata token of the method to find
  1381.      * the instance desired.  Note that this function has no effect on
  1382.      * already compiled code.
  1383.      *
  1384.      * GetILFunctionBody can return CORPROF_E_FUNCTION_NOT_IL if the methodId
  1385.      * points to a method without any IL (such as an abstract method, or a
  1386.      * P/Invoke method).
  1387.      */
  1388.     HRESULT GetILFunctionBody(
  1389.                 [in]  ModuleID    moduleId,
  1390.                 [in]  mdMethodDef methodId,
  1391.                 [out] LPCBYTE     *ppMethodHeader,
  1392.                 [out] ULONG       *pcbMethodSize);
  1393.  
  1394.     /*
  1395.      * IL method bodies must be located as RVA's to the loaded module, which
  1396.      * means they come after the module within 4 gb.  In order to make it
  1397.      * easier for a tool to swap out the body of a method, this allocator
  1398.      * will ensure memory is allocated after that point.
  1399.      */
  1400.     HRESULT GetILFunctionBodyAllocator(
  1401.                 [in]  ModuleID      moduleId,
  1402.                 [out] IMethodMalloc **ppMalloc);
  1403.  
  1404.     /*
  1405.      * Replaces the method body for a function in a module.  This will replace
  1406.      * the RVA of the method in the metadata to point to this new method body,
  1407.      * and adjust any internal data structures as required.  This function can
  1408.      * only be called on those methods which have never been compiled by a JITTER.
  1409.      * Please use the GetILFunctionAllocator to allocate space for the new method to
  1410.      * ensure the buffer is compatible.
  1411.      */
  1412.     HRESULT SetILFunctionBody(
  1413.                 [in] ModuleID    moduleId,
  1414.                 [in] mdMethodDef methodid,
  1415.                 [in] LPCBYTE     pbNewILMethodHeader);
  1416.  
  1417.     /*
  1418.      * Retrieve app domain information given its id.
  1419.      */
  1420.     HRESULT GetAppDomainInfo(
  1421.                 [in]  AppDomainID appDomainId,
  1422.                 [in]  ULONG32     cchName, 
  1423.                 [out] ULONG32     *pcchName,
  1424.                 [out, size_is(cchName), length_is(*pcchName)] 
  1425.                       WCHAR       szName[] ,
  1426.                 [out] ProcessID   *pProcessId);
  1427.  
  1428.     /*
  1429.      * Retrieve information about an assembly given its ID.
  1430.      */
  1431.     HRESULT GetAssemblyInfo(
  1432.                 [in]  AssemblyID  assemblyId,
  1433.                 [in]  ULONG32     cchName, 
  1434.                 [out] ULONG32     *pcchName,
  1435.                 [out, size_is(cchName), length_is(*pcchName)] 
  1436.                       WCHAR       szName[] ,
  1437.                 [out] AppDomainID *pAppDomainId,
  1438.                 [out] ModuleID    *pModuleId);
  1439.  
  1440.  
  1441.     /*
  1442.      * Marks a function as requiring a re-JIT.  The function will be re-JITted
  1443.      * at its next invocation.  The normal profiller events will give the profiller
  1444.      * an opportunity to replace the IL prior to the JIT.  By this means, a tool
  1445.      * can effectively replace a function at runtime.  Note that active instances
  1446.      * of the function are not affected by the replacement.
  1447.      *
  1448.      * NOTE: memory used by the current jitted code for this method will not be
  1449.      *       released, as it may currently be in use by one or more threads and
  1450.      *       may have associated data on the stack.
  1451.      */
  1452.     HRESULT SetFunctionReJIT(
  1453.                 [in] FunctionID functionId);
  1454.  
  1455.     /*
  1456.      * ForceGC forces a GC to occur within the runtime.
  1457.      * CURRENT STATUS: E_NOTIMPL
  1458.      */
  1459.     HRESULT ForceGC();
  1460.  
  1461.     /*
  1462.      * fStartJit should be set to true to indicate that the invocation is in advance
  1463.      *      of JITting the function.  If this is merely to say that the
  1464.      *      function's map is changing, it should be false.
  1465.      *
  1466.      * The format of the map is as follows: 
  1467.      *      The debugger will assume that each oldOffset refers to an IL offset
  1468.      *  within the original, unmodified IL code.  newOffset refers to the corresponding
  1469.      *  IL offset within the new, instrumented code. 
  1470.      *      If the offset of the original IL is exactly equal to an oldOffset, then
  1471.      *  it's new offset within the instrumented code is given by newOffset.  If the
  1472.      *  original offset isn't exactly equal, then the new offset is equal to 
  1473.      *  
  1474.      *      rgILMapEntries[i] .newOffset - rgILMapEntries[i] .oldOffset + original offset
  1475.      *
  1476.      *  where
  1477.      *
  1478.      *      0 <= i < cILMapEntries, and rgILMapEntries[i] .oldOffset < original offset,
  1479.      *  and there does not exist a j  such that
  1480.      *
  1481.      *      rgILMapEntries[i] .oldOffset < rgILMapEntries[j] .oldOffset < original offset
  1482.      */
  1483.     HRESULT SetILInstrumentedCodeMap(
  1484.                 [in]                         FunctionID functionId,
  1485.                 [in]                         BOOL       fStartJit,
  1486.                 [in]                         ULONG32    cILMapEntries,
  1487.                 [in, size_is(cILMapEntries)] COR_IL_MAP rgILMapEntries[] );
  1488.  
  1489.     /*
  1490.      * GetInprocInspectionInterface is used to get an interface to the
  1491.      * in-process portion of the debug interface, which is useful for things
  1492.      * like doing a stack trace.  It is expected that the returned interface
  1493.      * will be queried for ICorDebug.
  1494.      *
  1495.      * ppicd: *ppicd will be filled in with a pointer to the interface, or
  1496.      *          NULL if the interface is unavailable.
  1497.      */
  1498.     HRESULT GetInprocInspectionInterface(
  1499.                 [out] IUnknown **ppicd);
  1500.  
  1501.     /*
  1502.      * GetInprocInspectionIThisThread is used to get an interface to the
  1503.      * in-process portion of the debug interface, that is specific to
  1504.      * this thread.  It's expected that the returned interface will be
  1505.      * be queried for ICorDebugThread, which can then be used to immediately
  1506.      * do a stack trace.
  1507.      *
  1508.      * ppicd: *ppicd will be filled in with a pointer to the interface, or
  1509.      *          NULL if the interface is unavailable.
  1510.      */
  1511.     HRESULT GetInprocInspectionIThisThread(
  1512.                 [out] IUnknown **ppicd);
  1513.  
  1514.     /*
  1515.      * This will return the ContextID currently associated with the calling
  1516.      * runtime thread.  This will set pContextId to NULL if the calling thread
  1517.      * is not a runtime thread.
  1518.      */
  1519.     HRESULT GetThreadContext(
  1520.                 [in]  ThreadID  threadId,
  1521.                 [out] ContextID *pContextId);
  1522. }
  1523.  
  1524.  
  1525. /*
  1526.  * This is a very, very simple allocator that only allows you to allocate
  1527.  * memory.  You may not free it.  This should be used in conjunction with
  1528.  * SetILFunctionBody.
  1529.  */
  1530. [
  1531.     object,
  1532.     uuid(01B627FC-1FA5-11d3-8F75-00A0C9B4D50C),
  1533.     pointer_default(unique),
  1534.     local
  1535. interface IMethodMalloc : IUnknown
  1536. {
  1537.     void *Alloc( 
  1538.                 [in] ULONG cb);
  1539. }
  1540.