The ILStubCache was being allocated per domain unless the domain was a
compilation AppDomain. This is wrong for collectible assemblies, since
after an assembly is collected, the cache keeps stale entries referring
to already deleted MethodTables.
The fix is to make ILStubChange per LoaderAllocator instead (and keep
the per module instances for compilation AppDomain).
Commit migrated from https://github.com/dotnet/coreclr/commit/
8aa0869eb9153429091fdba49469d89ec33092cb
BaseDomain::Init();
- // Set up the IL stub cache
- m_ILStubCache.Init(GetLoaderAllocator()->GetHighFrequencyHeap());
-
// Set up the binding caches
m_AssemblyCache.Init(&m_DomainCacheCrst, GetHighFrequencyHeap());
m_UnmanagedCache.InitializeTable(this, &m_DomainCacheCrst);
#include "domainfile.h"
#include "objectlist.h"
#include "fptrstubs.h"
-#include "ilstubcache.h"
#include "testhookmgr.h"
#include "gcheaputilities.h"
#include "gchandleutilities.h"
DWORD m_TrackSpinLock;
#endif
-
- // IL stub cache with fabricated MethodTable parented by a random module in this AD.
- ILStubCache m_ILStubCache;
-
// The number of times we have entered this AD
ULONG m_dwThreadEnterCount;
// The number of threads that have entered this AD, for ADU only
BOOL IsBindingModelLocked();
BOOL LockBindingModel();
- ILStubCache* GetILStubCache()
- {
- LIMITED_METHOD_CONTRACT;
- return &m_ILStubCache;
- }
-
- static AppDomain* GetDomain(ILStubCache* pILStubCache)
- {
- return CONTAINING_RECORD(pILStubCache, AppDomain, m_ILStubCache);
- }
-
enum {
CONTEXT_INITIALIZED = 0x0001,
USER_CREATED_DOMAIN = 0x0002, // created by call to AppDomain.CreateDomain
}
CONTRACTL_END;
- // Use per-AD cache for domain specific modules when not NGENing
+ // Use per-LoaderAllocator cache for modules when not NGENing
BaseDomain *pDomain = GetDomain();
if (!IsSystem() && !pDomain->IsSharedDomain() && !pDomain->AsAppDomain()->IsCompilationDomain())
- return pDomain->AsAppDomain()->GetILStubCache();
+ return GetLoaderAllocator()->GetILStubCache();
if (m_pILStubCache == NULL)
{
}
else
{
- // otherwise we are associated with the AD
- AppDomain* pStubCacheDomain = AppDomain::GetDomain(this);
- CONSISTENCY_CHECK(pStubCacheDomain == pModule->GetDomain()->AsAppDomain());
+ // otherwise we are associated with the LoaderAllocator
+ LoaderAllocator* pStubLoaderAllocator = LoaderAllocator::GetLoaderAllocator(this);
+ CONSISTENCY_CHECK(pStubLoaderAllocator == pModule->GetLoaderAllocator());
}
#endif // _DEBUG
#else
m_pPrecodeHeap = new (&m_PrecodeHeapInstance) CodeFragmentHeap(this, STUB_CODE_BLOCK_PRECODE);
#endif
+
+ // Set up the IL stub cache
+ m_ILStubCache.Init(m_pHighFrequencyHeap);
}
class FuncPtrStubs;
#include "qcall.h"
+#include "ilstubcache.h"
#define VPTRU_LoaderAllocator 0x3200
// The cache is keyed by MethodDesc pointers.
UMEntryThunkCache * m_pUMEntryThunkCache;
+ // IL stub cache with fabricated MethodTable parented by a random module in this LoaderAllocator.
+ ILStubCache m_ILStubCache;
+
public:
BYTE *GetVSDHeapInitialBlock(DWORD *pSize);
BYTE *GetCodeHeapInitialBlock(const BYTE * loAddr, const BYTE * hiAddr, DWORD minimumSize, DWORD *pSize);
UMEntryThunkCache *GetUMEntryThunkCache();
#endif
+
+ static LoaderAllocator* GetLoaderAllocator(ILStubCache* pILStubCache)
+ {
+ return CONTAINING_RECORD(pILStubCache, LoaderAllocator, m_ILStubCache);
+ }
+
+ ILStubCache* GetILStubCache()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return &m_ILStubCache;
+ }
}; // class LoaderAllocator
typedef VPTR(LoaderAllocator) PTR_LoaderAllocator;