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());
        }
Exemple #2
0
        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"));
            }
        }
Exemple #3
0
        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"));
                        }
                    }
                }
            }
        }
Exemple #4
0
        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"));
                    }
                }
            }
        }