-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Generate calls to interface methods through resolve helper #112406
base: main
Are you sure you want to change the base?
Conversation
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas |
/azp run runtime-nativeaot-outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
This reverts commit 7f879d6.
For this not to be a throughput regression, we need to figure out a clean way to implement the hack in last two commits. I ran JSON serialization with/without this PR. Having to preserve argument registers before calling the resolve helper costs us about 1% in throughput. PR-hack is the hack where we allow RyuJIT to assume argument registers are not clobbered. We better not take a GC in the slow path.
Do we have a way to do this hack cleanly that doesn't involve building a new universal transition? |
/azp run runtime-nativeaot-outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-nativeaot-outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
342fb19
to
b370b17
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 3 out of 22 changed files in this pull request and generated no comments.
Files not reviewed (19)
- src/coreclr/inc/corinfo.h: Language not supported
- src/coreclr/inc/jiteeversionguid.h: Language not supported
- src/coreclr/inc/jithelpers.h: Language not supported
- src/coreclr/jit/codegencommon.cpp: Language not supported
- src/coreclr/jit/gentree.cpp: Language not supported
- src/coreclr/jit/gentree.h: Language not supported
- src/coreclr/jit/lower.cpp: Language not supported
- src/coreclr/jit/morph.cpp: Language not supported
- src/coreclr/jit/targetamd64.h: Language not supported
- src/coreclr/jit/targetarm64.h: Language not supported
- src/coreclr/nativeaot/Runtime/AsmOffsets.h: Language not supported
- src/coreclr/nativeaot/Runtime/CMakeLists.txt: Language not supported
- src/coreclr/nativeaot/Runtime/EHHelpers.cpp: Language not supported
- src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp: Language not supported
- src/coreclr/nativeaot/Runtime/amd64/DispatchResolve.asm: Language not supported
- src/coreclr/nativeaot/Runtime/amd64/UniversalTransition.asm: Language not supported
- src/coreclr/nativeaot/Runtime/arm64/DispatchResolve.asm: Language not supported
- src/coreclr/nativeaot/Runtime/arm64/UniversalTransition.asm: Language not supported
- src/coreclr/nativeaot/Runtime/inc/rhbinder.h: Language not supported
Comments suppressed due to low confidence (1)
src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs:267
- Ensure that the new helper CORINFO_HELP_INTERFACELOOKUP_FOR_SLOT is covered by tests to verify its behavior.
CORINFO_HELP_INTERFACELOOKUP_FOR_SLOT, // Resolve a non-generic interface method from this pointer and dispatch cell
@dotnet/ilc-contrib this is ready for review @jakobbotsch who would be the best to review the JIT side? |
I pushed a commit to fix the JIT assert and also a probable fix for the GC stress issue (only based on review, haven't tested that one). Will kick off the CFG job again. |
/azp run jit-cfg |
Azure Pipelines successfully started running 1 pipeline(s). |
There's still gcstress failures. I'm guessing there are some more fundamental issues around trying to give this helper a non standard calling convention where GC refs could be in the argument registers. I suspect they are not properly being reported and reflected back to the JIT on return. |
The GC info produced by the JIT does not look right. GC info without CFG - notice that tracking of rcx/rdx/r8/r9 is stopped after the interface call:
GC info with CFG - notice that tracking of rcx/rdx/r8/r9 is stopped before the interface call:
Test program source
|
I can look into that, but do you expect that this is going to make things work? My general wondering is if the runtime would know to report and relocate the GC refs in the argument registers of the transition frame if GC happens while inside the new helper. |
/azp run jit-cfg |
Azure Pipelines successfully started running 1 pipeline(s). |
There's some more JIT work needed to properly report non callee saves after a call. I opened #113071 for it. |
The runtime knows how to do it for the existing VSD helper that tailcalls, so it should be able to do it for helper that returns as well. The new helper uses the same GC reporting setup as the existing VSD helper that tailcalls. In order for this to work, the JIT has to setup all arguments before calling the new helper. It does not seem to be happening in all cases. For example, I see the following codegen for a call from
|
That's expected with how this is implemented in the JIT. The JIT just considers this helper to not trash the argument registers. It is free to leave any GC ref in those registers across the call. It is not considering the "resolve + dispatch" sequence as one unit that takes the arguments of the final call. (I am not sure if this would be feasible on arm64 that uses "resolve + validate + call" sequence). |
Yes, I have pushed a commit to do that (some of the changes in that commit are quick hack that needs cleaning up if it works). |
Track all integer registers for calls in `regPtrDsc`. This does not cost any extra memory and it saves us from going back and forth between an intermediate format. It also unblocks proper GC reporting for helper calls that are GC reported with non-standard calling convention.
/azp run jit-cfg |
Azure Pipelines successfully started running 1 pipeline(s). |
This changes interface calls when CFG is enabled to use a resolve helper instead of the stub dispatcher. I've also extended the CFG testing a bit to cover more of interface calls in the smoke test.
Before this change:
After this change: