Exemple #1
0
        public void AddDependency(DependencyNodeCore <NodeFactory> newDependency)
        {
            if (_dependenciesNoLongerMutable)
            {
                throw new Exception();
            }

            _dependencies.Add(newDependency);
        }
Exemple #2
0
 public void AddCompilationDiscoveredDependency(DependencyNodeCore <NodeFactory> node, string reason)
 {
     Debug.Assert(!_dependenciesQueried);
     if (_compilationDiscoveredDependencies == null)
     {
         _compilationDiscoveredDependencies = new List <DependencyListEntry>();
     }
     _compilationDiscoveredDependencies.Add(new DependencyNodeCore <NodeFactory> .DependencyListEntry(node, reason));
 }
Exemple #3
0
        protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            IMethodBodyNode methodBodyNode = obj as IMethodBodyNode;
            var             methodNode     = methodBodyNode as IMethodNode;

            if (methodNode != null)
            {
                _methodsGenerated.Add(methodNode.Method);
            }
        }
Exemple #4
0
        private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                _typesWithEETypesGenerated.Add(eetypeNode.Type);
                AddGeneratedType(eetypeNode.Type);
                return;
            }

            IMethodNode methodNode = obj as MethodCodeNode;

            if (methodNode == null)
            {
                methodNode = obj as ShadowConcreteMethodNode <MethodCodeNode>;
            }

            if (methodNode != null)
            {
                MethodDesc method = methodNode.Method;
                if (method.IsCanonicalMethod(CanonicalFormKind.Specific))
                {
                    // Canonical methods are not interesting.
                    return;
                }

                AddGeneratedType(method.OwningType);
                _methodDefinitionsGenerated.Add(method.GetTypicalMethodDefinition());
                _methodsGenerated.Add(method);
                return;
            }

            var nonGcStaticSectionNode = obj as NonGCStaticsNode;

            if (nonGcStaticSectionNode != null && _nodeFactory.TypeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type))
            {
                _cctorContextsGenerated.Add(nonGcStaticSectionNode);
            }

            var gvmEntryNode = obj as TypeGVMEntriesNode;

            if (gvmEntryNode != null)
            {
                _typeGVMEntries.Add(gvmEntryNode);
            }

            var dictionaryNode = obj as GenericDictionaryNode;

            if (dictionaryNode != null)
            {
                _genericDictionariesGenerated.Add(dictionaryNode);
            }
        }
Exemple #5
0
        protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
        {
            DependencyList dependencyList = new DependencyNodeCore <NodeFactory> .DependencyList();

            if (_type is MetadataType && _constructed && _type.RuntimeInterfaces.Length > 0)
            {
                dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map");
            }

            dependencyList.Add(factory.EETypeOptionalFields(_optionalFieldsBuilder), "EEType optional fields");
            return(dependencyList);
        }
Exemple #6
0
        private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                _typesWithEETypesGenerated.Add(eetypeNode.Type);
                AddGeneratedType(eetypeNode.Type);
                return;
            }

            IMethodNode methodNode = obj as MethodCodeNode;

            if (methodNode == null)
            {
                methodNode = obj as ShadowConcreteMethodNode <MethodCodeNode>;
            }

            if (methodNode == null)
            {
                methodNode = obj as NonExternMethodSymbolNode;
            }

            if (methodNode != null)
            {
                MethodDesc method = methodNode.Method;

                AddGeneratedMethod(method);
                return;
            }

            var nonGcStaticSectionNode = obj as NonGCStaticsNode;

            if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type))
            {
                _cctorContextsGenerated.Add(nonGcStaticSectionNode);
            }

            var gvmEntryNode = obj as TypeGVMEntriesNode;

            if (gvmEntryNode != null)
            {
                _typeGVMEntries.Add(gvmEntryNode);
            }

            var dictionaryNode = obj as GenericDictionaryNode;

            if (dictionaryNode != null)
            {
                _genericDictionariesGenerated.Add(dictionaryNode);
            }
        }
        protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            IMethodBodyNode methodBodyNode = obj as IMethodBodyNode;
            var             methodNode     = methodBodyNode as IMethodNode;

            if (methodNode != null)
            {
                lock (_methodsGenerated)
                {
                    Debug.Assert(!_sortedMethods);
                    _methodsGenerated.Add(methodNode.Method);
                }
            }
        }
Exemple #8
0
        private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                AddGeneratedType(eetypeNode.Type);
                return;
            }

            var methodNode = obj as MethodCodeNode;

            if (methodNode != null)
            {
                AddGeneratedType(methodNode.Method.OwningType);
                return;
            }
        }
            public int Compare(DependencyNodeCore<NodeFactory> x1, DependencyNodeCore<NodeFactory> y1)
            {
                ObjectNode x = x1 as ObjectNode;
                ObjectNode y = y1 as ObjectNode;

                if (x == y)
                {
                    return 0;
                }

                // Sort non-object nodes after ObjectNodes
                if (x == null)
                    return 1;

                if (y == null)
                    return -1;

                return CompareImpl(x, y, _comparer);
            }
        protected override void GetDependenciesDueToMethodCodePresence(ref DependencyNodeCore <NodeFactory> .DependencyList dependencies, NodeFactory factory, MethodDesc method)
        {
            if (_ilProvider != null)
            {
                MethodIL methodIL = _ilProvider.GetMethodIL(method);

                if (methodIL != null)
                {
                    try
                    {
                        ReflectionMethodBodyScanner.ScanMarshalOnly(ref dependencies, factory, methodIL);
                    }
                    catch (TypeSystemException)
                    {
                        // A problem with the IL - we just don't scan it...
                    }
                }
            }
        }
        protected override void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            base.Graph_NewMarkedNode(obj);

            var moduleMetadataNode = obj as ModuleMetadataNode;

            if (moduleMetadataNode != null)
            {
                _modulesWithMetadata.Add(moduleMetadataNode.Module);
            }

            var fieldMetadataNode = obj as FieldMetadataNode;

            if (fieldMetadataNode != null)
            {
                _fieldsWithMetadata.Add(fieldMetadataNode.Field);
            }

            var methodMetadataNode = obj as MethodMetadataNode;

            if (methodMetadataNode != null)
            {
                _methodsWithMetadata.Add(methodMetadataNode.Method);
            }

            var typeMetadataNode = obj as TypeMetadataNode;

            if (typeMetadataNode != null)
            {
                _typesWithMetadata.Add(typeMetadataNode.Type);
            }

            var customAttributeMetadataNode = obj as CustomAttributeMetadataNode;

            if (customAttributeMetadataNode != null)
            {
                _customAttributesWithMetadata.Add(customAttributeMetadataNode.CustomAttribute);
            }
        }
        void ComputeDependencySizeAndRelocData(ObjectNode.ObjectData objectData, Dictionary <DependencyNodeCore <NodeFactory>, object> relocTargets, List <ObjectNode> nodesToEmit, ref int totalAllocSizeNeeded, ref int nonObjectRelocTargets)
        {
            foreach (var reloc in objectData.Relocs)
            {
                DependencyNodeCore <NodeFactory> relocTargetAsNode = (DependencyNodeCore <NodeFactory>)reloc.Target;

                if (!relocTargets.ContainsKey(relocTargetAsNode))
                {
                    relocTargets.Add(relocTargetAsNode, null);
                    ObjectNode relocTargetObjectNode = relocTargetAsNode as ObjectNode;
                    if (relocTargetObjectNode != null)
                    {
                        UpdateBytesUsed(relocTargetObjectNode.GetData(_nodeFactory), ref totalAllocSizeNeeded);
                        nodesToEmit.Add(relocTargetObjectNode);
                    }
                    else
                    {
                        nonObjectRelocTargets++;
                    }
                }
            }
        }
Exemple #13
0
 public void Add(ReadyToRunSectionType id, DependencyNodeCore <NodeFactory> node, ISymbolNode startSymbol)
 {
     _items.Add(new HeaderItem(id, node, startSymbol));
 }
Exemple #14
0
 public HeaderItem(ReadyToRunSectionType id, DependencyNodeCore <NodeFactory> node, ISymbolNode startSymbol)
 {
     Id          = id;
     Node        = node;
     StartSymbol = startSymbol;
 }
Exemple #15
0
        protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                _typesWithEETypesGenerated.Add(eetypeNode.Type);

                if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode)
                {
                    _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type);
                }

                return;
            }

            IMethodBodyNode methodBodyNode = obj as IMethodBodyNode;

            if (methodBodyNode != null)
            {
                _methodBodiesGenerated.Add(methodBodyNode);
            }

            IMethodNode methodNode = methodBodyNode;

            if (methodNode != null)
            {
                if (AllMethodsCanBeReflectable)
                {
                    _reflectableMethods.Add(methodNode.Method);
                }
            }

            if (methodNode == null)
            {
                methodNode = obj as ShadowConcreteMethodNode;
            }

            if (methodNode != null)
            {
                _methodsGenerated.Add(methodNode.Method);
                return;
            }

            var reflectableMethodNode = obj as ReflectableMethodNode;

            if (reflectableMethodNode != null)
            {
                _reflectableMethods.Add(reflectableMethodNode.Method);
            }

            var nonGcStaticSectionNode = obj as NonGCStaticsNode;

            if (nonGcStaticSectionNode != null && nonGcStaticSectionNode.HasCCtorContext)
            {
                _cctorContextsGenerated.Add(nonGcStaticSectionNode);
            }

            var gvmEntryNode = obj as TypeGVMEntriesNode;

            if (gvmEntryNode != null)
            {
                _typeGVMEntries.Add(gvmEntryNode);
            }

            var dictionaryNode = obj as GenericDictionaryNode;

            if (dictionaryNode != null)
            {
                _genericDictionariesGenerated.Add(dictionaryNode);

                if (dictionaryNode.OwningEntity is MethodDesc method && AllMethodsCanBeReflectable)
                {
                    _reflectableMethods.Add(method);
                }
            }

            if (obj is StructMarshallingDataNode structMarshallingDataNode)
            {
                _typesWithStructMarshalling.Add(structMarshallingDataNode.Type);
            }

            if (obj is DelegateMarshallingDataNode delegateMarshallingDataNode)
            {
                _typesWithDelegateMarshalling.Add(delegateMarshallingDataNode.Type);
            }

            if (obj is NativeLayoutTemplateMethodSignatureVertexNode templateMethodEntry)
            {
                _templateMethodEntries.Add(templateMethodEntry);
            }
        }
