-
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
Simplify "secret stub arg" handling between JIT and EE #100823
Conversation
/azp run runtime-coreclr outerloop, runtime-nativeaot-outerloop, runtime-coreclr r2r |
Azure Pipelines successfully started running 3 pipeline(s). |
cc @dotnet/jit-contrib PTAL @kunalspathak @jkotas (no rush given you're on vacation) In the end I decided not to try to unify x86/arm32 |
Kunal is OOF, but this PR will also break LA64/RISCV64 until they implement #100744 and switch to the new register homing implementation, so I think I will just wait with merging this for now. |
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.
LGTM
/azp run runtime |
Azure Pipelines successfully started running 1 pipeline(s). |
When a pinvoke/reverse pinvoke needs marshalling the VM creates an IL stub to perform this marshalling. These IL stubs have a non-standard parameter called the "secret stub parameter". The VM uses this parameter to map the IL stub back to the user defined function that caused the IL stub to be required (multiple user functions can share the same IL stubs, so the mapping cannot be done by other means). To facilitate the access of this value the JIT must make the parameter's value available to the VM somehow. Previously this was done in two separate ways for 32-bit and 64-bit target: - For 32-bit targets the parameter was marked as do-not-enregister and always spilled to the stack frame at a location that was known by the VM. - For 64-bit targets the parameter was saved in the `InlinedCallFrame` as part of a VM helper call. We still marked it as do-not-enregister, probably because parameter homing did not handle it. For 64-bit targets this introduces a bit of inefficiency: the secret stub parameter is only needed for the IL stubs case, but `InlinedCallFrame` is used for all inlined pinvokes. So we ended up with a larger frame than necessary and with an additional store to the frame, even outside IL stubs. This change removes that inefficiency by unifying how 32-bit and 64-bit targets work: - Switch all platforms to only allocate space in `InlinedCallFrame` for the secret stub parameter when necessary - Move responsibility of storing the secret stub parameter out of `CORINFO_HELP_INIT_PINVOKE_FRAME` and to the JIT generated code - Remove special casing of frame layout around the secret stub parameter and frame structures within the JIT - Enable enregistration for the secret stub parameter Fix dotnet#100662
When a pinvoke/reverse pinvoke needs marshalling the VM creates an IL stub to perform this marshalling. These IL stubs have a non-standard parameter called the "secret stub parameter". The VM uses this parameter to map the IL stub back to the user defined function that caused the IL stub to be required (multiple user functions can share the same IL stubs, so the mapping cannot be done by other means).
To facilitate the access of this value the JIT must make the parameter's value available to the VM somehow. Previously this was done in two separate ways for 32-bit and 64-bit target:
InlinedCallFrame
as part of a VM helper call. We still marked it as do-not-enregister, probably because parameter homing did not handle it.For 64-bit targets this introduces a bit of inefficiency: the secret stub parameter is only needed for the IL stubs case, but
InlinedCallFrame
is used for all inlined pinvokes. So we ended up with a larger frame than necessary and with an additional store to the frame, even outside IL stubs.This change removes that inefficiency by unifying how 32-bit and 64-bit targets work:
InlinedCallFrame
for the secret stub parameter when necessaryCORINFO_HELP_INIT_PINVOKE_FRAME
and to the JIT generated codeFix #100662
Example diff
Benchmark:
Codegen + execution time diffs: x64 (improvement), x86 (no change)