summaryrefslogtreecommitdiff
path: root/src/vm/assembly.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/assembly.cpp')
-rw-r--r--src/vm/assembly.cpp54
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);
}
}