diff options
Diffstat (limited to 'src/vm/mixedmode.hpp')
-rw-r--r-- | src/vm/mixedmode.hpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/vm/mixedmode.hpp b/src/vm/mixedmode.hpp new file mode 100644 index 0000000000..9d5037af8d --- /dev/null +++ b/src/vm/mixedmode.hpp @@ -0,0 +1,139 @@ +// 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. +// =========================================================================== +// File: mixedmode.H +// + +// +// MIXEDMODE.H defines classes to support mixed mode dlls +// =========================================================================== + + +#ifndef _MIXEDMODE_H_ +#define _MIXEDMODE_H_ + +#ifdef FEATURE_MIXEDMODE + +#ifdef _TARGET_X86_ +extern "C" VOID __stdcall IJWNOADThunkJumpTarget(void); +#endif + + +#define IJWNOADThunkStubCacheSize 4 + +struct IJWNOADThunkStubCache +{ + ADID m_AppDomainID; // Must be the first member of the struct. + LPCVOID m_CodeAddr; +}; + + + +// Be sure to keep this structure and the assembly view in sync +class IJWNOADThunk +{ + UMEntryThunkCode m_code; + +protected: + static void __cdecl MakeCall(); + static void SafeNoModule(); + static void NoModule(); + + HMODULE m_pModulebase; + DWORD m_dwIndex; + mdToken m_Token; + + DWORD m_fAccessingCache; + +public: + IJWNOADThunkStubCache m_cache[IJWNOADThunkStubCacheSize]; + + BOOL IsCachedAppDomainID(ADID pID) + { + LIMITED_METHOD_CONTRACT; + + for (int i=0; i < IJWNOADThunkStubCacheSize; i++) + { + if (m_cache[i].m_AppDomainID == pID) + return TRUE; + } + + return FALSE; + }; + + void GetCachedInfo(ADID pID, LPCVOID* pCode) + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + INSTANCE_CHECK; + SO_TOLERANT; + PRECONDITION(CheckPointer(pCode)); + } + CONTRACTL_END; + + *pCode = NULL; + + for (int i=0; i < IJWNOADThunkStubCacheSize; i++) + { + if (m_cache[i].m_AppDomainID == pID) + *pCode = m_cache[i].m_CodeAddr; + } + } + + void SetCachedInfo(ADID pID, LPCVOID pCode) + { + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + MODE_ANY; + INSTANCE_CHECK; + SO_INTOLERANT; + } + CONTRACTL_END; + + YIELD_WHILE (FastInterlockCompareExchange((LONG*)&m_fAccessingCache, 1, 0) != 0); + + // Don't cache if the cache is already full. + for (int i=0; i < IJWNOADThunkStubCacheSize; i++) + { + if (m_cache[i].m_AppDomainID == (ADID)-1) + { + m_cache[i].m_CodeAddr = pCode; + MemoryBarrier(); + m_cache[i].m_AppDomainID = pID; + } + } + + m_fAccessingCache = 0; + } + + static IJWNOADThunk* FromCode(PCODE pCodeAddr) + { + LIMITED_METHOD_CONTRACT; + return (IJWNOADThunk*)(PCODEToPINSTR(pCodeAddr) - offsetof(IJWNOADThunk, m_code) - UMEntryThunkCode::GetEntryPointOffset()); + }; + mdToken GetToken() + { + LIMITED_METHOD_CONTRACT; + return m_Token; + } + + IJWNOADThunk(HMODULE pModulebase, DWORD dwIndex, mdToken Token); + + LPCBYTE GetCode() + { + WRAPPER_NO_CONTRACT; + return m_code.GetEntryPoint(); + } + + LPCVOID IJWNOADThunk::FindThunkTarget(); +}; + +#endif //FEATURE_MIXEDMODE + +#endif // _MIXEDMODE_H_ |