protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DefType closestDefType = _type.GetClosestDefType(); DependencyList dependencyList = new DependencyList(); if (_type.RuntimeInterfaces.Length > 0) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map"); // If any of the implemented interfaces have variance, calls against compatible interface methods // could result in interface methods of this type being used (e.g. IEnumberable<object>.GetEnumerator() // can dispatch to an implementation of IEnumerable<string>.GetEnumerator()). // For now, we will not try to optimize this and we will pretend all interface methods are necessary. foreach (var implementedInterface in _type.RuntimeInterfaces) { if (implementedInterface.HasVariance) { foreach (var interfaceMethod in implementedInterface.GetAllMethods()) { if (interfaceMethod.Signature.IsStatic) continue; MethodDesc implMethod = closestDefType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod); if (implMethod != null) { dependencyList.Add(factory.VirtualMethodUse(interfaceMethod), "Variant interface method"); dependencyList.Add(factory.VirtualMethodUse(implMethod), "Variant interface method"); } } } } } if (_type.IsArray) { // Array EEType depends on System.Array's virtuals. Array EETypes don't point to // their base type (i.e. there's no reloc based dependency making this "just work"). dependencyList.Add(factory.ConstructedTypeSymbol(_type.BaseType), "Array base type"); } dependencyList.Add(factory.VTable(_type), "VTable"); if (closestDefType.HasGenericDictionarySlot()) { // Generic dictionary pointer is part of the vtable and as such it gets only laid out // at the final data emission phase. We need to report it as a non-relocation dependency. dependencyList.Add(factory.TypeGenericDictionary(closestDefType), "Type generic dictionary"); } // Include the optional fields by default. We don't know if optional fields will be needed until // all of the interface usage has been stabilized. If we end up not needing it, the EEType node will not // generate any relocs to it, and the optional fields node will instruct the object writer to skip // emitting it. dependencyList.Add(_optionalFieldsNode, "Optional fields"); return dependencyList; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { if (factory.TypeSystemContext.HasEagerStaticConstructor(_type)) { var result = new DependencyList(); result.Add(factory.EagerCctorIndirection(_type.GetStaticConstructor()), "Eager .cctor"); return result; } return null; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory context) { if (Helper.Id == ReadyToRunHelperId.VirtualCall) { DependencyList dependencyList = new DependencyList(); dependencyList.Add(context.VirtualMethodUse((MethodDesc)Helper.Target), "ReadyToRun Virtual Method Call"); return dependencyList; } else { return null; } }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = new DependencyList(); if (factory.TypeSystemContext.HasEagerStaticConstructor(_type)) { dependencyList.Add(factory.EagerCctorIndirection(_type.GetStaticConstructor()), "Eager .cctor"); } dependencyList.Add(factory.GCStaticsRegion, "GCStatics Region"); dependencyList.Add(GetGCStaticEETypeNode(factory), "GCStatic EEType"); dependencyList.Add(factory.GCStaticIndirection(_type), "GC statics indirection"); return dependencyList; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencies = null; TypeDesc owningType = _method.OwningType; if (factory.TypeSystemContext.HasEagerStaticConstructor(owningType)) { if (dependencies == null) dependencies = new DependencyList(); dependencies.Add(factory.EagerCctorIndirection(owningType.GetStaticConstructor()), "Eager .cctor"); } if (_ehInfo != null && _ehInfo.Relocs != null) { if (dependencies == null) dependencies = new DependencyList(); foreach (Relocation reloc in _ehInfo.Relocs) { dependencies.Add(reloc.Target, "reloc"); } } // Reflection invoke stub handling is here because in the current reflection model we reflection-enable // all methods that are compiled. Ideally the list of reflection enabled methods should be known before // we even start the compilation process (with the invocation stubs being compilation roots like any other). // The existing model has it's problems: e.g. the invocability of the method depends on inliner decisions. if (factory.MetadataManager.HasReflectionInvokeStub(_method) && !_method.IsCanonicalMethod(CanonicalFormKind.Any) /* Shared generics handled in the shadow concrete method node */) { if (dependencies == null) dependencies = new DependencyList(); MethodDesc invokeStub = factory.MetadataManager.GetReflectionInvokeStub(Method); MethodDesc canonInvokeStub = invokeStub.GetCanonMethodTarget(CanonicalFormKind.Specific); if (invokeStub != canonInvokeStub) dependencies.Add(new DependencyListEntry(factory.FatFunctionPointer(invokeStub), "Reflection invoke")); else dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(invokeStub), "Reflection invoke")); } return dependencies; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); dependencies.Add(GetDictionaryLayout(factory), "Layout"); GenericMethodsHashtableNode.GetGenericMethodsHashtableDependenciesForMethod(ref dependencies, factory, _owningMethod); factory.InteropStubManager.AddMarshalAPIsGenericDependencies(ref dependencies, factory, _owningMethod); // Lazy generic use of the Activator.CreateInstance<T> heuristic requires tracking type parameters that are used in lazy generics. if (factory.LazyGenericsPolicy.UsesLazyGenerics(_owningMethod)) { foreach (var arg in _owningMethod.OwningType.Instantiation) { // Skip types that do not have a default constructor (not interesting). if (arg.IsValueType || arg.GetDefaultConstructor() == null) { continue; } dependencies.Add(new DependencyListEntry( factory.DefaultConstructorFromLazy(arg.ConvertToCanonForm(CanonicalFormKind.Specific)), "Default constructor for lazy generics")); } foreach (var arg in _owningMethod.Instantiation) { // Skip types that do not have a default constructor (not interesting). if (arg.IsValueType || arg.GetDefaultConstructor() == null) { continue; } dependencies.Add(new DependencyListEntry( factory.DefaultConstructorFromLazy(arg.ConvertToCanonForm(CanonicalFormKind.Specific)), "Default constructor for lazy generics")); } } return(dependencies); }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { _dependenciesQueried = true; DependencyList dependencies = null; CodeBasedDependencyAlgorithm.AddDependenciesDueToMethodCodePresence(ref dependencies, factory, _method); if (_compilationDiscoveredDependencies != null) { dependencies = dependencies ?? new DependencyList(); dependencies.AddRange(_compilationDiscoveredDependencies); } if (MethodAssociatedDataNode.MethodHasAssociatedData(factory, this)) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(new DependencyListEntry(factory.MethodAssociatedData(this), "Method associated data")); } return(dependencies); }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = new DependencyList(); if (factory.TypeSystemContext.HasEagerStaticConstructor(_type)) { dependencyList.Add(factory.EagerCctorIndirection(_type.GetStaticConstructor()), "Eager .cctor"); } dependencyList.Add(factory.GCStaticsRegion, "GCStatics Region"); dependencyList.Add(GetGCStaticEETypeNode(factory), "GCStatic EEType"); if (_preInitFieldInfos != null) { dependencyList.Add(factory.GCStaticsPreInitDataNode(_type), "PreInitData node"); } dependencyList.Add(factory.GCStaticIndirection(_type), "GC statics indirection"); EETypeNode.AddDependenciesForStaticsNode(factory, _type, ref dependencyList); return(dependencyList); }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); MethodDesc canonDecl = _decl.GetCanonMethodTarget(CanonicalFormKind.Specific); if (canonDecl != _decl) { dependencies.Add(new DependencyListEntry(factory.VirtualMethodUse(canonDecl), "Canonical method")); } dependencies.Add(new DependencyListEntry(factory.VTable(_decl.OwningType), "VTable of a VirtualMethodUse")); // Do not report things like Foo<object, __Canon>.Frob(). if (!_decl.IsCanonicalMethod(CanonicalFormKind.Any) || canonDecl == _decl) { factory.MetadataManager.GetDependenciesDueToVirtualMethodReflectability(ref dependencies, factory, _decl); } return(dependencies); }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); MethodDesc canonDecl = _decl.GetCanonMethodTarget(CanonicalFormKind.Specific); if (canonDecl != _decl) { dependencies.Add(new DependencyListEntry(factory.VirtualMethodUse(canonDecl), "Canonical method")); } dependencies.Add(new DependencyListEntry(factory.VTable(_decl.OwningType), "VTable of a VirtualMethodUse")); // TODO: https://github.com/dotnet/corert/issues/3224 if (_decl.IsAbstract) { dependencies.Add(factory.ReflectableMethod(_decl), "Abstract reflectable method"); } return(dependencies); }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = new DependencyList(); if (factory.PreinitializationManager.HasEagerStaticConstructor(_type)) { dependencyList.Add(factory.EagerCctorIndirection(_type.GetStaticConstructor()), "Eager .cctor"); } if (_type.Module.GetGlobalModuleType().GetStaticConstructor() is MethodDesc moduleCctor) { dependencyList.Add(factory.MethodEntrypoint(moduleCctor), "Static base in a module with initializer"); } dependencyList.Add(factory.GCStaticsRegion, "GCStatics Region"); dependencyList.Add(factory.GCStaticIndirection(_type), "GC statics indirection"); EETypeNode.AddDependenciesForStaticsNode(factory, _type, ref dependencyList); return(dependencyList); }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = new DependencyList(); if (_type.RuntimeInterfaces.Length > 0) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map"); // If any of the implemented interfaces have variance, calls against compatible interface methods // could result in interface methods of this type being used (e.g. IEnumberable<object>.GetEnumerator() // can dispatch to an implementation of IEnumerable<string>.GetEnumerator()). // For now, we will not try to optimize this and we will pretend all interface methods are necessary. DefType defType = _type.GetClosestDefType(); foreach (var implementedInterface in defType.RuntimeInterfaces) { if (implementedInterface.HasVariance) { foreach (var interfaceMethod in implementedInterface.GetAllVirtualMethods()) { MethodDesc implMethod = defType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod); if (implMethod != null) { dependencyList.Add(factory.VirtualMethodUse(interfaceMethod), "Variant interface method"); dependencyList.Add(factory.VirtualMethodUse(implMethod), "Variant interface method"); } } } } } if (_type.IsArray) { // Array EEType depends on System.Array's virtuals. Array EETypes don't point to // their base type (i.e. there's no reloc based dependency making this "just work"). dependencyList.Add(factory.ConstructedTypeSymbol(_type.BaseType), "Array base type"); } dependencyList.Add(factory.VTable(_type), "VTable"); return dependencyList; }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); // TODO: https://github.com/dotnet/corert/issues/3224 // Reflection invoke stub handling is here because in the current reflection model we reflection-enable // all methods that are compiled. Ideally the list of reflection enabled methods should be known before // we even start the compilation process (with the invocation stubs being compilation roots like any other). // The existing model has it's problems: e.g. the invocability of the method depends on inliner decisions. if (factory.MetadataManager.IsReflectionInvokable(_decl) && _decl.IsAbstract) { if (factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(_decl) && !_decl.IsCanonicalMethod(CanonicalFormKind.Any)) { MethodDesc invokeStub = factory.MetadataManager.GetReflectionInvokeStub(_decl); MethodDesc canonInvokeStub = invokeStub.GetCanonMethodTarget(CanonicalFormKind.Specific); if (invokeStub != canonInvokeStub) { dependencies.Add(new DependencyListEntry(factory.MetadataManager.DynamicInvokeTemplateData, "Reflection invoke template data")); factory.MetadataManager.DynamicInvokeTemplateData.AddDependenciesDueToInvokeTemplatePresence(ref dependencies, factory, canonInvokeStub); } else { dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(invokeStub), "Reflection invoke")); } } dependencies.AddRange(ReflectionVirtualInvokeMapNode.GetVirtualInvokeMapDependencies(factory, _decl)); } MethodDesc canonDecl = _decl.GetCanonMethodTarget(CanonicalFormKind.Specific); if (canonDecl != _decl) { dependencies.Add(new DependencyListEntry(factory.VirtualMethodUse(canonDecl), "Canonical method")); } dependencies.Add(new DependencyListEntry(factory.VTable(_decl.OwningType), "VTable of a VirtualMethodUse")); return(dependencies); }
// Find and return arraylist, and remove passed hash value. private List <SqlDependency> LookupCommandEntryWithRemove(string notificationId) { IntPtr hscp; Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependencyPerAppDomainDispatcher.LookupCommandEntryWithRemove|DEP> %d#, commandHash: '%ls'", ObjectID, notificationId); try { DependencyList entry = null; lock (this) { if (_notificationIdToDependenciesHash.TryGetValue(notificationId, out entry)) { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.LookupDependencyEntriesWithRemove|DEP> Entries found in hashtable - removing.\n"); // update the tables - do it inside finally block to avoid ThreadAbort exception interrupt this operation try { } finally { _notificationIdToDependenciesHash.Remove(notificationId); // VSTS 216991: cleanup the map between the command hash and associated notification ID _commandHashToNotificationId.Remove(entry.CommandHash); } } else { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.LookupDependencyEntriesWithRemove|DEP> Entries NOT found in hashtable.\n"); } Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in sync!"); } return(entry); // DependencyList inherits from List<SqlDependency> } finally { Bid.ScopeLeave(ref hscp); } }
/// <summary> /// Helper method to compute the dependencies that would be needed for reflection field lookup. /// </summary> public static void AddReflectionFieldMapEntryDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { if (!factory.MetadataManager.SupportsReflection) { return; } // TODO: https://github.com/dotnet/corert/issues/3224 // Reflection static field bases handling is here because in the current reflection model we reflection-enable // all fields of types that are compiled. Ideally the list of reflection enabled fields should be known before // we even start the compilation process (with the static bases being compilation roots like any other). if (type is MetadataType && !type.IsCanonicalSubtype(CanonicalFormKind.Any)) { MetadataType metadataType = (MetadataType)type; // For instantiated types, we write the static fields offsets directly into the table, and we do not reference the gc/non-gc statics nodes if (!type.HasInstantiation) { if (metadataType.GCStaticFieldSize.AsInt > 0) { dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics for ReflectionFieldMap entry"); } if (metadataType.NonGCStaticFieldSize.AsInt > 0) { dependencies.Add(factory.TypeNonGCStaticsSymbol(metadataType), "Non-GC statics for ReflectionFieldMap entry"); } } if (metadataType.ThreadStaticFieldSize.AsInt > 0) { if (factory.Target.Abi == TargetAbi.ProjectN) { dependencies.Add(((UtcNodeFactory)factory).TypeThreadStaticsOffsetSymbol(metadataType), "Thread statics for ReflectionFieldMap entry"); } // TODO: TLS for CoreRT } } }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); foreach (DependencyNodeCore <NodeFactory> dependency in _lookupSignature.NonRelocDependenciesFromUsage(factory)) { dependencies.Add(new DependencyListEntry(dependency, "GenericLookupResultDependency")); } // Root the template for the type while we're hitting its dictionary cells. In the future, we may // want to control this via type reflectability instead. if (_dictionaryOwner is MethodDesc) { dependencies.Add(factory.NativeLayout.TemplateMethodLayout((MethodDesc)_dictionaryOwner), "Type loader template"); } else { dependencies.Add(factory.NativeLayout.TemplateTypeLayout((TypeDesc)_dictionaryOwner), "Type loader template"); } return(dependencies); }
// Find and return arraylist, and remove passed hash value. private List <SqlDependency> LookupCommandEntryWithRemove(string notificationId) { long scopeID = SqlClientEventSource.Log.TryNotificationScopeEnterEvent("<sc.SqlDependencyPerAppDomainDispatcher.LookupCommandEntryWithRemove|DEP> {0}, commandHash: '{1}'", ObjectID, notificationId); try { DependencyList entry = null; lock (this) { if (_notificationIdToDependenciesHash.TryGetValue(notificationId, out entry)) { SqlClientEventSource.Log.TryNotificationTraceEvent("<sc.SqlDependencyPerAppDomainDispatcher.LookupDependencyEntriesWithRemove|DEP> Entries found in hashtable - removing."); // update the tables - do it inside finally block to avoid ThreadAbort exception interrupt this operation try { } finally { _notificationIdToDependenciesHash.Remove(notificationId); // VSTS 216991: cleanup the map between the command hash and associated notification ID _commandHashToNotificationId.Remove(entry.CommandHash); } } else { SqlClientEventSource.Log.TryNotificationTraceEvent("<sc.SqlDependencyPerAppDomainDispatcher.LookupDependencyEntriesWithRemove|DEP> Entries NOT found in hashtable."); } Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in sync!"); } return(entry); // DependencyList inherits from List<SqlDependency> } finally { SqlClientEventSource.Log.TryNotificationScopeLeaveEvent(scopeID); } }
public static void AddDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) { Debug.Assert(factory.MetadataManager.IsReflectionInvokable(method)); if (dependencies == null) { dependencies = new DependencyList(); } dependencies.Add(factory.MaximallyConstructableType(method.OwningType), "Reflection invoke"); if (factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(method)) { MethodDesc invokeStub = factory.MetadataManager.GetReflectionInvokeStub(method); dependencies.Add(factory.MethodEntrypoint(invokeStub), "Reflection invoke"); var signature = method.Signature; AddSignatureDependency(ref dependencies, factory, signature.ReturnType); foreach (var parameterType in signature) { AddSignatureDependency(ref dependencies, factory, parameterType); }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { if (_constructed) { DependencyList dependencyList = new DependencyList(); if (_type.RuntimeInterfaces.Length > 0) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map"); } if (_type.IsArray) { // Array EEType depends on System.Array's virtuals. Array EETypes don't point to // their base type (i.e. there's no reloc based dependency making this "just work"). dependencyList.Add(factory.ConstructedTypeSymbol(_type.BaseType), "Array base type"); } return(dependencyList); } return(null); }
/// <summary> /// Helper method to compute the dependencies that would be needed by a hashtable entry for statics info lookup. /// This helper is used by EETypeNode, which is used by the dependency analysis to compute the statics hashtable /// entries for the compiled types. /// </summary> public static void AddStaticsInfoDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { if (!factory.MetadataManager.SupportsReflection) { return; } if (type is MetadataType && type.HasInstantiation && !type.IsCanonicalSubtype(CanonicalFormKind.Any)) { MetadataType metadataType = (MetadataType)type; // NOTE: The StaticsInfoHashtable entries need to reference the gc and non-gc static nodes through an indirection cell. // The StaticsInfoHashtable entries only exist for static fields on generic types. if (metadataType.GCStaticFieldSize.AsInt > 0) { dependencies.Add(factory.Indirection(factory.TypeGCStaticsSymbol(metadataType)), "GC statics indirection for StaticsInfoHashtable"); } if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.TypeSystemContext.HasLazyStaticConstructor(type)) { // The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor // context offset. dependencies.Add(factory.Indirection(factory.TypeNonGCStaticsSymbol(metadataType)), "Non-GC statics indirection for StaticsInfoHashtable"); } if (metadataType.ThreadStaticFieldSize.AsInt > 0) { if (factory.Target.Abi == TargetAbi.ProjectN) { UtcNodeFactory utcFactory = (UtcNodeFactory)factory; dependencies.Add(utcFactory.TypeThreadStaticsIndexSymbol(metadataType), "Thread statics index indirection for StaticsInfoHashtable"); dependencies.Add(utcFactory.TypeThreadStaticsOffsetSymbol(metadataType), "Thread statics offset indirection for StaticsInfoHashtable"); } // TODO: TLS for CoreRT } } }
public static void GetVirtualInvokeMapDependencies(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) { if (!factory.MetadataManager.SupportsReflection) { return; } if (NeedsVirtualInvokeInfo(method)) { dependencies = dependencies ?? new DependencyList(); if (factory.Target.Abi == TargetAbi.ProjectN) { dependencies.Add( factory.NecessaryTypeSymbol(method.OwningType.GetTypeDefinition()), "Reflection virtual invoke owning type"); } else { dependencies.Add( factory.NecessaryTypeSymbol(method.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific)), "Reflection virtual invoke owning type"); } NativeLayoutMethodNameAndSignatureVertexNode nameAndSig = factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition()); NativeLayoutPlacedSignatureVertexNode placedNameAndSig = factory.NativeLayout.PlacedSignatureVertex(nameAndSig); dependencies.Add(placedNameAndSig, "Reflection virtual invoke method signature"); if (!method.HasInstantiation) { MethodDesc slotDefiningMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method); if (!factory.VTable(slotDefiningMethod.OwningType).HasFixedSlots) { dependencies.Add(factory.VirtualMethodUse(slotDefiningMethod), "Reflection virtual invoke method"); } } } }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencies = null; TypeDesc owningType = _method.OwningType; if (factory.TypeSystemContext.HasEagerStaticConstructor(owningType)) { if (dependencies == null) { dependencies = new DependencyList(); } dependencies.Add(factory.EagerCctorIndirection(owningType.GetStaticConstructor()), "Eager .cctor"); } if (_ehInfo != null && _ehInfo.Relocs != null) { if (dependencies == null) { dependencies = new DependencyList(); } foreach (Relocation reloc in _ehInfo.Relocs) { dependencies.Add(reloc.Target, "reloc"); } } if (MethodAssociatedDataNode.MethodHasAssociatedData(factory, this)) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(new DependencyListEntry(factory.MethodAssociatedData(this), "Method associated data")); } CodeBasedDependencyAlgorithm.AddDependenciesDueToMethodCodePresence(ref dependencies, factory, _method); return(dependencies); }
public static void GetTemplateTypeDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { if (!factory.MetadataManager.SupportsReflection) { return; } TypeDesc templateType = ConvertArrayOfTToRegularArray(factory, type); if (!IsEligibleToHaveATemplate(templateType)) { return; } if ((factory.Target.Abi == TargetAbi.ProjectN) && !ProjectNDependencyBehavior.EnableFullAnalysis) { // If the type does not have fully constructed type, don't track its dependencies. // TODO: Remove the workaround once we stop using the STS dependency analysis. IDependencyNode node; if (ConstructedEETypeNode.CreationAllowed(templateType)) { node = factory.ConstructedTypeSymbol(templateType); } else { node = factory.NecessaryTypeSymbol(templateType); } if (!node.Marked) { return; } } dependencies = dependencies ?? new DependencyList(); dependencies.Add(new DependencyListEntry(factory.NecessaryTypeSymbol(templateType), "Template type")); dependencies.Add(new DependencyListEntry(factory.NativeLayout.TemplateTypeLayout(templateType), "Template Type Layout")); }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); // Make sure the canonical body gets generated dependencies.Add(new DependencyListEntry(CanonicalMethodNode, "Canonical body")); // Instantiate the runtime determined dependencies of the canonical method body // with the concrete instantiation of the method to get concrete dependencies. Instantiation typeInst = Method.OwningType.Instantiation; Instantiation methodInst = Method.Instantiation; IEnumerable <DependencyListEntry> staticDependencies = CanonicalMethodNode.GetStaticDependencies(factory); if (staticDependencies != null) { foreach (DependencyListEntry canonDep in staticDependencies) { var runtimeDep = canonDep.Node as INodeWithRuntimeDeterminedDependencies; if (runtimeDep != null) { dependencies.AddRange(runtimeDep.InstantiateDependencies(factory, typeInst, methodInst)); } } } if (Method.HasInstantiation) { if (Method.IsVirtual) { dependencies.Add(new DependencyListEntry(factory.GVMDependencies(Method), "GVM Dependencies Support for method dictionary")); } // Dictionary dependency dependencies.Add(new DependencyListEntry(factory.MethodGenericDictionary(Method), "Method dictionary")); } return(dependencies); }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencies = null; if (!_targetMethod.IsMethodDefinition && !_targetMethod.OwningType.IsGenericDefinition && _targetMethod.HasInstantiation && _targetMethod.IsVirtual) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.GVMDependencies(_targetMethod), "GVM dependencies for runtime method handle"); } // TODO: https://github.com/dotnet/corert/issues/3224 // We should figure out reflectable methods when scanning for reflection MethodDesc methodDefinition = _targetMethod.GetTypicalMethodDefinition(); if (factory.MetadataManager.CanGenerateMetadata(methodDefinition)) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.MethodMetadata(methodDefinition), "LDTOKEN"); } return(dependencies); }
/// <summary> /// Helper method to compute the dependencies that would be needed for reflection field lookup. /// </summary> public static void AddReflectionFieldMapEntryDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { // TODO: https://github.com/dotnet/corert/issues/3224 // Reflection static field bases handling is here because in the current reflection model we reflection-enable // all fields of types that are compiled. Ideally the list of reflection enabled fields should be known before // we even start the compilation process (with the static bases being compilation roots like any other). if (type is MetadataType && !type.HasInstantiation && !type.IsCanonicalSubtype(CanonicalFormKind.Any)) { MetadataType metadataType = (MetadataType)type; if (metadataType.GCStaticFieldSize.AsInt > 0) { dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics for ReflectionFieldMap entry"); } if (metadataType.NonGCStaticFieldSize.AsInt > 0) { dependencies.Add(factory.TypeNonGCStaticsSymbol(metadataType), "Non-GC statics for ReflectionFieldMap entry"); } // TODO: TLS dependencies } }
public static void GetTemplateTypeDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeDesc templateType = ConvertArrayOfTToRegularArray(factory, type); if (!IsEligibleToHaveATemplate(templateType)) { return; } if (factory.Target.Abi == TargetAbi.ProjectN) { // If the type does not have fully constructed type, don't track its dependencies. // TODO: Remove the workaround once we stop using the STS dependency analysis. if (!factory.ConstructedTypeSymbol(templateType).Marked) { return; } } dependencies = dependencies ?? new DependencyList(); dependencies.Add(new DependencyListEntry(factory.NecessaryTypeSymbol(templateType), "Template type")); dependencies.Add(new DependencyListEntry(factory.NativeLayout.TemplateTypeLayout(templateType), "Template Type Layout")); }
static void AddSignatureDependency(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { if (type.IsByRef) { type = ((ParameterizedType)type).ParameterType; } // Pointer runtime type handles can be created at runtime if necessary while (type.IsPointer) { type = ((ParameterizedType)type).ParameterType; } // Skip tracking dependencies for primitive types. Assume that they are always present. if (type.IsPrimitive || type.IsVoid) { return; } // Function pointers are not supported yet. // https://github.com/dotnet/runtime/issues/71883 if (type.IsFunctionPointer) { return; } TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonType.IsCanonicalSubtype(CanonicalFormKind.Any)) { GenericTypesTemplateMap.GetTemplateTypeDependencies(ref dependencies, factory, type.ConvertToCanonForm(CanonicalFormKind.Specific)); } else { dependencies.Add(factory.MaximallyConstructableType(canonType), "Reflection invoke"); } }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory); // Ensure that we track the necessary type symbol if we are working with a constructed type symbol. // The emitter will ensure we don't emit both, but this allows us assert that we only generate // relocs to nodes we emit. dependencyList.Add(factory.NecessaryTypeSymbol(_type), "Necessary type symbol related to CanonicalEETypeNode"); DefType closestDefType = _type.GetClosestDefType(); if (_type.RuntimeInterfaces.Length > 0) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Canonical interface dispatch map"); } dependencyList.Add(factory.VTable(_type), "VTable"); // TODO: native layout dependencies (template type entries) // TODO: other dependencies needed by the dynamic type loader? return(dependencyList); }
public void AddDependency(BitArray from, BitArray to) { if (from.Count != Keys.Count) { return; } if (to.Count != Keys.Count) { return; } to.And(Utils.Not(from)); var index = DependencyList.FindIndex(tuple => tuple.Item1.EqualsTo(from)); if (index != -1) { DependencyList[index].Item2.Or(to); } else { DependencyList.Add(new Tuple <BitArray, BitArray>(from, to)); } _prepared = false; }
private List <SqlDependency> LookupCommandEntryWithRemove(string notificationId) { List <SqlDependency> list2; IntPtr ptr; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependencyPerAppDomainDispatcher.LookupCommandEntryWithRemove|DEP> %d#, commandHash: '%ls'", this.ObjectID, notificationId); try { DependencyList list = null; lock (this) { if (this._notificationIdToDependenciesHash.TryGetValue(notificationId, out list)) { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.LookupDependencyEntriesWithRemove|DEP> Entries found in hashtable - removing.\n"); try { } finally { this._notificationIdToDependenciesHash.Remove(notificationId); this._commandHashToNotificationId.Remove(list.CommandHash); } } else { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.LookupDependencyEntriesWithRemove|DEP> Entries NOT found in hashtable.\n"); } } list2 = list; } finally { Bid.ScopeLeave(ref ptr); } return(list2); }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory context) { DependencyList dependencies = null; context.MetadataManager.GetDependenciesDueToVirtualMethodReflectability(ref dependencies, context, _method); if (!_method.IsAbstract) { bool validInstantiation = _method.IsSharedByGenericInstantiations || ( // Non-exact methods are always valid instantiations (always pass constraints check) _method.Instantiation.CheckValidInstantiationArguments() && _method.OwningType.Instantiation.CheckValidInstantiationArguments() && _method.CheckConstraints()); if (validInstantiation) { if (context.TypeSystemContext.SupportsUniversalCanon && _method.IsGenericDepthGreaterThan(UniversalCanonGVMDepthHeuristic_CanonDepth)) { // fall back to using the universal generic variant of the generic method return(dependencies); } bool getUnboxingStub = _method.OwningType.IsValueType; dependencies = dependencies ?? new DependencyList(); dependencies.Add(context.MethodEntrypoint(_method, getUnboxingStub), "GVM Dependency - Canon method"); if (_method.IsSharedByGenericInstantiations) { dependencies.Add(context.NativeLayout.TemplateMethodEntry(_method), "GVM Dependency - Template entry"); dependencies.Add(context.NativeLayout.TemplateMethodLayout(_method), "GVM Dependency - Template"); } } } return(dependencies); }
/// <summary> /// Helper method to compute the dependencies that would be needed by a hashtable entry for statics info lookup. /// This helper is used by EETypeNode, which is used by the dependency analysis to compute the statics hashtable /// entries for the compiled types. /// </summary> public static void AddStaticsInfoDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { if (type is MetadataType && type.HasInstantiation && !type.IsCanonicalSubtype(CanonicalFormKind.Any)) { MetadataType metadataType = (MetadataType)type; // NOTE: The StaticsInfoHashtable entries need to reference the gc and non-gc static nodes through an indirection cell. // The StaticsInfoHashtable entries only exist for static fields on generic types. if (metadataType.GCStaticFieldSize.AsInt > 0) { dependencies.Add(factory.Indirection(factory.TypeGCStaticsSymbol(metadataType)), "GC statics indirection for StaticsInfoHashtable"); } if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.TypeSystemContext.HasLazyStaticConstructor(type)) { // The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor // context offset. dependencies.Add(factory.Indirection(factory.TypeNonGCStaticsSymbol(metadataType)), "Non-GC statics indirection for StaticsInfoHashtable"); } // TODO: TLS dependencies } }
public static DependencyList GetTemplateTypeDependencies(NodeFactory factory, TypeDesc type) { if (!IsEligibleToHaveATemplate(type)) { return(null); } if (factory.Target.Abi == TargetAbi.ProjectN) { // If the type does not have fully constructed type, don't track its dependencies. // TODO: Remove the workaround once we stop using the STS dependency analysis. if (!factory.ConstructedTypeSymbol(type).Marked) { return(null); } } DependencyList dependencies = new DependencyList(); dependencies.Add(new DependencyListEntry(factory.NecessaryTypeSymbol(type), "Template type")); dependencies.Add(new DependencyListEntry(factory.NativeLayout.TemplateTypeLayout(GetActualTemplateTypeForType(factory, type)), "Template Type Layout")); return(dependencies); }
public static void GetVirtualInvokeMapDependencies(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) { if (NeedsVirtualInvokeInfo(method)) { dependencies = dependencies ?? new DependencyList(); if (factory.Target.Abi == TargetAbi.ProjectN) { dependencies.Add( factory.NecessaryTypeSymbol(method.OwningType.GetTypeDefinition()), "Reflection virtual invoke owning type"); } else { dependencies.Add( factory.NecessaryTypeSymbol(method.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific)), "Reflection virtual invoke owning type"); } NativeLayoutMethodNameAndSignatureVertexNode nameAndSig = factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition()); NativeLayoutPlacedSignatureVertexNode placedNameAndSig = factory.NativeLayout.PlacedSignatureVertex(nameAndSig); dependencies.Add(placedNameAndSig, "Reflection virtual invoke method signature"); } }
// Remove from commandToDependenciesHash all references to the passed dependency. private void RemoveDependencyFromCommandToDependenciesHash(SqlDependency dependency) { lock (_instanceLock) { List <string> notificationIdsToRemove = new List <string>(); List <string> commandHashesToRemove = new List <string>(); foreach (KeyValuePair <string, DependencyList> entry in _notificationIdToDependenciesHash) { DependencyList dependencies = entry.Value; if (dependencies.Remove(dependency)) { if (dependencies.Count == 0) { // this dependency was the last associated with this notification ID, remove the entry // note: cannot do it inside foreach over dictionary notificationIdsToRemove.Add(entry.Key); commandHashesToRemove.Add(entry.Value.CommandHash); } } // same SqlDependency can be associated with more than one command, so we have to continue till the end... } Debug.Assert(commandHashesToRemove.Count == notificationIdsToRemove.Count, "maps should be kept in sync"); for (int i = 0; i < notificationIdsToRemove.Count; i++) { // cleanup the entry outside of foreach _notificationIdToDependenciesHash.Remove(notificationIdsToRemove[i]); // Cleanup the map between the command hash and associated notification ID _commandHashToNotificationId.Remove(commandHashesToRemove[i]); } Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in sync!"); } }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { if (_constructed) { DependencyList dependencyList = new DependencyList(); if (_type.RuntimeInterfaces.Length > 0) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map"); } if (_type.IsArray) { // Array EEType depends on System.Array's virtuals. Array EETypes don't point to // their base type (i.e. there's no reloc based dependency making this "just work"). dependencyList.Add(factory.ConstructedTypeSymbol(_type.BaseType), "Array base type"); } return dependencyList; } return null; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { if (_id == ReadyToRunHelperId.VirtualCall) { DependencyList dependencyList = new DependencyList(); dependencyList.Add(factory.VirtualMethodUse((MethodDesc)_target), "ReadyToRun Virtual Method Call"); dependencyList.Add(factory.VTable(((MethodDesc)_target).OwningType), "ReadyToRun Virtual Method Call Target VTable"); return dependencyList; } else if (_id == ReadyToRunHelperId.ResolveVirtualFunction) { DependencyList dependencyList = new DependencyList(); dependencyList.Add(factory.VirtualMethodUse((MethodDesc)_target), "ReadyToRun Virtual Method Address Load"); return dependencyList; } else { return null; } }
/// <summary> /// Runs any required bootstrapper tasks. /// </summary> private static void RunTasks() { var tasks = Container.GetExports<IBootstrapperTask, INamedDependencyMetadata>(); var list = new DependencyList<Lazy<IBootstrapperTask, INamedDependencyMetadata>, string>( l => l.Metadata.Name, l => l.Metadata.Dependencies); foreach (var task in tasks) list.Add(task); foreach (var task in list) task.Value.Run(Container); }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory context) { if (context.TypeInitializationManager.HasEagerStaticConstructor(_type)) { var result = new DependencyList(); result.Add(context.EagerCctorIndirection(_type.GetStaticConstructor()), "Eager .cctor"); return result; } return null; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList result = new DependencyList(); result.Add(new DependencyListEntry(factory.ShadowConcreteMethod(Method), "Method represented")); return result; }
protected override DependencyList InitExpectedDependencies() { DependencyList result = new DependencyList(); foreach (var input in Inputs) { result.Add(input.Type); } return result; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencies = null; TypeDesc owningType = _method.OwningType; if (factory.TypeSystemContext.HasEagerStaticConstructor(owningType)) { if (dependencies == null) dependencies = new DependencyList(); dependencies.Add(factory.EagerCctorIndirection(owningType.GetStaticConstructor()), "Eager .cctor"); } if (_ehInfo != null && _ehInfo.Relocs != null) { if (dependencies == null) dependencies = new DependencyList(); foreach (Relocation reloc in _ehInfo.Relocs) { dependencies.Add(reloc.Target, "reloc"); } } return dependencies; }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { var result = new DependencyList(); result.Add(factory.InterfaceDispatchMapIndirection(_type), "Interface dispatch map indirection node"); return result; }