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

Address StackOverflowExceptions in typechecking #17654

Merged
merged 10 commits into from
Sep 6, 2024

Conversation

T-Gro
Copy link
Member

@T-Gro T-Gro commented Sep 2, 2024

There have been two detected scenarios of System.StackoverFlowException crashing the IDE.

First was happening during typecheck, at TcModuleOrNamespaceElementNonMutRec (non recursive module/ns).
This is addressed by adding specific StackGuard calls integrated with the cancellable CE.

The second only happened in series of edits, which was eventually drilled down to be a consequence of System.OperationCanceledException triggered by the ID (new keystrokes invalidated previous requests for diagnostics).

It turned out that recursive calls into TcExpr were fitting into the stack (and they are wrapped in StackGuard as well), but when unrolling an exception, CLR has an overhead of roughly 10K for every catch+handler+rethrow.

The way the codegen for try .. with | SomeActivePatternOnException -> .. works lead to always hitting the catch handler, and rethrowing in the scenario of the active pattern not matching.
Which was happening every single frame with a catch handler, repeating this across 50-100 calls into TcExpr.

The change is to replace the IL generated .try ... catch with an .try ... filter ... catch in scenarios with either an active pattern or a when guard. With the filter IL block, the catch handler is invoked only if the filter passes.

The reproducible StackOverflow was added as a test, and the same test is recompiled with different compiler switch to demonstrate it no longer stack overflows.

Copy link
Contributor

github-actions bot commented Sep 2, 2024

❗ Release notes required


✅ Found changes and release notes in following paths:

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/9.0.100.md

@T-Gro T-Gro marked this pull request as ready for review September 3, 2024 08:33
@T-Gro T-Gro requested a review from a team as a code owner September 3, 2024 08:33
@T-Gro T-Gro changed the title [WIP] Address StackOverflowException happening at TcModuleOrNamespaceElementNonMutRec (non recursive module/ns) Address StackOverflowException happening at TcModuleOrNamespaceElementNonMutRec (non recursive module/ns) Sep 4, 2024
@T-Gro T-Gro changed the title Address StackOverflowException happening at TcModuleOrNamespaceElementNonMutRec (non recursive module/ns) Address StackOverflowExceptions in typechecking Sep 5, 2024

| SynModuleDecl.Expr _ -> failwith "unreachable: SynModuleDecl.Expr - ElimSynModuleDeclExpr"

| SynModuleDecl.NamespaceFragment _ as d -> error(Error(FSComp.SR.tcUnsupportedMutRecDecl(), d.Range)))
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to use errorR here too ?

Copy link
Member Author

Choose a reason for hiding this comment

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

TBH this was just a code block moved, I did not touch it nor investigate it.

@T-Gro T-Gro linked an issue Sep 5, 2024 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

SO in non-recursive bindings checks
4 participants