Exemple #16
0
        private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                _typesWithEETypesGenerated.Add(eetypeNode.Type);
                AddGeneratedType(eetypeNode.Type);

                if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode)
                {
                    _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type);
                }

                return;
            }

            IMethodNode methodNode = obj as MethodCodeNode;

            if (methodNode == null)
            {
                methodNode = obj as ShadowConcreteMethodNode;
            }

            if (methodNode == null)
            {
                methodNode = obj as NonExternMethodSymbolNode;
            }

            if (methodNode != null)
            {
                MethodDesc method = methodNode.Method;

                AddGeneratedMethod(method);
                return;
            }

            var runtimeMethodHandleNode = obj as RuntimeMethodHandleNode;

            if (runtimeMethodHandleNode != null)
            {
                AddMetadataOnlyMethod(runtimeMethodHandleNode.Method);
                return;
            }

            var nonGcStaticSectionNode = obj as NonGCStaticsNode;

            if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type))
            {
                _cctorContextsGenerated.Add(nonGcStaticSectionNode);
            }

            var gvmEntryNode = obj as TypeGVMEntriesNode;

            if (gvmEntryNode != null)
            {
                _typeGVMEntries.Add(gvmEntryNode);
            }

            var dictionaryNode = obj as GenericDictionaryNode;

            if (dictionaryNode != null)
            {
                _genericDictionariesGenerated.Add(dictionaryNode);
            }

            var virtualMethodUseNode = obj as VirtualMethodUseNode;

            if (virtualMethodUseNode != null && virtualMethodUseNode.Method.IsAbstract)
            {
                AddGeneratedMethod(virtualMethodUseNode.Method);
                return;
            }

            var gvmDependenciesNode = obj as GVMDependenciesNode;

            if (gvmDependenciesNode != null && gvmDependenciesNode.Method.IsAbstract)
            {
                AddGeneratedMethod(gvmDependenciesNode.Method);
            }
        }
Exemple #17
0
        protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
        {
            DependencyList dependencyList = new DependencyNodeCore<NodeFactory>.DependencyList();
            if (_type is MetadataType && _constructed && _type.RuntimeInterfaces.Length > 0)
            {
                dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map");
            }

            dependencyList.Add(factory.EETypeOptionalFields(_optionalFieldsBuilder), "EEType optional fields");
            return dependencyList;
        }
Exemple #18
0
        public override IEnumerable <CombinedDependencyListEntry> SearchDynamicDependencies(List <DependencyNodeCore <NodeFactory> > markedNodes, int firstNode, NodeFactory factory)
        {
            Debug.Assert(_method.IsVirtual && _method.HasInstantiation);

            List <CombinedDependencyListEntry> dynamicDependencies = new List <CombinedDependencyListEntry>();

            for (int i = firstNode; i < markedNodes.Count; i++)
            {
                DependencyNodeCore <NodeFactory> entry = markedNodes[i];
                EETypeNode entryAsEETypeNode           = entry as EETypeNode;

                if (entryAsEETypeNode == null)
                {
                    continue;
                }

                TypeDesc potentialOverrideType = entryAsEETypeNode.Type;
                if (!potentialOverrideType.IsDefType)
                {
                    continue;
                }

                Debug.Assert(!potentialOverrideType.IsRuntimeDeterminedSubtype);

                if (potentialOverrideType.IsInterface)
                {
                    if (_method.OwningType.HasSameTypeDefinition(potentialOverrideType) && (potentialOverrideType != _method.OwningType))
                    {
                        if (potentialOverrideType.CanCastTo(_method.OwningType))
                        {
                            // Variance expansion
                            MethodDesc matchingMethodOnRelatedVariantMethod = potentialOverrideType.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature);
                            matchingMethodOnRelatedVariantMethod = _method.Context.GetInstantiatedMethod(matchingMethodOnRelatedVariantMethod, _method.Instantiation);
                            dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(matchingMethodOnRelatedVariantMethod), null, "GVM Variant Interface dependency"));
                        }
                    }

                    continue;
                }

                // If this is an interface gvm, look for types that implement the interface
                // and other instantantiations that have the same canonical form.
                // This ensure the various slot numbers remain equivalent across all types where there is an equivalence
                // relationship in the vtable.
                if (_method.OwningType.IsInterface)
                {
                    foreach (DefType interfaceImpl in potentialOverrideType.RuntimeInterfaces)
                    {
                        if (interfaceImpl == _method.OwningType)
                        {
                            MethodDesc slotDecl = potentialOverrideType.ResolveInterfaceMethodTarget(_method.GetMethodDefinition());
                            if (slotDecl != null)
                            {
                                MethodDesc implementingMethodInstantiation = _method.Context.GetInstantiatedMethod(slotDecl, _method.Instantiation);
                                dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(implementingMethodInstantiation), null, "ImplementingMethodInstantiation"));
                            }
                        }
                    }
                }
                else
                {
                    // Quickly check if the potential overriding type is at all related to the GVM's owning type (there is no need
                    // to do any processing for a type that is not at all related to the GVM's owning type. Resolving virtuals is expensive).
                    TypeDesc overrideTypeCur = potentialOverrideType;
                    {
                        do
                        {
                            if (overrideTypeCur == _method.OwningType)
                            {
                                break;
                            }

                            overrideTypeCur = overrideTypeCur.BaseType;
                        }while (overrideTypeCur != null);

                        if (overrideTypeCur == null)
                        {
                            continue;
                        }
                    }

                    overrideTypeCur = potentialOverrideType;
                    while (overrideTypeCur != null)
                    {
                        if (overrideTypeCur == _method.OwningType)
                        {
                            // The GVMDependencyNode already declares the entrypoint/dictionary dependencies of the current method
                            // as static dependencies, therefore we can break the loop as soon we hit the current method's owning type
                            // while we're traversing the hierarchy of the potential derived types.
                            break;
                        }

                        MethodDesc instantiatedTargetMethod = overrideTypeCur.FindVirtualFunctionTargetMethodOnObjectType(_method);
                        if (instantiatedTargetMethod != null)
                        {
                            dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(instantiatedTargetMethod), null, "DerivedMethodInstantiation"));
                        }

                        overrideTypeCur = overrideTypeCur.BaseType;
                    }
                }
            }

            return(dynamicDependencies);
        }
Exemple #19
0
        protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                _typesWithEETypesGenerated.Add(eetypeNode.Type);

                if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode)
                {
                    _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type);
                }

                return;
            }

            IMethodBodyNode methodBodyNode = obj as IMethodBodyNode;

            if (methodBodyNode != null)
            {
                _methodBodiesGenerated.Add(methodBodyNode);
            }

            IMethodNode methodNode = methodBodyNode;

            if (methodNode == null)
            {
                methodNode = obj as ShadowConcreteMethodNode;
            }

            if (methodNode != null)
            {
                _methodsGenerated.Add(methodNode.Method);
                return;
            }

            var reflectableMethodNode = obj as ReflectableMethodNode;

            if (reflectableMethodNode != null)
            {
                _methodsGenerated.Add(reflectableMethodNode.Method);
            }

            var nonGcStaticSectionNode = obj as NonGCStaticsNode;

            if (nonGcStaticSectionNode != null && nonGcStaticSectionNode.HasCCtorContext)
            {
                _cctorContextsGenerated.Add(nonGcStaticSectionNode);
            }

            var gvmEntryNode = obj as TypeGVMEntriesNode;

            if (gvmEntryNode != null)
            {
                _typeGVMEntries.Add(gvmEntryNode);
            }

            var dictionaryNode = obj as GenericDictionaryNode;

            if (dictionaryNode != null)
            {
                _genericDictionariesGenerated.Add(dictionaryNode);
            }

            if (obj is StructMarshallingDataNode structMarshallingDataNode)
            {
                _typesWithStructMarshalling.Add(structMarshallingDataNode.Type);
            }

            if (obj is DelegateMarshallingDataNode delegateMarshallingDataNode)
            {
                _typesWithDelegateMarshalling.Add(delegateMarshallingDataNode.Type);
            }

            if (obj is DynamicInvokeTemplateNode dynamicInvokeTemplate)
            {
                _dynamicInvokeTemplates.Add(dynamicInvokeTemplate.Method);
            }
        }
