Skip to content

Conversation

@JoeRobich
Copy link
Member

We ship several analyzers and source-generators in the SDK that are added to most projects. We want to ship these as Ready2Run so that we reduce JIT time. However, when an assembly is loaded into a collectible AssemblyLoadContext it prevents any of the R2R logic from being used.

We ship several analyzers and source-generators in the SDK that are added to most projects. We want to ship these as Ready2Run so that we reduce JIT time. However, when an assembly is loaded into a collectible AssemblyLoadContext it prevents any of the R2R logic from being used.
@JoeRobich JoeRobich requested a review from a team as a code owner August 20, 2025 21:27
[CombinatorialData]
public void AssemblyLoading_DoesNotUseCollectibleALCs(AnalyzerTestKind kind)
{
// When an assembly is loaded into a collectible AssemblyLoadContext it prevents any of the R2R logic from being used.
Copy link
Member

Choose a reason for hiding this comment

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

Put a blurb that this R2R is critical to our VS / CLI perfromance scenarios. Basically a place for some future dev to look for context if they ever want to change this.

@chsienki
Copy link
Member

I'm curious, how does this affect generator/analyzer reloading in VS?

I assumed we were unloading the old ALCs when we load new ones, but maybe not? Are we just going to keep loading things into memory until you restart? That's probably fine as it'll just get paged out and never used again but just want to understand if so.

try
{
context.Unload();
CodeAnalysisEventSource.Log.DisposeAssemblyLoadContext(context.Directory, context.ToString());
Copy link
Member Author

Choose a reason for hiding this comment

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

I waffled on whether to remove these EventSource methods. I see that they are numbered and didn't want to throw off any telemetry. Would marking them as obsolete be the way to go?

Copy link
Member

Choose a reason for hiding this comment

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

Seems like a reasonable approach.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll do this in a follow up.


public DirectoryLoadContext(string directory, AnalyzerAssemblyLoader loader)
: base(isCollectible: true)
: base(isCollectible: false)
Copy link
Member Author

Choose a reason for hiding this comment

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

@CyrusNajmabadi I saw that Extensions use the assembly loader. Will this break those scenarios?

Copy link
Member

Choose a reason for hiding this comment

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

The extension assembly support is supposed to be able to hot unload extensions. We definitely are calling it here here -

public void Unload() => assemblyLoader.Dispose();

In this, are the assemblies still getting unloaded, but we're not disposing of the ALC? Or are both the assemblies and ALC staying around?

Copy link
Member Author

Choose a reason for hiding this comment

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

Going to take this as is but will follow up with a PR making isCollectible configurable.

Copy link
Member

Choose a reason for hiding this comment

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

yeah. we should make this configurable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Opened #79997

@JoeRobich
Copy link
Member Author

I'm curious, how does this affect generator/analyzer reloading in VS?

I assumed we were unloading the old ALCs when we load new ones, but maybe not? Are we just going to keep loading things into memory until you restart? That's probably fine as it'll just get paged out and never used again but just want to understand if so.

That matches my understanding. As the old IsolatedAnalyzerReferenceSets get finalized they dispose their AnalyzerAssemblyLoader which will no longer unload.

try
{
context.Unload();
CodeAnalysisEventSource.Log.DisposeAssemblyLoadContext(context.Directory, context.ToString());
Copy link
Member

Choose a reason for hiding this comment

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

Seems like a reasonable approach.

@JoeRobich JoeRobich merged commit 5fc4a5f into main Aug 21, 2025
24 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Aug 21, 2025
@akhera99 akhera99 modified the milestones: Next, 18.0 P1, 18.0 P2 Sep 22, 2025
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.

8 participants