private static IReadOnlyList <MethodDesc> ComputeSlots(TypeDesc type) { var slots = new ArrayBuilder <MethodDesc>(); bool isObjectType = type.IsObject; DefType defType = type.GetClosestDefType(); IEnumerable <MethodDesc> allSlots = type.IsInterface ? GetAllVirtualMethods(type) : defType.EnumAllVirtualSlots(); foreach (var method in allSlots) { // GVMs are not emitted in the type's vtable. if (method.HasInstantiation) { continue; } // Finalizers are called via a field on the EEType, not through the VTable if (isObjectType && method.Name == "Finalize") { continue; } // Current type doesn't define this slot. if (method.OwningType != defType) { continue; } slots.Add(method); } return(slots.ToArray()); }
public override IEnumerable <CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) { // VirtualMethodUse of Foo<SomeType>.Method will bring in VirtualMethodUse // of Foo<__Canon>.Method. This in turn should bring in Foo<OtherType>.Method. DefType defType = _type.GetClosestDefType(); IEnumerable <MethodDesc> allSlots = _type.IsInterface ? GetAllVirtualMethods() : defType.EnumAllVirtualSlots(); foreach (var method in allSlots) { // Generic virtual methods are tracked by an orthogonal mechanism. if (method.HasInstantiation) { continue; } // Current type doesn't define this slot. Another VTableSlice will take care of this. if (method.OwningType != defType) { continue; } yield return(new CombinedDependencyListEntry( factory.VirtualMethodUse(method), factory.VirtualMethodUse(method.GetCanonMethodTarget(CanonicalFormKind.Specific)), "Canonically equivalent virtual method use")); } }
public override IEnumerable <CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) { Debug.Assert(EmitVirtualSlotsAndInterfaces); DefType defType = _type.GetClosestDefType(); // If we're producing a full vtable, none of the dependencies are conditional. if (!factory.VTable(defType).HasFixedSlots) { foreach (MethodDesc decl in defType.EnumAllVirtualSlots()) { // Generic virtual methods are tracked by an orthogonal mechanism. if (decl.HasInstantiation) { continue; } MethodDesc impl = defType.FindVirtualFunctionTargetMethodOnObjectType(decl); if (impl.OwningType == defType && !impl.IsAbstract) { MethodDesc canonImpl = impl.GetCanonMethodTarget(CanonicalFormKind.Specific); yield return(new CombinedDependencyListEntry(factory.MethodEntrypoint(canonImpl, _type.IsValueType), factory.VirtualMethodUse(decl), "Virtual method")); } } Debug.Assert( _type == defType || ((System.Collections.IStructuralEquatable)defType.RuntimeInterfaces).Equals(_type.RuntimeInterfaces, EqualityComparer <DefType> .Default)); // Add conditional dependencies for interface methods the type implements. For example, if the type T implements // interface IFoo which has a method M1, add a dependency on T.M1 dependent on IFoo.M1 being called, since it's // possible for any IFoo object to actually be an instance of T. foreach (DefType interfaceType in defType.RuntimeInterfaces) { Debug.Assert(interfaceType.IsInterface); foreach (MethodDesc interfaceMethod in interfaceType.GetAllMethods()) { if (interfaceMethod.Signature.IsStatic) { continue; } // Generic virtual methods are tracked by an orthogonal mechanism. if (interfaceMethod.HasInstantiation) { continue; } MethodDesc implMethod = defType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod); if (implMethod != null) { yield return(new CombinedDependencyListEntry(factory.VirtualMethodUse(implMethod), factory.VirtualMethodUse(interfaceMethod), "Interface method")); } } } } }
public override IEnumerable <CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) { DefType defType = _type.GetClosestDefType(); foreach (MethodDesc decl in defType.EnumAllVirtualSlots()) { MethodDesc impl = defType.FindVirtualFunctionTargetMethodOnObjectType(decl); if (impl.OwningType == defType && !impl.IsAbstract) { yield return(new DependencyNodeCore <NodeFactory> .CombinedDependencyListEntry(factory.MethodEntrypoint(impl, _type.IsValueType), factory.VirtualMethodUse(decl), "Virtual method")); } } Debug.Assert( _type == defType || ((System.Collections.IStructuralEquatable)defType.RuntimeInterfaces).Equals(_type.RuntimeInterfaces, EqualityComparer <DefType> .Default)); // Add conditional dependencies for interface methods the type implements. For example, if the type T implements // interface IFoo which has a method M1, add a dependency on T.M1 dependent on IFoo.M1 being called, since it's // possible for any IFoo object to actually be an instance of T. foreach (DefType interfaceType in defType.RuntimeInterfaces) { Debug.Assert(interfaceType.IsInterface); foreach (MethodDesc interfaceMethod in interfaceType.GetAllVirtualMethods()) { MethodDesc implMethod = defType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod); if (implMethod != null) { yield return(new CombinedDependencyListEntry(factory.VirtualMethodUse(implMethod), factory.ReadyToRunHelper(ReadyToRunHelperId.InterfaceDispatch, interfaceMethod), "Interface method")); yield return(new CombinedDependencyListEntry(factory.VirtualMethodUse(implMethod), factory.ReadyToRunHelper(ReadyToRunHelperId.ResolveVirtualFunction, interfaceMethod), "Interface method address")); } } } }