Exemple #20
0
        public override IEnumerable <CombinedDependencyListEntry> SearchDynamicDependencies(List <DependencyNodeCore <NodeFactory> > markedNodes, int firstNode, NodeFactory factory)
        {
            List <CombinedDependencyListEntry> dynamicDependencies = new List <CombinedDependencyListEntry>();

            TypeDesc methodOwningType = _method.OwningType;
            bool     methodIsShared   = _method.IsSharedByGenericInstantiations;

            TypeSystemContext context = _method.Context;

            for (int i = firstNode; i < markedNodes.Count; i++)
            {
                DependencyNodeCore <NodeFactory> entry = markedNodes[i];
                EETypeNode entryAsEETypeNode           = entry as EETypeNode;

                if (entryAsEETypeNode == null)
                {
                    continue;
                }

                TypeDesc potentialOverrideType = entryAsEETypeNode.Type;
                if (!potentialOverrideType.IsDefType || potentialOverrideType.IsInterface)
                {
                    continue;
                }

                // If method is canonical, don't allow using it with non-canonical types - we can wait until
                // we see the __Canon instantiation. If there isn't one, the canonical method wouldn't be useful anyway.
                if (methodIsShared &&
                    potentialOverrideType.ConvertToCanonForm(CanonicalFormKind.Specific) != potentialOverrideType)
                {
                    continue;
                }

                // Similarly, if the type is canonical but this method instantiation isn't, don't mix them.
                if (!methodIsShared &&
                    potentialOverrideType.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    continue;
                }

                // If this is an interface gvm, look for types that implement the interface
                // and other instantantiations that have the same canonical form.
                // This ensure the various slot numbers remain equivalent across all types where there is an equivalence
                // relationship in the vtable.
                if (methodOwningType.IsInterface)
                {
                    // We go over definitions because a single canonical interface method could actually be implemented
                    // by multiple methods - consider:
                    //
                    // class Foo<T, U> : IFoo<T>, IFoo<U>, IFoo<string> { }
                    //
                    // If we ask what implements IFoo<__Canon>.Method, the answer could be "three methods"
                    // and that's expected. We therefore resolve IFoo<__Canon>.Method for each IFoo<!0>.Method,
                    // IFoo<!1>.Method, and IFoo<string>.Method, adding GVMDependencies for each.
                    TypeDesc  potentialOverrideDefinition   = potentialOverrideType.GetTypeDefinition();
                    DefType[] potentialInterfaces           = potentialOverrideType.RuntimeInterfaces;
                    DefType[] potentialDefinitionInterfaces = potentialOverrideDefinition.RuntimeInterfaces;
                    for (int interfaceIndex = 0; interfaceIndex < potentialInterfaces.Length; interfaceIndex++)
                    {
                        if (potentialInterfaces[interfaceIndex].ConvertToCanonForm(CanonicalFormKind.Specific) == methodOwningType)
                        {
                            MethodDesc interfaceMethod = _method.GetMethodDefinition();
                            if (methodOwningType.HasInstantiation)
                            {
                                interfaceMethod = context.GetMethodForInstantiatedType(
                                    _method.GetTypicalMethodDefinition(), (InstantiatedType)potentialDefinitionInterfaces[interfaceIndex]);
                            }

                            MethodDesc slotDecl = potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodTarget(interfaceMethod);
                            if (slotDecl == null)
                            {
                                // The method might be implemented through a default interface method
                                var result = potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodToDefaultImplementationOnType(interfaceMethod, out slotDecl);
                                if (result != DefaultInterfaceMethodResolution.DefaultImplementation)
                                {
                                    slotDecl = null;
                                }
                            }

                            if (slotDecl != null)
                            {
                                TypeDesc[] openInstantiation = new TypeDesc[_method.Instantiation.Length];
                                for (int instArg = 0; instArg < openInstantiation.Length; instArg++)
                                {
                                    openInstantiation[instArg] = context.GetSignatureVariable(instArg, method: true);
                                }
                                MethodDesc implementingMethodInstantiation = slotDecl.MakeInstantiatedMethod(openInstantiation).InstantiateSignature(potentialOverrideType.Instantiation, _method.Instantiation);
                                dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(implementingMethodInstantiation.GetCanonMethodTarget(CanonicalFormKind.Specific)), null, "ImplementingMethodInstantiation"));
                            }
                        }
                    }
                }
                else
                {
                    // This is not an interface GVM. Check whether the current type overrides the virtual method.
                    // We might need to change what virtual method we ask about - consider:
                    //
                    // class Base<T> { virtual Method(); }
                    // class Derived : Base<string> { override Method(); }
                    //
                    // We need to resolve Base<__Canon>.Method on Derived, but if we were to ask the virtual
                    // method resolution algorithm, the answer would be "does not override" because Base<__Canon>
                    // is not even in the inheritance hierarchy.
                    //
                    // So we need to modify the question to resolve Base<string>.Method instead and then
                    // canonicalize the result.

                    TypeDesc overrideTypeCur = potentialOverrideType;
                    do
                    {
                        if (overrideTypeCur.ConvertToCanonForm(CanonicalFormKind.Specific) == methodOwningType)
                        {
                            break;
                        }

                        overrideTypeCur = overrideTypeCur.BaseType;
                    }while (overrideTypeCur != null);

                    if (overrideTypeCur == null)
                    {
                        continue;
                    }

                    MethodDesc methodToResolve;
                    if (methodOwningType == overrideTypeCur)
                    {
                        methodToResolve = _method;
                    }
                    else
                    {
                        methodToResolve = context
                                          .GetMethodForInstantiatedType(_method.GetTypicalMethodDefinition(), (InstantiatedType)overrideTypeCur)
                                          .MakeInstantiatedMethod(_method.Instantiation);
                    }

                    MethodDesc instantiatedTargetMethod = potentialOverrideType.FindVirtualFunctionTargetMethodOnObjectType(methodToResolve)
                                                          .GetCanonMethodTarget(CanonicalFormKind.Specific);
                    if (instantiatedTargetMethod != _method)
                    {
                        dynamicDependencies.Add(new CombinedDependencyListEntry(
                                                    factory.GVMDependencies(instantiatedTargetMethod), null, "DerivedMethodInstantiation"));
                    }
                }
            }

            return(dynamicDependencies);
        }
