protected Compilation( DependencyAnalyzerBase<NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable<ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); // TODO: hacky static field NodeFactory.NameMangler = nameMangler; var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) rootProvider.AddCompilationRoots(rootingService); _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(nodeFactory.CompilationModuleGroup.GeneratedAssembly.GetGlobalModuleType()); PInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(!nodeFactory.CompilationModuleGroup.IsSingleFileCompilation)); _methodILCache = new ILProvider(PInvokeILProvider); }
protected Compilation( DependencyAnalyzerBase<NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable<ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); // TODO: hacky static field NodeFactory.NameMangler = nameMangler; var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) rootProvider.AddCompilationRoots(rootingService); // TODO: use a better owning type for multi-file friendliness _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(TypeSystemContext.SystemModule.GetGlobalModuleType()); }
internal CppCodegenCompilation( DependencyAnalyzerBase<NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable<ICompilationRootProvider> roots, Logger logger, CppCodegenConfigProvider options) : base(dependencyGraph, nodeFactory, GetCompilationRoots(roots, nodeFactory), new NameMangler(true), logger) { Options = options; }
internal RyuJitCompilation( DependencyAnalyzerBase<NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable<ICompilationRootProvider> roots, Logger logger, JitConfigProvider configProvider) : base(dependencyGraph, nodeFactory, roots, new NameMangler(false), logger) { _jitConfigProvider = configProvider; }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); // TODO: hacky static field NodeFactory.NameMangler = nameMangler; var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(nodeFactory.CompilationModuleGroup.GeneratedAssembly.GetGlobalModuleType()); bool?forceLazyPInvokeResolution = null; // TODO: Workaround lazy PInvoke resolution not working with CppCodeGen yet // https://github.com/dotnet/corert/issues/2454 // https://github.com/dotnet/corert/issues/2149 if (this is CppCodegenCompilation) { forceLazyPInvokeResolution = false; } // TODO: Workaround missing PInvokes with multifile compilation // https://github.com/dotnet/corert/issues/2454 if (!nodeFactory.CompilationModuleGroup.IsSingleFileCompilation) { forceLazyPInvokeResolution = true; } PInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyPInvokeResolution)); _methodILCache = new ILProvider(PInvokeILProvider); }
internal WebAssemblyCodegenCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, WebAssemblyCodegenNodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, DebugInformationProvider debugInformationProvider, Logger logger, WebAssemblyCodegenConfigProvider options) : base(dependencyGraph, nodeFactory, GetCompilationRoots(roots, nodeFactory), ilProvider, debugInformationProvider, null, logger) { NodeFactory = nodeFactory; Module = LLVM.ModuleCreateWithName("netscripten"); LLVM.SetTarget(Module, "asmjs-unknown-emscripten"); Options = options; DIBuilder = LLVMPInvokes.LLVMCreateDIBuilder(Module); DebugMetadataMap = new Dictionary <string, DebugMetadata>(); }
internal ReadyToRunCodegenCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, Logger logger, DevirtualizationManager devirtualizationManager, IEnumerable <string> inputFiles, InstructionSetSupport instructionSetSupport, bool resilient, bool generateMapFile, int parallelism, ProfileDataManager profileData, ReadyToRunMethodLayoutAlgorithm methodLayoutAlgorithm, ReadyToRunFileLayoutAlgorithm fileLayoutAlgorithm) : base( dependencyGraph, nodeFactory, roots, ilProvider, devirtualizationManager, modulesBeingInstrumented: nodeFactory.CompilationModuleGroup.CompilationModuleSet, logger, instructionSetSupport) { _resilient = resilient; _parallelism = parallelism; _generateMapFile = generateMapFile; SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory); _corInfoImpls = new ConditionalWeakTable <Thread, CorInfoImpl>(); _inputFiles = inputFiles; CompilationModuleGroup = (ReadyToRunCompilationModuleGroupBase)nodeFactory.CompilationModuleGroup; // Generate baseline support specification for InstructionSetSupport. This will prevent usage of the generated // code if the runtime environment doesn't support the specified instruction set string instructionSetSupportString = ReadyToRunInstructionSetSupportSignature.ToInstructionSetSupportString(instructionSetSupport); ReadyToRunInstructionSetSupportSignature instructionSetSupportSig = new ReadyToRunInstructionSetSupportSignature(instructionSetSupportString); _dependencyGraph.AddRoot(new Import(NodeFactory.EagerImports, instructionSetSupportSig), "Baseline instruction set support"); _profileData = profileData; _fileLayoutOptimizer = new ReadyToRunFileLayoutOptimizer(methodLayoutAlgorithm, fileLayoutAlgorithm, profileData, _nodeFactory); }
public override void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph) { ReadyToRunHeader = new ReadyToRunHeaderNode(Target); graph.AddRoot(ReadyToRunHeader, "ReadyToRunHeader is always generated"); graph.AddRoot(new ModulesSectionNode(Target), "ModulesSection is always generated"); graph.AddRoot(EagerCctorTable, "EagerCctorTable is always generated"); graph.AddRoot(DispatchMapTable, "DispatchMapTable is always generated"); graph.AddRoot(FrozenSegmentRegion, "FrozenSegmentRegion is always generated"); graph.AddRoot(TypeManagerIndirection, "ModuleManagerIndirection is always generated"); graph.AddRoot(GCStaticsRegion, "GC StaticsRegion is always generated"); graph.AddRoot(GCStaticDescRegion, "GC Static Desc is always generated"); graph.AddRoot(ThreadStaticsOffsetRegion, "Thread Statics Offset Region is always generated"); graph.AddRoot(ThreadStaticGCDescRegion, "Thread Statics GC Desc Region is always generated"); // The native part of the MRT library links against CRT which defines _tls_index and _tls_used. if (!buildMRT) { graph.AddRoot(ThreadStaticsIndex, "Thread statics index is always generated"); graph.AddRoot(TLSDirectory, "TLS Directory is always generated"); } ReadyToRunHeader.Add(ReadyToRunSectionType.EagerCctor, EagerCctorTable, EagerCctorTable.StartSymbol, EagerCctorTable.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.InterfaceDispatchTable, DispatchMapTable, DispatchMapTable.StartSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.FrozenObjectRegion, FrozenSegmentRegion, FrozenSegmentRegion.StartSymbol, FrozenSegmentRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.TypeManagerIndirection, TypeManagerIndirection, TypeManagerIndirection); ReadyToRunHeader.Add(ReadyToRunSectionType.GCStaticRegion, GCStaticsRegion, GCStaticsRegion.StartSymbol, GCStaticsRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.GCStaticDesc, GCStaticDescRegion, GCStaticDescRegion.StartSymbol, GCStaticDescRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.ThreadStaticOffsetRegion, ThreadStaticsOffsetRegion, ThreadStaticsOffsetRegion.StartSymbol, ThreadStaticsOffsetRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.ThreadStaticGCDescRegion, ThreadStaticGCDescRegion, ThreadStaticGCDescRegion.StartSymbol, ThreadStaticGCDescRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.LoopHijackFlag, LoopHijackFlag, LoopHijackFlag); if (!buildMRT) { ReadyToRunHeader.Add(ReadyToRunSectionType.ThreadStaticIndex, ThreadStaticsIndex, ThreadStaticsIndex); } var commonFixupsTableNode = new ExternalReferencesTableNode("CommonFixupsTable", this); InteropStubManager.AddToReadyToRunHeader(ReadyToRunHeader, this, commonFixupsTableNode); MetadataManager.AddToReadyToRunHeader(ReadyToRunHeader, this, commonFixupsTableNode); MetadataManager.AttachToDependencyGraph(graph); }
public override ICompilation ToCompilation() { ArrayBuilder <CorJitFlag> jitFlagBuilder = new ArrayBuilder <CorJitFlag>(); switch (_optimizationMode) { case OptimizationMode.None: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_CODE); break; case OptimizationMode.PreferSize: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SIZE_OPT); break; case OptimizationMode.PreferSpeed: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SPEED_OPT); break; default: // Not setting a flag results in BLENDED_CODE. break; } // Do not bother with debug information if the debug info provider never gives anything. if (!(_debugInformationProvider is NullDebugInformationProvider)) { jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_INFO); } if (_context.Target.MaximumSimdVectorLength != SimdVectorLength.None) { // TODO: AVX Debug.Assert(_context.Target.MaximumSimdVectorLength == SimdVectorLength.Vector128Bit); jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_FEATURE_SIMD); } var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_context.GeneratedAssembly)); var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider); var jitConfig = new JitConfigProvider(jitFlagBuilder.ToArray(), _ryujitOptions); DependencyAnalyzerBase <NodeFactory> graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(new CompilerComparer())); return(new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _pinvokePolicy, _logger, _devirtualizationManager, jitConfig)); }
internal ReadyToRunCodegenCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, ReadyToRunCodegenNodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, DebugInformationProvider debugInformationProvider, Logger logger, DevirtualizationManager devirtualizationManager, JitConfigProvider configProvider, string inputFilePath) : base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, devirtualizationManager, logger) { NodeFactory = nodeFactory; SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory); _corInfo = new Dictionary <EcmaModule, CorInfoImpl>(); _jitConfigProvider = configProvider; _inputFilePath = inputFilePath; }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, DebugInformationProvider debugInformationProvider, DevirtualizationManager devirtualizationManager, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _logger = logger; _debugInformationProvider = debugInformationProvider; _devirtualizationManager = devirtualizationManager; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } MetadataType globalModuleGeneratedType = nodeFactory.CompilationModuleGroup.GeneratedAssembly.GetGlobalModuleType(); _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(globalModuleGeneratedType); _assemblyGetExecutingAssemblyMethodThunks = new AssemblyGetExecutingAssemblyMethodThunkCache(globalModuleGeneratedType); _methodBaseGetCurrentMethodThunks = new MethodBaseGetCurrentMethodThunkCache(); bool?forceLazyPInvokeResolution = null; // TODO: Workaround lazy PInvoke resolution not working with CppCodeGen yet // https://github.com/dotnet/corert/issues/2454 // https://github.com/dotnet/corert/issues/2149 if (nodeFactory.IsCppCodegenTemporaryWorkaround) { forceLazyPInvokeResolution = false; } PInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyPInvokeResolution), nodeFactory.InteropStubManager.InteropStateManager); _methodILCache = new ILProvider(PInvokeILProvider); }
internal ReadyToRunCodegenCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, ReadyToRunCodegenNodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, Logger logger, DevirtualizationManager devirtualizationManager, JitConfigProvider configProvider, string inputFilePath, IEnumerable <ModuleDesc> modulesBeingInstrumented) : base(dependencyGraph, nodeFactory, roots, ilProvider, devirtualizationManager, modulesBeingInstrumented, logger) { NodeFactory = nodeFactory; SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory); _jitConfigProvider = configProvider; _inputFilePath = inputFilePath; _corInfo = new CorInfoImpl(this, _jitConfigProvider); }
public override ICompilation ToCompilation() { ArrayBuilder <CorJitFlag> jitFlagBuilder = new ArrayBuilder <CorJitFlag>(); switch (_optimizationMode) { case OptimizationMode.None: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_CODE); break; case OptimizationMode.PreferSize: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SIZE_OPT); break; case OptimizationMode.PreferSpeed: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SPEED_OPT); break; default: // Not setting a flag results in BLENDED_CODE. break; } if (_generateDebugInfo) { jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_INFO); } if (_context.Target.MaximumSimdVectorLength != SimdVectorLength.None) { // TODO: AVX Debug.Assert(_context.Target.MaximumSimdVectorLength == SimdVectorLength.Vector128Bit); jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_FEATURE_SIMD); } var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_compilationGroup.GeneratedAssembly)); var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider); var jitConfig = new JitConfigProvider(jitFlagBuilder.ToArray(), _ryujitOptions); DependencyAnalyzerBase <NodeFactory> graph = CreateDependencyGraph(factory); return(new RyuJitCompilation(graph, factory, _compilationRoots, _logger, jitConfig)); }
internal ReadyToRunCodegenCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, ReadyToRunCodegenNodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, DebugInformationProvider debugInformationProvider, PInvokeILEmitterConfiguration pInvokePolicy, Logger logger, DevirtualizationManager devirtualizationManager, JitConfigProvider configProvider, string inputFilePath) : base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, devirtualizationManager, pInvokePolicy, logger) { NodeFactory = nodeFactory; SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory); _jitConfigProvider = configProvider; _inputFilePath = inputFilePath; _corInfo = new CorInfoImpl(this, _jitConfigProvider); }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, ILProvider ilProvider, DebugInformationProvider debugInformationProvider, DevirtualizationManager devirtualizationManager, IInliningPolicy inliningPolicy, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _logger = logger; _debugInformationProvider = debugInformationProvider; _devirtualizationManager = devirtualizationManager; _inliningPolicy = inliningPolicy; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); var rootingService = new RootingServiceProvider(nodeFactory, _dependencyGraph.AddRoot); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } MetadataType globalModuleGeneratedType = nodeFactory.TypeSystemContext.GeneratedAssembly.GetGlobalModuleType(); _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(globalModuleGeneratedType); _assemblyGetExecutingAssemblyMethodThunks = new AssemblyGetExecutingAssemblyMethodThunkCache(globalModuleGeneratedType); _methodBaseGetCurrentMethodThunks = new MethodBaseGetCurrentMethodThunkCache(); PInvokeILProvider = _nodeFactory.InteropStubManager.CreatePInvokeILProvider(); if (PInvokeILProvider != null) { ilProvider = new CombinedILProvider(ilProvider, PInvokeILProvider); } _methodILCache = new ILCache(ilProvider); }
private void BuildGraphUsingAllTypesOfRules(TestGraph testGraph, DependencyAnalyzerBase <TestGraph> analyzer) { testGraph.SetDynamicDependencyRule((string nodeA, string nodeB) => { if (nodeA.EndsWith("*") && nodeB.StartsWith("*")) { return(new Tuple <string, string>(nodeA + nodeB, "DynamicRule")); } return(null); }); testGraph.AddConditionalRule("A**C", "B**D", "D", "A**C depends on D if B**D"); testGraph.AddStaticRule("D", "E", "D depends on E"); // Rules to ensure that there are some nodes that have multiple reasons to exist testGraph.AddStaticRule("A*", "E", "A* depends on E"); testGraph.AddStaticRule("*C", "E", "*C depends on E"); testGraph.AddRoot("A*", "A* is root"); testGraph.AddRoot("B*", "B* is root"); testGraph.AddRoot("*C", "*C is root"); testGraph.AddRoot("*D", "*D is root"); testGraph.AddRoot("A*B", "A*B is root"); List <string> results = testGraph.AnalysisResults; Assert.Contains("A*", results); Assert.Contains("B*", results); Assert.Contains("*C", results); Assert.Contains("*D", results); Assert.Contains("A*B", results); Assert.Contains("A**C", results); Assert.Contains("A**D", results); Assert.Contains("B**C", results); Assert.Contains("B**D", results); Assert.Contains("D", results); Assert.Contains("E", results); Assert.True(results.Count == 11); }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } }
protected Compilation( DependencyAnalyzerBase<NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable<ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); // TODO: hacky static field NodeFactory.NameMangler = nameMangler; var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) rootProvider.AddCompilationRoots(rootingService); }
public virtual void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph) { ReadyToRunHeader = new ReadyToRunHeaderNode(Target); graph.AddRoot(ReadyToRunHeader, "ReadyToRunHeader is always generated"); graph.AddRoot(new ModulesSectionNode(Target), "ModulesSection is always generated"); graph.AddRoot(GCStaticsRegion, "GC StaticsRegion is always generated"); graph.AddRoot(ThreadStaticsRegion, "ThreadStaticsRegion is always generated"); graph.AddRoot(EagerCctorTable, "EagerCctorTable is always generated"); graph.AddRoot(TypeManagerIndirection, "TypeManagerIndirection is always generated"); graph.AddRoot(DispatchMapTable, "DispatchMapTable is always generated"); graph.AddRoot(FrozenSegmentRegion, "FrozenSegmentRegion is always generated"); graph.AddRoot(InterfaceDispatchCellSection, "Interface dispatch cell section is always generated"); if (Target.IsWindows) { // We need 2 delimiter symbols to bound the unboxing stubs region on Windows platforms (these symbols are // accessed using extern "C" variables in the bootstrapper) // On non-Windows platforms, the linker emits special symbols with special names at the begining/end of a section // so we do not need to emit them ourselves. graph.AddRoot(new WindowsUnboxingStubsRegionNode(false), "UnboxingStubsRegion delimiter for Windows platform"); graph.AddRoot(new WindowsUnboxingStubsRegionNode(true), "UnboxingStubsRegion delimiter for Windows platform"); } ReadyToRunHeader.Add(ReadyToRunSectionType.GCStaticRegion, GCStaticsRegion, GCStaticsRegion.StartSymbol, GCStaticsRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.ThreadStaticRegion, ThreadStaticsRegion, ThreadStaticsRegion.StartSymbol, ThreadStaticsRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.EagerCctor, EagerCctorTable, EagerCctorTable.StartSymbol, EagerCctorTable.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.TypeManagerIndirection, TypeManagerIndirection, TypeManagerIndirection); ReadyToRunHeader.Add(ReadyToRunSectionType.InterfaceDispatchTable, DispatchMapTable, DispatchMapTable.StartSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.FrozenObjectRegion, FrozenSegmentRegion, FrozenSegmentRegion.StartSymbol, FrozenSegmentRegion.EndSymbol); var commonFixupsTableNode = new ExternalReferencesTableNode("CommonFixupsTable", this); InteropStubManager.AddToReadyToRunHeader(ReadyToRunHeader, this, commonFixupsTableNode); MetadataManager.AddToReadyToRunHeader(ReadyToRunHeader, this, commonFixupsTableNode); MetadataManager.AttachToDependencyGraph(graph); ReadyToRunHeader.Add(MetadataManager.BlobIdToReadyToRunSection(ReflectionMapBlob.CommonFixupsTable), commonFixupsTableNode, commonFixupsTableNode, commonFixupsTableNode.EndSymbol); }
internal ReadyToRunCodegenCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, Logger logger, DevirtualizationManager devirtualizationManager, string inputFilePath, IEnumerable <ModuleDesc> modulesBeingInstrumented, bool resilient, bool generateMapFile, int parallelism) : base(dependencyGraph, nodeFactory, roots, ilProvider, devirtualizationManager, modulesBeingInstrumented, logger) { _resilient = resilient; _parallelism = parallelism; _generateMapFile = generateMapFile; SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory); _inputFilePath = inputFilePath; _corInfoImpls = new ConditionalWeakTable <Thread, CorInfoImpl>(); }
public override ICompilation ToCompilation() { ArrayBuilder <CorJitFlag> jitFlagBuilder = new ArrayBuilder <CorJitFlag>(); switch (_optimizationMode) { case OptimizationMode.None: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_CODE); break; case OptimizationMode.PreferSize: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SIZE_OPT); break; case OptimizationMode.PreferSpeed: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SPEED_OPT); break; default: // Not setting a flag results in BLENDED_CODE. break; } if (_generateDebugInfo) { jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_INFO); } MetadataManager metadataManager = CreateMetadataManager(); var factory = new RyuJitNodeFactory(_context, _compilationGroup, metadataManager, _nameMangler); var jitConfig = new JitConfigProvider(jitFlagBuilder.ToArray(), _ryujitOptions); DependencyAnalyzerBase <NodeFactory> graph = CreateDependencyGraph(factory); return(new RyuJitCompilation(graph, factory, _compilationRoots, _logger, jitConfig)); }
internal RyuJitCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, DebugInformationProvider debugInformationProvider, Logger logger, DevirtualizationManager devirtualizationManager, IInliningPolicy inliningPolicy, InstructionSetSupport instructionSetSupport, ProfileDataManager profileDataManager, MethodImportationErrorProvider errorProvider, RyuJitCompilationOptions options, int parallelism) : base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, devirtualizationManager, inliningPolicy, logger) { _compilationOptions = options; _hardwareIntrinsicFlags = new ExternSymbolMappedField(nodeFactory.TypeSystemContext.GetWellKnownType(WellKnownType.Int32), "g_cpuFeatures"); InstructionSetSupport = instructionSetSupport; _instructionSetMap = new Dictionary <string, InstructionSet>(); foreach (var instructionSetInfo in InstructionSetFlags.ArchitectureToValidInstructionSets(TypeSystemContext.Target.Architecture)) { if (!instructionSetInfo.Specifiable) { continue; } _instructionSetMap.Add(instructionSetInfo.ManagedName, instructionSetInfo.InstructionSet); } _profileDataManager = profileDataManager; _methodImportationErrorProvider = errorProvider; _parallelism = parallelism; }
public virtual void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph) { ReadyToRunHeader = new ReadyToRunHeaderNode(Target); graph.AddRoot(ReadyToRunHeader, "ReadyToRunHeader is always generated"); graph.AddRoot(new ModulesSectionNode(Target), "ModulesSection is always generated"); graph.AddRoot(GCStaticsRegion, "GC StaticsRegion is always generated"); graph.AddRoot(ThreadStaticsRegion, "ThreadStaticsRegion is always generated"); graph.AddRoot(EagerCctorTable, "EagerCctorTable is always generated"); graph.AddRoot(TypeManagerIndirection, "TypeManagerIndirection is always generated"); graph.AddRoot(DispatchMapTable, "DispatchMapTable is always generated"); graph.AddRoot(FrozenSegmentRegion, "FrozenSegmentRegion is always generated"); ReadyToRunHeader.Add(ReadyToRunSectionType.GCStaticRegion, GCStaticsRegion, GCStaticsRegion.StartSymbol, GCStaticsRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.ThreadStaticRegion, ThreadStaticsRegion, ThreadStaticsRegion.StartSymbol, ThreadStaticsRegion.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.EagerCctor, EagerCctorTable, EagerCctorTable.StartSymbol, EagerCctorTable.EndSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.TypeManagerIndirection, TypeManagerIndirection, TypeManagerIndirection); ReadyToRunHeader.Add(ReadyToRunSectionType.InterfaceDispatchTable, DispatchMapTable, DispatchMapTable.StartSymbol); ReadyToRunHeader.Add(ReadyToRunSectionType.FrozenObjectRegion, FrozenSegmentRegion, FrozenSegmentRegion.StartSymbol, FrozenSegmentRegion.EndSymbol); MetadataManager.AddToReadyToRunHeader(ReadyToRunHeader); MetadataManager.AttachToDependencyGraph(graph); }
public void CompileSingleFile() { NodeFactory.NameMangler = NameMangler; _nodeFactory = new NodeFactory(_typeSystemContext, _typeInitManager, _compilationModuleGroup, _options.IsCppCodeGen); // Choose which dependency graph implementation to use based on the amount of logging requested. if (_options.DgmlLog == null) { // No log uses the NoLogStrategy _dependencyGraph = new DependencyAnalyzer<NoLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { if (_options.FullLog) { // Full log uses the full log strategy _dependencyGraph = new DependencyAnalyzer<FullGraphLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { // Otherwise, use the first mark strategy _dependencyGraph = new DependencyAnalyzer<FirstMarkLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } } _nodeFactory.AttachToDependencyGraph(_dependencyGraph); _compilationModuleGroup.AddWellKnownTypes(); _compilationModuleGroup.AddCompilationRoots(); if (!_options.IsCppCodeGen && !_options.MultiFile) { // TODO: build a general purpose way to hook up pieces that would be part of the core library // if factoring of the core library respected how things are, versus how they would be in // a magic world (future customers of this mechanism will be interop and serialization). var refExec = _typeSystemContext.GetModuleForSimpleName("System.Private.Reflection.Execution"); var exec = refExec.GetKnownType("Internal.Reflection.Execution", "ReflectionExecution"); AddCompilationRoot(exec.GetStaticConstructor(), "Reflection execution"); } if (_options.IsCppCodeGen) { _cppWriter = new CppCodeGen.CppWriter(this); _dependencyGraph.ComputeDependencyRoutine += CppCodeGenComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; _cppWriter.OutputCode(nodes, _compilationModuleGroup.StartupCodeMain); } else { _corInfo = new CorInfoImpl(this); _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; ObjectWriter.EmitObject(_options.OutputFilePath, nodes, _nodeFactory); } if (_options.DgmlLog != null) { using (FileStream dgmlOutput = new FileStream(_options.DgmlLog, FileMode.Create)) { DgmlWriter.WriteDependencyGraphToStream(dgmlOutput, _dependencyGraph); dgmlOutput.Flush(); } } }
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 CompileSingleFile(MethodDesc mainMethod) { if (_options.IsCppCodeGen) { _cppWriter = new CppCodeGen.CppWriter(this); } else { _corInfo = new CorInfoImpl(this); } _mainMethod = mainMethod; if (!_options.IsCppCodeGen) { NodeFactory.NameMangler = NameMangler; _nodeFactory = new NodeFactory(_typeSystemContext); // Choose which dependency graph implementation to use based on the amount of logging requested. if (_options.DgmlLog == null) { // No log uses the NoLogStrategy _dependencyGraph = new DependencyAnalyzer<NoLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { if (_options.FullLog) { // Full log uses the full log strategy _dependencyGraph = new DependencyAnalyzer<FullGraphLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { // Otherwise, use the first mark strategy _dependencyGraph = new DependencyAnalyzer<FirstMarkLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } } _nodeFactory.AttachToDependencyGraph(_dependencyGraph); AddWellKnownTypes(); AddCompilationRoots(); _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; ObjectWriter.EmitObject(OutputPath, nodes, _nodeFactory); if (_options.DgmlLog != null) { using (FileStream dgmlOutput = new FileStream(_options.DgmlLog, FileMode.Create)) { DgmlWriter.WriteDependencyGraphToStream(dgmlOutput, _dependencyGraph); dgmlOutput.Flush(); } } } else { AddWellKnownTypes(); AddCompilationRoots(); while (_methodsThatNeedsCompilation != null) { CompileMethods(); ExpandVirtualMethods(); } _cppWriter.OutputCode(); } }
internal CompilationResults(DependencyAnalyzerBase <NodeFactory> graph, NodeFactory factory) { _graph = graph; _factory = factory; }
public override ICompilation ToCompilation() { // TODO: only copy COR headers for single-assembly build and for composite build with embedded MSIL IEnumerable <EcmaModule> inputModules = _compilationGroup.CompilationModuleSet; EcmaModule singleModule = _compilationGroup.IsCompositeBuildMode ? null : inputModules.First(); CopiedCorHeaderNode corHeaderNode = new CopiedCorHeaderNode(singleModule); // TODO: proper support for multiple input files DebugDirectoryNode debugDirectoryNode = new DebugDirectoryNode(singleModule, _outputFile); // Produce a ResourceData where the IBC PROFILE_DATA entry has been filtered out // TODO: proper support for multiple input files ResourceData win32Resources = new ResourceData(inputModules.First(), (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); }); ReadyToRunFlags flags = ReadyToRunFlags.READYTORUN_FLAG_NonSharedPInvokeStubs; if (inputModules.All(module => module.IsPlatformNeutral)) { flags |= ReadyToRunFlags.READYTORUN_FLAG_PlatformNeutralSource; } flags |= _compilationGroup.GetReadyToRunFlags(); NodeFactory factory = new NodeFactory( _context, _compilationGroup, _nameMangler, corHeaderNode, debugDirectoryNode, win32Resources, flags); 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); } JitConfigProvider.Initialize(_context.Target, corJitFlags, _ryujitOptions, _jitPath); return(new ReadyToRunCodegenCompilation( graph, factory, _compilationRoots, _ilProvider, _logger, new DependencyAnalysis.ReadyToRun.DevirtualizationManager(_compilationGroup), _inputFiles, _compositeRootPath, _instructionSetSupport, _resilient, _generateMapFile, _parallelism, _profileData, _r2rMethodLayoutAlgorithm, _r2rFileLayoutAlgorithm, _customPESectionAlignment, _verifyTypeAndFieldLayout)); }
public void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph) { graph.NewMarkedNode += Graph_NewMarkedNode; }
public override void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph) { Header = new HeaderNode(Target); 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"); 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); 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(Target); 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( ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_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( ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_PersonalityRoutine)); PersonalityRoutine = new ImportThunk( ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_PersonalityRoutine, this, personalityRoutineImport); 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( ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_PersonalityRoutineFilterFunclet)); FilterFuncletPersonalityRoutine = new ImportThunk( ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_PersonalityRoutineFilterFunclet, this, filterFuncletPersonalityRoutineImport); 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 imports are always generated"); graph.AddRoot(StringImports, "String imports are always generated"); graph.AddRoot(Header, "ReadyToRunHeader is always generated"); MetadataManager.AttachToDependencyGraph(graph); }
public abstract void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph);
public override void AttachToDependencyGraph(DependencyAnalyzerBase <NodeFactory> graph) { Header = new HeaderNode(Target); 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); 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); // 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( ILCompiler.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( ILCompiler.ReadyToRunHelper.PersonalityRoutine)); PersonalityRoutine = new ImportThunk( ILCompiler.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( ILCompiler.ReadyToRunHelper.PersonalityRoutineFilterFunclet)); FilterFuncletPersonalityRoutine = new ImportThunk( ILCompiler.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"); if (Win32ResourcesNode != null) { graph.AddRoot(Win32ResourcesNode, "Win32 Resources are placed if not empty"); } MetadataManager.AttachToDependencyGraph(graph); }
public RootingServiceProvider(DependencyAnalyzerBase<NodeFactory> graph, NodeFactory factory) { _graph = graph; _factory = factory; }
public RootingServiceProvider(DependencyAnalyzerBase <NodeFactory> graph, NodeFactory factory) { _graph = graph; _factory = factory; }
private void BuildGraphUsingAllTypesOfRules(TestGraph testGraph, DependencyAnalyzerBase<TestGraph> analyzer) { testGraph.SetDynamicDependencyRule((string nodeA, string nodeB) => { if (nodeA.EndsWith("*") && nodeB.StartsWith("*")) { return new Tuple<string, string>(nodeA + nodeB, "DynamicRule"); } return null; }); testGraph.AddConditionalRule("A**C", "B**D", "D", "A**C depends on D if B**D"); testGraph.AddStaticRule("D", "E", "D depends on E"); // Rules to ensure that there are some nodes that have multiple reasons to exist testGraph.AddStaticRule("A*", "E", "A* depends on E"); testGraph.AddStaticRule("*C", "E", "*C depends on E"); testGraph.AddRoot("A*", "A* is root"); testGraph.AddRoot("B*", "B* is root"); testGraph.AddRoot("*C", "*C is root"); testGraph.AddRoot("*D", "*D is root"); testGraph.AddRoot("A*B", "A*B is root"); List<string> results = testGraph.AnalysisResults; Assert.Contains("A*", results); Assert.Contains("B*", results); Assert.Contains("*C", results); Assert.Contains("*D", results); Assert.Contains("A*B", results); Assert.Contains("A**C", results); Assert.Contains("A**D", results); Assert.Contains("B**C", results); Assert.Contains("B**D", results); Assert.Contains("D", results); Assert.Contains("E", results); Assert.True(results.Count == 11); }
internal ReadyToRunCodegenCompilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> roots, ILProvider ilProvider, Logger logger, DevirtualizationManager devirtualizationManager, IEnumerable <string> inputFiles, string compositeRootPath, InstructionSetSupport instructionSetSupport, bool resilient, bool generateMapFile, bool generateMapCsvFile, bool generatePdbFile, Func <MethodDesc, string> printReproInstructions, string pdbPath, bool generatePerfMapFile, string perfMapPath, Guid?perfMapMvid, bool generateProfileFile, int parallelism, ProfileDataManager profileData, ReadyToRunMethodLayoutAlgorithm methodLayoutAlgorithm, ReadyToRunFileLayoutAlgorithm fileLayoutAlgorithm, int customPESectionAlignment, bool verifyTypeAndFieldLayout) : base( dependencyGraph, nodeFactory, roots, ilProvider, devirtualizationManager, modulesBeingInstrumented: nodeFactory.CompilationModuleGroup.CompilationModuleSet, logger, instructionSetSupport) { _resilient = resilient; _parallelism = parallelism; _generateMapFile = generateMapFile; _generateMapCsvFile = generateMapCsvFile; _generatePdbFile = generatePdbFile; _pdbPath = pdbPath; _generatePerfMapFile = generatePerfMapFile; _perfMapPath = perfMapPath; _perfMapMvid = perfMapMvid; _generateProfileFile = generateProfileFile; _customPESectionAlignment = customPESectionAlignment; SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory, verifyTypeAndFieldLayout); if (nodeFactory.InstrumentationDataTable != null) { nodeFactory.InstrumentationDataTable.Initialize(SymbolNodeFactory); } _corInfoImpls = new ConditionalWeakTable <Thread, CorInfoImpl>(); _inputFiles = inputFiles; _compositeRootPath = compositeRootPath; _printReproInstructions = printReproInstructions; CompilationModuleGroup = (ReadyToRunCompilationModuleGroupBase)nodeFactory.CompilationModuleGroup; // Generate baseline support specification for InstructionSetSupport. This will prevent usage of the generated // code if the runtime environment doesn't support the specified instruction set string instructionSetSupportString = ReadyToRunInstructionSetSupportSignature.ToInstructionSetSupportString(instructionSetSupport); ReadyToRunInstructionSetSupportSignature instructionSetSupportSig = new ReadyToRunInstructionSetSupportSignature(instructionSetSupportString); _dependencyGraph.AddRoot(new Import(NodeFactory.EagerImports, instructionSetSupportSig), "Baseline instruction set support"); _profileData = profileData; _fileLayoutOptimizer = new ReadyToRunFileLayoutOptimizer(methodLayoutAlgorithm, fileLayoutAlgorithm, profileData, _nodeFactory); }
public void Compile() { NodeFactory.NameMangler = NameMangler; string systemModuleName = ((IAssemblyDesc)_typeSystemContext.SystemModule).GetName().Name; // TODO: just something to get Runtime.Base compiled if (systemModuleName != "System.Private.CoreLib") { NodeFactory.CompilationUnitPrefix = systemModuleName.Replace(".", "_"); } else { NodeFactory.CompilationUnitPrefix = NameMangler.SanitizeName(Path.GetFileNameWithoutExtension(Options.OutputFilePath)); } if (_options.IsCppCodeGen) { _nodeFactory = new CppCodegenNodeFactory(_typeSystemContext, _compilationModuleGroup); } else { _nodeFactory = new RyuJitNodeFactory(_typeSystemContext, _compilationModuleGroup); } // Choose which dependency graph implementation to use based on the amount of logging requested. if (_options.DgmlLog == null) { // No log uses the NoLogStrategy _dependencyGraph = new DependencyAnalyzer <NoLogStrategy <NodeFactory>, NodeFactory>(_nodeFactory, null); } else { if (_options.FullLog) { // Full log uses the full log strategy _dependencyGraph = new DependencyAnalyzer <FullGraphLogStrategy <NodeFactory>, NodeFactory>(_nodeFactory, null); } else { // Otherwise, use the first mark strategy _dependencyGraph = new DependencyAnalyzer <FirstMarkLogStrategy <NodeFactory>, NodeFactory>(_nodeFactory, null); } } _nodeFactory.AttachToDependencyGraph(_dependencyGraph); if (_options.IsCppCodeGen) { _cppWriter = new CppCodeGen.CppWriter(this); _dependencyGraph.ComputeDependencyRoutine += CppCodeGenComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; _cppWriter.OutputCode(nodes, _compilationModuleGroup.StartupCodeMain, _nodeFactory); } else { _corInfo = new CorInfoImpl(this); _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; ObjectWriter.EmitObject(_options.OutputFilePath, nodes, _nodeFactory); } if (_options.DgmlLog != null) { using (FileStream dgmlOutput = new FileStream(_options.DgmlLog, FileMode.Create)) { DgmlWriter.WriteDependencyGraphToStream(dgmlOutput, _dependencyGraph); dgmlOutput.Flush(); } } }
internal ILScanResults(DependencyAnalyzerBase <NodeFactory> graph, NodeFactory factory) : base(graph, factory) { }
public void CompileSingleFile() { NodeFactory.NameMangler = NameMangler; _nodeFactory = new NodeFactory(_typeSystemContext, _typeInitManager, _compilationModuleGroup, _options.IsCppCodeGen); // Choose which dependency graph implementation to use based on the amount of logging requested. if (_options.DgmlLog == null) { // No log uses the NoLogStrategy _dependencyGraph = new DependencyAnalyzer<NoLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { if (_options.FullLog) { // Full log uses the full log strategy _dependencyGraph = new DependencyAnalyzer<FullGraphLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { // Otherwise, use the first mark strategy _dependencyGraph = new DependencyAnalyzer<FirstMarkLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } } _nodeFactory.AttachToDependencyGraph(_dependencyGraph); _compilationModuleGroup.AddWellKnownTypes(); _compilationModuleGroup.AddCompilationRoots(); if (_options.IsCppCodeGen) { _cppWriter = new CppCodeGen.CppWriter(this); _dependencyGraph.ComputeDependencyRoutine += CppCodeGenComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; _cppWriter.OutputCode(nodes, _compilationModuleGroup.StartupCodeMain); } else { _corInfo = new CorInfoImpl(this); _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; ObjectWriter.EmitObject(_options.OutputFilePath, nodes, _nodeFactory); } if (_options.DgmlLog != null) { using (FileStream dgmlOutput = new FileStream(_options.DgmlLog, FileMode.Create)) { DgmlWriter.WriteDependencyGraphToStream(dgmlOutput, _dependencyGraph); dgmlOutput.Flush(); } } }
/// <summary> /// Initialize the WindowsDebugData emission pipeline. /// Cannot be called twice /// </summary> /// <param name="nonSectionBasedDebugInfoWriter">debug$T section generation interface. If null, use managed implementation that generates a object file section.</param> /// <param name="mergedAssemblyRecords">record of how assemblies are merged. If null, do not genearate extended debug information</param> /// <param name="graph">Graph to attach WindowsDebugData to</param> public void Init(ITypesDebugInfoWriter nonSectionBasedDebugInfoWriter, MergedAssemblyRecords mergedAssemblyRecords, DependencyAnalyzerBase <NodeFactory> graph) { Debug.Assert(_userDefinedTypeDescriptor == null); // Cannot be called twice Debug.Assert(graph != null); _debugNeedTypeIndicesStore = new WindowsDebugNeedTypeIndicesStoreNode(); if (mergedAssemblyRecords != null) { _debugPseudoAssemblySection = new WindowsDebugPseudoAssemblySection(_nodeFactory.TypeSystemContext); _debugMergedAssembliesSection = new WindowsDebugMergedAssembliesSection(mergedAssemblyRecords); _debugILImagesSection = new WindowsDebugILImagesSection(mergedAssemblyRecords); _debugManagedNativeDictionaryInfoSection = new WindowsDebugManagedNativeDictionaryInfoSection(); } bool is64Bit = _nodeFactory.Target.PointerSize == 8 ? true : false; if (nonSectionBasedDebugInfoWriter != null) { _userDefinedTypeDescriptor = new UserDefinedTypeDescriptor(nonSectionBasedDebugInfoWriter, is64Bit, _nodeFactory.Target.Abi); } else { _debugTypeRecordsSection = new WindowsDebugTypeRecordsSection(new DebugInfoWriter(), _nodeFactory); _userDefinedTypeDescriptor = new UserDefinedTypeDescriptor(_debugTypeRecordsSection, is64Bit, _nodeFactory.Target.Abi); } if (mergedAssemblyRecords != null) { _debugTypeSignatureMapSection = new WindowsDebugTypeSignatureMapSection(_userDefinedTypeDescriptor); _debugMethodSignatureMapSection = new WindowsDebugMethodSignatureMapSection(); } graph.AddRoot(_debugNeedTypeIndicesStore, "Debug Force All EETypes to have type indices"); if (_debugManagedNativeDictionaryInfoSection != null) { graph.AddRoot(_debugManagedNativeDictionaryInfoSection, "Debug Method MDToken map"); } if (_debugMethodSignatureMapSection != null) { graph.AddRoot(_debugMethodSignatureMapSection, "Debug Method MDToken map"); } if (_debugTypeSignatureMapSection != null) { graph.AddRoot(_debugTypeSignatureMapSection, "Debug Type MDToken map"); } if (_debugILImagesSection != null) { graph.AddRoot(_debugILImagesSection, "Debug Merged ILImages"); } if (_debugMergedAssembliesSection != null) { graph.AddRoot(_debugMergedAssembliesSection, "Debug MergedAssemblyRecords"); } if (_debugPseudoAssemblySection != null) { graph.AddRoot(_debugPseudoAssemblySection, "Debug PseudoAssembly"); } if (_debugTypeRecordsSection != null) { graph.AddRoot(_debugTypeRecordsSection, "Debug Type Records"); } }
public void Compile() { NodeFactory.NameMangler = NameMangler; string systemModuleName = ((IAssemblyDesc)_typeSystemContext.SystemModule).GetName().Name; // TODO: just something to get Runtime.Base compiled if (systemModuleName != "System.Private.CoreLib") { NodeFactory.CompilationUnitPrefix = systemModuleName.Replace(".", "_"); } else { NodeFactory.CompilationUnitPrefix = NameMangler.SanitizeName(Path.GetFileNameWithoutExtension(Options.OutputFilePath)); } if (_options.IsCppCodeGen) { _nodeFactory = new CppCodegenNodeFactory(_typeSystemContext, _compilationModuleGroup); } else { _nodeFactory = new RyuJitNodeFactory(_typeSystemContext, _compilationModuleGroup); } // Choose which dependency graph implementation to use based on the amount of logging requested. if (_options.DgmlLog == null) { // No log uses the NoLogStrategy _dependencyGraph = new DependencyAnalyzer<NoLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { if (_options.FullLog) { // Full log uses the full log strategy _dependencyGraph = new DependencyAnalyzer<FullGraphLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } else { // Otherwise, use the first mark strategy _dependencyGraph = new DependencyAnalyzer<FirstMarkLogStrategy<NodeFactory>, NodeFactory>(_nodeFactory, null); } } _nodeFactory.AttachToDependencyGraph(_dependencyGraph); if (_options.IsCppCodeGen) { _cppWriter = new CppCodeGen.CppWriter(this); _dependencyGraph.ComputeDependencyRoutine += CppCodeGenComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; _cppWriter.OutputCode(nodes, _compilationModuleGroup.StartupCodeMain, _nodeFactory); } else { _corInfo = new CorInfoImpl(this); _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; ObjectWriter.EmitObject(_options.OutputFilePath, nodes, _nodeFactory); } if (_options.DgmlLog != null) { using (FileStream dgmlOutput = new FileStream(_options.DgmlLog, FileMode.Create)) { DgmlWriter.WriteDependencyGraphToStream(dgmlOutput, _dependencyGraph); dgmlOutput.Flush(); } } }