diff options
Diffstat (limited to 'src/vm/assembly.cpp')
-rw-r--r-- | src/vm/assembly.cpp | 54 |
1 files changed, 8 insertions, 46 deletions
diff --git a/src/vm/assembly.cpp b/src/vm/assembly.cpp index 4f9f13cf01..0eb1e2a8c6 100644 --- a/src/vm/assembly.cpp +++ b/src/vm/assembly.cpp @@ -402,53 +402,8 @@ void Assembly::Terminate( BOOL signalProfiler ) m_pClassLoader = NULL; } - if (m_pLoaderAllocator != NULL) - { - if (IsCollectible()) - { - // This cleanup code starts resembling parts of AppDomain::Terminate too much. - // It would be useful to reduce duplication and also establish clear responsibilites - // for LoaderAllocator::Destroy, Assembly::Terminate, LoaderAllocator::Terminate - // and LoaderAllocator::~LoaderAllocator. We need to establish how these - // cleanup paths interact with app-domain unload and process tear-down, too. - - if (!IsAtProcessExit()) - { - // 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 - // SuspendEE cares about the reason flag only when invoked for a GC - // Other values are typically ignored. If using SUSPEND_FOR_APPDOMAIN_SHUTDOWN - // is inappropriate, we can introduce a new flag or hijack an unused one. - ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_FOR_APPDOMAIN_SHUTDOWN); - } - - ExecutionManager::Unload(m_pLoaderAllocator); - - m_pLoaderAllocator->UninitVirtualCallStubManager(); - MethodTable::ClearMethodDataCache(); - _ASSERTE(m_pDomain->IsAppDomain()); - AppDomain *pAppDomain = m_pDomain->AsAppDomain(); - ClearJitGenericHandleCache(pAppDomain); - - if (!IsAtProcessExit()) - { - // Resume the EE. - ThreadSuspend::RestartEE(FALSE, TRUE); - } - - // Once the manifest file is tenured, the managed LoaderAllocatorScout is responsible for cleanup. - if (m_pManifest != NULL && m_pManifest->IsTenured()) - { - pAppDomain->RegisterLoaderAllocatorForDeletion(m_pLoaderAllocator); - } - } - m_pLoaderAllocator = NULL; - } - COUNTER_ONLY(GetPerfCounters().m_Loading.cAssemblies--); - #ifdef PROFILING_SUPPORTED if (CORProfilerTrackAssemblyLoads()) { @@ -709,6 +664,7 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs if ((args->access & ASSEMBLY_ACCESS_COLLECT) != 0) { AssemblyLoaderAllocator *pAssemblyLoaderAllocator = new AssemblyLoaderAllocator(); + pAssemblyLoaderAllocator->SetCollectible(); pLoaderAllocator = pAssemblyLoaderAllocator; // Some of the initialization functions are not virtual. Call through the derived class @@ -728,6 +684,12 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs // Create a domain assembly pDomainAssembly = new DomainAssembly(pDomain, pFile, pLoaderAllocator); + if (pDomainAssembly->IsCollectible()) + { + // We add the assembly to the LoaderAllocator only when we are sure that it can be added + // and won't be deleted in case of a concurrent load from the same ALC + ((AssemblyLoaderAllocator *)(LoaderAllocator *)pLoaderAllocator)->AddDomainAssembly(pDomainAssembly); + } } // Start loading process @@ -749,7 +711,7 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs { // Initializing the virtual call stub manager is delayed to remove the need for the LoaderAllocator destructor to properly handle // uninitializing the VSD system. (There is a need to suspend the runtime, and that's tricky) - pLoaderAllocator->InitVirtualCallStubManager(pDomain, TRUE); + pLoaderAllocator->InitVirtualCallStubManager(pDomain); } } |