Exemple #21
0
        private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                _typesWithEETypesGenerated.Add(eetypeNode.Type);

                if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode)
                {
                    _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type);
                }

                return;
            }

            IMethodNode methodNode = obj as MethodCodeNode;

            if (methodNode == null)
            {
                methodNode = obj as ShadowConcreteMethodNode;
            }

            if (methodNode == null)
            {
                methodNode = obj as NonExternMethodSymbolNode;
            }

            if (methodNode != null)
            {
                _methodsGenerated.Add(methodNode.Method);
                return;
            }

            var reflectableMethodNode = obj as ReflectableMethodNode;

            if (reflectableMethodNode != null)
            {
                _methodsGenerated.Add(reflectableMethodNode.Method);
            }

            var nonGcStaticSectionNode = obj as NonGCStaticsNode;

            if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type))
            {
                _cctorContextsGenerated.Add(nonGcStaticSectionNode);
            }

            var gvmEntryNode = obj as TypeGVMEntriesNode;

            if (gvmEntryNode != null)
            {
                _typeGVMEntries.Add(gvmEntryNode);
            }

            var dictionaryNode = obj as GenericDictionaryNode;

            if (dictionaryNode != null)
            {
                _genericDictionariesGenerated.Add(dictionaryNode);
            }

            // TODO: temporary until we have an IL scanning Metadata Manager. We shouldn't have to keep track of these.
            var moduleMetadataNode = obj as ModuleMetadataNode;

            if (moduleMetadataNode != null)
            {
                _modulesWithMetadata.Add(moduleMetadataNode.Module);
            }
        }
        public override IntPtr OnEntryPoint(MethodEntrypointPtr methodEntrypoint, IntPtr callerArgs)
        {
            lock (this)
            {
                if (_corInfoImpl == null)
                {
                    InitJitCodeManager(RuntimeAugments.RhGetOSModuleForMrt());

                    // TODO: Recycle jit interface object and TypeSystemContext
                    _context = TypeSystemContextFactory.Create();

                    Compilation compilation = new Compilation(_context);
                    _nodeFactory = compilation.NodeFactory;

                    JitConfigProvider configProvider = new JitConfigProvider(new CorJitFlag[] { CorJitFlag.CORJIT_FLAG_DEBUG_CODE }, Array.Empty <KeyValuePair <string, string> >());

                    _corInfoImpl = new CorInfoImpl(compilation, configProvider);
                }

                MethodDesc methodToCompile = methodEntrypoint.MethodIdentifier.ToMethodDesc(_context);

                JitMethodCodeNode codeNode = new JitMethodCodeNode(methodToCompile);
                _corInfoImpl.CompileMethod(codeNode);

                ObjectNode.ObjectData codeData = codeNode.GetData(null, false);

                List <ObjectNode> nodesToEmit = new List <ObjectNode>();
                Dictionary <DependencyNodeCore <NodeFactory>, object> relocTargets = new Dictionary <DependencyNodeCore <NodeFactory>, object>();
                int totalAllocSizeNeeded  = 0;
                int nonObjectRelocTargets = 0;

                nodesToEmit.Add(codeNode);
                UpdateBytesUsed(codeNode.GetData(_nodeFactory), ref totalAllocSizeNeeded);

                int offsetOfEHData = totalAllocSizeNeeded;

                if (codeNode.EHInfo != null)
                {
                    Debug.Assert(codeNode.EHInfo.Alignment == 1); // Assert needed as otherwise offsetOfEHData will be wrong

                    UpdateBytesUsed(codeNode.EHInfo, ref totalAllocSizeNeeded);
                    ComputeDependencySizeAndRelocData(codeNode.EHInfo, relocTargets, nodesToEmit, ref totalAllocSizeNeeded, ref nonObjectRelocTargets);
                }

                for (int i = 0; i < nodesToEmit.Count; i++)
                {
                    ObjectNode objNode = nodesToEmit[i];
                    ComputeDependencySizeAndRelocData(objNode.GetData(_nodeFactory, true), relocTargets, nodesToEmit, ref totalAllocSizeNeeded, ref nonObjectRelocTargets);
                }

                if (nonObjectRelocTargets != 0)
                {
                    totalAllocSizeNeeded = totalAllocSizeNeeded.AlignUp(IntPtr.Size);
                }

                int relocTargetOffsetStart = totalAllocSizeNeeded;

                DependencyNodeCore <NodeFactory>[] relocTargetsArray = new DependencyNodeCore <NodeFactory> [nonObjectRelocTargets];
                {
                    int iRelocTarget = 0;
                    foreach (var relocTarget in relocTargets)
                    {
                        if (!(relocTarget.Key is ObjectNode))
                        {
                            relocTargetsArray[iRelocTarget] = relocTarget.Key;
                            totalAllocSizeNeeded           += IntPtr.Size;
                            iRelocTarget++;
                        }
                    }
                    Debug.Assert(iRelocTarget == nonObjectRelocTargets);
                }

                GenericDictionaryCell[] genDictCells = new GenericDictionaryCell[relocTargetsArray.Length];
                for (int iRelocTarget = 0; iRelocTarget < relocTargetsArray.Length; iRelocTarget++)
                {
                    DependencyNodeCore <NodeFactory> relocTarget = relocTargetsArray[iRelocTarget];
                    GenericDictionaryCell            newCell     = null;

                    if (relocTarget is ExternObjectSymbolNode)
                    {
                        var externObjectSymbolNode = (ExternObjectSymbolNode)relocTarget;
                        var newMethodCell          = externObjectSymbolNode.GetDictionaryCell();
                        newCell = newMethodCell;
                    }

                    if (newCell == null)
                    {
                        Environment.FailFast("Unknown reloc target type");
                    }
                    genDictCells[iRelocTarget] = newCell;
                }

                IntPtr[] relocTargetsAsIntPtr = null;

                TypeLoaderEnvironment.Instance.RunUnderTypeLoaderLock(
                    () =>
                {
                    TypeBuilderApi.ResolveMultipleCells(genDictCells, out relocTargetsAsIntPtr);
                });

                // Layout of allocated memory...
                // ObjectNodes (aligned as appropriate)
                IntPtr pCodeManager;
                IntPtr jittedCode    = AllocJittedCode(checked ((uint)totalAllocSizeNeeded), 8 /* TODO, alignment calculation */, out pCodeManager);
                int    currentOffset = 0;

                foreach (var node in nodesToEmit)
                {
                    ObjectNode.ObjectData objectData = node.GetData(_nodeFactory);
                    EmitAndRelocData(objectData, jittedCode, relocTargetOffsetStart, ref currentOffset, relocTargetsArray, relocTargetsAsIntPtr);

                    // EHInfo doesn't get its own node, but it does get emitted into the stream.
                    if ((node == codeNode) && (codeNode.EHInfo != null))
                    {
                        Debug.Assert(offsetOfEHData == currentOffset);
                        EmitAndRelocData(codeNode.EHInfo, jittedCode, relocTargetOffsetStart, ref currentOffset, relocTargetsArray, relocTargetsAsIntPtr);
                    }
                }

                foreach (IntPtr ptr in relocTargetsAsIntPtr)
                {
                    currentOffset = currentOffset.AlignUp(IntPtr.Size);
                    Marshal.WriteIntPtr(jittedCode, currentOffset, ptr);
                    currentOffset += IntPtr.Size;
                }

                SetEHInfoPtr(pCodeManager, jittedCode, jittedCode + offsetOfEHData);

                IntPtr mainRuntimeFunction = IntPtr.Zero;

                for (int i = 0; i < codeNode.FrameInfos.Length; i++)
                {
                    FrameInfo frame           = codeNode.FrameInfos[i];
                    byte[]    frameData       = frame.BlobData;
                    byte[]    gcInfoData      = Array.Empty <byte>();
                    byte[]    gcInfoDataDeref = frameData;

                    if (i == 0)
                    {
                        // For main function, add the gc info to the data
                        gcInfoDataDeref = gcInfoData = codeNode.GCInfo;
                    }

                    IntPtr publishedFunction = PublishRuntimeFunction(pCodeManager,
                                                                      jittedCode,
                                                                      mainRuntimeFunction,
                                                                      checked ((uint)frame.StartOffset),
                                                                      checked ((uint)frame.EndOffset),
                                                                      frameData,
                                                                      checked ((uint)frameData.Length),
                                                                      gcInfoDataDeref,
                                                                      checked ((uint)gcInfoData.Length));

                    if (i == 0)
                    {
                        mainRuntimeFunction = publishedFunction;
                    }
                }

                if (mainRuntimeFunction != IntPtr.Zero)
                {
                    UpdateRuntimeFunctionTable(pCodeManager);
                }

                methodEntrypoint.MethodCode = jittedCode;

                return(jittedCode);
            }
        }
