Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Add #ifdef FEATURE_COLLECTIBLE_ALC
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Dec 30, 2016
1 parent c2b428d commit c3dfee1
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 21 deletions.
12 changes: 10 additions & 2 deletions src/binder/clrprivbinderassemblyloadcontext.cpp
Expand Up @@ -223,12 +223,16 @@ HRESULT CLRPrivBinderAssemblyLoadContext::GetLoaderAllocator(LoaderAllocator **p
/* static */
HRESULT CLRPrivBinderAssemblyLoadContext::SetupContext(DWORD dwAppDomainId,
CLRPrivBinderCoreCLR *pTPABinder,
#ifdef FEATURE_COLLECTIBLE_ALC
LoaderAllocator* pLoaderAllocator,
void* loaderAllocatorHandle,
#endif
UINT_PTR ptrAssemblyLoadContext,
CLRPrivBinderAssemblyLoadContext **ppBindContext)
{
#ifdef FEATURE_COLLECTIBLE_ALC
_ASSERTE(pLoaderAllocator != NULL);
#endif

HRESULT hr = E_FAIL;
EX_TRY
Expand All @@ -255,6 +259,7 @@ HRESULT CLRPrivBinderAssemblyLoadContext::SetupContext(DWORD dwAppDomainId,
// AssemblyLoadContext instance
pBinder->m_ptrManagedAssemblyLoadContext = ptrAssemblyLoadContext;

#ifdef FEATURE_COLLECTIBLE_ALC
// Link to LoaderAllocator, keep a reference to it
VERIFY(pLoaderAllocator->AddReferenceIfAlive());
pBinder->m_pAssemblyLoaderAllocator = pLoaderAllocator;
Expand All @@ -263,7 +268,7 @@ HRESULT CLRPrivBinderAssemblyLoadContext::SetupContext(DWORD dwAppDomainId,
#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
((AssemblyLoaderAllocator*)pLoaderAllocator)->RegisterBinder(pBinder);
#endif

#endif // FEATURE_COLLECTIBLE_ALC
// Return reference to the allocated Binder instance
*ppBindContext = clr::SafeAddRef(pBinder.Extract());
}
Expand All @@ -275,6 +280,7 @@ HRESULT CLRPrivBinderAssemblyLoadContext::SetupContext(DWORD dwAppDomainId,
return hr;
}

#ifdef FEATURE_COLLECTIBLE_ALC
void CLRPrivBinderAssemblyLoadContext::PrepareForLoadContextRelease(INT_PTR ptrManagedStrongAssemblyLoadContext)
{
CONTRACTL
Expand Down Expand Up @@ -303,12 +309,14 @@ void CLRPrivBinderAssemblyLoadContext::PrepareForLoadContextRelease(INT_PTR ptrM
DestroyHandle(reinterpret_cast<OBJECTHANDLE>(m_loaderAllocatorHandle));
m_loaderAllocatorHandle = NULL;
}
#endif // FEATURE_COLLECTIBLE_ALC

CLRPrivBinderAssemblyLoadContext::CLRPrivBinderAssemblyLoadContext()
{
m_pTPABinder = NULL;
}

#ifdef FEATURE_COLLECTIBLE_ALC
void CLRPrivBinderAssemblyLoadContext::ReleaseLoadContext()
{
VERIFY(m_ptrManagedAssemblyLoadContext != NULL);
Expand All @@ -319,6 +327,6 @@ void CLRPrivBinderAssemblyLoadContext::ReleaseLoadContext()
DestroyHandle(handle);
m_ptrManagedAssemblyLoadContext = NULL;
}

#endif // FEATURE_COLLECTIBLE_ALC

#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
10 changes: 7 additions & 3 deletions src/binder/inc/clrprivbinderassemblyloadcontext.h
Expand Up @@ -84,12 +84,17 @@ class CLRPrivBinderAssemblyLoadContext :

static HRESULT SetupContext(DWORD dwAppDomainId,
CLRPrivBinderCoreCLR *pTPABinder,
#ifdef FEATURE_COLLECTIBLE_ALC
LoaderAllocator* pLoaderAllocator,
void* loaderAllocatorHandle,
#endif
UINT_PTR ptrAssemblyLoadContext,
CLRPrivBinderAssemblyLoadContext **ppBindContext);

#ifdef FEATURE_COLLECTIBLE_ALC
void PrepareForLoadContextRelease(INT_PTR ptrManagedStrongAssemblyLoadContext);
void ReleaseLoadContext();
#endif

CLRPrivBinderAssemblyLoadContext();

Expand All @@ -103,8 +108,6 @@ class CLRPrivBinderAssemblyLoadContext :
return m_ptrManagedAssemblyLoadContext;
}

void ReleaseLoadContext();

HRESULT BindUsingPEImage( /* in */ PEImage *pPEImage,
/* in */ BOOL fIsNativeImage,
/* [retval][out] */ ICLRPrivAssembly **ppAssembly);
Expand All @@ -121,9 +124,10 @@ class CLRPrivBinderAssemblyLoadContext :

INT_PTR m_ptrManagedAssemblyLoadContext;

#ifdef FEATURE_COLLECTIBLE_ALC
LoaderAllocator* m_pAssemblyLoaderAllocator;

void* m_loaderAllocatorHandle;
#endif
};

#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
Expand Down
10 changes: 5 additions & 5 deletions src/mscorlib/model.xml
Expand Up @@ -1051,9 +1051,9 @@
</Type>
<Type Name="System.Runtime.Loader.AssemblyLoadContext" condition="FEATURE_HOST_ASSEMBLY_RESOLVER">
<Member Name="#ctor" />
<Member Name="#ctor(System.Boolean)" />
<Member Name="Finalize" />
<Member MemberType="Property" Name="IsCollectible" />
<Member Name="#ctor(System.Boolean)" condition="FEATURE_COLLECTIBLE_ALC"/>
<Member Name="Finalize" condition="FEATURE_COLLECTIBLE_ALC"/>
<Member MemberType="Property" Name="IsCollectible" condition="FEATURE_COLLECTIBLE_ALC"/>
<Member MemberType="Property" Name="Default" />
<Member Name="GetAssemblyName(System.String)" />
<Member Name="GetLoadContext(System.Reflection.Assembly)" />
Expand All @@ -1070,8 +1070,8 @@
<Member Name="OnUnloading" />
<Member Name="LoadUnmanagedDll(System.String)" />
<Member Name="LoadUnmanagedDllFromPath(System.String)" />
<Member Name="Unload" />
<Member Name="UnloadCollectible" />
<Member Name="Unload" condition="FEATURE_COLLECTIBLE_ALC"/>
<Member Name="UnloadCollectible" condition="FEATURE_COLLECTIBLE_ALC"/>
<Member Name="GetLoadedAssemblies" />
<Member Name="get_Default" />
<Member Name="SetProfileOptimizationRoot(System.String)" />
Expand Down
27 changes: 26 additions & 1 deletion src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
Expand Up @@ -43,11 +43,15 @@ public abstract class AssemblyLoadContext

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
#if FEATURE_COLLECTIBLE_ALC
private static extern IntPtr InitializeAssemblyLoadContext(IntPtr ptrAssemblyLoadContext, bool fRepresentsTPALoadContext, bool isCollectible);

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void PrepareForAssemblyLoadContextRelease(IntPtr ptrNativeAssemblyLoadContext, IntPtr ptrAssemblyLoadContextStrong);
#else
private static extern IntPtr InitializeAssemblyLoadContext(IntPtr ptrAssemblyLoadContext, bool fRepresentsTPALoadContext);
#endif

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
Expand All @@ -73,6 +77,7 @@ static AssemblyLoadContext()
AppContext.Unloading += OnAppContextUnloading;
}

#if FEATURE_COLLECTIBLE_ALC
protected AssemblyLoadContext() : this(false, false)
{
}
Expand All @@ -82,10 +87,18 @@ protected AssemblyLoadContext(bool isCollectible) : this(false, isCollectible)
}

