Spill the eval stack when storing to a pinned local.
authorAndy Ayers <andya@microsoft.com>
Wed, 3 Jan 2018 22:11:18 +0000 (14:11 -0800)
committerAndy Ayers <andya@microsoft.com>
Wed, 3 Jan 2018 22:11:18 +0000 (14:11 -0800)
The jit may not see direct interference between a pinned local and expressions that use the pinned value. So worst case it should assume that such interference exists and spill the stack when storing to a pinned local. Otherwise the jit may reorder unpins and calls that refer to pinned storage.

Fixes DevDiv 545749

[tfs-changeset: 1685045]

src/jit/importer.cpp

index 23262f3..d463ae2 100644 (file)
@@ -10749,13 +10749,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
 
                 op2 = gtNewLclvNode(lclNum, lclTyp, opcodeOffs + sz + 1);
 
-                /* If the local is aliased, we need to spill calls and
+                /* If the local is aliased or pinned, we need to spill calls and
                    indirections from the stack. */
 
-                if ((lvaTable[lclNum].lvAddrExposed || lvaTable[lclNum].lvHasLdAddrOp) &&
-                    verCurrentState.esStackDepth > 0)
+                if ((lvaTable[lclNum].lvAddrExposed || lvaTable[lclNum].lvHasLdAddrOp || lvaTable[lclNum].lvPinned) &&
+                    (verCurrentState.esStackDepth > 0))
                 {
-                    impSpillSideEffects(false, (unsigned)CHECK_SPILL_ALL DEBUGARG("Local could be aliased"));
+                    impSpillSideEffects(false, (unsigned)CHECK_SPILL_ALL DEBUGARG("Local could be aliased or is pinned"));
                 }
 
                 /* Spill any refs to the local from the stack */