Fix TailCallStress mode to do more legality checks (#17763)
authorEugene Rozenfeld <erozen@microsoft.com>
Wed, 25 Apr 2018 05:36:19 +0000 (22:36 -0700)
committerGitHub <noreply@github.com>
Wed, 25 Apr 2018 05:36:19 +0000 (22:36 -0700)
Check with EE whether tail call is allowed before adding
tail. prefix in TailCallStress mode.

src/jit/importer.cpp

index 6383ba5..905cb97 100644 (file)
@@ -13395,16 +13395,24 @@ void Compiler::impImportBlockCode(BasicBlock* block)
                                                              // 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;
+                            }
                         }
                     }
                 }