Exemple #1
0
        public ReadyToRunCodegenNodeFactory(
            CompilerTypeSystemContext context,
            CompilationModuleGroup compilationModuleGroup,
            NameMangler nameMangler,
            ModuleTokenResolver moduleTokenResolver,
            SignatureContext signatureContext,
            CopiedCorHeaderNode corHeaderNode,
            ResourceData win32Resources,
            AttributePresenceFilterNode attributePresenceFilterNode)
            : base(context,
                   compilationModuleGroup,
                   nameMangler,
                   new ReadyToRunTableManager(context))
        {
            Resolver                = moduleTokenResolver;
            InputModuleContext      = signatureContext;
            CopiedCorHeaderNode     = corHeaderNode;
            AttributePresenceFilter = attributePresenceFilterNode;
            if (!win32Resources.IsEmpty)
            {
                Win32ResourcesNode = new Win32ResourcesNode(win32Resources);
            }

            CreateNodeCaches();
        }
Exemple #2
0
        public NodeFactory(
            CompilerTypeSystemContext context,
            CompilationModuleGroup compilationModuleGroup,
            NameMangler nameMangler,
            ModuleTokenResolver moduleTokenResolver,
            SignatureContext signatureContext,
            CopiedCorHeaderNode corHeaderNode,
            DebugDirectoryNode debugDirectoryNode,
            ResourceData win32Resources,
            AttributePresenceFilterNode attributePresenceFilterNode,
            HeaderNode headerNode)
        {
            TypeSystemContext      = context;
            CompilationModuleGroup = compilationModuleGroup;
            Target                  = context.Target;
            NameMangler             = nameMangler;
            MetadataManager         = new ReadyToRunTableManager(context);
            Resolver                = moduleTokenResolver;
            InputModuleContext      = signatureContext;
            CopiedCorHeaderNode     = corHeaderNode;
            DebugDirectoryNode      = debugDirectoryNode;
            AttributePresenceFilter = attributePresenceFilterNode;
            Header                  = headerNode;
            if (!win32Resources.IsEmpty)
            {
                Win32ResourcesNode = new Win32ResourcesNode(win32Resources);
            }

            CreateNodeCaches();
        }
Exemple #3
0
        public ReadyToRunCodegenNodeFactory(
            CompilerTypeSystemContext context,
            CompilationModuleGroup compilationModuleGroup,
            NameMangler nameMangler,
            ModuleTokenResolver moduleTokenResolver,
            SignatureContext signatureContext,
            CopiedCorHeaderNode corHeaderNode,
            ResourceData win32Resources,
            AttributePresenceFilterNode attributePresenceFilterNode)
            : base(context,
                   compilationModuleGroup,
                   nameMangler,
                   new ReadyToRunTableManager(context))
        {
            // To make the code future compatible to the composite R2R story
            // do NOT attempt to pass and store _inputModule here
            _importMethods = new Dictionary <TypeAndMethod, IMethodNode>();

            Resolver                = moduleTokenResolver;
            InputModuleContext      = signatureContext;
            CopiedCorHeaderNode     = corHeaderNode;
            AttributePresenceFilter = attributePresenceFilterNode;
            if (!win32Resources.IsEmpty)
            {
                Win32ResourcesNode = new Win32ResourcesNode(win32Resources);
            }
        }
        public void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph)
        {
            graph.ComputingDependencyPhaseChange += Graph_ComputingDependencyPhaseChange;

            var compilerIdentifierNode = new CompilerIdentifierNode(Target);

            Header.Add(Internal.Runtime.ReadyToRunSectionType.CompilerIdentifier, compilerIdentifierNode, compilerIdentifierNode);

            RuntimeFunctionsTable = new RuntimeFunctionsTableNode(this);
            Header.Add(Internal.Runtime.ReadyToRunSectionType.RuntimeFunctions, RuntimeFunctionsTable, RuntimeFunctionsTable);

            RuntimeFunctionsGCInfo = new RuntimeFunctionsGCInfoNode();
            graph.AddRoot(RuntimeFunctionsGCInfo, "GC info is always generated");

            ProfileDataSection = new ProfileDataSectionNode();
            Header.Add(Internal.Runtime.ReadyToRunSectionType.ProfileDataInfo, ProfileDataSection, ProfileDataSection.StartSymbol);

            DelayLoadMethodCallThunks = new DelayLoadMethodCallThunkNodeRange();
            Header.Add(Internal.Runtime.ReadyToRunSectionType.DelayLoadMethodCallThunks, DelayLoadMethodCallThunks, DelayLoadMethodCallThunks);

            ExceptionInfoLookupTableNode exceptionInfoLookupTableNode = new ExceptionInfoLookupTableNode(this);

            Header.Add(Internal.Runtime.ReadyToRunSectionType.ExceptionInfo, exceptionInfoLookupTableNode, exceptionInfoLookupTableNode);
            graph.AddRoot(exceptionInfoLookupTableNode, "ExceptionInfoLookupTable is always generated");

            ManifestMetadataTable = new ManifestMetadataTableNode(this);
            Header.Add(Internal.Runtime.ReadyToRunSectionType.ManifestMetadata, ManifestMetadataTable, ManifestMetadataTable);
            Resolver.SetModuleIndexLookup(ManifestMetadataTable.ModuleToIndex);

            ManifestAssemblyMvidHeaderNode mvidTableNode = new ManifestAssemblyMvidHeaderNode(ManifestMetadataTable);

            Header.Add(Internal.Runtime.ReadyToRunSectionType.ManifestAssemblyMvids, mvidTableNode, mvidTableNode);

            AssemblyTableNode assemblyTable = null;

            if (CompilationModuleGroup.IsCompositeBuildMode)
            {
                assemblyTable = new AssemblyTableNode(Target);
                Header.Add(Internal.Runtime.ReadyToRunSectionType.ComponentAssemblies, assemblyTable, assemblyTable);
            }

            // Generate per assembly header tables
            int assemblyIndex = -1;

            foreach (EcmaModule inputModule in CompilationModuleGroup.CompilationModuleSet)
            {
                assemblyIndex++;
                HeaderNode tableHeader = Header;
                if (assemblyTable != null)
                {
                    AssemblyHeaderNode perAssemblyHeader = new AssemblyHeaderNode(Target, ReadyToRunFlags.READYTORUN_FLAG_Component, assemblyIndex);
                    assemblyTable.Add(perAssemblyHeader);
                    tableHeader = perAssemblyHeader;
                }

                MethodEntryPointTableNode methodEntryPointTable = new MethodEntryPointTableNode(inputModule, Target);
                tableHeader.Add(Internal.Runtime.ReadyToRunSectionType.MethodDefEntryPoints, methodEntryPointTable, methodEntryPointTable);

                TypesTableNode typesTable = new TypesTableNode(Target, inputModule);
                tableHeader.Add(Internal.Runtime.ReadyToRunSectionType.AvailableTypes, typesTable, typesTable);

                InliningInfoNode inliningInfoTable = new InliningInfoNode(Target, inputModule);
                tableHeader.Add(Internal.Runtime.ReadyToRunSectionType.InliningInfo2, inliningInfoTable, inliningInfoTable);

                // Core library attributes are checked FAR more often than other dlls
                // attributes, so produce a highly efficient table for determining if they are
                // present. Other assemblies *MAY* benefit from this feature, but it doesn't show
                // as useful at this time.
                if (inputModule == TypeSystemContext.SystemModule)
                {
                    AttributePresenceFilterNode attributePresenceTable = new AttributePresenceFilterNode(inputModule);
                    Header.Add(Internal.Runtime.ReadyToRunSectionType.AttributePresence, attributePresenceTable, attributePresenceTable);
                }
            }

            InstanceEntryPointTable = new InstanceEntryPointTableNode(this);
            Header.Add(Internal.Runtime.ReadyToRunSectionType.InstanceMethodEntryPoints, InstanceEntryPointTable, InstanceEntryPointTable);

            ImportSectionsTable = new ImportSectionsTableNode(this);
            Header.Add(Internal.Runtime.ReadyToRunSectionType.ImportSections, ImportSectionsTable, ImportSectionsTable.StartSymbol);

            DebugInfoTable = new DebugInfoTableNode(Target);
            Header.Add(Internal.Runtime.ReadyToRunSectionType.DebugInfo, DebugInfoTable, DebugInfoTable);

            EagerImports = new ImportSectionNode(
                "EagerImports",
                CorCompileImportType.CORCOMPILE_IMPORT_TYPE_UNKNOWN,
                CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_EAGER,
                (byte)Target.PointerSize,
                emitPrecode: false,
                emitGCRefMap: false);
            ImportSectionsTable.AddEmbeddedObject(EagerImports);

            // All ready-to-run images have a module import helper which gets patched by the runtime on image load
            ModuleImport = new Import(EagerImports, new ReadyToRunHelperSignature(
                                          ReadyToRunHelper.Module));
            graph.AddRoot(ModuleImport, "Module import is required by the R2R format spec");

            if (Target.Architecture != TargetArchitecture.X86)
            {
                Import personalityRoutineImport = new Import(EagerImports, new ReadyToRunHelperSignature(
                                                                 ReadyToRunHelper.PersonalityRoutine));
                PersonalityRoutine = new ImportThunk(this,
                                                     ReadyToRunHelper.PersonalityRoutine, EagerImports, useVirtualCall: false, useJumpableStub: false);
                graph.AddRoot(PersonalityRoutine, "Personality routine is faster to root early rather than referencing it from each unwind info");

                Import filterFuncletPersonalityRoutineImport = new Import(EagerImports, new ReadyToRunHelperSignature(
                                                                              ReadyToRunHelper.PersonalityRoutineFilterFunclet));
                FilterFuncletPersonalityRoutine = new ImportThunk(this,
                                                                  ReadyToRunHelper.PersonalityRoutineFilterFunclet, EagerImports, useVirtualCall: false, useJumpableStub: false);
                graph.AddRoot(FilterFuncletPersonalityRoutine, "Filter funclet personality routine is faster to root early rather than referencing it from each unwind info");
            }

            if ((ProfileDataManager != null) && (ProfileDataManager.EmbedPgoDataInR2RImage))
            {
                // Profile instrumentation data attaches here
                HashSet <MethodDesc> methodsToInsertInstrumentationDataFor = new HashSet <MethodDesc>();
                foreach (EcmaModule inputModule in CompilationModuleGroup.CompilationModuleSet)
                {
                    foreach (MethodDesc method in ProfileDataManager.GetMethodsForModuleDesc(inputModule))
                    {
                        if (ProfileDataManager[method].SchemaData != null)
                        {
                            methodsToInsertInstrumentationDataFor.Add(method);
                        }
                    }
                }
                if (methodsToInsertInstrumentationDataFor.Count != 0)
                {
                    MethodDesc[] methodsToInsert = methodsToInsertInstrumentationDataFor.ToArray();
                    methodsToInsert.MergeSort(new TypeSystemComparer().Compare);
                    InstrumentationDataTable = new InstrumentationDataTableNode(this, methodsToInsert, ProfileDataManager);
                    Header.Add(Internal.Runtime.ReadyToRunSectionType.PgoInstrumentationData, InstrumentationDataTable, InstrumentationDataTable);
                }
            }

            MethodImports = new ImportSectionNode(
                "MethodImports",
                CorCompileImportType.CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH,
                CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_PCODE,
                (byte)Target.PointerSize,
                emitPrecode: false,
                emitGCRefMap: true);
            ImportSectionsTable.AddEmbeddedObject(MethodImports);

            DispatchImports = new ImportSectionNode(
                "DispatchImports",
                CorCompileImportType.CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH,
                CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_PCODE,
                (byte)Target.PointerSize,
                emitPrecode: false,
                emitGCRefMap: true);
            ImportSectionsTable.AddEmbeddedObject(DispatchImports);

            HelperImports = new ImportSectionNode(
                "HelperImports",
                CorCompileImportType.CORCOMPILE_IMPORT_TYPE_UNKNOWN,
                CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_PCODE,
                (byte)Target.PointerSize,
                emitPrecode: false,
                emitGCRefMap: false);
            ImportSectionsTable.AddEmbeddedObject(HelperImports);

            PrecodeImports = new ImportSectionNode(
                "PrecodeImports",
                CorCompileImportType.CORCOMPILE_IMPORT_TYPE_UNKNOWN,
                CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_PCODE,
                (byte)Target.PointerSize,
                emitPrecode: true,
                emitGCRefMap: false);
            ImportSectionsTable.AddEmbeddedObject(PrecodeImports);

            StringImports = new ImportSectionNode(
                "StringImports",
                CorCompileImportType.CORCOMPILE_IMPORT_TYPE_STRING_HANDLE,
                CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_UNKNOWN,
                (byte)Target.PointerSize,
                emitPrecode: true,
                emitGCRefMap: false);
            ImportSectionsTable.AddEmbeddedObject(StringImports);

            graph.AddRoot(ImportSectionsTable, "Import sections table is always generated");
            graph.AddRoot(ModuleImport, "Module import is always generated");
            graph.AddRoot(EagerImports, "Eager imports are always generated");
            graph.AddRoot(MethodImports, "Method imports are always generated");
            graph.AddRoot(DispatchImports, "Dispatch imports are always generated");
            graph.AddRoot(HelperImports, "Helper imports are always generated");
            graph.AddRoot(PrecodeImports, "Precode helper imports are always generated");
            graph.AddRoot(StringImports, "String imports are always generated");
            graph.AddRoot(Header, "ReadyToRunHeader is always generated");
            graph.AddRoot(CopiedCorHeaderNode, "MSIL COR header is always generated for R2R files");
            graph.AddRoot(DebugDirectoryNode, "Debug Directory will always contain at least one entry");

            if (Win32ResourcesNode != null)
            {
                graph.AddRoot(Win32ResourcesNode, "Win32 Resources are placed if not empty");
            }

            MetadataManager.AttachToDependencyGraph(graph);
        }
