// make it jump to RET.
(OPCODE)getU1LittleEndian(codeAddr + sz) == CEE_RET; // Next opcode is a CEE_RET
- if (newBBcreatedForTailcallStress &&
- !(prefixFlags & PREFIX_TAILCALL_EXPLICIT) && // User hasn't set "tail." prefix yet.
+ bool hasTailPrefix = (prefixFlags & PREFIX_TAILCALL_EXPLICIT);
+ if (newBBcreatedForTailcallStress && !hasTailPrefix && // User hasn't set "tail." prefix yet.
verCheckTailCallConstraint(opcode, &resolvedToken,
constraintCall ? &constrainedResolvedToken : nullptr,
true) // Is it legal to do tailcall?
)
{
- // Stress the tailcall.
- JITDUMP(" (Tailcall stress: prefixFlags |= PREFIX_TAILCALL_EXPLICIT)");
- prefixFlags |= PREFIX_TAILCALL_EXPLICIT;
+ CORINFO_METHOD_HANDLE declaredCalleeHnd = callInfo.hMethod;
+ bool isVirtual = (callInfo.kind == CORINFO_VIRTUALCALL_STUB) ||
+ (callInfo.kind == CORINFO_VIRTUALCALL_VTABLE);
+ CORINFO_METHOD_HANDLE exactCalleeHnd = isVirtual ? nullptr : declaredCalleeHnd;
+ if (info.compCompHnd->canTailCall(info.compMethodHnd, declaredCalleeHnd, exactCalleeHnd,
+ hasTailPrefix)) // Is it legal to do tailcall?
+ {
+ // Stress the tailcall.
+ JITDUMP(" (Tailcall stress: prefixFlags |= PREFIX_TAILCALL_EXPLICIT)");
+ prefixFlags |= PREFIX_TAILCALL_EXPLICIT;
+ }
}
}
}