Skip to content

Conversation

@JoeRobich
Copy link
Member

Some scenario where AnalyzerAssemblyLoader was useds, such as Extensions, relied on the ALC to be collectible.

Some scenario where AnalyzerAssemblyLoader was useds, such as Extensions, relied on the ALC to be collectible.
ImmutableArray<IAnalyzerAssemblyResolver> assemblyResolvers = default,
System.Runtime.Loader.AssemblyLoadContext? compilerLoadContext = null)
System.Runtime.Loader.AssemblyLoadContext? compilerLoadContext = null,
bool isCollectible = false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name isCollectible is not quite sitting right with me. The behavior it's controlling is what happens on dispose vs. the instance itself being collectible. Maybe collectOnDispose? @jjonescz may have suggestions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collectOnDispose sounds good to me

ImmutableArray<IAnalyzerAssemblyResolver> assemblyResolvers = default,
System.Runtime.Loader.AssemblyLoadContext? compilerLoadContext = null)
System.Runtime.Loader.AssemblyLoadContext? compilerLoadContext = null,
bool isCollectible = false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collectOnDispose sounds good to me

chsienki
chsienki previously approved these changes Aug 21, 2025
Copy link
Member

@chsienki chsienki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, a moral approve as I don't count as a Compiler sign off anymore.

@chsienki chsienki dismissed their stale review August 21, 2025 16:37

No longer on the compiler team

// to bubble out as it must be fixed.
var analyzerAssemblyLoaderProvider = _workspaceServices.GetRequiredService<IAnalyzerAssemblyLoaderProvider>();
var analyzerAssemblyLoader = analyzerAssemblyLoaderProvider.CreateNewShadowCopyLoader();
var analyzerAssemblyLoader = analyzerAssemblyLoaderProvider.CreateNewShadowCopyLoader(collectOnDispose: true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was there another place where we need to set this to true, e.g. for analyzers and generators in the OOP process? cc @CyrusNajmabadi

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can imagine we would want those analyzers and generators to run with R2R when possible. Also, are we certain that these assemblies are ever actually unloaded?

/// cref="ISourceGenerator"/>s in a fresh <see cref="AssemblyLoadContext"/>.
/// </summary>
IAnalyzerAssemblyLoaderInternal CreateNewShadowCopyLoader();
IAnalyzerAssemblyLoaderInternal CreateNewShadowCopyLoader() => CreateNewShadowCopyLoader(collectOnDispose: false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems undesirable for the workspace layer. can we make this either collectOnDispose: true, or have this not be optional so that we are forced to decide what to do with every caller.

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the defualt, as it makes it too easy for the IDE to potentially do the wrong thing.


internal AnalyzerAssemblyLoader(ImmutableArray<IAnalyzerPathResolver> pathResolvers)
: this(pathResolvers, assemblyResolvers: [DiskAnalyzerAssemblyResolver], compilerLoadContext: null)
: this(pathResolvers, assemblyResolvers: [DiskAnalyzerAssemblyResolver], compilerLoadContext: null, collectOnDispose: false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we want to collect here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe collecting will free memory, assuming nothing has somehow pinned the ALC. But collecting will definitely disable R2R leading to performance issues down the road as more analyzers and generators shipped in the SDK are crossgen'd.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is R2R and why does collecting cause a payment for them.

The purpose of us making this collectible is for the important scenario of someone developing their own generators/analyzers and continually recompiling them and wanting them reloaded in OOP without having to restart VS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants