protected override void GetDependenciesDueToEETypePresence(ref DependencyList dependencies, NodeFactory factory, TypeDesc type)
        {
            if (!ConstructedEETypeNode.CreationAllowed(type))
            {
                // Both EETypeNode and ConstructedEETypeNode call into this logic. EETypeNode will only call for unconstructable
                // EETypes. We don't have templates for those.
                return;
            }

            DefType closestDefType = type.GetClosestDefType();

            // TODO-SIZE: this is overly generous in the templates we create
            if (closestDefType.HasInstantiation)
            {
                TypeDesc canonType           = type.ConvertToCanonForm(CanonicalFormKind.Specific);
                TypeDesc canonClosestDefType = closestDefType.ConvertToCanonForm(CanonicalFormKind.Specific);

                // Add a dependency on the template for this type, if the canonical type should be generated into this binary.
                // If the type is an array type, the check should be on its underlying Array<T> type. This is because a copy of
                // an array type gets placed into each module but the Array<T> type only exists in the defining module and only
                // one template is needed for the Array<T> type by the dynamic type loader.
                if (canonType.IsCanonicalSubtype(CanonicalFormKind.Any) && !factory.NecessaryTypeSymbol(canonClosestDefType).RepresentsIndirectionCell)
                {
                    dependencies.Add(factory.NativeLayout.TemplateTypeLayout(canonType), "Template Type Layout");
                }
            }
        }
Example #2
0
 public void AddCompilationRoot(TypeDesc type, string reason)
 {
     if (!ConstructedEETypeNode.CreationAllowed(type))
     {
         _graph.AddRoot(_factory.NecessaryTypeSymbol(type), reason);
     }
     else
     {
         _graph.AddRoot(_factory.ConstructedTypeSymbol(type), reason);
     }
 }
        private IEnumerable <TypeDesc> GetTypesWithRuntimeMapping()
        {
            // All constructed types that are not blocked get runtime mapping
            foreach (var constructedType in GetTypesWithConstructedEETypes())
            {
                if (!IsReflectionBlocked(constructedType))
                {
                    yield return(constructedType);
                }
            }

            // All necessary types for which this is the highest load level that are not blocked
            // get runtime mapping.
            foreach (var necessaryType in GetTypesWithEETypes())
            {
                if (!ConstructedEETypeNode.CreationAllowed(necessaryType) &&
                    !IsReflectionBlocked(necessaryType))
                {
                    yield return(necessaryType);
                }
            }
        }
 public override bool ShouldProduceFullVTable(TypeDesc type)
 {
     return(ConstructedEETypeNode.CreationAllowed(type));
 }
Example #5
0
        private void ImportLdToken(int token)
        {
            object obj = _methodIL.GetObject(token);

            if (obj is TypeDesc)
            {
                var type = (TypeDesc)obj;

                if (type.IsRuntimeDeterminedSubtype)
                {
                    _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, type), "ldtoken");
                }
                else
                {
                    if (ConstructedEETypeNode.CreationAllowed(type))
                    {
                        _dependencies.Add(_factory.ConstructedTypeSymbol(type), "ldtoken");
                    }
                    else
                    {
                        _dependencies.Add(_factory.NecessaryTypeSymbol(type), "ldtoken");
                    }
                }

                // If this is a ldtoken Type / GetValueInternal sequence, we're done.
                BasicBlock nextBasicBlock = _basicBlocks[_currentOffset];
                if (nextBasicBlock == null)
                {
                    if ((ILOpcode)_ilBytes[_currentOffset] == ILOpcode.call)
                    {
                        int methodToken = ReadILTokenAt(_currentOffset + 1);
                        var method      = (MethodDesc)_methodIL.GetObject(methodToken);
                        if (IsRuntimeTypeHandleGetValueInternal(method))
                        {
                            // Codegen expands this and doesn't do the normal ldtoken.
                            return;
                        }
                    }
                }

                _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeTypeHandle), "ldtoken");
            }
            else if (obj is MethodDesc)
            {
                var method = (MethodDesc)obj;
                if (method.IsRuntimeDeterminedExactMethod)
                {
                    _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodHandle, method), "ldtoken");
                }
                else
                {
                    _dependencies.Add(_factory.RuntimeMethodHandle(method), "ldtoken");
                }

                _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeMethodHandle), "ldtoken");
            }
            else
            {
                Debug.Assert(obj is FieldDesc);

                // First check if this is a ldtoken Field / InitializeArray sequence.
                BasicBlock nextBasicBlock = _basicBlocks[_currentOffset];
                if (nextBasicBlock == null)
                {
                    if ((ILOpcode)_ilBytes[_currentOffset] == ILOpcode.call)
                    {
                        int methodToken = ReadILTokenAt(_currentOffset + 1);
                        var method      = (MethodDesc)_methodIL.GetObject(methodToken);
                        if (IsRuntimeHelpersInitializeArray(method))
                        {
                            // Codegen expands this and doesn't do the normal ldtoken.
                            return;
                        }
                    }
                }

                var field = (FieldDesc)obj;
                if (field.OwningType.IsRuntimeDeterminedSubtype)
                {
                    _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.FieldHandle, field), "ldtoken");
                }
                else
                {
                    _dependencies.Add(_factory.RuntimeFieldHandle(field), "ldtoken");
                }

                _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeFieldHandle), "ldtoken");
            }
        }
Example #6
0
        public MetadataManager ToAnalysisBasedMetadataManager()
        {
            var reflectableTypes = ReflectableEntityBuilder <TypeDesc> .Create();

            // Collect the list of types that are generating reflection metadata
            foreach (var typeWithMetadata in _typesWithMetadata)
            {
                reflectableTypes[typeWithMetadata] = MetadataCategory.Description;
            }

            // All the constructed types we generated that are not blocked are required to have runtime artifacts
            foreach (var constructedType in GetTypesWithConstructedEETypes())
            {
                if (!IsReflectionBlocked(constructedType))
                {
                    reflectableTypes[constructedType] |= MetadataCategory.RuntimeMapping;

                    // Also set the description bit if the definition is getting metadata.
                    TypeDesc constructedTypeDefinition = constructedType.GetTypeDefinition();
                    if (constructedType != constructedTypeDefinition &&
                        (reflectableTypes[constructedTypeDefinition] & MetadataCategory.Description) != 0)
                    {
                        reflectableTypes[constructedType] |= MetadataCategory.Description;
                    }
                }
            }

            // All the necessary types for which this is the higest load level are required to have runtime artifacts
            foreach (var necessaryType in GetTypesWithEETypes())
            {
                if (!ConstructedEETypeNode.CreationAllowed(necessaryType) &&
                    !IsReflectionBlocked(necessaryType))
                {
                    reflectableTypes[necessaryType] |= MetadataCategory.RuntimeMapping;

                    // Also set the description bit if the definition is getting metadata.
                    TypeDesc necessaryTypeDefinition = necessaryType.GetTypeDefinition();
                    if (necessaryType != necessaryTypeDefinition &&
                        (reflectableTypes[necessaryTypeDefinition] & MetadataCategory.Description) != 0)
                    {
                        reflectableTypes[necessaryType] |= MetadataCategory.Description;
                    }
                }
            }

            var reflectableMethods = ReflectableEntityBuilder <MethodDesc> .Create();

            foreach (var methodWithMetadata in _methodsWithMetadata)
            {
                reflectableMethods[methodWithMetadata] = MetadataCategory.Description;
            }

            foreach (var method in GetCompiledMethods())
            {
                if (!method.IsCanonicalMethod(CanonicalFormKind.Specific) &&
                    !IsReflectionBlocked(method))
                {
                    if ((reflectableTypes[method.OwningType] & MetadataCategory.RuntimeMapping) != 0)
                    {
                        reflectableMethods[method] |= MetadataCategory.RuntimeMapping;
                    }

                    // Also set the description bit if the definition is getting metadata.
                    MethodDesc typicalMethod = method.GetTypicalMethodDefinition();
                    if (method != typicalMethod &&
                        (reflectableMethods[typicalMethod] & MetadataCategory.Description) != 0)
                    {
                        reflectableMethods[method]          |= MetadataCategory.Description;
                        reflectableTypes[method.OwningType] |= MetadataCategory.Description;
                    }
                }
            }

            var reflectableFields = ReflectableEntityBuilder <FieldDesc> .Create();

            foreach (var fieldWithMetadata in _fieldsWithMetadata)
            {
                reflectableFields[fieldWithMetadata] = MetadataCategory.Description;
            }

            // TODO: this should be more precise
            foreach (var reflectableType in reflectableTypes.ToEnumerable())
            {
                if (reflectableType.Entity.IsGenericDefinition)
                {
                    continue;
                }

                if (reflectableType.Entity.IsCanonicalSubtype(CanonicalFormKind.Specific))
                {
                    continue;
                }

                foreach (var field in reflectableType.Entity.GetFields())
                {
                    if (CanGenerateMetadata(field.GetTypicalFieldDefinition()))
                    {
                        reflectableFields[field] |= reflectableType.Category;
                    }
                }
            }

            return(new AnalysisBasedMetadataManager(_compilationModuleGroup.GeneratedAssembly,
                                                    _typeSystemContext, _blockingPolicy, _metadataLogFile, _stackTraceEmissionPolicy,
                                                    _modulesWithMetadata, reflectableTypes.ToEnumerable(), reflectableMethods.ToEnumerable(),
                                                    reflectableFields.ToEnumerable()));
        }