diff options
author | David Wrighton <davidwr@microsoft.com> | 2019-04-03 15:54:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-03 15:54:05 -0700 |
commit | d3e39bc2f81e3dbf9e4b96347f62b49d8700336c (patch) | |
tree | 78b72499a0f38e9dbf6ae4d6d24c77779ac543dc /src/vm/appdomain.cpp | |
parent | a7dd6192530dec1d424c359233a1b92f559fa92a (diff) | |
download | coreclr-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.cpp | 890 |
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 |