Insert int3 after non-returning calls at the end of basic blocks. (#17535)
authorEugene Rozenfeld <erozen@microsoft.com>
Fri, 13 Apr 2018 23:29:12 +0000 (16:29 -0700)
committerGitHub <noreply@github.com>
Fri, 13 Apr 2018 23:29:12 +0000 (16:29 -0700)
This is a follow-up to #17501 that fixed #17398.

gc pointer reporting in fully-interruptible mode: the latter assumed that
register gc pointer liveness doesn't change across calls while #6103 introduced
codegen where it wasn't true.

doesn't change across calls.

This change inserts int3 after non-returning calls at the end of basic blocks
so that gc pointer liveness doesn't change across calls. This is additional
insurance in case any other place in the runtime is dependent on that contract.

src/jit/codegenlinear.cpp

index 6faaf61..26b52c2 100644 (file)
@@ -602,6 +602,22 @@ void CodeGen::genCodeForBBlist()
                 {
                     instGen(INS_BREAKPOINT); // This should never get executed
                 }
+                // Do likewise for blocks that end in DOES_NOT_RETURN calls
+                // that were not caught by the above rules. This ensures that
+                // gc register liveness doesn't change across call instructions
+                // in fully-interruptible mode.
+                else
+                {
+                    GenTree* call = block->lastNode();
+
+                    if ((call != nullptr) && (call->gtOper == GT_CALL))
+                    {
+                        if ((call->gtCall.gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN) != 0)
+                        {
+                            instGen(INS_BREAKPOINT); // This should never get executed
+                        }
+                    }
+                }
 
                 break;