Exemple #23
0
        public override IEnumerable <CombinedDependencyListEntry> SearchDynamicDependencies(List <DependencyNodeCore <NodeFactory> > markedNodes, int firstNode, NodeFactory factory)
        {
            Debug.Assert(_method.IsVirtual && _method.HasInstantiation);

            List <CombinedDependencyListEntry> dynamicDependencies = new List <CombinedDependencyListEntry>();

            for (int i = firstNode; i < markedNodes.Count; i++)
            {
                DependencyNodeCore <NodeFactory> entry = markedNodes[i];
                EETypeNode entryAsEETypeNode           = entry as EETypeNode;

                if (entryAsEETypeNode == null)
                {
                    continue;
                }

                TypeDesc potentialOverrideType = entryAsEETypeNode.Type;
                if (!(potentialOverrideType is DefType))
                {
                    continue;
                }

                Debug.Assert(!potentialOverrideType.IsRuntimeDeterminedSubtype);

                if (_method.OwningType.HasSameTypeDefinition(potentialOverrideType) && potentialOverrideType.IsInterface && (potentialOverrideType != _method.OwningType))
                {
                    if (_method.OwningType.CanCastTo(potentialOverrideType))
                    {
                        // Variance expansion
                        MethodDesc matchingMethodOnRelatedVariantMethod = potentialOverrideType.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature);
                        matchingMethodOnRelatedVariantMethod = _method.Context.GetInstantiatedMethod(matchingMethodOnRelatedVariantMethod, _method.Instantiation);
                        dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(matchingMethodOnRelatedVariantMethod), null, "GVM Variant Interface dependency"));
                    }
                }

                // If this is an interface gvm, look for types that implement the interface
                // and other instantantiations that have the same canonical form.
                // This ensure the various slot numbers remain equivalent across all types where there is an equivalence
                // relationship in the vtable.
                if (_method.OwningType.IsInterface)
                {
                    if (potentialOverrideType.IsInterface)
                    {
                        continue;
                    }

                    foreach (DefType interfaceImpl in potentialOverrideType.RuntimeInterfaces)
                    {
                        if (interfaceImpl.ConvertToCanonForm(CanonicalFormKind.Specific) == _method.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific))
                        {
                            // Find if the type implements this method. (Note, do this comparision against the generic definition of the method, not the
                            // specific method instantiation that is "method"
                            MethodDesc genericDefinition = interfaceImpl.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature);
                            MethodDesc slotDecl          = potentialOverrideType.ResolveInterfaceMethodTarget(genericDefinition);
                            if (slotDecl != null)
                            {
                                CreateDependencyForMethodSlotAndInstantiation(slotDecl, dynamicDependencies, factory);
                            }
                        }
                    }
                }
                else
                {
                    // TODO: Ensure GVM Canon Target

                    TypeDesc overrideTypeCanonCur      = potentialOverrideType;
                    TypeDesc methodCanonContainingType = _method.OwningType;
                    while (overrideTypeCanonCur != null)
                    {
                        if (overrideTypeCanonCur.ConvertToCanonForm(CanonicalFormKind.Specific) == methodCanonContainingType.ConvertToCanonForm(CanonicalFormKind.Specific))
                        {
                            MethodDesc methodDefInDerivedType = potentialOverrideType.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature);
                            if (methodDefInDerivedType != null)
                            {
                                CreateDependencyForMethodSlotAndInstantiation(methodDefInDerivedType, dynamicDependencies, factory);
                            }

                            MethodDesc slotDecl = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(_method);
                            if (slotDecl != null)
                            {
                                CreateDependencyForMethodSlotAndInstantiation(slotDecl.GetMethodDefinition(), dynamicDependencies, factory);
                            }
                        }

                        overrideTypeCanonCur = overrideTypeCanonCur.BaseType;
                    }
                }
            }
            return(dynamicDependencies);
        }
