class __declspec()

in src/InstrumentationEngine/ModuleInfo.h [20:243]


    class __declspec(uuid("CDD3824F-B876-4450-9459-885BA1C21540"))
    CModuleInfo : public IModuleInfo3, public CDataContainer
    {
    private:
        class CMethodKey
        {
        public:

            mdMethodDef m_token;
            FunctionID m_functionID;

            CMethodKey(mdMethodDef token, FunctionID functionId) : m_token(token), m_functionID(functionId) {}

            bool operator==(const CMethodKey& other) const
            {
                return m_token == other.m_token && m_functionID == other.m_functionID;
            }

            struct Hash
            {
                size_t operator()(const CMethodKey& key) const
                {
                    return key.m_token ^ key.m_functionID;
                }
            };
        };
    private:
        // Non-addref'd back pointer the profiler manager.
        CProfilerManager* m_pProfilerManager;

        CRITICAL_SECTION m_cs;

        ModuleID m_moduleID;
        CComBSTR m_bstrModulePath;
        CComBSTR m_bstrModuleName;
        GUID m_mvid;
        bool m_bIs64bit;
        bool m_bIsIlOnly;
        bool m_bIsMscorlib;
        bool m_bIsDynamic;
        bool m_bIsLoadedFromDisk;
        bool m_bIsNgen;
        bool m_bIsWinRT;
        bool m_bIsFlatLayout;

        const IMAGE_COR20_HEADER* m_pCorHeader;
        mdMemberRef m_tkEntrypoint;

        // Note circular reference to assembly info and appdomain info
        // broken when module unload is received
        CComPtr<IAssemblyInfo> m_pAssemblyInfo;
        CComPtr<IAppDomainInfo> m_pAppDomainInfo;

        LPCBYTE m_pModuleBaseLoadAddress;
        LPCBYTE m_pbSectionStart;
        WORD m_numSections;

        CAutoPtr<VS_FIXEDFILEINFO> m_pFixedFileVersion;

        CComPtr<IMetaDataImport2> m_pMetadataImport;
        CComPtr<IMetaDataAssemblyImport> m_pMetadataAssemblyImport;
        CComPtr<IMetaDataEmit2> m_pMetaDataEmit2;
        CComPtr<IMetaDataAssemblyEmit> m_pMetaDataAssemblyEmit;

        unordered_map<FunctionID, CComPtr<CMethodInfo>> m_methodInfos;
        unordered_map<mdMethodDef, CComPtr<CMethodInfo>> m_methodInfosByToken;

        unordered_map<mdToken, std::shared_ptr<CCachedILMethodBody>> m_methodTokenToCachedILMap;
        unordered_set<mdMethodDef> m_instrumentedMethods;
        unordered_map<CMethodKey, CSharedArray<COR_IL_MAP>, CMethodKey::Hash> m_ilMaps;

        CComPtr<ITypeCreator> m_pTypeFactory;

        // Map the method token to the number of times that method has rejitted.
        // Note this is not the same as the CLR's REJITID becase it is not functionid
        // specific
        unordered_map<mdToken, UINT32> m_methodTokenToRejitCountMap;

        // Map used to track where methods from this module have been inlined into.
        CComPtr<CInlineSiteMap> m_pInlineSiteMap;

    public:
        DEFINE_DELEGATED_REFCOUNT_ADDREF(CModuleInfo);
        DEFINE_DELEGATED_REFCOUNT_RELEASE(CModuleInfo);
        STDMETHOD(QueryInterface)(_In_ REFIID riid, _Out_ void **ppvObject) override
        {
            return ImplQueryInterface(
                static_cast<IModuleInfo3*>(this),
                static_cast<IModuleInfo2*>(this),
                static_cast<IModuleInfo*>(this),
                static_cast<IDataContainer*>(static_cast<CDataContainer*>(this)),
                riid,
                ppvObject
            );
        }

    public:
        CModuleInfo(_In_ CProfilerManager* pProfilerManager);
        ~CModuleInfo();

        HRESULT Initialize(
            _In_ ModuleID moduleID,
            _In_ const WCHAR* wszModulePath,
            _In_ IAssemblyInfo* pAssemblyInfo,
            _In_ IAppDomainInfo* pAppDomainInfo,
            _In_ LPCBYTE pModuleBaseLoadAddress,
            _In_ IMetaDataImport2* pMetadataImport,
            _In_ IMetaDataAssemblyImport* pMetadataAssemblyImport,
            _In_ IMetaDataEmit2* pMetaDataEmit2,
            _In_ IMetaDataAssemblyEmit* pMetaDataAssemblyEmit
            );

        HRESULT Dispose();

    public:
        HRESULT GetMethodInfoById(_In_ FunctionID functionId, CMethodInfo** ppMethodInfo);
        HRESULT GetMethodInfoByToken(_In_ mdToken methodToken, CMethodInfo** ppMethodInfo);

        HRESULT AddMethodInfo(_In_ FunctionID functionId, CMethodInfo* pMethodInfo);
        HRESULT ReleaseMethodInfo(_In_ FunctionID functionId);

        // The profiler apis have issues around rejit request revert and generics
        // If a function is modified by the profiler, GetILFunctionBody may return
        // the modified IL (example: rejit before original jit).
        // So, if any consumer requests the il function body, the original il is cached
        // and resused in requests that come later.
        //
        // NOTE: this is unfortunate as this is yet another copy of the il.
        HRESULT GetMethodIl(
            _In_ ICorProfilerInfo* pCorProfilerInfo,
            _In_ mdToken tkFunction,
            _Out_ IMAGE_COR_ILMETHOD** ppMethodHeader,
            _Out_ ULONG* pcbMethodSize
            );

        HRESULT IncrementMethodRejitCount(_In_ mdToken token);
        HRESULT GetMethodRejitCount(_In_ mdToken token, _Out_ DWORD* pdwRejitCount);

        HRESULT SetRejitMethodInfo(_In_ mdToken token, _In_opt_ CMethodInfo* pMethodInfo);

        HRESULT GetInlineSiteMap(_Out_ CInlineSiteMap** ppInilineSiteMap);

        // Sets the instrumentation map for normal, non rejit scenarios.
        void SetILInstrumentationMap(_In_ CMethodInfo* pMethodInfo, _In_ CSharedArray<COR_IL_MAP> map);

        HRESULT GetILInstrumentationMap(_In_ CMethodJitInfo* pMethodJitInfo, _In_ ULONG32 cMap, _Out_writes_opt_(cMap) COR_IL_MAP* pMap, _Out_ ULONG32* pcNeeded);
        void SetMethodIsTransformed(_In_ mdMethodDef methodDef, bool isInstrumented);
        bool GetIsMethodInstrumented(_In_ mdMethodDef methodDef);

        // IModuleInfo methods
    public:
        virtual HRESULT __stdcall GetModuleName(_Out_ BSTR* pbstrModuleName) override;
        virtual HRESULT __stdcall GetFullPath(_Out_ BSTR* pbstrFullPath) override;

        // Get info about the assembly that contains this module
        virtual HRESULT __stdcall GetAssemblyInfo(_Out_ IAssemblyInfo** pAssemblyInfo) override;

        virtual HRESULT __stdcall GetAppDomainInfo(_Out_ IAppDomainInfo** ppAppDomainInfo) override;

        virtual HRESULT __stdcall GetMetaDataImport(_Out_ IUnknown** ppMetaDataImport) override;
        virtual HRESULT __stdcall GetMetaDataAssemblyImport(_Out_ IUnknown** ppMetaDataAssemblyImport) override;
        virtual HRESULT __stdcall GetMetaDataEmit(_Out_ IUnknown** ppMetaDataEmit) override;
        virtual HRESULT __stdcall GetMetaDataAssemblyEmit(_Out_ IUnknown** ppMetaDataAssemblyEmit) override;

        virtual HRESULT __stdcall GetModuleID(_Out_ ModuleID* pModuleId) override;

        // Get the managed module version id
        virtual HRESULT __stdcall GetMVID(_Out_ GUID* pguidMvid) override;

        virtual HRESULT __stdcall GetIsILOnly(_Out_ BOOL* pbValue) override;
        virtual HRESULT __stdcall GetIsMscorlib(_Out_ BOOL* pbValue) override;
        virtual HRESULT __stdcall GetIsDynamic(_Out_ BOOL* pbValue) override;
        virtual HRESULT __stdcall GetIsNgen(_Out_ BOOL* pbValue) override;
        virtual HRESULT __stdcall GetIsWinRT(_Out_ BOOL* pbValue) override;
        virtual HRESULT __stdcall GetIs64bit(_Out_ BOOL* pbValue) override;

        virtual HRESULT __stdcall GetImageBase(_Out_ LPCBYTE* pbValue) override;

        virtual HRESULT __stdcall  GetCorHeader(_In_ DWORD cbValue, _Out_writes_(cbValue) BYTE* pbValue) override;

        // Returns the modules entrypoint token. If the module has no entrypoint token, returns E_FAIL;
        virtual HRESULT __stdcall GetEntrypointToken(_Out_ DWORD* pdwEntrypointToken) override;

        // Returns the VS_FIXEDFILEINFO for this module.
        virtual HRESULT __stdcall GetModuleVersion(_In_ DWORD cbValue, _Out_writes_(cbValue) BYTE* pbValue) override;

        // Request a rejit on a method
        virtual HRESULT __stdcall RequestRejit(_In_ mdToken methodToken) override;

        virtual HRESULT __stdcall CreateTypeFactory(_Out_ ITypeCreator** ppTypeFactory) override;

        // Allow instrumentation methods to receive an instance of IMethodInfo for a FunctionID.
        // This method info is only for obtaining information about the method and cannot be used
        // for instrumenation.
        virtual HRESULT __stdcall GetMethodInfoById(_In_ FunctionID functionID, _Out_ IMethodInfo** ppMethodInfo) override;

        // Allow instrumentation methods to receive an instance of IMethodInfo for a token.
        // This method info is only for obtaining information about the method and cannot be used
        // for instrumenation.
        virtual HRESULT __stdcall GetMethodInfoByToken(_In_ mdToken token, _Out_ IMethodInfo** ppMethodInfo) override;

        // Import source module into the current one
        virtual HRESULT __stdcall ImportModule(_In_ IUnknown* pSourceModule, _In_ LPCBYTE* pSourceImage) override;

        // IModuleInfo2 methods
    public:
        virtual HRESULT __stdcall GetIsFlatLayout(_Out_ BOOL* pbValue) override;
        virtual HRESULT __stdcall ResolveRva(_In_ DWORD rva, _Out_ LPCBYTE* ppbResolvedAddress) override;

        // IModuleInfo3
    public:
        virtual HRESULT __stdcall GetIsLoadedFromDisk(_Out_ BOOL* pbValue) override;


    private:
        HRESULT GetModuleTypeFlags();
        HRESULT ReadModuleHeaders();
        HRESULT DetermineIfIsMscorlib();
        HRESULT ReadFixedFileVersion();

        HRESULT AddInlineSitesForRejit(_In_ mdToken methodToken, _In_ vector<ModuleID>& moduleIds, _In_ vector<mdToken>& methodTokens);

        HRESULT ResolveRva(_In_ LPCBYTE pbSectionStart, _In_ WORD numSections, _In_ DWORD rva, _Out_ LPCBYTE* ppbResolvedAddress);
    };