summaryrefslogtreecommitdiff
path: root/src/vm/appdomain.cpp
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2019-04-03 15:54:05 -0700
committerGitHub <noreply@github.com>2019-04-03 15:54:05 -0700
commitd3e39bc2f81e3dbf9e4b96347f62b49d8700336c (patch)
tree78b72499a0f38e9dbf6ae4d6d24c77779ac543dc /src/vm/appdomain.cpp
parenta7dd6192530dec1d424c359233a1b92f559fa92a (diff)
downloadcoreclr-d3e39bc2f81e3dbf9e4b96347f62b49d8700336c.tar.gz
coreclr-d3e39bc2f81e3dbf9e4b96347f62b49d8700336c.tar.bz2
coreclr-d3e39bc2f81e3dbf9e4b96347f62b49d8700336c.zip
Remove ADID and ADIndex from CoreCLR (#23588)
- Remove concept of AppDomain from object api in VM - Various infrastructure around entering/leaving appdomains is removed - Add small implementation of GetAppDomain for use by DAC (to match existing behavior) - Simplify finalizer thread operations - Eliminate AppDomain::Terminate - Remove use of ADID from stresslog - Remove thread enter/leave tracking from AppDomain - Remove unused asm constants across all architectures - Re-order header inclusion order to put gcenv.h before handletable - Remove retail only sync block code involving appdomain index
Diffstat (limited to 'src/vm/appdomain.cpp')
-rw-r--r--src/vm/appdomain.cpp890
1 files changed, 46 insertions, 844 deletions
diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp
index bcffb3b8aa..ea69f41ee6 100644
--- a/src/vm/appdomain.cpp
+++ b/src/vm/appdomain.cpp
@@ -99,7 +99,6 @@ static const WCHAR OTHER_DOMAIN_FRIENDLY_NAME_PREFIX[] = W("Domain");
SPTR_IMPL(AppDomain, AppDomain, m_pTheAppDomain);
SPTR_IMPL(SystemDomain, SystemDomain, m_pSystemDomain);
-SVAL_IMPL(ArrayListStatic, SystemDomain, m_appDomainIndexList);
SVAL_IMPL(BOOL, SystemDomain, s_fForceDebug);
SVAL_IMPL(BOOL, SystemDomain, s_fForceProfiling);
SVAL_IMPL(BOOL, SystemDomain, s_fForceInstrument);
@@ -126,8 +125,6 @@ CrstStatic SystemDomain::m_DelayedUnloadCrst;
ULONG SystemDomain::s_dNumAppDomains = 0;
-ArrayListStatic SystemDomain::m_appDomainIdList;
-
DWORD SystemDomain::m_dwLowestFreeIndex = 0;
@@ -199,12 +196,9 @@ LargeHeapHandleBucket::LargeHeapHandleBucket(LargeHeapHandleBucket *pNext, DWORD
ClassLoader::LoadArrayTypeThrowing(g_pObjectClass),
(INT32 *)(&Size),
1,
- TRUE
- DEBUG_ARG(TRUE));
+ TRUE);
}
- array->SetAppDomain(pAD);
-
HandleArrayObj = (PTRARRAYREF)array;
}
@@ -549,7 +543,7 @@ void LargeHeapHandleTable::ReleaseHandles(OBJECTREF *pObjRef, DWORD nReleased)
// Add the released handles to the list of available handles.
for (DWORD i = 0; i < nReleased; i++)
{
- SetObjectReference(&pObjRef[i], pPreallocatedSentinalObject, NULL);
+ SetObjectReference(&pObjRef[i], pPreallocatedSentinalObject);
}
m_cEmbeddedFree += nReleased;
@@ -809,116 +803,6 @@ void BaseDomain::Init()
#undef LOADERHEAP_PROFILE_COUNTER
-#ifndef CROSSGEN_COMPILE
-//*****************************************************************************
-void BaseDomain::Terminate()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_crstLoaderAllocatorReferences.Destroy();
- m_DomainCrst.Destroy();
- m_DomainCacheCrst.Destroy();
- m_DomainLocalBlockCrst.Destroy();
- m_InteropDataCrst.Destroy();
-
- JitListLockEntry* pJitElement;
- ListLockEntry* pElement;
-
- // All the threads that are in this domain had better be stopped by this
- // point.
- //
- // We might be jitting or running a .cctor so we need to empty that queue.
- pJitElement = m_JITLock.Pop(TRUE);
- while (pJitElement)
- {
-#ifdef STRICT_JITLOCK_ENTRY_LEAK_DETECTION
- _ASSERTE ((m_JITLock.m_pHead->m_dwRefCount == 1
- && m_JITLock.m_pHead->m_hrResultCode == E_FAIL) ||
- dbg_fDrasticShutdown || g_fInControlC);
-#endif // STRICT_JITLOCK_ENTRY_LEAK_DETECTION
- delete(pJitElement);
- pJitElement = m_JITLock.Pop(TRUE);
-
- }
- m_JITLock.Destroy();
-
- pElement = m_ClassInitLock.Pop(TRUE);
- while (pElement)
- {
-#ifdef STRICT_CLSINITLOCK_ENTRY_LEAK_DETECTION
- _ASSERTE (dbg_fDrasticShutdown || g_fInControlC);
-#endif
- delete(pElement);
- pElement = m_ClassInitLock.Pop(TRUE);
- }
- m_ClassInitLock.Destroy();
-
- FileLoadLock* pFileElement;
- pFileElement = (FileLoadLock*) m_FileLoadLock.Pop(TRUE);
- while (pFileElement)
- {
-#ifdef STRICT_CLSINITLOCK_ENTRY_LEAK_DETECTION
- _ASSERTE (dbg_fDrasticShutdown || g_fInControlC);
-#endif
- pFileElement->Release();
- pFileElement = (FileLoadLock*) m_FileLoadLock.Pop(TRUE);
- }
- m_FileLoadLock.Destroy();
-
- pElement = m_ILStubGenLock.Pop(TRUE);
- while (pElement)
- {
-#ifdef STRICT_JITLOCK_ENTRY_LEAK_DETECTION
- _ASSERTE ((m_ILStubGenLock.m_pHead->m_dwRefCount == 1
- && m_ILStubGenLock.m_pHead->m_hrResultCode == E_FAIL) ||
- dbg_fDrasticShutdown || g_fInControlC);
-#endif // STRICT_JITLOCK_ENTRY_LEAK_DETECTION
- delete(pElement);
- pElement = m_ILStubGenLock.Pop(TRUE);
- }
- m_ILStubGenLock.Destroy();
-
- m_LargeHeapHandleTableCrst.Destroy();
-
- if (m_pLargeHeapHandleTable != NULL)
- {
- delete m_pLargeHeapHandleTable;
- m_pLargeHeapHandleTable = NULL;
- }
-
- if (!IsAppDomain())
- {
- // Kind of a workaround - during unloading, we need to have an EE halt
- // around deleting this stuff. So it gets deleted in AppDomain::Terminate()
- // for those things (because there is a convenient place there.)
- GetLoaderAllocator()->CleanupStringLiteralMap();
- }
-
-#ifdef FEATURE_COMINTEROP
- if (m_pMngStdInterfacesInfo)
- {
- delete m_pMngStdInterfacesInfo;
- m_pMngStdInterfacesInfo = NULL;
- }
-
- if (m_pWinRtBinder != NULL)
- {
- m_pWinRtBinder->Release();
- }
-#endif // FEATURE_COMINTEROP
-
- ClearFusionContext();
-
- m_dwSizedRefHandles = 0;
-}
-#endif // CROSSGEN_COMPILE
-
void BaseDomain::InitVSD()
{
STANDARD_VM_CONTRACT;
@@ -968,87 +852,7 @@ void BaseDomain::ClearFusionContext()
}
}
-#ifdef FEATURE_PREJIT
-void AppDomain::DeleteNativeCodeRanges()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- FORBID_FAULT;
- }
- CONTRACTL_END;
-
- // Fast path to skip using the assembly iterator when the appdomain has not yet completely been initialized
- // and yet we are destroying it. (This is the case if we OOM during AppDomain creation.)
- if (m_Assemblies.IsEmpty())
- return;
-
- // Shutdown assemblies
- AssemblyIterator i = IterateAssembliesEx( (AssemblyIterationFlags)(kIncludeLoaded | kIncludeLoading | kIncludeExecution | kIncludeFailedToLoad) );
- CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
-
- while (i.Next(pDomainAssembly.This()))
- {
- Assembly * assembly = pDomainAssembly->m_pAssembly;
- if ((assembly != NULL))
- assembly->DeleteNativeCodeRanges();
- }
-}
-#endif
-
-void AppDomain::ShutdownAssemblies()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Fast path to skip using the assembly iterator when the appdomain has not yet completely been initialized
- // and yet we are destroying it. (This is the case if we OOM during AppDomain creation.)
- if (m_Assemblies.IsEmpty())
- return;
-
- // Shutdown assemblies
- // has two stages because Terminate needs info from the Assembly's dependencies
-
- // Stage 1: call code:Assembly::Terminate
- AssemblyIterator i = IterateAssembliesEx((AssemblyIterationFlags)(
- kIncludeLoaded | kIncludeLoading | kIncludeExecution | kIncludeFailedToLoad | kIncludeCollected));
- DomainAssembly * pDomainAssembly = NULL;
-
- while (i.Next_UnsafeNoAddRef(&pDomainAssembly))
- {
- // Note: cannot use DomainAssembly::GetAssembly() here as it asserts that the assembly has been
- // loaded to at least the FILE_LOAD_ALLOCATE level. Since domain shutdown can take place
- // asynchronously this property cannot be guaranteed. Access the m_pAssembly field directly instead.
- Assembly * assembly = pDomainAssembly->m_pAssembly;
- if (assembly)
- assembly->Terminate();
- }
-
- // Stage 2: Clear the list of assemblies
- i = IterateAssembliesEx((AssemblyIterationFlags)(
- kIncludeLoaded | kIncludeLoading | kIncludeExecution | kIncludeFailedToLoad | kIncludeCollected));
- while (i.Next_UnsafeNoAddRef(&pDomainAssembly))
- {
- // We are in shutdown path, no one else can get to the list anymore
- delete pDomainAssembly;
- }
- m_Assemblies.Clear(this);
-
- // Stage 2: Clear the loader allocators registered for deletion from code:Assembly:Terminate calls in
- // stage 1
- // Note: It is not clear to me why we cannot delete the loader allocator from within
- // code:DomainAssembly::~DomainAssembly
- ShutdownFreeLoaderAllocators(FALSE);
-} // AppDomain::ShutdownAssemblies
-
-void AppDomain::ShutdownFreeLoaderAllocators(BOOL bFromManagedCode)
+void AppDomain::ShutdownFreeLoaderAllocators()
{
// If we're called from managed code (i.e. the finalizer thread) we take a lock in
// LoaderAllocator::CleanupFailedTypeInit, which may throw. Otherwise we're called
@@ -1056,7 +860,7 @@ void AppDomain::ShutdownFreeLoaderAllocators(BOOL bFromManagedCode)
CONTRACTL
{
GC_TRIGGERS;
- if (bFromManagedCode) THROWS; else NOTHROW;
+ THROWS;
MODE_ANY;
CAN_TAKE_LOCK;
}
@@ -1071,24 +875,16 @@ void AppDomain::ShutdownFreeLoaderAllocators(BOOL bFromManagedCode)
// Remove next loader allocator from the list
m_pDelayedLoaderAllocatorUnloadList = m_pDelayedLoaderAllocatorUnloadList->m_pLoaderAllocatorDestroyNext;
- if (bFromManagedCode)
- {
- // For loader allocator finalization, we need to be careful about cleaning up per-appdomain allocations
- // and synchronizing with GC using delay unload list. We need to wait for next Gen2 GC to finish to ensure
- // that GC heap does not have any references to the MethodTables being unloaded.
+ // For loader allocator finalization, we need to be careful about cleaning up per-appdomain allocations
+ // and synchronizing with GC using delay unload list. We need to wait for next Gen2 GC to finish to ensure
+ // that GC heap does not have any references to the MethodTables being unloaded.
- pCurrentLoaderAllocator->CleanupFailedTypeInit();
+ pCurrentLoaderAllocator->CleanupFailedTypeInit();
- pCurrentLoaderAllocator->CleanupHandles();
+ pCurrentLoaderAllocator->CleanupHandles();
- GCX_COOP();
- SystemDomain::System()->AddToDelayedUnloadList(pCurrentLoaderAllocator);
- }
- else
- {
- // For appdomain unload, delete the loader allocator right away
- delete pCurrentLoaderAllocator;
- }
+ GCX_COOP();
+ SystemDomain::System()->AddToDelayedUnloadList(pCurrentLoaderAllocator);
}
} // AppDomain::ShutdownFreeLoaderAllocators
@@ -1159,20 +955,6 @@ void AppDomain::SetNativeDllSearchDirectories(LPCWSTR wszNativeDllSearchDirector
}
}
-void AppDomain::ShutdownNativeDllSearchDirectories()
-{
- LIMITED_METHOD_CONTRACT;
- // Shutdown assemblies
- PathIterator i = IterateNativeDllSearchDirectories();
-
- while (i.Next())
- {
- delete i.GetPath();
- }
-
- m_NativeDllSearchDirectories.Clear();
-}
-
void AppDomain::ReleaseFiles()
{
STANDARD_VM_CONTRACT;
@@ -1899,9 +1681,6 @@ void SystemDomain::Attach()
PerAppDomainTPCountList::InitAppDomainIndexList();
#endif // CROSSGEN_COMPILE
- m_appDomainIndexList.Init();
- m_appDomainIdList.Init();
-
m_SystemDomainCrst.Init(CrstSystemDomain, (CrstFlags)(CRST_REENTRANCY | CRST_TAKEN_DURING_SHUTDOWN));
m_DelayedUnloadCrst.Init(CrstSystemDomainDelayedUnloadList, CRST_UNSAFE_COOPGC);
@@ -1977,49 +1756,6 @@ void SystemDomain::Stop()
i.GetDomain()->Stop();
}
-
-void SystemDomain::Terminate() // bNotifyProfiler is ignored
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // This ignores the refences and terminates the appdomains
- AppDomainIterator i(FALSE);
-
- while (i.Next())
- {
- delete i.GetDomain();
- // Keep the iterator from Releasing the current domain
- i.m_pCurrent = NULL;
- }
-
- if (m_pSystemFile != NULL) {
- m_pSystemFile->Release();
- m_pSystemFile = NULL;
- }
-
- m_pSystemAssembly = NULL;
-
- if (m_pGlobalStringLiteralMap) {
- delete m_pGlobalStringLiteralMap;
- m_pGlobalStringLiteralMap = NULL;
- }
-
- BaseDomain::Terminate();
-
-#ifdef FEATURE_COMINTEROP
- if (g_pRCWCleanupList != NULL)
- delete g_pRCWCleanupList;
-#endif // FEATURE_COMINTEROP
- m_GlobalAllocator.Terminate();
-}
-
-
void SystemDomain::PreallocateSpecialObjects()
{
CONTRACTL
@@ -2246,21 +1982,16 @@ void SystemDomain::LazyInitGlobalStringLiteralMap()
SystemDomain* sysDomain = SystemDomain::System();
if (sysDomain)
{
- DWORD i;
- DWORD count = (DWORD) m_appDomainIdList.GetCount();
- for (i = 0 ; i < count ; i++)
+ AppDomain* pAppDomain = ::GetAppDomain();
+ if (pAppDomain && pAppDomain->IsActive())
{
- AppDomain* pAppDomain = (AppDomain *)m_appDomainIdList.Get(i);
- if (pAppDomain && pAppDomain->IsActive())
- {
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
- if (g_fEnableARM)
- {
- sc->pCurrentDomain = pAppDomain;
- }
-#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
- pAppDomain->EnumStaticGCRefs(fn, sc);
+ if (g_fEnableARM)
+ {
+ sc->pCurrentDomain = pAppDomain;
}
+#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
+ pAppDomain->EnumStaticGCRefs(fn, sc);
}
}
@@ -2283,15 +2014,10 @@ void SystemDomain::ResetADSurvivedBytes()
SystemDomain* sysDomain = SystemDomain::System();
if (sysDomain)
{
- DWORD i;
- DWORD count = (DWORD) m_appDomainIdList.GetCount();
- for (i = 0 ; i < count ; i++)
+ AppDomain* pAppDomain = ::GetAppDomain();
+ if (pAppDomain && pAppDomain->IsUserActive())
{
- AppDomain* pAppDomain = (AppDomain *)m_appDomainIdList.Get(i);
- if (pAppDomain && pAppDomain->IsUserActive())
- {
- pAppDomain->ResetSurvivedBytes();
- }
+ pAppDomain->ResetSurvivedBytes();
}
}
@@ -2312,16 +2038,11 @@ ULONGLONG SystemDomain::GetADSurvivedBytes()
ULONGLONG ullTotalADSurvived = 0;
if (sysDomain)
{
- DWORD i;
- DWORD count = (DWORD) m_appDomainIdList.GetCount();
- for (i = 0 ; i < count ; i++)
+ AppDomain* pAppDomain = ::GetAppDomain();
+ if (pAppDomain && pAppDomain->IsUserActive())
{
- AppDomain* pAppDomain = (AppDomain *)m_appDomainIdList.Get(i);
- if (pAppDomain && pAppDomain->IsUserActive())
- {
- ULONGLONG ullSurvived = pAppDomain->GetSurvivedBytes();
- ullTotalADSurvived += ullSurvived;
- }
+ ULONGLONG ullSurvived = pAppDomain->GetSurvivedBytes();
+ ullTotalADSurvived += ullSurvived;
}
}
@@ -2343,15 +2064,10 @@ void SystemDomain::RecordTotalSurvivedBytes(size_t totalSurvivedBytes)
SystemDomain* sysDomain = SystemDomain::System();
if (sysDomain)
{
- DWORD i;
- DWORD count = (DWORD) m_appDomainIdList.GetCount();
- for (i = 0 ; i < count ; i++)
+ AppDomain* pAppDomain = ::GetAppDomain();
+ if (pAppDomain && pAppDomain->IsUserActive())
{
- AppDomain* pAppDomain = (AppDomain *)m_appDomainIdList.Get(i);
- if (pAppDomain && pAppDomain->IsUserActive())
- {
- FireEtwAppDomainMemSurvived((ULONGLONG)pAppDomain, pAppDomain->GetSurvivedBytes(), totalSurvivedBytes, GetClrInstanceId());
- }
+ FireEtwAppDomainMemSurvived((ULONGLONG)pAppDomain, pAppDomain->GetSurvivedBytes(), totalSurvivedBytes, GetClrInstanceId());
}
}
@@ -2374,15 +2090,10 @@ DWORD SystemDomain::GetTotalNumSizedRefHandles()
DWORD dwTotalNumSizedRefHandles = 0;
if (sysDomain)
{
- DWORD i;
- DWORD count = (DWORD) m_appDomainIdList.GetCount();
- for (i = 0 ; i < count ; i++)
+ AppDomain* pAppDomain = ::GetAppDomain();
+ if (pAppDomain && pAppDomain->IsActive())
{
- AppDomain* pAppDomain = (AppDomain *)m_appDomainIdList.Get(i);
- if (pAppDomain && pAppDomain->IsActive())
- {
- dwTotalNumSizedRefHandles += pAppDomain->GetNumSizedRefHandles();
- }
+ dwTotalNumSizedRefHandles += pAppDomain->GetNumSizedRefHandles();
}
}
@@ -2587,171 +2298,10 @@ void SystemDomain::LoadDomain(AppDomain *pDomain)
SystemDomain::System()->AddDomain(pDomain);
}
-ADIndex SystemDomain::GetNewAppDomainIndex(AppDomain *pAppDomain)
-{
- STANDARD_VM_CONTRACT;
-
- DWORD count = m_appDomainIndexList.GetCount();
- DWORD i;
-
-#ifdef _DEBUG
- if (count < 2000)
- {
- // So that we can keep AD index inside object header.
- // We do not want to create syncblock unless needed.
- i = count;
- }
- else
- {
-#endif // _DEBUG
- //
- // Look for an unused index. Note that in a checked build,
- // we never reuse indexes - this makes it easier to tell
- // when we are looking at a stale app domain.
- //
-
- i = m_appDomainIndexList.FindElement(m_dwLowestFreeIndex, NULL);
- if (i == (DWORD) ArrayList::NOT_FOUND)
- i = count;
- m_dwLowestFreeIndex = i+1;
-#ifdef _DEBUG
- if (m_dwLowestFreeIndex >= 2000)
- {
- m_dwLowestFreeIndex = 0;
- }
- }
-#endif // _DEBUG
-
- if (i == count)
- IfFailThrow(m_appDomainIndexList.Append(pAppDomain));
- else
- m_appDomainIndexList.Set(i, pAppDomain);
-
- _ASSERTE(i < m_appDomainIndexList.GetCount());
-
- // Note that index 0 means domain agile.
- return ADIndex(i+1);
-}
-
-void SystemDomain::ReleaseAppDomainIndex(ADIndex index)
-{
- WRAPPER_NO_CONTRACT;
- SystemDomain::LockHolder lh;
- // Note that index 0 means domain agile.
- index.m_dwIndex--;
-
- _ASSERTE(m_appDomainIndexList.Get(index.m_dwIndex) != NULL);
-
- m_appDomainIndexList.Set(index.m_dwIndex, NULL);
-
-#ifndef _DEBUG
- if (index.m_dwIndex < m_dwLowestFreeIndex)
- m_dwLowestFreeIndex = index.m_dwIndex;
-#endif // !_DEBUG
-}
-
#endif // !DACCESS_COMPILE
-PTR_AppDomain SystemDomain::GetAppDomainAtIndex(ADIndex index)
-{
- LIMITED_METHOD_CONTRACT;
- SUPPORTS_DAC;
- _ASSERTE(index.m_dwIndex != 0);
-
- PTR_AppDomain pAppDomain = TestGetAppDomainAtIndex(index);
-
- _ASSERTE(pAppDomain || !"Attempt to access unloaded app domain");
-
- return pAppDomain;
-}
-
-PTR_AppDomain SystemDomain::TestGetAppDomainAtIndex(ADIndex index)
-{
- LIMITED_METHOD_CONTRACT;
- SUPPORTS_DAC;
- _ASSERTE(index.m_dwIndex != 0);
- index.m_dwIndex--;
-
-#ifndef DACCESS_COMPILE
- _ASSERTE(index.m_dwIndex < (DWORD)m_appDomainIndexList.GetCount());
- AppDomain *pAppDomain = (AppDomain*) m_appDomainIndexList.Get(index.m_dwIndex);
-#else // DACCESS_COMPILE
- PTR_ArrayListStatic pList = &m_appDomainIndexList;
- AppDomain *pAppDomain = dac_cast<PTR_AppDomain>(pList->Get(index.m_dwIndex));
-#endif // DACCESS_COMPILE
- return PTR_AppDomain(pAppDomain);
-}
-
#ifndef DACCESS_COMPILE
-// See also code:SystemDomain::ReleaseAppDomainId
-ADID SystemDomain::GetNewAppDomainId(AppDomain *pAppDomain)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- DWORD i = m_appDomainIdList.GetCount();
-
- IfFailThrow(m_appDomainIdList.Append(pAppDomain));
-
- _ASSERTE(i < m_appDomainIdList.GetCount());
-
- return ADID(i+1);
-}
-
-AppDomain *SystemDomain::GetAppDomainAtId(ADID index)
-{
- CONTRACTL
- {
-#ifdef _DEBUG
- if (!SystemDomain::IsUnderDomainLock() && !IsGCThread()) { MODE_COOPERATIVE;} else { DISABLED(MODE_ANY);}
-#endif
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
-
- if(index.m_dwId == 0)
- return NULL;
- DWORD requestedID = index.m_dwId - 1;
-
- if(requestedID >= (DWORD)m_appDomainIdList.GetCount())
- return NULL;
-
- AppDomain * result = (AppDomain *)m_appDomainIdList.Get(requestedID);
-
-#ifndef CROSSGEN_COMPILE
- // If the current thread can't enter the AppDomain, then don't return it.
- if (!result)
- return NULL;
-#endif // CROSSGEN_COMPILE
-
- return result;
-}
-
-// Releases an appdomain index. Note that today we have code that depends on these
-// indexes not being recycled, so we don't actually shrink m_appDomainIdList, but
-// simply zero out an entry. THus we 'leak' the memory associated the slot in
-// m_appDomainIdList.
-//
-// TODO make this a sparse structure so that we avoid that leak.
-//
-void SystemDomain::ReleaseAppDomainId(ADID index)
-{
- LIMITED_METHOD_CONTRACT;
- index.m_dwId--;
-
- _ASSERTE(index.m_dwId < (DWORD)m_appDomainIdList.GetCount());
-
- m_appDomainIdList.Set(index.m_dwId, NULL);
-}
-
#if defined(FEATURE_COMINTEROP_APARTMENT_SUPPORT) && !defined(CROSSGEN_COMPILE)
Thread::ApartmentState SystemDomain::GetEntryPointThreadAptState(IMDInternalImport* pScope, mdMethodDef mdMethod)
@@ -3245,12 +2795,6 @@ void AppDomain::Create()
pDomain->Init();
- // need to make this assignment here since we'll be releasing
- // the lock before calling AddDomain. So any other thread
- // grabbing this lock after we release it will find that
- // the COM Domain has already been created
- _ASSERTE (pDomain->GetId().m_dwId == DefaultADID);
-
// allocate a Virtual Call Stub Manager for the default domain
pDomain->InitVSD();
@@ -3307,7 +2851,6 @@ void SystemDomain::AddDomain(AppDomain* pDomain)
pDomain->m_Stage == AppDomain::STAGE_ACTIVE)
{
pDomain->SetStage(AppDomain::STAGE_OPEN);
- IncrementNumAppDomains(); // Maintain a count of app domains added to the list.
}
}
@@ -3423,14 +2966,6 @@ HRESULT SystemDomain::NotifyProfilerShutdown()
}
#endif // PROFILING_SUPPORTED
-
-#ifdef _DEBUG
-struct AppDomain::ThreadTrackInfo {
- Thread *pThread;
- CDynArray<Frame *> frameStack;
-};
-#endif // _DEBUG
-
AppDomain::AppDomain()
{
// initialize fields so the appdomain can be safely destructed
@@ -3457,15 +2992,10 @@ AppDomain::AppDomain()
m_handleStore = NULL;
- #ifdef _DEBUG
- m_pThreadTrackInfoList = NULL;
- m_TrackSpinLock = 0;
+#ifdef _DEBUG
m_Assemblies.Debug_SetAppDomain(this);
#endif // _DEBUG
- m_dwThreadEnterCount = 0;
- m_dwThreadsStillInAppDomain = (ULONG)-1;
-
#ifdef FEATURE_COMINTEROP
m_pRefDispIDCache = NULL;
m_hndMissing = NULL;
@@ -3525,17 +3055,8 @@ AppDomain::~AppDomain()
if (GetTPIndex().m_dwIndex != 0)
PerAppDomainTPCountList::ResetAppDomainIndex(GetTPIndex());
- if (m_dwId.m_dwId!=0)
- SystemDomain::ReleaseAppDomainId(m_dwId);
-
m_AssemblyCache.Clear();
- if(!g_fEEInit)
- Terminate();
-
-
-
-
#ifdef FEATURE_COMINTEROP
if (m_pNameToTypeMap != nullptr)
{
@@ -3549,29 +3070,6 @@ AppDomain::~AppDomain()
}
#endif //FEATURE_COMINTEROP
-#ifdef _DEBUG
- // If we were tracking thread AD transitions, cleanup the list on shutdown
- if (m_pThreadTrackInfoList)
- {
- while (m_pThreadTrackInfoList->Count() > 0)
- {
- // Get the very last element
- ThreadTrackInfo *pElem = *(m_pThreadTrackInfoList->Get(m_pThreadTrackInfoList->Count() - 1));
- _ASSERTE(pElem);
-
- // Free the memory
- delete pElem;
-
- // Remove pointer entry from the list
- m_pThreadTrackInfoList->Delete(m_pThreadTrackInfoList->Count() - 1);
- }
-
- // Now delete the list itself
- delete m_pThreadTrackInfoList;
- m_pThreadTrackInfoList = NULL;
- }
-#endif // _DEBUG
-
#endif // CROSSGEN_COMPILE
}
@@ -3601,8 +3099,6 @@ void AppDomain::Init()
INDEBUG(| CRST_DEBUG_ONLY_CHECK_FORBID_SUSPEND_THREAD)));
m_crstHostAssemblyMapAdd.Init(CrstHostAssemblyMapAdd);
- m_dwId = SystemDomain::GetNewAppDomainId(this);
-
#ifndef CROSSGEN_COMPILE
//Allocate the threadpool entry before the appdomain id list. Otherwise,
//the thread pool list will be out of sync if insertion of id in
@@ -3610,12 +3106,6 @@ void AppDomain::Init()
m_tpIndex = PerAppDomainTPCountList::AddNewTPIndex();
#endif // CROSSGEN_COMPILE
- m_dwIndex = SystemDomain::GetNewAppDomainIndex(this);
-
-#ifndef CROSSGEN_COMPILE
- PerAppDomainTPCountList::SetAppDomainId(m_tpIndex, m_dwId);
-#endif
-
BaseDomain::Init();
// Set up the binding caches
@@ -3649,16 +3139,8 @@ void AppDomain::Init()
m_ullLastEtwAllocBytes = 0;
#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
- // Default domain reuses the handletablemap that was created during EEStartup since
- // default domain cannot be unloaded.
- if (GetId().m_dwId == DefaultADID)
- {
- m_handleStore = GCHandleUtilities::GetGCHandleManager()->GetGlobalHandleStore();
- }
- else
- {
- m_handleStore = GCHandleUtilities::GetGCHandleManager()->CreateHandleStore((void*)(uintptr_t)m_dwIndex.m_dwIndex);
- }
+ // Default domain reuses the handletablemap that was created during EEStartup
+ m_handleStore = GCHandleUtilities::GetGCHandleManager()->GetGlobalHandleStore();
if (!m_handleStore)
{
@@ -3684,7 +3166,7 @@ void AppDomain::Init()
#ifndef CROSSGEN_COMPILE
#ifdef FEATURE_TIERED_COMPILATION
- m_tieredCompilationManager.Init(GetId());
+ m_tieredCompilationManager.Init();
#endif
#endif // CROSSGEN_COMPILE
} // AppDomain::Init
@@ -3739,135 +3221,6 @@ void AppDomain::Stop()
#endif // DEBUGGING_SUPPORTED
}
-void AppDomain::Terminate()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- GCX_PREEMP();
-
- _ASSERTE(m_dwThreadEnterCount == 0 || IsDefaultDomain());
-
-#ifdef FEATURE_COMINTEROP
- if (m_pRCWCache)
- {
- delete m_pRCWCache;
- m_pRCWCache = NULL;
- }
-
- if (m_pRCWRefCache)
- {
- delete m_pRCWRefCache;
- m_pRCWRefCache = NULL;
- }
-#endif // FEATURE_COMINTEROP
-
- if (!IsAtProcessExit())
- {
- // if we're not shutting down everything then clean up the string literals associated
- // with this appdomain -- note that is no longer needs to happen while suspended
- // because the appropriate locks are taken in the GlobalStringLiteralMap
- // this is important as this locks have a higher lock number than does the
- // thread-store lock which is taken when we suspend.
- GetLoaderAllocator()->CleanupStringLiteralMap();
-
- // Suspend the EE to do some clean up that can only occur
- // while no threads are running.
- GCX_COOP (); // SuspendEE may require current thread to be in Coop mode
- ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_FOR_APPDOMAIN_SHUTDOWN);
- }
-
- // Note that this must be performed before restarting the EE. It will clean
- // the cache and prevent others from using stale cache entries.
- //@TODO: Would be nice to get this back to BaseDomain, but need larger fix for that.
- // NOTE: Must have the runtime suspended to unlink managers
- // NOTE: May be NULL due to OOM during initialization. Can skip in that case.
- GetLoaderAllocator()->UninitVirtualCallStubManager();
- MethodTable::ClearMethodDataCache();
- ClearJitGenericHandleCache(this);
-
- // @TODO s_TPMethodTableCrst prevents us from from keeping the whole
- // assembly shutdown logic here. See if we can do better in the next milestone
-#ifdef FEATURE_PREJIT
- DeleteNativeCodeRanges();
-#endif
-
- if (!IsAtProcessExit())
- {
- // Resume the EE.
- ThreadSuspend::RestartEE(FALSE, TRUE);
- }
-
- ShutdownAssemblies();
- ShutdownNativeDllSearchDirectories();
-
- if (m_pRefClassFactHash)
- {
- m_pRefClassFactHash->Destroy();
- // storage for m_pRefClassFactHash itself is allocated on the loader heap
- }
-
-#ifdef FEATURE_TYPEEQUIVALENCE
- m_TypeEquivalenceCrst.Destroy();
-#endif
-
- m_ReflectionCrst.Destroy();
- m_RefClassFactCrst.Destroy();
-
- BaseDomain::Terminate();
-
- if (m_handleStore)
- {
- GCHandleUtilities::GetGCHandleManager()->DestroyHandleStore(m_handleStore);
- m_handleStore = NULL;
- }
-
-#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
- if (m_pullAllocBytes)
- {
- delete [] m_pullAllocBytes;
- }
- if (m_pullSurvivedBytes)
- {
- delete [] m_pullSurvivedBytes;
- }
-#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-
- if(m_dwIndex.m_dwIndex != 0)
- SystemDomain::ReleaseAppDomainIndex(m_dwIndex);
-} // AppDomain::Terminate
-
-void AppDomain::CloseDomain()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-
- BOOL bADRemoved=FALSE;;
-
- AddRef(); // Hold a reference
- AppDomainRefHolder AdHolder(this);
- {
- SystemDomain::LockHolder lh;
-
- SystemDomain::System()->DecrementNumAppDomains(); // Maintain a count of app domains added to the list.
- bADRemoved = SystemDomain::System()->RemoveDomain(this);
- }
-
- if(bADRemoved)
- Stop();
-}
-
#endif // !CROSSGEN_COMPILE
#ifdef FEATURE_COMINTEROP
@@ -4166,12 +3519,6 @@ FileLoadLevel FileLoadLock::GetLoadLevel()
return m_level;
}
-ADID FileLoadLock::GetAppDomainId()
-{
- LIMITED_METHOD_CONTRACT;
- return m_AppDomainId;
-}
-
// Acquire will return FALSE and not take the lock if the file
// has already been loaded to the target level. Otherwise,
// it will return TRUE and take the lock.
@@ -4294,7 +3641,7 @@ BOOL FileLoadLock::CompleteLoadLevel(FileLoadLevel level, BOOL success)
case FILE_LOAD_DELIVER_EVENTS:
case FILE_LOADED:
case FILE_ACTIVE: // The timing of stress logs is not critical, so even for the FILE_ACTIVE stage we need not do it while the m_pList lock is held.
- STRESS_LOG4(LF_CLASSLOADER, LL_INFO100, "Completed Load Level %s for DomainFile %p in AD %i - success = %i\n", fileLoadLevelName[level], m_pDomainFile, m_AppDomainId.m_dwId, success);
+ STRESS_LOG3(LF_CLASSLOADER, LL_INFO100, "Completed Load Level %s for DomainFile %p - success = %i\n", fileLoadLevelName[level], m_pDomainFile, success);
break;
default:
break;
@@ -4357,8 +3704,7 @@ FileLoadLock::FileLoadLock(PEFileListLock *pLock, PEFile *pFile, DomainFile *pDo
: ListLockEntry(pLock, pFile, "File load lock"),
m_level((FileLoadLevel) (FILE_LOAD_CREATE)),
m_pDomainFile(pDomainFile),
- m_cachedHR(S_OK),
- m_AppDomainId(pDomainFile->GetAppDomain()->GetId())
+ m_cachedHR(S_OK)
{
WRAPPER_NO_CONTRACT;
pFile->AddRef();
@@ -4939,7 +4285,7 @@ DomainFile *AppDomain::LoadDomainFile(FileLoadLock *pLock, FileLoadLevel targetL
TryIncrementalLoad(pFile, workLevel, fileLock);
}
- TESTHOOKCALL(CompletedFileLoadLevel(GetId().m_dwId,pFile,workLevel));
+ TESTHOOKCALL(CompletedFileLoadLevel(DefaultADID,pFile,workLevel));
}
if (pLock->GetLoadLevel() == immediateTargetLevel-1)
@@ -5004,9 +4350,9 @@ void AppDomain::TryIncrementalLoad(DomainFile *pFile, FileLoadLevel workLevel, F
}
// Do the work
- TESTHOOKCALL(NextFileLoadLevel(GetId().m_dwId,pFile,workLevel));
+ TESTHOOKCALL(NextFileLoadLevel(DefaultADID,pFile,workLevel));
BOOL success = pFile->DoIncrementalLoad(workLevel);
- TESTHOOKCALL(CompletingFileLoadLevel(GetId().m_dwId,pFile,workLevel));
+ TESTHOOKCALL(CompletingFileLoadLevel(DefaultADID,pFile,workLevel));
if (released)
{
// Reobtain lock to increment level. (Note that another thread may
@@ -5217,7 +4563,7 @@ void AppDomain::SetupSharedStatics()
FieldDesc * pEmptyStringFD = MscorlibBinder::GetField(FIELD__STRING__EMPTY);
OBJECTREF* pEmptyStringHandle = (OBJECTREF*)
((TADDR)pLocalModule->GetPrecomputedGCStaticsBasePointer()+pEmptyStringFD->GetOffset());
- SetObjectReference( pEmptyStringHandle, StringObject::GetEmptyString(), this );
+ SetObjectReference( pEmptyStringHandle, StringObject::GetEmptyString());
#endif // CROSSGEN_COMPILE
}
@@ -5300,18 +4646,8 @@ void AppDomain::SetFriendlyName(LPCWSTR pwzFriendlyName, BOOL fDebuggerCares/*=T
}
else
{
- if (IsDefaultDomain())
- tmpFriendlyName.Set(DEFAULT_DOMAIN_FRIENDLY_NAME);
-
- // This is for the profiler - if they call GetFriendlyName on an AppdomainCreateStarted
- // event, then we want to give them a temporary name they can use.
- else if (GetId().m_dwId != 0)
- {
- tmpFriendlyName.Clear();
- tmpFriendlyName.Printf(W("%s %d"), OTHER_DOMAIN_FRIENDLY_NAME_PREFIX, GetId().m_dwId);
- }
+ tmpFriendlyName.Set(DEFAULT_DOMAIN_FRIENDLY_NAME);
}
-
}
tmpFriendlyName.Normalize();
@@ -6278,9 +5614,8 @@ ULONG AppDomain::Release()
if (!cRef)
{
_ASSERTE (m_Stage == STAGE_CREATING);
- ADID adid=GetId();
delete this;
- TESTHOOKCALL(AppDomainDestroyed(adid.m_dwId));
+ TESTHOOKCALL(AppDomainDestroyed(DefaultADID));
}
return (cRef);
}
@@ -6444,7 +5779,7 @@ IUnknown *AppDomain::CreateFusionContext()
GCX_PREEMP();
// Initialize the assembly binder for the default context loads for CoreCLR.
- IfFailThrow(CCoreCLRBinderHelper::DefaultBinderSetupContext(GetId().m_dwId, &pTPABinder));
+ IfFailThrow(CCoreCLRBinderHelper::DefaultBinderSetupContext(DefaultADID, &pTPABinder));
m_pFusionContext = reinterpret_cast<IUnknown *>(pTPABinder);
// By default, initial binding context setup for CoreCLR is also the TPABinding context
@@ -6519,8 +5854,8 @@ void AppDomain::NotifyDebuggerUnload()
if (!IsDebuggerAttached())
return;
- LOG((LF_CORDB, LL_INFO10, "AD::NDD domain [%d] %#08x %ls\n",
- GetId().m_dwId, this, GetFriendlyNameForLogging()));
+ LOG((LF_CORDB, LL_INFO10, "AD::NDD domain %#08x %ls\n",
+ this, GetFriendlyNameForLogging()));
LOG((LF_CORDB, LL_INFO100, "AD::NDD: Interating domain bound assemblies\n"));
AssemblyIterator i = IterateAssembliesEx((AssemblyIterationFlags)(kIncludeLoaded | kIncludeLoading | kIncludeExecution));
@@ -6644,136 +5979,6 @@ void AppDomain::ExceptionUnwind(Frame *pFrame)
LOG((LF_APPDOMAIN, LL_INFO10, "AppDomain::ExceptionUnwind: not first transition or abort\n"));
}
-#ifdef _DEBUG
-
-void AppDomain::TrackADThreadEnter(Thread *pThread, Frame *pFrame)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- // REENTRANT
- PRECONDITION(CheckPointer(pThread));
- PRECONDITION(pFrame != (Frame*)(size_t) INVALID_POINTER_CD);
- }
- CONTRACTL_END;
-
- while (FastInterlockCompareExchange((LONG*)&m_TrackSpinLock, 1, 0) != 0)
- ;
- if (m_pThreadTrackInfoList == NULL)
- m_pThreadTrackInfoList = new (nothrow) ThreadTrackInfoList;
- // If we don't assert here, we will AV in the for loop below
- _ASSERTE(m_pThreadTrackInfoList);
-
- ThreadTrackInfoList *pTrackList= m_pThreadTrackInfoList;
-
- ThreadTrackInfo *pTrack = NULL;
- int i;
- for (i=0; i < pTrackList->Count(); i++) {
- if ((*(pTrackList->Get(i)))->pThread == pThread) {
- pTrack = *(pTrackList->Get(i));
- break;
- }
- }
- if (! pTrack) {
- pTrack = new (nothrow) ThreadTrackInfo;
- // If we don't assert here, we will AV in the for loop below.
- _ASSERTE(pTrack);
- pTrack->pThread = pThread;
- ThreadTrackInfo **pSlot = pTrackList->Append();
- *pSlot = pTrack;
- }
-
- InterlockedIncrement((LONG*)&m_dwThreadEnterCount);
- Frame **pSlot;
- if (pTrack)
- {
- pSlot = pTrack->frameStack.Insert(0);
- *pSlot = pFrame;
- }
- int totThreads = 0;
- for (i=0; i < pTrackList->Count(); i++)
- totThreads += (*(pTrackList->Get(i)))->frameStack.Count();
- _ASSERTE(totThreads == (int)m_dwThreadEnterCount);
-
- InterlockedExchange((LONG*)&m_TrackSpinLock, 0);
-}
-
-
-void AppDomain::TrackADThreadExit(Thread *pThread, Frame *pFrame)
-{
- CONTRACTL
- {
- if (GetThread()) {MODE_COOPERATIVE;}
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- while (FastInterlockCompareExchange((LONG*)&m_TrackSpinLock, 1, 0) != 0)
- ;
- ThreadTrackInfoList *pTrackList= m_pThreadTrackInfoList;
- _ASSERTE(pTrackList);
- ThreadTrackInfo *pTrack = NULL;
- int i;
- for (i=0; i < pTrackList->Count(); i++)
- {
- if ((*(pTrackList->Get(i)))->pThread == pThread)
- {
- pTrack = *(pTrackList->Get(i));
- break;
- }
- }
- _ASSERTE(pTrack);
- _ASSERTE(*(pTrack->frameStack.Get(0)) == pFrame);
- pTrack->frameStack.Delete(0);
- InterlockedDecrement((LONG*)&m_dwThreadEnterCount);
-
- int totThreads = 0;
- for (i=0; i < pTrackList->Count(); i++)
- totThreads += (*(pTrackList->Get(i)))->frameStack.Count();
- _ASSERTE(totThreads == (int)m_dwThreadEnterCount);
-
- InterlockedExchange((LONG*)&m_TrackSpinLock, 0);
-}
-
-void AppDomain::DumpADThreadTrack()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- while (FastInterlockCompareExchange((LONG*)&m_TrackSpinLock, 1, 0) != 0)
- ;
- ThreadTrackInfoList *pTrackList= m_pThreadTrackInfoList;
- if (!pTrackList)
- goto end;
-
- {
- LOG((LF_APPDOMAIN, LL_INFO10000, "\nThread dump of %d threads for [%d] %#08x %S\n",
- m_dwThreadEnterCount, GetId().m_dwId, this, GetFriendlyNameForLogging()));
- int totThreads = 0;
- for (int i=0; i < pTrackList->Count(); i++)
- {
- ThreadTrackInfo *pTrack = *(pTrackList->Get(i));
- if (pTrack->frameStack.Count()==0)
- continue;
- LOG((LF_APPDOMAIN, LL_INFO100, " ADEnterCount for %x is %d\n", pTrack->pThread->GetThreadId(), pTrack->frameStack.Count()));
- totThreads += pTrack->frameStack.Count();
- for (int j=0; j < pTrack->frameStack.Count(); j++)
- LOG((LF_APPDOMAIN, LL_INFO100, " frame %8.8x\n", *(pTrack->frameStack.Get(j))));
- }
- _ASSERTE(totThreads == (int)m_dwThreadEnterCount);
- }
-end:
- InterlockedExchange((LONG*)&m_TrackSpinLock, 0);
-}
-#endif // _DEBUG
-
#endif // CROSSGEN_COMPILE
#endif // !DACCESS_COMPILE
@@ -7963,9 +7168,6 @@ SystemDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
{
AppDomain::GetCurrentDomain()->EnumMemoryRegions(flags, true);
}
-
- m_appDomainIndexList.EnumMem();
- (&m_appDomainIndexList)->EnumMemoryRegions(flags);
}
#endif //DACCESS_COMPILE