Example #1
0
        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;
        }
Example #2
0
        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;
        }
Example #3
0
 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;
     }
 }
Example #4
0
        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;
        }
Example #5
0
        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;
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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;
        }
Example #13
0
        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);
            }
        }
Example #15
0
        /// <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);
        }
Example #17
0
        // 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);
                }
Example #19
0
        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);
        }
Example #20
0
        /// <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
                }
            }
        }
Example #21
0
        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);
        }
Example #23
0
        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"));
        }
Example #24
0
        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);
        }
Example #25
0
        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);
        }
Example #26
0
        /// <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
            }
        }
Example #27
0
        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");
                    }
                }
Example #29
0
        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);
        }
Example #30
0
        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;
        }
Example #31
0
        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);
        }
Example #32
0
        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);
        }
Example #33
0
        /// <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
            }
        }
Example #34
0
        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");
            }
        }
Example #36
0
        // 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!");
            }
        }
Example #37
0
        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;
        }
Example #38
0
 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;
     }
 }
Example #39
0
        /// <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);
        }
Example #40
0
        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;
        }
Example #41
0
 protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
 {
     DependencyList result = new DependencyList();
     result.Add(new DependencyListEntry(factory.ShadowConcreteMethod(Method), "Method represented"));
     return result;
 }
Example #42
0
 protected override DependencyList InitExpectedDependencies()
 {
     DependencyList result = new DependencyList();
     foreach (var input in Inputs)
     {
         result.Add(input.Type);
     }
     return result;
 }
Example #43
0
        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;
 }