public EagerlyBuiltVTableSliceNode(TypeDesc type) : base(type) { var slots = new ArrayBuilder <MethodDesc>(); MethodDesc finalizerMethod = type.GetFinalizer(); DefType defType = _type.GetClosestDefType(); foreach (var method in defType.GetAllMethods()) { if (!method.IsVirtual) { continue; } // 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 (finalizerMethod == method || (type.IsObject && method.Name == "Finalize")) { continue; } slots.Add(method); } _slots = slots.ToArray(); }
public EagerlyBuiltVTableSliceNode(TypeDesc type) : base(type) { var slots = new ArrayBuilder <MethodDesc>(); DefType defType = _type.GetClosestDefType(); foreach (var method in defType.GetAllMethods()) { if (!method.IsVirtual) { continue; } // GVMs are not emitted in the type's vtable. if (method.HasInstantiation) { continue; } slots.Add(method); } _slots = slots.ToArray(); }
/// <summary> /// Gets a value indicating whether '<paramref name="type"/>' might have a non-empty dispatch map. /// Note that this is only an approximation because we might not be able to take into account /// whether the interface methods are actually used. /// </summary> public static bool MightHaveInterfaceDispatchMap(TypeDesc type, NodeFactory factory) { if (type.IsArrayTypeWithoutGenericInterfaces()) { return(false); } if (!type.IsArray && !type.IsDefType) { return(false); } TypeDesc declType = type.GetClosestDefType(); for (int interfaceIndex = 0; interfaceIndex < declType.RuntimeInterfaces.Length; interfaceIndex++) { DefType interfaceType = declType.RuntimeInterfaces[interfaceIndex]; InstantiatedType interfaceOnDefinitionType = interfaceType.IsTypeDefinition ? null : (InstantiatedType)declType.GetTypeDefinition().RuntimeInterfaces[interfaceIndex]; IEnumerable <MethodDesc> slots; // If the vtable has fixed slots, we can query it directly. // If it's a lazily built vtable, we might not be able to query slots // just yet, so approximate by looking at all methods. VTableSliceNode vtableSlice = factory.VTable(interfaceType); if (vtableSlice.HasFixedSlots) { slots = vtableSlice.Slots; } else { slots = interfaceType.GetAllMethods(); } foreach (MethodDesc slotMethod in slots) { MethodDesc declMethod = slotMethod; if (interfaceOnDefinitionType != null) { declMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(declMethod.GetTypicalMethodDefinition(), interfaceOnDefinitionType); } if (declMethod.Signature.IsStatic) { continue; } var implMethod = declType.GetTypeDefinition().ResolveInterfaceMethodToVirtualMethodOnType(declMethod); if (implMethod != null) { return(true); } } } return(false); }
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(); foreach (var method in defType.GetAllMethods()) { if (!method.IsVirtual) { continue; } yield return(new CombinedDependencyListEntry( factory.VirtualMethodUse(method), factory.VirtualMethodUse(method.GetCanonMethodTarget(CanonicalFormKind.Specific)), "Canonically equivalent virtual method use")); } }
public EagerlyBuiltVTableSliceNode(TypeDesc type) : base(type) { var slots = new ArrayBuilder <MethodDesc>(); DefType defType = _type.GetClosestDefType(); foreach (var method in defType.GetAllMethods()) { if (!method.IsVirtual) { continue; } slots.Add(method); } _slots = slots.ToArray(); }