internal AssemblyLoadContext(bool fRepresentsTPALoadContext, bool isCollectible)
#else
protected AssemblyLoadContext() : this(false)
{
}

internal AssemblyLoadContext(bool fRepresentsTPALoadContext)
#endif
{
#if FEATURE_COLLECTIBLE_ALC
// Initialize the VM side of AssemblyLoadContext if not already done.
IsCollectible = isCollectible;

#endif
// Add this instance to the list of alive ALC
lock (contextsToUnload)
{
Expand All @@ -98,9 +111,15 @@ internal AssemblyLoadContext(bool fRepresentsTPALoadContext, bool isCollectible)
// If this is a collectible ALC, we are creating a weak handle that will be transformed to
// a strong handle on unloading otherwise we use a strong handle in order to call any subscriber
// to the Unload event when AppDomain.ProcessExit is called
#if FEATURE_COLLECTIBLE_ALC
var thisHandle = GCHandle.Alloc(this, IsCollectible ? GCHandleType.Weak : GCHandleType.Normal);
var thisHandlePtr = GCHandle.ToIntPtr(thisHandle);
m_pNativeAssemblyLoadContext = InitializeAssemblyLoadContext(thisHandlePtr, fRepresentsTPALoadContext, isCollectible);
#else
var thisHandle = GCHandle.Alloc(this, GCHandleType.Normal);
var thisHandlePtr = GCHandle.ToIntPtr(thisHandle);
m_pNativeAssemblyLoadContext = InitializeAssemblyLoadContext(thisHandlePtr, fRepresentsTPALoadContext);
#endif

// Initialize event handlers to be null by default
Resolving = null;
Expand All @@ -111,6 +130,7 @@ internal AssemblyLoadContext(bool fRepresentsTPALoadContext, bool isCollectible)
}
}

