private void RewriteComponentFile(string inputFile, string outputFile, string ownerExecutableName) { EcmaModule inputModule = NodeFactory.TypeSystemContext.GetModuleFromPath(inputFile); CopiedCorHeaderNode copiedCorHeader = new CopiedCorHeaderNode(inputModule); DebugDirectoryNode debugDirectory = new DebugDirectoryNode(inputModule, outputFile); NodeFactory componentFactory = new NodeFactory( _nodeFactory.TypeSystemContext, _nodeFactory.CompilationModuleGroup, _nodeFactory.NameMangler, copiedCorHeader, debugDirectory, win32Resources: new Win32Resources.ResourceData(inputModule), Internal.ReadyToRunConstants.ReadyToRunFlags.READYTORUN_FLAG_Component | Internal.ReadyToRunConstants.ReadyToRunFlags.READYTORUN_FLAG_NonSharedPInvokeStubs); IComparer <DependencyNodeCore <NodeFactory> > comparer = new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer()); DependencyAnalyzerBase <NodeFactory> componentGraph = new DependencyAnalyzer <NoLogStrategy <NodeFactory>, NodeFactory>(componentFactory, comparer); componentGraph.AddRoot(componentFactory.Header, "Component module R2R header"); OwnerCompositeExecutableNode ownerExecutableNode = new OwnerCompositeExecutableNode(_nodeFactory.Target, ownerExecutableName); componentGraph.AddRoot(ownerExecutableNode, "Owner composite executable name"); componentGraph.AddRoot(copiedCorHeader, "Copied COR header"); componentGraph.AddRoot(debugDirectory, "Debug directory"); if (componentFactory.Win32ResourcesNode != null) { componentGraph.AddRoot(componentFactory.Win32ResourcesNode, "Win32 resources"); } componentGraph.ComputeMarkedNodes(); componentFactory.Header.Add(Internal.Runtime.ReadyToRunSectionType.OwnerCompositeExecutable, ownerExecutableNode, ownerExecutableNode); ReadyToRunObjectWriter.EmitObject(outputFile, componentModule: inputModule, componentGraph.MarkedNodeList, componentFactory, generateMapFile: false, customPESectionAlignment: null); }
private void RewriteComponentFile(string inputFile, string outputFile, string ownerExecutableName) { EcmaModule inputModule = NodeFactory.TypeSystemContext.GetModuleFromPath(inputFile); Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); ReadyToRunFlags flags = ReadyToRunFlags.READYTORUN_FLAG_Component | ReadyToRunFlags.READYTORUN_FLAG_NonSharedPInvokeStubs; if (inputModule.IsPlatformNeutral) { flags |= ReadyToRunFlags.READYTORUN_FLAG_PlatformNeutralSource; } CopiedCorHeaderNode copiedCorHeader = new CopiedCorHeaderNode(inputModule); DebugDirectoryNode debugDirectory = new DebugDirectoryNode(inputModule, outputFile); NodeFactory componentFactory = new NodeFactory( _nodeFactory.TypeSystemContext, _nodeFactory.CompilationModuleGroup, null, _nodeFactory.NameMangler, copiedCorHeader, debugDirectory, win32Resources: new Win32Resources.ResourceData(inputModule), flags); IComparer <DependencyNodeCore <NodeFactory> > comparer = new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer()); DependencyAnalyzerBase <NodeFactory> componentGraph = new DependencyAnalyzer <NoLogStrategy <NodeFactory>, NodeFactory>(componentFactory, comparer); componentGraph.AddRoot(componentFactory.Header, "Component module R2R header"); OwnerCompositeExecutableNode ownerExecutableNode = new OwnerCompositeExecutableNode(_nodeFactory.Target, ownerExecutableName); componentGraph.AddRoot(ownerExecutableNode, "Owner composite executable name"); componentGraph.AddRoot(copiedCorHeader, "Copied COR header"); componentGraph.AddRoot(debugDirectory, "Debug directory"); if (componentFactory.Win32ResourcesNode != null) { componentGraph.AddRoot(componentFactory.Win32ResourcesNode, "Win32 resources"); } componentGraph.ComputeMarkedNodes(); componentFactory.Header.Add(Internal.Runtime.ReadyToRunSectionType.OwnerCompositeExecutable, ownerExecutableNode, ownerExecutableNode); ReadyToRunObjectWriter.EmitObject( outputFile, componentModule: inputModule, inputFiles: new string[] { inputFile }, componentGraph.MarkedNodeList, componentFactory, generateMapFile: false, generateMapCsvFile: false, generatePdbFile: false, pdbPath: null, generatePerfMapFile: false, perfMapPath: null, perfMapFormatVersion: _perfMapFormatVersion, generateProfileFile: false, _profileData.CallChainProfile, customPESectionAlignment: 0); }
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 IEnumerable <IMethodNode> GetCompiledMethods(EcmaModule moduleToEnumerate, CompiledMethodCategory methodCategory) { lock (_methodsGenerated) { if (!_sortedMethods) { CompilerComparer comparer = CompilerComparer.Instance; SortableDependencyNode.ObjectNodeComparer objectNodeComparer = new SortableDependencyNode.ObjectNodeComparer(comparer); Comparison <IMethodNode> sortHelper = (x, y) => { int nodeComparerResult = objectNodeComparer.Compare((SortableDependencyNode)x, (SortableDependencyNode)y); #if DEBUG int methodOnlyResult = comparer.Compare(x.Method, y.Method); // Assert the two sorting techniques produce the same result unless there is a CustomSort applied Debug.Assert((nodeComparerResult == methodOnlyResult) || ((x is SortableDependencyNode sortableX && sortableX.CustomSort != Int32.MaxValue) || (y is SortableDependencyNode sortableY && sortableY.CustomSort != Int32.MaxValue))); #endif return(nodeComparerResult); }; Comparison <IMethodNode> sortHelperNoCustomSort = (x, y) => comparer.Compare(x, y); List <PerModuleMethodsGenerated> perModuleDatas = new List <PerModuleMethodsGenerated>(_methodsGenerated.Values); perModuleDatas.Sort((x, y) => x.Module.CompareTo(y.Module)); foreach (var perModuleData in perModuleDatas) { perModuleData.MethodsGenerated.MergeSort(sortHelperNoCustomSort); perModuleData.GenericMethodsGenerated.MergeSort(sortHelperNoCustomSort); _completeSortedMethods.AddRange(perModuleData.MethodsGenerated); _completeSortedMethods.AddRange(perModuleData.GenericMethodsGenerated); _completeSortedGenericMethods.AddRange(perModuleData.GenericMethodsGenerated); } _completeSortedMethods.MergeSort(sortHelper); _completeSortedGenericMethods.MergeSort(sortHelper); _sortedMethods = true; } } if (moduleToEnumerate == null) { if (methodCategory == CompiledMethodCategory.All) { return(_completeSortedMethods); } else if (methodCategory == CompiledMethodCategory.Instantiated) { return(_completeSortedGenericMethods); } else { // This isn't expected to be needed, and thus isn't implemented throw new ArgumentException(); } } else if (_methodsGenerated.TryGetValue(moduleToEnumerate, out var perModuleData)) { if (methodCategory == CompiledMethodCategory.All) { return(GetCompiledMethodsAllMethodsInModuleHelper(moduleToEnumerate)); } if (methodCategory == CompiledMethodCategory.Instantiated) { return(perModuleData.GenericMethodsGenerated); } else { Debug.Assert(methodCategory == CompiledMethodCategory.NonInstantiated); return(perModuleData.MethodsGenerated); } } else { return(Array.Empty <IMethodNode>()); } }
private void RewriteComponentFile(string inputFile, string outputFile, string ownerExecutableName) { EcmaModule inputModule = NodeFactory.TypeSystemContext.GetModuleFromPath(inputFile); Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); ReadyToRunFlags flags = ReadyToRunFlags.READYTORUN_FLAG_Component | ReadyToRunFlags.READYTORUN_FLAG_NonSharedPInvokeStubs; if (inputModule.IsPlatformNeutral) { flags |= ReadyToRunFlags.READYTORUN_FLAG_PlatformNeutralSource; } flags |= _nodeFactory.CompilationModuleGroup.GetReadyToRunFlags() & ReadyToRunFlags.READYTORUN_FLAG_MultiModuleVersionBubble; CopiedCorHeaderNode copiedCorHeader = new CopiedCorHeaderNode(inputModule); // Re-written components shouldn't have any additional diagnostic information - only information about the forwards. // Even with all of this, we might be modifying the image in a silly manner - adding a directory when if didn't have one. DebugDirectoryNode debugDirectory = new DebugDirectoryNode(inputModule, outputFile, shouldAddNiPdb: false, shouldGeneratePerfmap: false); NodeFactory componentFactory = new NodeFactory( _nodeFactory.TypeSystemContext, _nodeFactory.CompilationModuleGroup, null, _nodeFactory.NameMangler, copiedCorHeader, debugDirectory, win32Resources: new Win32Resources.ResourceData(inputModule), flags, _nodeFactory.OptimizationFlags, _nodeFactory.ImageBase); IComparer <DependencyNodeCore <NodeFactory> > comparer = new SortableDependencyNode.ObjectNodeComparer(CompilerComparer.Instance); DependencyAnalyzerBase <NodeFactory> componentGraph = new DependencyAnalyzer <NoLogStrategy <NodeFactory>, NodeFactory>(componentFactory, comparer); componentGraph.AddRoot(componentFactory.Header, "Component module R2R header"); OwnerCompositeExecutableNode ownerExecutableNode = new OwnerCompositeExecutableNode(_nodeFactory.Target, ownerExecutableName); componentGraph.AddRoot(ownerExecutableNode, "Owner composite executable name"); componentGraph.AddRoot(copiedCorHeader, "Copied COR header"); componentGraph.AddRoot(debugDirectory, "Debug directory"); if (componentFactory.Win32ResourcesNode != null) { componentGraph.AddRoot(componentFactory.Win32ResourcesNode, "Win32 resources"); } componentGraph.ComputeMarkedNodes(); componentFactory.Header.Add(Internal.Runtime.ReadyToRunSectionType.OwnerCompositeExecutable, ownerExecutableNode, ownerExecutableNode); ReadyToRunObjectWriter.EmitObject( outputFile, componentModule: inputModule, inputFiles: new string[] { inputFile }, componentGraph.MarkedNodeList, componentFactory, generateMapFile: false, generateMapCsvFile: false, generatePdbFile: false, pdbPath: null, generatePerfMapFile: false, perfMapPath: null, perfMapFormatVersion: _perfMapFormatVersion, generateProfileFile: false, _profileData.CallChainProfile, customPESectionAlignment: 0); }
public override ICompilation ToCompilation() { ModuleTokenResolver moduleTokenResolver = new ModuleTokenResolver(_compilationGroup, _context); SignatureContext signatureContext = new SignatureContext(_inputModule, moduleTokenResolver); CopiedCorHeaderNode corHeaderNode = new CopiedCorHeaderNode(_inputModule); AttributePresenceFilterNode attributePresenceFilterNode = null; // Core library attributes are checked FAR more often than other dlls // attributes, so produce a highly efficient table for determining if they are // present. Other assemblies *MAY* benefit from this feature, but it doesn't show // as useful at this time. if (_inputModule == _inputModule.Context.SystemModule) { attributePresenceFilterNode = new AttributePresenceFilterNode(_inputModule); } // Produce a ResourceData where the IBC PROFILE_DATA entry has been filtered out ResourceData win32Resources = new ResourceData(_inputModule, (object type, object name, ushort language) => { if (!(type is string) || !(name is string)) { return(true); } if (language != 0) { return(true); } string typeString = (string)type; string nameString = (string)name; if ((typeString == "IBC") && (nameString == "PROFILE_DATA")) { return(false); } return(true); }); ReadyToRunCodegenNodeFactory factory = new ReadyToRunCodegenNodeFactory( _context, _compilationGroup, _nameMangler, moduleTokenResolver, signatureContext, corHeaderNode, win32Resources, attributePresenceFilterNode); IComparer <DependencyNodeCore <NodeFactory> > comparer = new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer()); DependencyAnalyzerBase <NodeFactory> graph = CreateDependencyGraph(factory, comparer); List <CorJitFlag> corJitFlags = new List <CorJitFlag> { CorJitFlag.CORJIT_FLAG_DEBUG_INFO }; switch (_optimizationMode) { case OptimizationMode.None: corJitFlags.Add(CorJitFlag.CORJIT_FLAG_DEBUG_CODE); break; case OptimizationMode.PreferSize: corJitFlags.Add(CorJitFlag.CORJIT_FLAG_SIZE_OPT); break; case OptimizationMode.PreferSpeed: corJitFlags.Add(CorJitFlag.CORJIT_FLAG_SPEED_OPT); break; default: // Not setting a flag results in BLENDED_CODE. break; } if (_ibcTuning) { corJitFlags.Add(CorJitFlag.CORJIT_FLAG_BBINSTR); } corJitFlags.Add(CorJitFlag.CORJIT_FLAG_FEATURE_SIMD); var jitConfig = new JitConfigProvider(corJitFlags, _ryujitOptions, _jitPath); return(new ReadyToRunCodegenCompilation( graph, factory, _compilationRoots, _ilProvider, _logger, new DependencyAnalysis.ReadyToRun.DevirtualizationManager(_compilationGroup), jitConfig, _inputFilePath, new ModuleDesc[] { _inputModule }, _resilient)); }