Skip to content

Commit

Permalink
Always use portable tailcalling mechanism for delegate tailcalls
Browse files Browse the repository at this point in the history
It is rare but possible to have delegates that point to VSD stubs. Since
VSD stubs on x86 may disassemble the call-site we cannot allow tail
calling these with the old mechanism.

Fix dotnet#70259
  • Loading branch information
jakobbotsch committed Jun 5, 2022
1 parent f21ace5 commit 77a4450
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5649,7 +5649,7 @@ class Compiler
#endif
bool fgCheckStmtAfterTailCall();
GenTree* fgMorphTailCallViaHelpers(GenTreeCall* call, CORINFO_TAILCALL_HELPERS& help);
bool fgCanTailCallViaJitHelper();
bool fgCanTailCallViaJitHelper(GenTreeCall* call);
void fgMorphTailCallViaJitHelper(GenTreeCall* call);
GenTree* fgCreateCallDispatcherAndGetResult(GenTreeCall* origCall,
CORINFO_METHOD_HANDLE callTargetStubHnd,
Expand Down
18 changes: 16 additions & 2 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6645,7 +6645,7 @@ GenTree* Compiler::fgMorphPotentialTailCall(GenTreeCall* call)

// On x86 we have a faster mechanism than the general one which we use
// in almost all cases. See fgCanTailCallViaJitHelper for more information.
if (fgCanTailCallViaJitHelper())
if (fgCanTailCallViaJitHelper(call))
{
tailCallViaJitHelper = true;
}
Expand Down Expand Up @@ -17688,10 +17688,13 @@ bool Compiler::fgCheckStmtAfterTailCall()
// fgCanTailCallViaJitHelper: check whether we can use the faster tailcall
// JIT helper on x86.
//
// Arguments:
// call - the tailcall
//
// Return Value:
// 'true' if we can; or 'false' if we should use the generic tailcall mechanism.
//
bool Compiler::fgCanTailCallViaJitHelper()
bool Compiler::fgCanTailCallViaJitHelper(GenTreeCall* call)
{
#if !defined(TARGET_X86) || defined(UNIX_X86_ABI)
// On anything except windows X86 we have no faster mechanism available.
Expand All @@ -17700,11 +17703,22 @@ bool Compiler::fgCanTailCallViaJitHelper()
// For R2R make sure we go through portable mechanism that the 'EE' side
// will properly turn into a runtime JIT.
if (opts.IsReadyToRun())
{
return false;
}

// The JIT helper does not properly handle the case where localloc was used.
if (compLocallocUsed)
{
return false;
}

// Delegate calls may go through VSD stub in rare cases. Those look at the
// call site so we cannot use the JIT helper.
if (call->IsDelegateInvoke())
{
return false;
}

return true;
#endif
Expand Down

0 comments on commit 77a4450

Please sign in to comment.