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

Fix ILGenerator maxstack computation #70388

Merged
merged 6 commits into from
Jun 22, 2022
Merged

Fix ILGenerator maxstack computation #70388

merged 6 commits into from
Jun 22, 2022

Conversation

panguye
Copy link
Contributor

@panguye panguye commented Jun 7, 2022

When generating a dynamic method both with many unconditional jumps, the
ILGenerator's computation of maxstack is way to large - it adds the max
stack of each basic block ending with an unconditional transfer
(br, ret, throw, etc). If the generated code has many such bbs
(eg, from the "then" clauses of if-then-else constructs) this sum can
overflow 2^16. When it does, the maxstack recorded/used is the computed
value mod 2^16. When that is less than the correct value, the
JIT throws an InvalidProgramException.

Keep track of the stack depth at various positions and use it to
calculate an adjustment to the depth.

Fix #63805

When generating a dynamic method both with many unconditional jumps, the
ILGenerator's computation of maxstack is way to large - it adds the max
stack of each basic block ending with an unconditional transfer
(br, ret, throw, etc). If the generated code has many such bbs
(eg, from the "then" clauses of if-then-else constructs) this sum can
overflow 2^16. When it does, the maxstack recorded/used is the computed
value mod 2^16. When that is less than the correct value, the
JIT throws an InvalidProgramException.

Keep track of the stack depth at various positions and use it to
calculate an adjustment to the depth.

Fix dotnet#63805
@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Jun 7, 2022
@ghost
Copy link

ghost commented Jun 7, 2022

Tagging subscribers to this area: @dotnet/area-system-reflection-emit
See info in area-owners.md if you want to be subscribed.

Issue Details

When generating a dynamic method both with many unconditional jumps, the
ILGenerator's computation of maxstack is way to large - it adds the max
stack of each basic block ending with an unconditional transfer
(br, ret, throw, etc). If the generated code has many such bbs
(eg, from the "then" clauses of if-then-else constructs) this sum can
overflow 2^16. When it does, the maxstack recorded/used is the computed
value mod 2^16. When that is less than the correct value, the
JIT throws an InvalidProgramException.

Keep track of the stack depth at various positions and use it to
calculate an adjustment to the depth.

Fix #63805

Author: panguye
Assignees: -
Labels:

area-System.Reflection.Emit

Milestone: -

@dnfadmin
Copy link

dnfadmin commented Jun 7, 2022

CLA assistant check
All CLA requirements met.

@steveharter steveharter requested a review from jakobbotsch June 9, 2022 14:50
@jkotas jkotas merged commit f310367 into dotnet:main Jun 22, 2022
@jkotas
Copy link
Member

jkotas commented Jun 22, 2022

Thank you!

@ghost ghost locked as resolved and limited conversation to collaborators Jul 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Reflection.Emit community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ILGenerator computation of maxstack is too conservative
5 participants