Remove overly eager devirtualization optimization
authorSimon Nattress <nattress@gmail.com>
Wed, 4 Dec 2019 19:53:11 +0000 (11:53 -0800)
committerSimon Nattress <nattress@gmail.com>
Wed, 4 Dec 2019 19:53:11 +0000 (11:53 -0800)
Earlying out when `declMethod.OwningType == implType` is incorrect when the devirtualization manager resolves a call to `C2::M3` due to the presence of MethodImpls which redirect the slot (if a .override changes the slot, we bail on devirtualizing the call). In the example below (which is taken from https://github.com/dotnet/runtime/blob/859926f4c37158c683157bcd0f2b9d3c62d1f650/src/coreclr/tests/src/Loader/classloader/methodoverriding/regressions/576621/test.il#L10), `C2::M1` provides an override for `C1::M3` (which says the method body now comes from the virtual method `C2::M1`) which comes from a different vtable slot.

```
.class public C1
{
   .method public   virtual instance int32 M1()
   {
      ldc.i4 1
      ret
   }
   .method public   virtual instance int32 M3()
   {
      ldc.i4 3
      ret
   }
}

.class public C2 extends C1
{
   .method public   virtual instance int32 M3()
   {
      ldc.i4 4
      ret
   }
   .method public virtual instance int32 M1()
   {
    .override C1::M3
      ldc.i4 5
      ret
   }
}
```

src/coreclr/src/tools/Common/Compiler/DevirtualizationManager.cs

index 92467d0..6191ebd 100644 (file)
@@ -65,10 +65,6 @@ namespace ILCompiler
 
         protected virtual MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType implType)
         {
-            // Quick check: if decl matches impl, we're done.
-            if (declMethod.OwningType == implType)
-                return declMethod;
-
             MethodDesc impl;
 
             if (declMethod.OwningType.IsInterface)