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(); }
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(); }
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); }
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)); }