Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid concurrent use of ConditionalWeakTable on net472 #57643

Closed
wants to merge 1 commit into from

Conversation

sharwell
Copy link
Member

@sharwell sharwell commented Nov 9, 2021

Avoids a read lock in ConditionalWeakTable for .NET Framework, which results in extreme contention on concurrent paths. For source generators producing large amounts of code in parallel, the default use of ElasticMarker made most SyntaxFactory methods completely unusable (e.g. CsWin32 wrote a complete new syntax factory just to avoid this).

The clear downside of this change is it increases the size of GreenNode by 8 bytes when executing on .NET Framework (including inside Visual Studio), which is heavily allocated.

Fixes AB#1420484

@sharwell sharwell requested a review from a team as a code owner November 9, 2021 00:48
@sharwell
Copy link
Member Author

sharwell commented Nov 9, 2021

This is going to be a tough call since the change offers significant benefits to one scenario (heavy use of SyntaxFactory) with a non-trivial disadvantage across all .NET Framework usage. The problems resolve themselves when .NET Core / .NET is used, but some environments including Visual Studio and certain builds still use .NET Framework.

/cc @jaredpar @cston @VSadov

/cc @davkean @AArnott

@jaredpar
Copy link
Member

jaredpar commented Nov 9, 2021

Seems like we should start a permanent exception thread with the VS team before taking this PR. Seemingly we need to decide between the idea of taking a higher allocation hit here or living with the contention issue on .NET Framework. Those are the only viable options that we have on the table right now.

Certainly open to other ideas here but thus far those seem like the only two viable ones.

@davkean
Copy link
Member

davkean commented Nov 9, 2021

This has a pretty wild stats in the wild, it's ranked #3 of all thread pool issues in 16.11:

Failure Score Session % Cab Count Threads 90th Threads 50th Avg Threads
Stk_ThdPl_Microsoft_CodeAnalysis!Microsoft.CodeAnalysis.GreenNode.GetAnnotations() 313 0.06 16 260 11 66

While it's not seen in a large number of cabs, when it hits, it hits hard.

@CyrusNajmabadi
Copy link
Member

it increases the size of GreenNode by 8 bytes

Whooboy...

when executing on .NET Framework (including inside Visual Studio

Ok. That seems less impactful for me. With VS2022 we are now doing all automatic processing of files (outside of those opened/edited) in our external OOP process.

So you should only potentially run into something here specifically when doing something like a Fix-All or large refactoring that actually touches a significant amount of the in-process solution.

If we can get those things running OOP, then we greatly mitigate that single vector for issues here.

--

Overall then, i think this seems ok.

SyntaxAnnotation[]? annotations;
if (s_annotationsTable.TryGetValue(this, out annotations))
#if NETCOREAPP
if (s_annotationsTable.TryGetValue(this, out var annotations))
Copy link
Contributor

Choose a reason for hiding this comment

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

var

Please spell out the type.

Copy link
Member Author

Choose a reason for hiding this comment

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

➡️ Changed. If this is a common item for code reviews in this path, to save time and make reviews less negative consider updating .editorconfig settings to reveal the situation during initial development.

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.

5 participants