From e4cb4dd894472a9c5efef31e588a9caefd635d24 Mon Sep 17 00:00:00 2001 From: Joseph Tremoulet Date: Mon, 22 Aug 2016 21:14:24 -0400 Subject: [PATCH] Fix IMGREL32 static field addr value-num blindspot When `fgMorphField` lowers a static field reference for which `eeGetRelocTypeHint` returns `IMAGE_REL_BASED_REL32`, it creates an `IntCon`, flagged with `GFT_ICON_STATIC_HDL` and marked with the static field in its `gtFieldSeq` field, to represent the field's address (as opposed to the normal case where it generates a `ClsVar`). This change updates the `IsFieldAddr` helper used by value-numbering/loop-hoisting to recognize such constants as the appropriate field address, which then allows the disambiguation/tracking of accesses to these fields to kick in as it does for `ClsVar` nodes. Also update test GC/Scenarios/FinalizeTimeout to mark a bool volatile that otherwise can get hoisted (the test aims to observe finalization from a side-effect-free busy-loop by communicating through this bool). Fixes #6900. --- src/jit/gentree.cpp | 26 +++++++++++-------- .../FinalizeTimeout/FinalizeTimeout.cs | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index 01c383a7f908..63603d8b0ff5 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -15275,19 +15275,23 @@ bool GenTree::IsFieldAddr(Compiler* comp, GenTreePtr* pObj, GenTreePtr* pStatic, baseAddr = gtOp.gtOp1; } } + // Check if "this" has a zero-offset annotation. + else if (comp->GetZeroOffsetFieldMap()->Lookup(this, &newFldSeq)) + { + baseAddr = this; + mustBeStatic = true; + } + else if (OperGet() == GT_CNS_INT && gtIntCon.gtFieldSeq != nullptr) + { + // Address is a literal constant; must be a static field. + newFldSeq = gtIntCon.gtFieldSeq; + baseAddr = this; + mustBeStatic = true; + } else { - // Check if "this" has a zero-offset annotation. - if (!comp->GetZeroOffsetFieldMap()->Lookup(this, &newFldSeq)) - { - // If not, this is not a field address. - return false; - } - else - { - baseAddr = this; - mustBeStatic = true; - } + // This is not a field address. + return false; } // If not we don't have a field seq, it's not a field address. diff --git a/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs b/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs index 0fda8172e49f..0935b4524f7f 100644 --- a/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs +++ b/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs @@ -47,7 +47,7 @@ private static void ThreadMain() private class BlockingFinalizerOnShutdown { - public static bool finalizerCompletedOnce = false; + public volatile static bool finalizerCompletedOnce = false; public bool isLastObject = false; ~BlockingFinalizerOnShutdown()