JIT: relax method attribute assertion check in devirtualization (#11730)
authorAndy Ayers <andya@microsoft.com>
Fri, 19 May 2017 15:24:20 +0000 (08:24 -0700)
committerGitHub <noreply@github.com>
Fri, 19 May 2017 15:24:20 +0000 (08:24 -0700)
The jit may see `CORINFO_FLG_DONT_INLINE` change between the time it
first reads a method's attributes and the time it re-reads it, since
jitting on some other thread may have deduced the method as noinline
in between the two reads. This bit doesn't affect devirtualization
and so the bit change is harmless.

Tolerate this by masking out this flag bit when comparing attributes.

No changes to generated code.

Closes #11619.

src/jit/importer.cpp

index 97f538b9b173d30f8c8fa8eb48eb1ff0f1a698b8..5d2603f521940d3cebb3145343c0323b7063506c 100644 (file)
@@ -18592,7 +18592,20 @@ void Compiler::impDevirtualizeCall(GenTreeCall*            call,
 #if defined(DEBUG)
         // Validate that callInfo has up to date method flags
         const DWORD freshBaseMethodAttribs = info.compCompHnd->getMethodAttribs(baseMethod);
-        assert(freshBaseMethodAttribs == baseMethodAttribs);
+
+        // All the base method attributes should agree, save that
+        // CORINFO_FLG_DONT_INLINE may have changed from 0 to 1
+        // because of concurrent jitting activity.
+        //
+        // Note we don't look at this particular flag bit below, and
+        // later on (if we do try and inline) we will rediscover why
+        // the method can't be inlined, so there's no danger here in
+        // seeing this particular flag bit in different states between
+        // the cached and fresh values.
+        if ((freshBaseMethodAttribs & ~CORINFO_FLG_DONT_INLINE) != (baseMethodAttribs & ~CORINFO_FLG_DONT_INLINE))
+        {
+            assert(!"mismatched method attributes");
+        }
 #endif // DEBUG
     }