#if FEATURE_COLLECTIBLE_ALC
~AssemblyLoadContext()
{
// Only valid for a Collectible ALC
Expand All @@ -132,6 +152,7 @@ internal AssemblyLoadContext(bool fRepresentsTPALoadContext, bool isCollectible)
}

public bool IsCollectible { get; }
#endif

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
Expand Down Expand Up @@ -251,6 +272,7 @@ public Assembly LoadFromStream(Stream assembly, Stream assemblySymbols)
}
}

#if FEATURE_COLLECTIBLE_ALC
public void Unload()
{
if (!IsCollectible)
Expand Down Expand Up @@ -283,6 +305,7 @@ private void UnloadCollectible()
}
state = InternalState.Unloading;
}
#endif

private void VerifyIsAlive()
{
Expand Down Expand Up @@ -421,12 +444,14 @@ private void OnUnloading()
}
}

#if FEATURE_COLLECTIBLE_ALC
private static void OnUnloadingStatic(IntPtr gchManagedAssemblyLoadContext)
{
// This method is invoked by the VM after an Unload has been requested
var context = (AssemblyLoadContext) GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target;
context.OnUnloading();
}
#endif

public Assembly LoadFromAssemblyName(AssemblyName assemblyName)
{
Expand Down
17 changes: 17 additions & 0 deletions src/vm/appdomain.cpp
Expand Up @@ -7571,11 +7571,28 @@ void AppDomain::CheckForMismatchedNativeImages(AssemblySpec * pSpec, const GUID
//
// No entry yet - create one
//
#ifndef FEATURE_COLLECTIBLE_ALC
AllocMemTracker amTracker;
AllocMemTracker *pamTracker = &amTracker;

NativeImageDependenciesEntry * pNewEntry =
new (pamTracker->Track(GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(NativeImageDependenciesEntry)))))
NativeImageDependenciesEntry();

pNewEntry->m_AssemblySpec.CopyFrom(pSpec);
pNewEntry->m_AssemblySpec.CloneFieldsToLoaderHeap(AssemblySpec::ALL_OWNED, GetLowFrequencyHeap(), pamTracker);

pNewEntry->m_guidMVID = *pGuid;

