Always treat incoming on-stack parameters as GC-untracked.
authorPat Gavlin <pagavlin@microsoft.com>
Tue, 18 Oct 2016 20:04:28 +0000 (13:04 -0700)
committerPat Gavlin <pagavlin@microsoft.com>
Tue, 18 Oct 2016 20:04:28 +0000 (13:04 -0700)
Incoming parameters that are passed on the stack are never reported as
tracked to the GC, but `lvaIsGCTracked` (which is used to determine
whether or not to report liveness for a lclVar's stack slot) still
returned true if the corresponding lclVar was tracked. This caused
problems on x86 when dealing with incoming GC stack parameters in ESP
frames: in this case, writes to a GC stack parameter could incorrectly
change the liveness for a lclVar at the same offset from ESP as the
parameter's offset from EBP.

Fixes dotnet/coreclr#7696.

Commit migrated from https://github.com/dotnet/coreclr/commit/a24d7e9eca0d1d8bf93f854bd9985a8e97526fab

src/coreclr/src/jit/codegencommon.cpp
src/coreclr/src/jit/compiler.hpp

index 91977e9..02e4d46 100755 (executable)
@@ -361,7 +361,7 @@ void CodeGen::genPrepForCompiler()
             {
                 VarSetOps::AddElemD(compiler, compiler->raRegVarsMask, varDsc->lvVarIndex);
             }
-            else if (compiler->lvaIsGCTracked(varDsc) && (!varDsc->lvIsParam || varDsc->lvIsRegArg))
+            else if (compiler->lvaIsGCTracked(varDsc))
             {
                 VarSetOps::AddElemD(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex);
             }
index 0a0687a..22bc288 100644 (file)
@@ -4371,10 +4371,12 @@ inline bool Compiler::lvaIsGCTracked(const LclVarDsc* varDsc)
 {
     if (varDsc->lvTracked && (varDsc->lvType == TYP_REF || varDsc->lvType == TYP_BYREF))
     {
+        // Stack parameters are always untracked w.r.t. GC reportings
+        const bool isStackParam = varDsc->lvIsParam && !varDsc->lvIsRegArg;
 #ifdef _TARGET_AMD64_
-        return !lvaIsFieldOfDependentlyPromotedStruct(varDsc);
+        return !isStackParam && !lvaIsFieldOfDependentlyPromotedStruct(varDsc);
 #else  // !_TARGET_AMD64_
-        return true;
+        return !isStackParam;
 #endif // !_TARGET_AMD64_
     }
     else