Exemple #5
0
        public override ICompilation ToCompilation()
        {
            ModuleTokenResolver         moduleTokenResolver         = new ModuleTokenResolver(_compilationGroup, _context);
            SignatureContext            signatureContext            = new SignatureContext(_inputModule, moduleTokenResolver);
            CopiedCorHeaderNode         corHeaderNode               = new CopiedCorHeaderNode(_inputModule);
            AttributePresenceFilterNode attributePresenceFilterNode = null;

            // Core library attributes are checked FAR more often than other dlls
            // attributes, so produce a highly efficient table for determining if they are
            // present. Other assemblies *MAY* benefit from this feature, but it doesn't show
            // as useful at this time.
            if (_inputModule == _inputModule.Context.SystemModule)
            {
                attributePresenceFilterNode = new AttributePresenceFilterNode(_inputModule);
            }

            // Produce a ResourceData where the IBC PROFILE_DATA entry has been filtered out
            ResourceData win32Resources = new ResourceData(_inputModule, (object type, object name, ushort language) =>
            {
                if (!(type is string) || !(name is string))
                {
                    return(true);
                }
                if (language != 0)
                {
                    return(true);
                }

                string typeString = (string)type;
                string nameString = (string)name;

                if ((typeString == "IBC") && (nameString == "PROFILE_DATA"))
                {
                    return(false);
                }

                return(true);
            });

            ReadyToRunCodegenNodeFactory factory = new ReadyToRunCodegenNodeFactory(
                _context,
                _compilationGroup,
                _nameMangler,
                moduleTokenResolver,
                signatureContext,
                corHeaderNode,
                win32Resources,
                attributePresenceFilterNode);

            IComparer <DependencyNodeCore <NodeFactory> > comparer = new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer());
            DependencyAnalyzerBase <NodeFactory>          graph    = CreateDependencyGraph(factory, comparer);

            List <CorJitFlag> corJitFlags = new List <CorJitFlag> {
                CorJitFlag.CORJIT_FLAG_DEBUG_INFO
            };

            switch (_optimizationMode)
            {
            case OptimizationMode.None:
                corJitFlags.Add(CorJitFlag.CORJIT_FLAG_DEBUG_CODE);
                break;

            case OptimizationMode.PreferSize:
                corJitFlags.Add(CorJitFlag.CORJIT_FLAG_SIZE_OPT);
                break;

            case OptimizationMode.PreferSpeed:
                corJitFlags.Add(CorJitFlag.CORJIT_FLAG_SPEED_OPT);
                break;

            default:
                // Not setting a flag results in BLENDED_CODE.
                break;
            }

            if (_ibcTuning)
            {
                corJitFlags.Add(CorJitFlag.CORJIT_FLAG_BBINSTR);
            }

            corJitFlags.Add(CorJitFlag.CORJIT_FLAG_FEATURE_SIMD);
            var jitConfig = new JitConfigProvider(corJitFlags, _ryujitOptions, _jitPath);

            return(new ReadyToRunCodegenCompilation(
                       graph,
                       factory,
                       _compilationRoots,
                       _ilProvider,
                       _logger,
                       new DependencyAnalysis.ReadyToRun.DevirtualizationManager(_compilationGroup),
                       jitConfig,
                       _inputFilePath,
                       new ModuleDesc[] { _inputModule },
                       _resilient));
        }