diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 624d6879510ca..60c8041555930 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -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, diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index e1d1ad751107e..609569d145c63 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -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; } @@ -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. @@ -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