m_NativeImageDependencies.Add(pNewEntry);
amTracker.SuppressRelease();
#else
NativeImageDependenciesEntry * pNewEntry = new NativeImageDependenciesEntry();
pNewEntry->m_AssemblySpec.CopyFrom(pSpec);
pNewEntry->m_AssemblySpec.CloneFields(AssemblySpec::ALL_OWNED);
pNewEntry->m_guidMVID = *pGuid;
m_NativeImageDependencies.Add(pNewEntry);
#endif
}
}

Expand Down
15 changes: 14 additions & 1 deletion src/vm/assemblynative.cpp
Expand Up @@ -2484,7 +2484,12 @@ BOOL QCALLTYPE AssemblyNative::IsDesignerBindingContext(QCall::AssemblyHandle pA

#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
/*static*/

#ifdef FEATURE_COLLECTIBLE_ALC
INT_PTR QCALLTYPE AssemblyNative::InitializeAssemblyLoadContext(INT_PTR ptrManagedAssemblyLoadContext, BOOL fRepresentsTPALoadContext, BOOL fIsCollectible)
#else
INT_PTR QCALLTYPE AssemblyNative::InitializeAssemblyLoadContext(INT_PTR ptrManagedAssemblyLoadContext, BOOL fRepresentsTPALoadContext)
#endif
{
QCALL_CONTRACT;

Expand All @@ -2506,10 +2511,12 @@ INT_PTR QCALLTYPE AssemblyNative::InitializeAssemblyLoadContext(INT_PTR ptrManag

// Create a new AssemblyLoaderAllocator for an AssemblyLoadContext
AssemblyLoaderAllocator* loaderAllocator = new AssemblyLoaderAllocator();
#ifdef FEATURE_COLLECTIBLE_ALC
if (fIsCollectible)
{
loaderAllocator->SetCollectible();
}
#endif

OBJECTHANDLE loaderAllocatorHandle;
GCX_COOP();
Expand All @@ -2527,14 +2534,18 @@ INT_PTR QCALLTYPE AssemblyNative::InitializeAssemblyLoadContext(INT_PTR ptrManag
}

// Create a strong handle to the LoaderAllocator
// If FEATURE_COLLECTIBLE_ALC is not defined, the LoaderAllocator will get never released
loaderAllocatorHandle = pCurDomain->CreateHandle(pManagedLoaderAllocator);

GCPROTECT_END();

loaderAllocator->ActivateManagedTracking();

#ifdef FEATURE_COLLECTIBLE_ALC
IfFailThrow(CLRPrivBinderAssemblyLoadContext::SetupContext(pCurDomain->GetId().m_dwId, pTPABinderContext, loaderAllocator, loaderAllocatorHandle, ptrManagedAssemblyLoadContext, &pBindContext));

#else
IfFailThrow(CLRPrivBinderAssemblyLoadContext::SetupContext(pCurDomain->GetId().m_dwId, pTPABinderContext, ptrManagedAssemblyLoadContext, &pBindContext));
#endif
ptrNativeAssemblyLoadContext = reinterpret_cast<INT_PTR>(pBindContext);
}
else
Expand All @@ -2557,6 +2568,7 @@ INT_PTR QCALLTYPE AssemblyNative::InitializeAssemblyLoadContext(INT_PTR ptrManag
return ptrNativeAssemblyLoadContext;
}

#ifdef FEATURE_COLLECTIBLE_ALC
/*static*/
void QCALLTYPE AssemblyNative::PrepareForAssemblyLoadContextRelease(INT_PTR ptrNativeAssemblyLoadContext, INT_PTR ptrManagedStrongAssemblyLoadContext)
{
Expand All @@ -2574,6 +2586,7 @@ void QCALLTYPE AssemblyNative::PrepareForAssemblyLoadContextRelease(INT_PTR ptrN

END_QCALL;
}
#endif

/*static*/
BOOL QCALLTYPE AssemblyNative::OverrideDefaultAssemblyLoadContextForCurrentDomain(INT_PTR ptrNativeAssemblyLoadContext)
Expand Down
4 changes: 4 additions & 0 deletions src/vm/assemblynative.hpp
Expand Up @@ -248,8 +248,12 @@ class AssemblyNative
BOOL QCALLTYPE IsDesignerBindingContext(QCall::AssemblyHandle pAssembly);
#endif

#ifdef FEATURE_COLLECTIBLE_ALC
static INT_PTR QCALLTYPE InitializeAssemblyLoadContext(INT_PTR ptrManagedAssemblyLoadContext, BOOL fRepresentsTPALoadContext, BOOL fIsCollectible);
static void QCALLTYPE PrepareForAssemblyLoadContextRelease(INT_PTR ptrNativeAssemblyLoadContext, INT_PTR ptrManagedStrongAssemblyLoadContext);
#else
static INT_PTR QCALLTYPE InitializeAssemblyLoadContext(INT_PTR ptrManagedAssemblyLoadContext, BOOL fRepresentsTPALoadContext);
#endif
static BOOL QCALLTYPE OverrideDefaultAssemblyLoadContextForCurrentDomain(INT_PTR ptrNativeAssemblyLoadContext);
static BOOL QCALLTYPE CanUseAppPathAssemblyLoadContextInCurrentDomain();
static void QCALLTYPE LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext, LPCWSTR pwzILPath, LPCWSTR pwzNIPath, QCall::ObjectHandleOnStack retLoadedAssembly);
Expand Down
6 changes: 2 additions & 4 deletions src/vm/assemblyspec.cpp
Expand Up @@ -1812,7 +1812,7 @@ void AssemblySpecBindingCache::Init(CrstBase *pCrst, LoaderHeap *pHeap)
m_pHeap = pHeap;
}

AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInternal(AssemblySpec* pSpec, BOOL fThrow, BOOL remove)
AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInternal(AssemblySpec* pSpec, BOOL fThrow)
{
CONTRACTL
{
Expand Down Expand Up @@ -1872,9 +1872,7 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInter
}
#endif

AssemblyBinding* pEntry = (AssemblyBinding *)(remove ?
m_map.DeleteValue(lookupKey, pSpec)
: m_map.LookupValue(lookupKey, pSpec));
AssemblyBinding* pEntry = (AssemblyBinding *)m_map.LookupValue(lookupKey, pSpec);

#if defined(FEATURE_CORECLR)
// Reset the binding context if one was originally never present in the AssemblySpec and we didnt find any entry
Expand Down
2 changes: 1 addition & 1 deletion src/vm/assemblyspec.hpp
Expand Up @@ -653,7 +653,7 @@ class AssemblySpecBindingCache
PtrHashMap m_map;
LoaderHeap *m_pHeap;

AssemblySpecBindingCache::AssemblyBinding* LookupInternal(AssemblySpec* pSpec, BOOL fThrow = FALSE, BOOL remove = FALSE);
AssemblySpecBindingCache::AssemblyBinding* LookupInternal(AssemblySpec* pSpec, BOOL fThrow = FALSE);

public:

Expand Down
2 changes: 2 additions & 0 deletions src/vm/ecalllist.h
Expand Up @@ -1140,7 +1140,9 @@ FCFuncEnd()
#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
FCFuncStart(gAssemblyLoadContextFuncs)
QCFuncElement("InitializeAssemblyLoadContext", AssemblyNative::InitializeAssemblyLoadContext)
#ifdef FEATURE_COLLECTIBLE_ALC
QCFuncElement("PrepareForAssemblyLoadContextRelease", AssemblyNative::PrepareForAssemblyLoadContextRelease)
#endif
QCFuncElement("LoadFromPath", AssemblyNative::LoadFromPath)
QCFuncElement("GetLoadedAssembliesInternal", AssemblyNative::GetLoadedAssembliesInternal)
QCFuncElement("InternalLoadUnmanagedDllFromPath", AssemblyNative::InternalLoadUnmanagedDllFromPath)
Expand Down

0 comments on commit c3dfee1

Please sign in to comment.