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 void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph) { 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); ExceptionInfoLookupTableNode exceptionInfoLookupTableNode = new ExceptionInfoLookupTableNode(this); Header.Add(Internal.Runtime.ReadyToRunSectionType.ExceptionInfo, exceptionInfoLookupTableNode, exceptionInfoLookupTableNode); graph.AddRoot(exceptionInfoLookupTableNode, "ExceptionInfoLookupTable is always generated"); MethodEntryPointTable = new MethodEntryPointTableNode(Target); Header.Add(Internal.Runtime.ReadyToRunSectionType.MethodDefEntryPoints, MethodEntryPointTable, MethodEntryPointTable); ManifestMetadataTable = new ManifestMetadataTableNode(InputModuleContext.GlobalContext, this); Header.Add(Internal.Runtime.ReadyToRunSectionType.ManifestMetadata, ManifestMetadataTable, ManifestMetadataTable); Resolver.SetModuleIndexLookup(ManifestMetadataTable.ModuleToIndex); InstanceEntryPointTable = new InstanceEntryPointTableNode(Target); Header.Add(Internal.Runtime.ReadyToRunSectionType.InstanceMethodEntryPoints, InstanceEntryPointTable, InstanceEntryPointTable); TypesTable = new TypesTableNode(Target); Header.Add(Internal.Runtime.ReadyToRunSectionType.AvailableTypes, TypesTable, TypesTable); 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); InliningInfoTable = new InliningInfoNode(Target, InputModuleContext.GlobalContext); Header.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 (this.AttributePresenceFilter != null) { Header.Add(Internal.Runtime.ReadyToRunSectionType.AttributePresence, AttributePresenceFilter, AttributePresenceFilter); } 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( ReadyToRunHelper.PersonalityRoutine, this, personalityRoutineImport, useVirtualCall: 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( ReadyToRunHelper.PersonalityRoutineFilterFunclet, this, filterFuncletPersonalityRoutineImport, useVirtualCall: false); graph.AddRoot(FilterFuncletPersonalityRoutine, "Filter funclet personality routine is faster to root early rather than referencing it from each unwind info"); } 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"); 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); }