Exemple #24
0
        protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj)
        {
            var eetypeNode = obj as EETypeNode;

            if (eetypeNode != null)
            {
                _typesWithEETypesGenerated.Add(eetypeNode.Type);

                if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode)
                {
                    _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type);
                }

                return;
            }

            IMethodBodyNode methodBodyNode = obj as IMethodBodyNode;

            if (methodBodyNode != null)
            {
                _methodBodiesGenerated.Add(methodBodyNode);
            }

            IMethodNode methodNode = methodBodyNode;

            if (methodNode == null)
            {
                methodNode = obj as ShadowConcreteMethodNode;
            }

            if (methodNode != null)
            {
                _methodsGenerated.Add(methodNode.Method);
                return;
            }

            var reflectableMethodNode = obj as ReflectableMethodNode;

            if (reflectableMethodNode != null)
            {
                _methodsGenerated.Add(reflectableMethodNode.Method);
            }

            var nonGcStaticSectionNode = obj as NonGCStaticsNode;

            if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type))
            {
                _cctorContextsGenerated.Add(nonGcStaticSectionNode);
            }

            var gvmEntryNode = obj as TypeGVMEntriesNode;

            if (gvmEntryNode != null)
            {
                _typeGVMEntries.Add(gvmEntryNode);
            }

            var dictionaryNode = obj as GenericDictionaryNode;

            if (dictionaryNode != null)
            {
                _genericDictionariesGenerated.Add(dictionaryNode);
            }

            var ctorFromLazyGenericsNode = obj as DefaultConstructorFromLazyNode;

            if (ctorFromLazyGenericsNode != null)
            {
                _defaultConstructorsNeeded.Add(ctorFromLazyGenericsNode);
            }
        }