Closed jkotas closed 10 months ago
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.
Author: | jkotas |
---|---|
Assignees: | - |
Labels: | `area-CodeGen-coreclr`, `untriaged` |
Milestone: | - |
Thanks for tracking this down. The JIT has had this behavior dating back to .NET Core 2.0 or so. This could cause problems even without R2R, if a profiler driven rejit changed a method that always threw into one that didn't always throw. Presumably not something people do very often. Do you think we need to fix this when jitting as well?
I don't think we expose the cross-version-bubble info to the jit yet...?
I think we want to introduce a new JIT/EE API that the JIT will use to report and confirm attempt to use inlining observations that affect behavior. notifyInstructionSetUsage
is an existing API that follows similar pattern.
The EE side can tell the JIT:
If this sounds overengineered to you, we can do just the first one, ie always treat the dependency on observations same way as inlining.
@jkotas Looks like no-return is the only observation that can cause problems.
Should we call it something like bool canRelyOnObservations(method)
or bool canAssumeMethodWontChange(method)
?
Presumably, the same issue can happen with some hot-reload/ReJIT? if we change IL for a method that was recognized as never-return already.
Should we call it something like bool canRelyOnObservations(method) or bool canAssumeMethodWontChange(method)?
I would expect canXXX
method to be side-effect free. If you are going with my proposal that the EE side is going to do bookkeeping (e.g. similar to existing AddInlining in reportInliningDecision), I think the method name should imply that it is not side-effect free.
I think a good name can be something like notifyMethodInfoUsage
(prior art - notifyInstructionSetUsage
). Alternatively, we can overload the existing reportInliningDecision
- but that makes the contract of reportInliningDecision
even more complicated. I think a new dedicated method would be better.
Presumably, the same issue can happen with some hot-reload/ReJIT?
Correct. The new JIT/EE method should be implemented in both runtime JIT and R2R compiler.
I think a good name can be something like
notifyMethodInfoUsage
Should we stop inlining/IL inspecting if it returns false? Or inlining is fine, only observations should be discarded?
Inlining and observing is fine, just the observation cannot be used for anything that affects observable behavior. For example, the JIT can assume that the method is probably not going to return, but it cannot assume that the method is guaranteed no return.
Reported by internal Microsoft team. Internal link: Watson crash from hitting breakpoint?
Observed behavior
R2R images created with
--opt-cross-module:*
option have spuriousint3
instructions.Analysis of the problem
Inlining in RyuJIT is a two-step process:
We record the dependency on the exact version of the inlined method body only when we perform the actual inlining. I do not see any code for recording dependency on observations.
The problem is that the optimizations can use results from observations even when the inlining is not performed. The observation causing problem here is CALLEE_DOES_NOT_RETURN that makes codegen to think that the code after the method is unreachable and replace it with int3. RyuJIT should drop observations like this for methods outside the current version bubble.