public MethodDesc ResolveVirtualMethod(MethodDesc declMethod, TypeDesc implType, out CORINFO_DEVIRTUALIZATION_DETAIL devirtualizationDetail)
 {
     return(_devirtualizationManager.ResolveVirtualMethod(declMethod, implType, out devirtualizationDetail));
 }
Exemplo n.º 2
0
            protected override MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType implType, out CORINFO_DEVIRTUALIZATION_DETAIL devirtualizationDetail)
            {
                MethodDesc result = base.ResolveVirtualMethod(declMethod, implType, out devirtualizationDetail);

                if (result != null && result.IsFinal && result.OwningType is MetadataType mdType && mdType.IsAbstract)
                {
                    // If this type is abstract check that we saw a non-abstract type deriving from it.
                    // We don't look at virtual methods introduced by abstract classes unless there's a non-abstract
                    // class that needs them (i.e. the non-abstract class doesn't immediately override them).
                    // This lets us optimize out some unused virtual method implementations.
                    // Allowing this to devirtualize would cause trouble because we didn't scan the method
                    // and expected it would be optimized out.
                    if (!_abstractButNonabstractlyOverridenTypes.Contains(mdType.ConvertToCanonForm(CanonicalFormKind.Specific)))
                    {
                        // FAILED_BUBBLE_IMPL_NOT_REFERENCEABLE is close enough...
                        devirtualizationDetail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE_IMPL_NOT_REFERENCEABLE;
                        return(null);
                    }
                }

                return(result);
            }