Skip to content

Conversation

@jakobbotsch
Copy link
Member

In the helper-based tailcall mechanism it is possible that we expand the target call into two actual calls: first, a call to CORINFO_HELP_VIRTUAL_FUNC_PTR to compute the target, and second a call to that target. We were not taking into account that the return address needed for the tailcall mechanism needs to be from the second call.

In this particular case the runtime does not request the JIT to pass the target; that means we end up resolving the target from both the caller and from the CallTailCallTarget stub. Ideally the JIT would be able to eliminate the CORINFO_HELP_VIRTUAL_FUNC_PTR call in the caller since it turns out to be unused, but that requires changes in DCE (and is somewhat non-trivial, as we have to preserve a null-check).

A simpler way to improve the case is to just change the runtime to always request the target from the JIT for GVMs, which means the CallTailCallTarget stub no longer needs to resolve it. That also has the effect of fixing the original issue, but I have left the original fix in as well.

Fix #87393

…esolving

In the helper-based tailcall mechanism it is possible that we expand the
target call into two actual calls: first, a call to
CORINFO_HELP_VIRTUAL_FUNC_PTR to compute the target, and second a call
to that target. We were not taking into account that the return address
needed for the tailcall mechanism needs to be from the second call.

In this particular case the runtime does not request the JIT to pass the
target; that means we end up resolving the target from both the caller
and from the CallTailCallTarget stub. Ideally the JIT would be able to
eliminate the CORINFO_HELP_VIRTUAL_FUNC_PTR call in the caller since it
turns out to be unused, but that requires changes in DCE (and is
somewhat non-trivial, as we have to preserve a null-check).

A simpler way to improve the case is to just change the runtime to
always request the target from the JIT for GVMs, which means the
CallTailCallTarget stub no longer needs to resolve it. That also has the
effect of fixing the original issue, but I have left the original fix in
as well.

Fix dotnet#87393
@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jun 12, 2023
@ghost ghost assigned jakobbotsch Jun 12, 2023
@ghost
Copy link

ghost commented Jun 12, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

In the helper-based tailcall mechanism it is possible that we expand the target call into two actual calls: first, a call to CORINFO_HELP_VIRTUAL_FUNC_PTR to compute the target, and second a call to that target. We were not taking into account that the return address needed for the tailcall mechanism needs to be from the second call.

In this particular case the runtime does not request the JIT to pass the target; that means we end up resolving the target from both the caller and from the CallTailCallTarget stub. Ideally the JIT would be able to eliminate the CORINFO_HELP_VIRTUAL_FUNC_PTR call in the caller since it turns out to be unused, but that requires changes in DCE (and is somewhat non-trivial, as we have to preserve a null-check).

A simpler way to improve the case is to just change the runtime to always request the target from the JIT for GVMs, which means the CallTailCallTarget stub no longer needs to resolve it. That also has the effect of fixing the original issue, but I have left the original fix in as well.

Fix #87393

Author: jakobbotsch
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@jakobbotsch
Copy link
Member Author

/azp run runtime-coreclr jitstress, runtime-coreclr libraries-jitstress

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@jakobbotsch jakobbotsch marked this pull request as ready for review June 12, 2023 17:23
@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @kunalspathak.

Also cc @jkotas for the small VM change

@jakobbotsch jakobbotsch requested a review from kunalspathak June 12, 2023 17:24
@jkotas
Copy link
Member

jkotas commented Jun 12, 2023

VM change LGTM

Copy link
Contributor

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

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

I would probably rename genDefinePendingCallLabel() to genTryDefinePendingCallLabel(), the method will not always define it.

@jakobbotsch
Copy link
Member Author

I would probably rename genDefinePendingCallLabel() to genTryDefinePendingCallLabel(), the method will not always define it.

"Try" to me implies it can fail to define it, but it can't, it just only defines it when it is necessary. genDefinePendingCallLabelIfNecessary could be an alternative but I think I will avoid rerunning CI for it... I'll try to do it in a future change.

@jakobbotsch jakobbotsch merged commit 98926e2 into dotnet:main Jun 12, 2023
@jakobbotsch jakobbotsch deleted the fix-87393 branch June 12, 2023 21:25
@ghost ghost locked as resolved and limited conversation to collaborators Jul 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stack Overflow when using curried interface member, no stack overflow with tupled version

3 participants