public Compilation(CompilerTypeSystemContext typeSystemContext, CompilationOptions options) { _typeSystemContext = typeSystemContext; _options = options; _nameMangler = new NameMangler(this); }
public Compilation(CompilationOptions options, CompilerTypeSystemContext context, CompilationModuleGroup compilationGroup) { _options = options; _nameMangler = new NameMangler(options.IsCppCodeGen); _typeSystemContext = context; _compilationModuleGroup = compilationGroup; }
public Compilation(CompilationOptions options) { _options = options; _typeSystemContext = new CompilerTypeSystemContext(new TargetDetails(options.TargetArchitecture, options.TargetOS)); _typeSystemContext.InputFilePaths = options.InputFilePaths; _typeSystemContext.ReferenceFilePaths = options.ReferenceFilePaths; _typeSystemContext.SetSystemModule(_typeSystemContext.GetModuleForSimpleName(options.SystemModuleName)); _nameMangler = new NameMangler(this); }
public Compilation(CompilationOptions options) { _options = options; _typeSystemContext = new CompilerTypeSystemContext(new TargetDetails(options.TargetArchitecture, options.TargetOS)); _typeSystemContext.InputFilePaths = options.InputFilePaths; _typeSystemContext.ReferenceFilePaths = options.ReferenceFilePaths; _typeSystemContext.SetSystemModule(_typeSystemContext.GetModuleForSimpleName(options.SystemModuleName)); _nameMangler = new NameMangler(this); _typeInitManager = new TypeInitialization(); if (options.MultiFile) { _compilationModuleGroup = new MultiFileCompilationModuleGroup(_typeSystemContext, this); } else { _compilationModuleGroup = new SingleFileCompilationModuleGroup(_typeSystemContext, this); } }
public AnalysisBasedMetadataManager( CompilerTypeSystemContext typeSystemContext, MetadataBlockingPolicy blockingPolicy, ManifestResourceBlockingPolicy resourceBlockingPolicy, string logFile, StackTraceEmissionPolicy stackTracePolicy, DynamicInvokeThunkGenerationPolicy invokeThunkGenerationPolicy, IEnumerable <ModuleDesc> modulesWithMetadata, IEnumerable <ReflectableEntity <TypeDesc> > reflectableTypes, IEnumerable <ReflectableEntity <MethodDesc> > reflectableMethods, IEnumerable <ReflectableEntity <FieldDesc> > reflectableFields) : base(typeSystemContext, blockingPolicy, resourceBlockingPolicy, logFile, stackTracePolicy, invokeThunkGenerationPolicy) { _modulesWithMetadata = new List <ModuleDesc>(modulesWithMetadata); foreach (var refType in reflectableTypes) { _reflectableTypes.Add(refType.Entity, refType.Category); } foreach (var refMethod in reflectableMethods) { // Asking for description or runtime mapping for a member without asking // for the owning type would mean we can't actually satisfy the request. Debug.Assert((refMethod.Category & MetadataCategory.Description) == 0 || (_reflectableTypes[refMethod.Entity.OwningType] & MetadataCategory.Description) != 0); Debug.Assert((refMethod.Category & MetadataCategory.RuntimeMapping) == 0 || (_reflectableTypes[refMethod.Entity.OwningType] & MetadataCategory.RuntimeMapping) != 0); _reflectableMethods.Add(refMethod.Entity, refMethod.Category); } foreach (var refField in reflectableFields) { // Asking for description or runtime mapping for a member without asking // for the owning type would mean we can't actually satisfy the request. Debug.Assert((refField.Category & MetadataCategory.Description) == 0 || (_reflectableTypes[refField.Entity.OwningType] & MetadataCategory.Description) != 0); Debug.Assert((refField.Category & MetadataCategory.RuntimeMapping) == 0 || (_reflectableTypes[refField.Entity.OwningType] & MetadataCategory.RuntimeMapping) != 0); _reflectableFields.Add(refField.Entity, refField.Category); } #if DEBUG HashSet <ModuleDesc> moduleHash = new HashSet <ModuleDesc>(_modulesWithMetadata); foreach (var refType in reflectableTypes) { // The instantiated types need to agree on the Description bit with the definition. // GetMetadataCategory relies on that. Debug.Assert((GetMetadataCategory(refType.Entity.GetTypeDefinition()) & MetadataCategory.Description) == (GetMetadataCategory(refType.Entity) & MetadataCategory.Description)); Debug.Assert(!(refType.Entity is MetadataType) || moduleHash.Contains(((MetadataType)refType.Entity).Module)); } foreach (var refMethod in reflectableMethods) { // The instantiated methods need to agree on the Description bit with the definition. // GetMetadataCategory relies on that. Debug.Assert((GetMetadataCategory(refMethod.Entity.GetTypicalMethodDefinition()) & MetadataCategory.Description) == (GetMetadataCategory(refMethod.Entity) & MetadataCategory.Description)); // Canonical form of the method needs to agree with the logical form Debug.Assert(GetMetadataCategory(refMethod.Entity) == GetMetadataCategory(refMethod.Entity.GetCanonMethodTarget(CanonicalFormKind.Specific))); } foreach (var refField in reflectableFields) { // The instantiated fields need to agree on the Description bit with the definition. // GetMetadataCategory relies on that. Debug.Assert((GetMetadataCategory(refField.Entity.GetTypicalFieldDefinition()) & MetadataCategory.Description) == (GetMetadataCategory(refField.Entity) & MetadataCategory.Description)); } #endif }
private int Run(string[] args) { InitializeDefaultOptions(); ArgumentSyntax syntax = ParseCommandLine(args); if (_help) { Help(syntax.GetHelpText()); return(1); } if (_outputFilePath == null) { throw new CommandLineException("Output filename must be specified (/out <file>)"); } // // Set target Architecture and OS // if (_targetArchitectureStr != null) { if (_targetArchitectureStr.Equals("x86", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.X86; } else if (_targetArchitectureStr.Equals("x64", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.X64; } else if (_targetArchitectureStr.Equals("arm", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM; } else if (_targetArchitectureStr.Equals("armel", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARMEL; } else if (_targetArchitectureStr.Equals("arm64", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM64; } else { throw new CommandLineException("Target architecture is not supported"); } } if (_targetOSStr != null) { if (_targetOSStr.Equals("windows", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.Windows; } else if (_targetOSStr.Equals("linux", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.Linux; } else if (_targetOSStr.Equals("osx", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.OSX; } else { throw new CommandLineException("Target OS is not supported"); } } // // Initialize type system context // SharedGenericsMode genericsMode = _useSharedGenerics || !_isCppCodegen ? SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled; // TODO: compiler switch for SIMD support? var simdVectorLength = _isCppCodegen ? SimdVectorLength.None : SimdVectorLength.Vector128Bit; var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, TargetAbi.CoreRT, simdVectorLength); var typeSystemContext = new CompilerTypeSystemContext(targetDetails, genericsMode); // // TODO: To support our pre-compiled test tree, allow input files that aren't managed assemblies since // some tests contain a mixture of both managed and native binaries. // // See: https://github.com/dotnet/corert/issues/2785 // // When we undo this this hack, replace this foreach with // typeSystemContext.InputFilePaths = _inputFilePaths; // Dictionary <string, string> inputFilePaths = new Dictionary <string, string>(); foreach (var inputFile in _inputFilePaths) { try { var module = typeSystemContext.GetModuleFromPath(inputFile.Value); inputFilePaths.Add(inputFile.Key, inputFile.Value); } catch (TypeSystemException.BadImageFormatException) { // Keep calm and carry on. } } typeSystemContext.InputFilePaths = inputFilePaths; typeSystemContext.ReferenceFilePaths = _referenceFilePaths; typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName)); if (typeSystemContext.InputFilePaths.Count == 0) { throw new CommandLineException("No input files specified"); } // // Initialize compilation group and compilation roots // // Single method mode? MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext); CompilationModuleGroup compilationGroup; List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>(); if (singleMethod != null) { // Compiling just a single method compilationGroup = new SingleMethodCompilationModuleGroup(singleMethod); compilationRoots.Add(new SingleMethodRootProvider(singleMethod)); } else { // Either single file, or multifile library, or multifile consumption. EcmaModule entrypointModule = null; foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (module.PEReader.PEHeaders.IsExe) { if (entrypointModule != null) { throw new Exception("Multiple EXE modules"); } entrypointModule = module; } compilationRoots.Add(new ExportedMethodsRootProvider(module)); } if (entrypointModule != null) { LibraryInitializers libraryInitializers = new LibraryInitializers(typeSystemContext, _isCppCodegen); compilationRoots.Add(new MainMethodRootProvider(entrypointModule, libraryInitializers.LibraryInitializerMethods)); } if (_multiFile) { List <EcmaModule> inputModules = new List <EcmaModule>(); foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (entrypointModule == null) { // This is a multifile production build - we need to root all methods compilationRoots.Add(new LibraryRootProvider(module)); } inputModules.Add(module); } compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules); } else { if (entrypointModule == null) { throw new Exception("No entrypoint module"); } compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule)); compilationGroup = new SingleFileCompilationModuleGroup(typeSystemContext); } foreach (var rdXmlFilePath in _rdXmlFilePaths) { compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath)); } } // // Compile // CompilationBuilder builder; if (_isCppCodegen) { builder = new CppCodegenCompilationBuilder(typeSystemContext, compilationGroup); } else { builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup); } ILScanResults scanResults = null; if (_useScanner && !_isCppCodegen) { ILScannerBuilder scannerBuilder = builder.GetILScannerBuilder() .UseCompilationRoots(compilationRoots); if (_scanDgmlLogFileName != null) { scannerBuilder.UseDependencyTracking(_generateFullScanDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); } IILScanner scanner = scannerBuilder.ToILScanner(); scanResults = scanner.Scan(); } var logger = _isVerbose ? new Logger(Console.Out, true) : Logger.Null; DependencyTrackingLevel trackingLevel = _dgmlLogFileName == null ? DependencyTrackingLevel.None : (_generateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); CompilerGeneratedMetadataManager metadataManager = new CompilerGeneratedMetadataManager(compilationGroup, typeSystemContext, _metadataLogFileName); builder .UseBackendOptions(_codegenOptions) .UseMetadataManager(metadataManager) .UseLogger(logger) .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .UseOptimizationMode(_optimizationMode) .UseDebugInfo(_enableDebugInfo); if (scanResults != null) { // If we have a scanner, feed the vtable analysis results to the compilation. // This could be a command line switch if we really wanted to. builder.UseVTableSliceProvider(scanResults.GetVTableLayoutInfo()); // If we have a scanner, feed the generic dictionary results to the compilation. // This could be a command line switch if we really wanted to. builder.UseGenericDictionaryLayoutProvider(scanResults.GetDictionaryLayoutInfo()); } ICompilation compilation = builder.ToCompilation(); ObjectDumper dumper = _mapFileName != null ? new ObjectDumper(_mapFileName) : null; CompilationResults compilationResults = compilation.Compile(_outputFilePath, dumper); if (_dgmlLogFileName != null) { compilationResults.WriteDependencyLog(_dgmlLogFileName); } if (scanResults != null) { SimdHelper simdHelper = new SimdHelper(); if (_scanDgmlLogFileName != null) { scanResults.WriteDependencyLog(_scanDgmlLogFileName); } // If the scanner and compiler don't agree on what to compile, the outputs of the scanner might not actually be usable. // We are going to check this two ways: // 1. The methods and types generated during compilation are a subset of method and types scanned // 2. The methods and types scanned are a subset of methods and types compiled (this has a chance to hold for unoptimized builds only). // Check that methods and types generated during compilation are a subset of method and types scanned bool scanningFail = false; DiffCompilationResults(ref scanningFail, compilationResults.CompiledMethodBodies, scanResults.CompiledMethodBodies, "Methods", "compiled", "scanned", method => !(method.GetTypicalMethodDefinition() is EcmaMethod)); DiffCompilationResults(ref scanningFail, compilationResults.ConstructedEETypes, scanResults.ConstructedEETypes, "EETypes", "compiled", "scanned", type => !(type.GetTypeDefinition() is EcmaType)); // If optimizations are enabled, the results will for sure not match in the other direction due to inlining, etc. // But there's at least some value in checking the scanner doesn't expand the universe too much in debug. if (_optimizationMode == OptimizationMode.None) { // Check that methods and types scanned are a subset of methods and types compiled // If we find diffs here, they're not critical, but still might be causing a Size on Disk regression. bool dummy = false; // We additionally skip methods in SIMD module because there's just too many intrisics to handle and IL scanner // doesn't expand them. They would show up as noisy diffs. DiffCompilationResults(ref dummy, scanResults.CompiledMethodBodies, compilationResults.CompiledMethodBodies, "Methods", "scanned", "compiled", method => !(method.GetTypicalMethodDefinition() is EcmaMethod) || simdHelper.IsInSimdModule(method.OwningType)); DiffCompilationResults(ref dummy, scanResults.ConstructedEETypes, compilationResults.ConstructedEETypes, "EETypes", "scanned", "compiled", type => !(type.GetTypeDefinition() is EcmaType)); } if (scanningFail) { throw new Exception("Scanning failure"); } } return(0); }
public RyuJitCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group) : base(context, group, new CoreRTNameMangler(context.Target.IsWindows ? (NodeMangler) new WindowsNodeMangler() : (NodeMangler) new UnixNodeMangler(), false)) { }
private void RunSingleCompilation(Dictionary <string, string> inFilePaths, InstructionSetSupport instructionSetSupport, string compositeRootPath, Dictionary <string, string> unrootedInputFilePaths, HashSet <ModuleDesc> versionBubbleModulesHash, CompilerTypeSystemContext typeSystemContext) { // // Initialize output filename // var outFile = _commandLineOptions.OutNearInput ? inFilePaths.First().Value.Replace(".dll", ".ni.dll") : _commandLineOptions.OutputFilePath; using (PerfEventSource.StartStopEvents.CompilationEvents()) { ICompilation compilation; using (PerfEventSource.StartStopEvents.LoadingEvents()) { List <EcmaModule> inputModules = new List <EcmaModule>(); List <EcmaModule> rootingModules = new List <EcmaModule>(); Guid?inputModuleMvid = null; foreach (var inputFile in inFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); inputModules.Add(module); rootingModules.Add(module); versionBubbleModulesHash.Add(module); if (!_commandLineOptions.Composite && !inputModuleMvid.HasValue) { inputModuleMvid = module.MetadataReader.GetGuid(module.MetadataReader.GetModuleDefinition().Mvid); } if (!_commandLineOptions.CompositeOrInputBubble) { break; } } foreach (var unrootedInputFile in unrootedInputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(unrootedInputFile.Value); inputModules.Add(module); versionBubbleModulesHash.Add(module); } // // Initialize compilation group and compilation roots // // Single method mode? MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext); var logger = new Logger(Console.Out, _commandLineOptions.Verbose); List <string> mibcFiles = new List <string>(); foreach (var file in _commandLineOptions.MibcFilePaths) { mibcFiles.Add(file); } List <ModuleDesc> versionBubbleModules = new List <ModuleDesc>(versionBubbleModulesHash); if (!_commandLineOptions.Composite && inputModules.Count != 1) { throw new Exception(string.Format(SR.ErrorMultipleInputFilesCompositeModeOnly, string.Join("; ", inputModules))); } ReadyToRunCompilationModuleGroupBase compilationGroup; List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>(); if (singleMethod != null) { // Compiling just a single method compilationGroup = new SingleMethodCompilationModuleGroup( typeSystemContext, _commandLineOptions.Composite, _commandLineOptions.InputBubble, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics, singleMethod); compilationRoots.Add(new SingleMethodRootProvider(singleMethod)); } else if (_commandLineOptions.CompileNoMethods) { compilationGroup = new NoMethodsCompilationModuleGroup( typeSystemContext, _commandLineOptions.Composite, _commandLineOptions.InputBubble, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics); } else { // Single assembly compilation. compilationGroup = new ReadyToRunSingleAssemblyCompilationModuleGroup( typeSystemContext, _commandLineOptions.Composite, _commandLineOptions.InputBubble, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics); } // Load any profiles generated by method call chain analyis CallChainProfile jsonProfile = null; if (!string.IsNullOrEmpty(_commandLineOptions.CallChainProfileFile)) { jsonProfile = new CallChainProfile(_commandLineOptions.CallChainProfileFile, typeSystemContext, _referenceableModules); } // Examine profile guided information as appropriate ProfileDataManager profileDataManager = new ProfileDataManager(logger, _referenceableModules, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics ? inputModules[0] : null, mibcFiles, jsonProfile, typeSystemContext, compilationGroup, _commandLineOptions.EmbedPgoData); if (_commandLineOptions.Partial) { compilationGroup.ApplyProfilerGuidedCompilationRestriction(profileDataManager); } else { compilationGroup.ApplyProfilerGuidedCompilationRestriction(null); } if ((singleMethod == null) && !_commandLineOptions.CompileNoMethods) { // For normal compilations add compilation roots. foreach (var module in rootingModules) { compilationRoots.Add(new ReadyToRunRootProvider( module, profileDataManager, profileDrivenPartialNGen: _commandLineOptions.Partial)); if (!_commandLineOptions.CompositeOrInputBubble) { break; } } } // In single-file compilation mode, use the assembly's DebuggableAttribute to determine whether to optimize // or produce debuggable code if an explicit optimization level was not specified on the command line OptimizationMode optimizationMode = _optimizationMode; if (optimizationMode == OptimizationMode.None && !_commandLineOptions.OptimizeDisabled && !_commandLineOptions.Composite) { System.Diagnostics.Debug.Assert(inputModules.Count == 1); optimizationMode = ((EcmaAssembly)inputModules[0].Assembly).HasOptimizationsDisabled() ? OptimizationMode.None : OptimizationMode.Blended; } CompositeImageSettings compositeImageSettings = new CompositeImageSettings(); if (_commandLineOptions.CompositeKeyFile != null) { ImmutableArray <byte> compositeStrongNameKey = File.ReadAllBytes(_commandLineOptions.CompositeKeyFile).ToImmutableArray(); if (!IsValidPublicKey(compositeStrongNameKey)) { throw new Exception(string.Format(SR.ErrorCompositeKeyFileNotPublicKey)); } compositeImageSettings.PublicKey = compositeStrongNameKey; } // // Compile // ReadyToRunCodegenCompilationBuilder builder = new ReadyToRunCodegenCompilationBuilder( typeSystemContext, compilationGroup, _allInputFilePaths.Values, compositeRootPath); string compilationUnitPrefix = ""; builder.UseCompilationUnitPrefix(compilationUnitPrefix); ILProvider ilProvider = new ReadyToRunILProvider(); DependencyTrackingLevel trackingLevel = _commandLineOptions.DgmlLogFileName == null ? DependencyTrackingLevel.None : (_commandLineOptions.GenerateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); builder .UseIbcTuning(_commandLineOptions.Tuning) .UseResilience(_commandLineOptions.Resilient) .UseMapFile(_commandLineOptions.Map) .UseMapCsvFile(_commandLineOptions.MapCsv) .UsePdbFile(_commandLineOptions.Pdb, _commandLineOptions.PdbPath) .UsePerfMapFile(_commandLineOptions.PerfMap, _commandLineOptions.PerfMapPath, inputModuleMvid) .UseProfileFile(jsonProfile != null) .UseParallelism(_commandLineOptions.Parallelism) .UseProfileData(profileDataManager) .FileLayoutAlgorithms(_methodLayout, _fileLayout) .UseCompositeImageSettings(compositeImageSettings) .UseJitPath(_commandLineOptions.JitPath) .UseInstructionSetSupport(instructionSetSupport) .UseCustomPESectionAlignment(_commandLineOptions.CustomPESectionAlignment) .UseVerifyTypeAndFieldLayout(_commandLineOptions.VerifyTypeAndFieldLayout) .GenerateOutputFile(outFile) .UseILProvider(ilProvider) .UseBackendOptions(_commandLineOptions.CodegenOptions) .UseLogger(logger) .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .UseOptimizationMode(optimizationMode); if (_commandLineOptions.PrintReproInstructions) { builder.UsePrintReproInstructions(CreateReproArgumentString); } compilation = builder.ToCompilation(); } compilation.Compile(outFile); if (_commandLineOptions.DgmlLogFileName != null) { compilation.WriteDependencyLog(_commandLineOptions.DgmlLogFileName); } compilation.Dispose(); } }
private int Run() { using (PerfEventSource.StartStopEvents.CompilationEvents()) { ICompilation compilation; using (PerfEventSource.StartStopEvents.LoadingEvents()) { InitializeDefaultOptions(); ProcessCommandLine(); if (_commandLineOptions.OutputFilePath == null) { throw new CommandLineException(SR.MissingOutputFile); } CheckCustomPESectionAlignment(); ConfigureTarget(); InstructionSetSupport instructionSetSupport = ConfigureInstructionSetSupport(); // // Initialize type system context // SharedGenericsMode genericsMode = SharedGenericsMode.CanonicalReferenceTypes; var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, TargetAbi.CoreRT, instructionSetSupport.GetVectorTSimdVector()); _typeSystemContext = new ReadyToRunCompilerContext(targetDetails, genericsMode); string compositeRootPath = _commandLineOptions.CompositeRootPath?.FullName; // // TODO: To support our pre-compiled test tree, allow input files that aren't managed assemblies since // some tests contain a mixture of both managed and native binaries. // // See: https://github.com/dotnet/corert/issues/2785 // // When we undo this this hack, replace this foreach with // typeSystemContext.InputFilePaths = _inputFilePaths; // Dictionary <string, string> allInputFilePaths = new Dictionary <string, string>(); Dictionary <string, string> inputFilePaths = new Dictionary <string, string>(); List <ModuleDesc> referenceableModules = new List <ModuleDesc>(); foreach (var inputFile in _inputFilePaths) { try { var module = _typeSystemContext.GetModuleFromPath(inputFile.Value); allInputFilePaths.Add(inputFile.Key, inputFile.Value); inputFilePaths.Add(inputFile.Key, inputFile.Value); referenceableModules.Add(module); if (compositeRootPath == null) { compositeRootPath = Path.GetDirectoryName(inputFile.Value); } } catch (TypeSystemException.BadImageFormatException) { // Keep calm and carry on. } } Dictionary <string, string> unrootedInputFilePaths = new Dictionary <string, string>(); foreach (var unrootedInputFile in _unrootedInputFilePaths) { try { var module = _typeSystemContext.GetModuleFromPath(unrootedInputFile.Value); if (!allInputFilePaths.ContainsKey(unrootedInputFile.Key)) { allInputFilePaths.Add(unrootedInputFile.Key, unrootedInputFile.Value); unrootedInputFilePaths.Add(unrootedInputFile.Key, unrootedInputFile.Value); referenceableModules.Add(module); if (compositeRootPath == null) { compositeRootPath = Path.GetDirectoryName(unrootedInputFile.Value); } } } catch (TypeSystemException.BadImageFormatException) { // Keep calm and carry on. } } CheckManagedCppInputFiles(allInputFilePaths.Values); _typeSystemContext.InputFilePaths = allInputFilePaths; _typeSystemContext.ReferenceFilePaths = _referenceFilePaths; List <EcmaModule> inputModules = new List <EcmaModule>(); List <EcmaModule> rootingModules = new List <EcmaModule>(); HashSet <ModuleDesc> versionBubbleModulesHash = new HashSet <ModuleDesc>(); foreach (var inputFile in inputFilePaths) { EcmaModule module = _typeSystemContext.GetModuleFromPath(inputFile.Value); inputModules.Add(module); rootingModules.Add(module); versionBubbleModulesHash.Add(module); if (!_commandLineOptions.CompositeOrInputBubble) { break; } } foreach (var unrootedInputFile in unrootedInputFilePaths) { EcmaModule module = _typeSystemContext.GetModuleFromPath(unrootedInputFile.Value); inputModules.Add(module); versionBubbleModulesHash.Add(module); } string systemModuleName = _commandLineOptions.SystemModule ?? DefaultSystemModule; _typeSystemContext.SetSystemModule((EcmaModule)_typeSystemContext.GetModuleForSimpleName(systemModuleName)); if (_typeSystemContext.InputFilePaths.Count == 0) { if (_commandLineOptions.InputFilePaths.Count() > 0) { Console.WriteLine(SR.InputWasNotLoadable); return(2); } throw new CommandLineException(SR.NoInputFiles); } // // Initialize compilation group and compilation roots // // Single method mode? MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(_typeSystemContext); var logger = new Logger(Console.Out, _commandLineOptions.Verbose); List <string> mibcFiles = new List <string>(); if (_commandLineOptions.Mibc != null) { foreach (var file in _commandLineOptions.Mibc) { mibcFiles.Add(file.FullName); } } foreach (var referenceFile in _referenceFilePaths.Values) { try { EcmaModule module = _typeSystemContext.GetModuleFromPath(referenceFile); if (versionBubbleModulesHash.Contains(module)) { // Ignore reference assemblies that have also been passed as inputs continue; } referenceableModules.Add(module); if (_commandLineOptions.InputBubble) { // In large version bubble mode add reference paths to the compilation group versionBubbleModulesHash.Add(module); } } catch { } // Ignore non-managed pe files } List <ModuleDesc> versionBubbleModules = new List <ModuleDesc>(versionBubbleModulesHash); if (!_commandLineOptions.Composite && inputModules.Count != 1) { throw new Exception(string.Format(SR.ErrorMultipleInputFilesCompositeModeOnly, string.Join("; ", inputModules))); } ReadyToRunCompilationModuleGroupBase compilationGroup; List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>(); if (singleMethod != null) { // Compiling just a single method compilationGroup = new SingleMethodCompilationModuleGroup( _typeSystemContext, _commandLineOptions.Composite, _commandLineOptions.InputBubble, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics, singleMethod); compilationRoots.Add(new SingleMethodRootProvider(singleMethod)); } else if (_commandLineOptions.CompileNoMethods) { compilationGroup = new NoMethodsCompilationModuleGroup( _typeSystemContext, _commandLineOptions.Composite, _commandLineOptions.InputBubble, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics); } else { // Single assembly compilation. compilationGroup = new ReadyToRunSingleAssemblyCompilationModuleGroup( _typeSystemContext, _commandLineOptions.Composite, _commandLineOptions.InputBubble, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics); } // Examine profile guided information as appropriate ProfileDataManager profileDataManager = new ProfileDataManager(logger, referenceableModules, inputModules, versionBubbleModules, _commandLineOptions.CompileBubbleGenerics ? inputModules[0] : null, mibcFiles, _typeSystemContext, compilationGroup); if (_commandLineOptions.Partial) { compilationGroup.ApplyProfilerGuidedCompilationRestriction(profileDataManager); } else { compilationGroup.ApplyProfilerGuidedCompilationRestriction(null); } if ((singleMethod == null) && !_commandLineOptions.CompileNoMethods) { // For normal compilations add compilation roots. foreach (var module in rootingModules) { compilationRoots.Add(new ReadyToRunRootProvider( module, profileDataManager, profileDrivenPartialNGen: _commandLineOptions.Partial)); if (!_commandLineOptions.CompositeOrInputBubble) { break; } } } // // Compile // ReadyToRunCodegenCompilationBuilder builder = new ReadyToRunCodegenCompilationBuilder( _typeSystemContext, compilationGroup, allInputFilePaths.Values, compositeRootPath); string compilationUnitPrefix = ""; builder.UseCompilationUnitPrefix(compilationUnitPrefix); ILProvider ilProvider = new ReadyToRunILProvider(); DependencyTrackingLevel trackingLevel = _commandLineOptions.DgmlLogFileName == null ? DependencyTrackingLevel.None : (_commandLineOptions.GenerateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); builder .UseIbcTuning(_commandLineOptions.Tuning) .UseResilience(_commandLineOptions.Resilient) .UseMapFile(_commandLineOptions.Map) .UseParallelism(_commandLineOptions.Parallelism) .UseProfileData(profileDataManager) .FileLayoutAlgorithms(_commandLineOptions.MethodLayout, _commandLineOptions.FileLayout) .UseJitPath(_commandLineOptions.JitPath) .UseInstructionSetSupport(instructionSetSupport) .UseCustomPESectionAlignment(_commandLineOptions.CustomPESectionAlignment) .UseVerifyTypeAndFieldLayout(_commandLineOptions.VerifyTypeAndFieldLayout) .GenerateOutputFile(_commandLineOptions.OutputFilePath.FullName) .UseILProvider(ilProvider) .UseBackendOptions(_commandLineOptions.CodegenOptions) .UseLogger(logger) .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .UseOptimizationMode(_optimizationMode); compilation = builder.ToCompilation(); } compilation.Compile(_commandLineOptions.OutputFilePath.FullName); if (_commandLineOptions.DgmlLogFileName != null) { compilation.WriteDependencyLog(_commandLineOptions.DgmlLogFileName.FullName); } } return(0); }
public CppCodegenCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group) : base(new CppCodegenNodeFactory(context, group)) { }
public WebAssemblyCodegenCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group) : base(context, group, new CoreRTNameMangler(new WebAssemblyNodeMangler(), false)) { }
public MultiFileCompilationModuleGroup(CompilerTypeSystemContext typeSystemContext) : base(typeSystemContext) { }
public MultiFileSharedCompilationModuleGroup(CompilerTypeSystemContext context, IEnumerable <ModuleDesc> compilationModuleSet) : base(context, compilationModuleSet) { }
public CompilerGeneratedInteropStubManager(CompilationModuleGroup compilationModuleGroup, CompilerTypeSystemContext typeSystemContext, InteropStateManager interopStateManager) : base(compilationModuleGroup, typeSystemContext, interopStateManager) { }
public EmptyMetadataManager(CompilerTypeSystemContext typeSystemContext) : base(typeSystemContext, new FullyBlockedMetadataPolicy(), new FullyBlockedManifestResourcePolicy()) { }
public InteropStubManager(CompilationModuleGroup compilationModuleGroup, CompilerTypeSystemContext typeSystemContext, InteropStateManager interopStateManager) { _compilationModuleGroup = compilationModuleGroup; _typeSystemContext = typeSystemContext; InteropStateManager = interopStateManager; }
public SingleFileCompilationModuleGroup(CompilerTypeSystemContext typeSystemContext) : base(typeSystemContext) { }
public ProfileDataManager(Logger logger, IEnumerable <ModuleDesc> possibleReferenceModules, IEnumerable <ModuleDesc> inputModules, IEnumerable <ModuleDesc> versionBubbleModules, ModuleDesc nonLocalGenericsHome, IReadOnlyList <string> mibcFiles, CompilerTypeSystemContext context, ReadyToRunCompilationModuleGroupBase compilationGroup) { _ibcParser = new IBCProfileParser(logger, possibleReferenceModules); _compilationGroup = compilationGroup; HashSet <ModuleDesc> versionBubble = new HashSet <ModuleDesc>(versionBubbleModules); { // Parse MIbc Data string onlyParseItemsDefinedInAssembly = nonLocalGenericsHome == null?inputModules.First().Assembly.GetName().Name : null; HashSet <string> versionBubbleModuleStrings = new HashSet <string>(); foreach (ModuleDesc versionBubbleModule in versionBubble) { versionBubbleModuleStrings.Add(versionBubbleModule.Assembly.GetName().Name); } foreach (string file in mibcFiles) { _inputData.Add(MIbcProfileParser.ParseMIbcFile(context, file, versionBubbleModuleStrings, onlyParseItemsDefinedInAssembly)); } } { // Parse Ibc data foreach (var module in inputModules) { _inputData.Add(_ibcParser.ParseIBCDataFromModule((EcmaModule)module)); _placedProfileMethods.Add(module, new HashSet <MethodDesc>()); } } // Merge all data together foreach (ProfileData profileData in _inputData) { MergeProfileData(ref _partialNGen, _mergedProfileData, profileData); } // With the merged data find the set of methods to be placed within this module foreach (var profileData in _mergedProfileData) { // If the method is not excluded from processing if (!profileData.Value.Flags.HasFlag(MethodProfilingDataFlags.ExcludeHotMethodCode) && !profileData.Value.Flags.HasFlag(MethodProfilingDataFlags.ExcludeColdMethodCode)) { // Check for methods which are defined within the version bubble, and only rely on other modules within the bubble if (!_compilationGroup.VersionsWithMethodBody(profileData.Key)) { continue; // Method not contained within version bubble } if (_compilationGroup.ContainsType(profileData.Key.OwningType) && (profileData.Key.OwningType is MetadataType declaringType)) { // In this case the method is placed in its natural home (which is the defining module of the method) _placedProfileMethods[declaringType.Module].Add(profileData.Key); _placedProfileMethodsAll.Add(profileData.Key); } else { // If the defining module is not within the input set, if the nonLocalGenericsHome is provided, place it there if ((nonLocalGenericsHome != null) && (profileData.Key.GetTypicalMethodDefinition() != profileData.Key)) { _placedProfileMethods[nonLocalGenericsHome].Add(profileData.Key); _placedProfileMethodsAll.Add(profileData.Key); } } } } }
private int Run(string[] args) { InitializeDefaultOptions(); ArgumentSyntax syntax = ParseCommandLine(args); if (_help) { Help(syntax.GetHelpText()); return(1); } if (_outputFilePath == null) { throw new CommandLineException("Output filename must be specified (/out <file>)"); } // // Set target Architecture and OS // if (_targetArchitectureStr != null) { if (_targetArchitectureStr.Equals("x86", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.X86; } else if (_targetArchitectureStr.Equals("x64", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.X64; } else if (_targetArchitectureStr.Equals("arm", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM; } else if (_targetArchitectureStr.Equals("armel", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM; } else if (_targetArchitectureStr.Equals("arm64", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM64; } else if (_targetArchitectureStr.Equals("wasm", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.Wasm32; _isWasmCodegen = true; } else { throw new CommandLineException("Target architecture is not supported"); } } if (_targetOSStr != null) { if (_targetOSStr.Equals("windows", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.Windows; } else if (_targetOSStr.Equals("linux", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.Linux; } else if (_targetOSStr.Equals("osx", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.OSX; } else { throw new CommandLineException("Target OS is not supported"); } } if (_isWasmCodegen) { _targetArchitecture = TargetArchitecture.Wasm32; } bool supportsReflection = !_disableReflection && !_isReadyToRunCodeGen && _systemModuleName == DefaultSystemModule; // // Initialize type system context // SharedGenericsMode genericsMode = _useSharedGenerics || !_isWasmCodegen ? SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled; // TODO: compiler switch for SIMD support? var simdVectorLength = (_isCppCodegen || _isWasmCodegen) ? SimdVectorLength.None : SimdVectorLength.Vector128Bit; var targetAbi = _isCppCodegen ? TargetAbi.CppCodegen : TargetAbi.CoreRT; var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, targetAbi, simdVectorLength); CompilerTypeSystemContext typeSystemContext = (_isReadyToRunCodeGen ? new ReadyToRunCompilerContext(targetDetails, genericsMode) : new CompilerTypeSystemContext(targetDetails, genericsMode, supportsReflection ? DelegateFeature.All : 0)); // // TODO: To support our pre-compiled test tree, allow input files that aren't managed assemblies since // some tests contain a mixture of both managed and native binaries. // // See: https://github.com/dotnet/corert/issues/2785 // // When we undo this this hack, replace this foreach with // typeSystemContext.InputFilePaths = _inputFilePaths; // Dictionary <string, string> inputFilePaths = new Dictionary <string, string>(); foreach (var inputFile in _inputFilePaths) { try { var module = typeSystemContext.GetModuleFromPath(inputFile.Value); inputFilePaths.Add(inputFile.Key, inputFile.Value); } catch (TypeSystemException.BadImageFormatException) { // Keep calm and carry on. } } typeSystemContext.InputFilePaths = inputFilePaths; typeSystemContext.ReferenceFilePaths = _referenceFilePaths; typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName)); if (typeSystemContext.InputFilePaths.Count == 0) { throw new CommandLineException("No input files specified"); } // // Initialize compilation group and compilation roots // // Single method mode? MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext); CompilationModuleGroup compilationGroup; List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>(); if (singleMethod != null) { // Compiling just a single method compilationGroup = new SingleMethodCompilationModuleGroup(singleMethod); compilationRoots.Add(new SingleMethodRootProvider(singleMethod)); } else { // Either single file, or multifile library, or multifile consumption. EcmaModule entrypointModule = null; bool systemModuleIsInputModule = false; foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (module.PEReader.PEHeaders.IsExe) { if (entrypointModule != null) { throw new Exception("Multiple EXE modules"); } entrypointModule = module; } if (module == typeSystemContext.SystemModule) { systemModuleIsInputModule = true; } if (!_isReadyToRunCodeGen) { compilationRoots.Add(new ExportedMethodsRootProvider(module)); } } if (entrypointModule != null && !_isReadyToRunCodeGen) { compilationRoots.Add(new MainMethodRootProvider(entrypointModule, CreateInitializerList(typeSystemContext))); compilationRoots.Add(new RuntimeConfigurationRootProvider(_runtimeOptions)); } if (_isReadyToRunCodeGen) { List <EcmaModule> inputModules = new List <EcmaModule>(); foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); compilationRoots.Add(new ReadyToRunRootProvider(module)); inputModules.Add(module); if (!_isInputVersionBubble) { break; } } List <ModuleDesc> versionBubbleModules = new List <ModuleDesc>(); if (_isInputVersionBubble) { // In large version bubble mode add reference paths to the compilation group foreach (string referenceFile in _referenceFilePaths.Values) { try { // Currently SimpleTest.targets has no easy way to filter out non-managed assemblies // from the reference list. EcmaModule module = typeSystemContext.GetModuleFromPath(referenceFile); versionBubbleModules.Add(module); } catch (TypeSystemException.BadImageFormatException ex) { Console.WriteLine("Warning: cannot open reference assembly '{0}': {1}", referenceFile, ex.Message); } } } compilationGroup = new ReadyToRunSingleAssemblyCompilationModuleGroup( typeSystemContext, inputModules, versionBubbleModules); } else if (_multiFile) { List <EcmaModule> inputModules = new List <EcmaModule>(); foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (entrypointModule == null) { // This is a multifile production build - we need to root all methods compilationRoots.Add(new LibraryRootProvider(module)); } inputModules.Add(module); } compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules); } else { if (entrypointModule == null && !_nativeLib) { throw new Exception("No entrypoint module"); } if (!systemModuleIsInputModule) { compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule)); } compilationGroup = new SingleFileCompilationModuleGroup(); } if (_nativeLib) { // Set owning module of generated native library startup method to compiler generated module, // to ensure the startup method is included in the object file during multimodule mode build compilationRoots.Add(new NativeLibraryInitializerRootProvider(typeSystemContext.GeneratedAssembly, CreateInitializerList(typeSystemContext))); compilationRoots.Add(new RuntimeConfigurationRootProvider(_runtimeOptions)); } if (_rdXmlFilePaths.Count > 0) { Console.WriteLine("Warning: RD.XML processing will change before release (https://github.com/dotnet/corert/issues/5001)"); } foreach (var rdXmlFilePath in _rdXmlFilePaths) { compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath)); } } // // Compile // CompilationBuilder builder; if (_isWasmCodegen) { builder = new WebAssemblyCodegenCompilationBuilder(typeSystemContext, compilationGroup); } else if (_isReadyToRunCodeGen) { string inputFilePath = ""; foreach (var input in typeSystemContext.InputFilePaths) { inputFilePath = input.Value; break; } builder = new ReadyToRunCodegenCompilationBuilder(typeSystemContext, compilationGroup, inputFilePath); } else if (_isCppCodegen) { builder = new CppCodegenCompilationBuilder(typeSystemContext, compilationGroup); } else { builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup); } string compilationUnitPrefix = _multiFile ? System.IO.Path.GetFileNameWithoutExtension(_outputFilePath) : ""; builder.UseCompilationUnitPrefix(compilationUnitPrefix); if (!_isCppCodegen && !_isWasmCodegen) { builder.UsePInvokePolicy(new ConfigurablePInvokePolicy(typeSystemContext.Target)); } RemovedFeature removedFeatures = 0; foreach (string feature in _removedFeatures) { if (feature == "EventSource") { removedFeatures |= RemovedFeature.Etw; } else if (feature == "FrameworkStrings") { removedFeatures |= RemovedFeature.FrameworkResources; } else if (feature == "Globalization") { removedFeatures |= RemovedFeature.Globalization; } else if (feature == "Comparers") { removedFeatures |= RemovedFeature.Comparers; } else if (feature == "CurlHandler") { removedFeatures |= RemovedFeature.CurlHandler; } } ILProvider ilProvider = _isReadyToRunCodeGen ? (ILProvider) new ReadyToRunILProvider() : new CoreRTILProvider(); if (removedFeatures != 0) { ilProvider = new RemovingILProvider(ilProvider, removedFeatures); } var stackTracePolicy = _emitStackTraceData ? (StackTraceEmissionPolicy) new EcmaMethodStackTraceEmissionPolicy() : new NoStackTraceEmissionPolicy(); MetadataBlockingPolicy mdBlockingPolicy = _noMetadataBlocking ? (MetadataBlockingPolicy) new NoMetadataBlockingPolicy() : new BlockedInternalsBlockingPolicy(typeSystemContext); ManifestResourceBlockingPolicy resBlockingPolicy = (removedFeatures & RemovedFeature.FrameworkResources) != 0 ? new FrameworkStringResourceBlockingPolicy() : (ManifestResourceBlockingPolicy) new NoManifestResourceBlockingPolicy(); UsageBasedMetadataGenerationOptions metadataGenerationOptions = UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic; if (_completeTypesMetadata) { metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.CompleteTypesOnly; } if (_scanReflection) { metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.ILScanning; } if (_rootAllApplicationAssemblies) { metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.FullUserAssemblyRooting; } DynamicInvokeThunkGenerationPolicy invokeThunkGenerationPolicy = new DefaultDynamicInvokeThunkGenerationPolicy(); MetadataManager metadataManager; if (_isReadyToRunCodeGen) { metadataManager = new ReadyToRunTableManager(typeSystemContext); } else if (supportsReflection) { metadataManager = new UsageBasedMetadataManager( compilationGroup, typeSystemContext, mdBlockingPolicy, resBlockingPolicy, _metadataLogFileName, stackTracePolicy, invokeThunkGenerationPolicy, ilProvider, metadataGenerationOptions); } else { metadataManager = new EmptyMetadataManager(typeSystemContext); } // Unless explicitly opted in at the command line, we enable scanner for retail builds by default. // We don't do this for CppCodegen and Wasm, because those codegens are behind. // We also don't do this for multifile because scanner doesn't simulate inlining (this would be // fixable by using a CompilationGroup for the scanner that has a bigger worldview, but // let's cross that bridge when we get there). bool useScanner = _useScanner || (_optimizationMode != OptimizationMode.None && !_isCppCodegen && !_isWasmCodegen && !_isReadyToRunCodeGen && !_multiFile); useScanner &= !_noScanner; builder.UseILProvider(ilProvider); ILScanResults scanResults = null; if (useScanner) { ILScannerBuilder scannerBuilder = builder.GetILScannerBuilder() .UseCompilationRoots(compilationRoots) .UseMetadataManager(metadataManager); if (_scanDgmlLogFileName != null) { scannerBuilder.UseDependencyTracking(_generateFullScanDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); } IILScanner scanner = scannerBuilder.ToILScanner(); scanResults = scanner.Scan(); if (metadataManager is UsageBasedMetadataManager usageBasedManager) { metadataManager = usageBasedManager.ToAnalysisBasedMetadataManager(); } } var logger = new Logger(Console.Out, _isVerbose); DebugInformationProvider debugInfoProvider = _enableDebugInfo ? (_ilDump == null ? new DebugInformationProvider() : new ILAssemblyGeneratingMethodDebugInfoProvider(_ilDump, new EcmaOnlyDebugInformationProvider())) : new NullDebugInformationProvider(); DependencyTrackingLevel trackingLevel = _dgmlLogFileName == null ? DependencyTrackingLevel.None : (_generateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); compilationRoots.Add(metadataManager); builder .UseBackendOptions(_codegenOptions) .UseMethodBodyFolding(_methodBodyFolding) .UseMetadataManager(metadataManager) .UseLogger(logger) .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .UseOptimizationMode(_optimizationMode) .UseDebugInfoProvider(debugInfoProvider); if (scanResults != null) { // If we have a scanner, feed the vtable analysis results to the compilation. // This could be a command line switch if we really wanted to. builder.UseVTableSliceProvider(scanResults.GetVTableLayoutInfo()); // If we have a scanner, feed the generic dictionary results to the compilation. // This could be a command line switch if we really wanted to. builder.UseGenericDictionaryLayoutProvider(scanResults.GetDictionaryLayoutInfo()); // If we feed any outputs of the scanner into the compilation, it's essential // we use scanner's devirtualization manager. It prevents optimizing codegens // from accidentally devirtualizing cases that can never happen at runtime // (e.g. devirtualizing a method on a type that never gets allocated). builder.UseDevirtualizationManager(scanResults.GetDevirtualizationManager()); } ICompilation compilation = builder.ToCompilation(); ObjectDumper dumper = _mapFileName != null ? new ObjectDumper(_mapFileName) : null; CompilationResults compilationResults = compilation.Compile(_outputFilePath, dumper); if (_exportsFile != null) { ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, _exportsFile); foreach (var compilationRoot in compilationRoots) { if (compilationRoot is ExportedMethodsRootProvider provider) { defFileWriter.AddExportedMethods(provider.ExportedMethods); } } defFileWriter.EmitExportedMethods(); } if (_dgmlLogFileName != null) { compilationResults.WriteDependencyLog(_dgmlLogFileName); } if (scanResults != null) { SimdHelper simdHelper = new SimdHelper(); if (_scanDgmlLogFileName != null) { scanResults.WriteDependencyLog(_scanDgmlLogFileName); } // If the scanner and compiler don't agree on what to compile, the outputs of the scanner might not actually be usable. // We are going to check this two ways: // 1. The methods and types generated during compilation are a subset of method and types scanned // 2. The methods and types scanned are a subset of methods and types compiled (this has a chance to hold for unoptimized builds only). // Check that methods and types generated during compilation are a subset of method and types scanned bool scanningFail = false; DiffCompilationResults(ref scanningFail, compilationResults.CompiledMethodBodies, scanResults.CompiledMethodBodies, "Methods", "compiled", "scanned", method => !(method.GetTypicalMethodDefinition() is EcmaMethod) || method.Name == "ThrowPlatformNotSupportedException"); DiffCompilationResults(ref scanningFail, compilationResults.ConstructedEETypes, scanResults.ConstructedEETypes, "EETypes", "compiled", "scanned", type => !(type.GetTypeDefinition() is EcmaType)); // If optimizations are enabled, the results will for sure not match in the other direction due to inlining, etc. // But there's at least some value in checking the scanner doesn't expand the universe too much in debug. if (_optimizationMode == OptimizationMode.None) { // Check that methods and types scanned are a subset of methods and types compiled // If we find diffs here, they're not critical, but still might be causing a Size on Disk regression. bool dummy = false; // We additionally skip methods in SIMD module because there's just too many intrisics to handle and IL scanner // doesn't expand them. They would show up as noisy diffs. DiffCompilationResults(ref dummy, scanResults.CompiledMethodBodies, compilationResults.CompiledMethodBodies, "Methods", "scanned", "compiled", method => !(method.GetTypicalMethodDefinition() is EcmaMethod) || simdHelper.IsSimdType(method.OwningType)); DiffCompilationResults(ref dummy, scanResults.ConstructedEETypes, compilationResults.ConstructedEETypes, "EETypes", "scanned", "compiled", type => !(type.GetTypeDefinition() is EcmaType)); } if (scanningFail) { throw new Exception("Scanning failure"); } } if (debugInfoProvider is IDisposable) { ((IDisposable)debugInfoProvider).Dispose(); } return(0); }
public ReadyToRunTableManager(CompilerTypeSystemContext typeSystemContext) : base(typeSystemContext) { }
public EmptyMetadataManager(CompilationModuleGroup group, CompilerTypeSystemContext typeSystemContext) : base(group, typeSystemContext) { }
public MultiFileCompilationModuleGroup(CompilerTypeSystemContext typeSystemContext, ICompilationRootProvider rootProvider) : base(typeSystemContext, rootProvider) { }
protected CompilationModuleGroup(CompilerTypeSystemContext typeSystemContext, ICompilationRootProvider rootProvider) { _typeSystemContext = typeSystemContext; _rootProvider = rootProvider; }
public CompilerGeneratedMetadataManager(CompilationModuleGroup group, CompilerTypeSystemContext typeSystemContext) : base(group, typeSystemContext) { _metadataPolicy = new GeneratedTypesAndCodeMetadataPolicy(this); }
public SingleFileCompilationModuleGroup(CompilerTypeSystemContext typeSystemContext, ICompilationRootProvider rootProvider) : base(typeSystemContext, rootProvider) { }
/// <summary> /// Constructs a new instance of <see cref="DelegateCreationInfo"/> set up to construct a delegate of type /// '<paramref name="delegateType"/>' pointing to '<paramref name="targetMethod"/>'. /// </summary> public static DelegateCreationInfo Create(TypeDesc delegateType, MethodDesc targetMethod, TypeDesc constrainedType, NodeFactory factory, bool followVirtualDispatch) { CompilerTypeSystemContext context = factory.TypeSystemContext; DefType systemDelegate = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; int paramCountTargetMethod = targetMethod.Signature.Length; if (!targetMethod.Signature.IsStatic) { paramCountTargetMethod++; } DelegateInfo delegateInfo = context.GetDelegateInfo(delegateType.GetTypeDefinition()); int paramCountDelegateClosed = delegateInfo.Signature.Length + 1; bool closed = false; if (paramCountDelegateClosed == paramCountTargetMethod) { closed = true; } else { Debug.Assert(paramCountDelegateClosed == paramCountTargetMethod + 1); } if (targetMethod.Signature.IsStatic) { MethodDesc invokeThunk; MethodDesc initMethod; if (!closed) { initMethod = systemDelegate.GetKnownMethod("InitializeOpenStaticThunk", null); invokeThunk = delegateInfo.Thunks[DelegateThunkKind.OpenStaticThunk]; } else { // Closed delegate to a static method (i.e. delegate to an extension method that locks the first parameter) invokeThunk = delegateInfo.Thunks[DelegateThunkKind.ClosedStaticThunk]; initMethod = systemDelegate.GetKnownMethod("InitializeClosedStaticThunk", null); } var instantiatedDelegateType = delegateType as InstantiatedType; if (instantiatedDelegateType != null) { invokeThunk = context.GetMethodForInstantiatedType(invokeThunk, instantiatedDelegateType); } return(new DelegateCreationInfo( factory.MethodEntrypoint(initMethod), targetMethod, constrainedType, constrainedType == null ? TargetKind.ExactCallableAddress : TargetKind.ConstrainedMethod, factory.MethodEntrypoint(invokeThunk))); } else { if (!closed) { throw new NotImplementedException("Open instance delegates"); } string initializeMethodName = "InitializeClosedInstance"; MethodDesc targetCanonMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); TargetKind kind; if (targetMethod.HasInstantiation) { if (followVirtualDispatch && targetMethod.IsVirtual) { initializeMethodName = "InitializeClosedInstanceWithGVMResolution"; kind = TargetKind.MethodHandle; } else { if (targetMethod != targetCanonMethod) { // Closed delegates to generic instance methods need to be constructed through a slow helper that // checks for the fat function pointer case (function pointer + instantiation argument in a single // pointer) and injects an invocation thunk to unwrap the fat function pointer as part of // the invocation if necessary. initializeMethodName = "InitializeClosedInstanceSlow"; } kind = TargetKind.ExactCallableAddress; } } else { if (followVirtualDispatch && targetMethod.IsVirtual) { if (targetMethod.OwningType.IsInterface) { kind = TargetKind.InterfaceDispatch; initializeMethodName = "InitializeClosedInstanceToInterface"; } else { kind = TargetKind.VTableLookup; targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); } } else { kind = TargetKind.CanonicalEntrypoint; targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); } } Debug.Assert(constrainedType == null); return(new DelegateCreationInfo( factory.MethodEntrypoint(systemDelegate.GetKnownMethod(initializeMethodName, null)), targetMethod, constrainedType, kind)); } }
private int Run(string[] args) { InitializeDefaultOptions(); ProcessCommandLine(args); if (_commandLineOptions.Help) { Console.WriteLine(_commandLineOptions.HelpText); return(1); } if (_commandLineOptions.OutputFilePath == null && !_commandLineOptions.OutNearInput) { throw new CommandLineException(SR.MissingOutputFile); } ConfigureTarget(); InstructionSetSupport instructionSetSupport = ConfigureInstructionSetSupport(); SharedGenericsMode genericsMode = SharedGenericsMode.CanonicalReferenceTypes; var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, _armelAbi ? TargetAbi.CoreRTArmel : TargetAbi.CoreRT, instructionSetSupport.GetVectorTSimdVector()); bool versionBubbleIncludesCoreLib = false; if (_commandLineOptions.InputBubble) { versionBubbleIncludesCoreLib = true; } else { if (!_commandLineOptions.SingleFileCompilation) { foreach (var inputFile in _inputFilePaths) { if (String.Compare(inputFile.Key, "System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) == 0) { versionBubbleIncludesCoreLib = true; break; } } } if (!versionBubbleIncludesCoreLib) { foreach (var inputFile in _unrootedInputFilePaths) { if (String.Compare(inputFile.Key, "System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) == 0) { versionBubbleIncludesCoreLib = true; break; } } } } // // Initialize type system context // _typeSystemContext = new ReadyToRunCompilerContext(targetDetails, genericsMode, versionBubbleIncludesCoreLib); string compositeRootPath = _commandLineOptions.CompositeRootPath; // Collections for already loaded modules Dictionary <string, string> inputFilePaths = new Dictionary <string, string>(); Dictionary <string, string> unrootedInputFilePaths = new Dictionary <string, string>(); HashSet <ModuleDesc> versionBubbleModulesHash = new HashSet <ModuleDesc>(); using (PerfEventSource.StartStopEvents.LoadingEvents()) { // // TODO: To support our pre-compiled test tree, allow input files that aren't managed assemblies since // some tests contain a mixture of both managed and native binaries. // // See: https://github.com/dotnet/corert/issues/2785 // // When we undo this this hack, replace this foreach with // typeSystemContext.InputFilePaths = inFilePaths; // foreach (var inputFile in _inputFilePaths) { try { var module = _typeSystemContext.GetModuleFromPath(inputFile.Value); _allInputFilePaths.Add(inputFile.Key, inputFile.Value); inputFilePaths.Add(inputFile.Key, inputFile.Value); _referenceableModules.Add(module); if (compositeRootPath == null) { compositeRootPath = Path.GetDirectoryName(inputFile.Value); } } catch (TypeSystemException.BadImageFormatException) { // Keep calm and carry on. } } foreach (var unrootedInputFile in _unrootedInputFilePaths) { try { var module = _typeSystemContext.GetModuleFromPath(unrootedInputFile.Value); if (!_allInputFilePaths.ContainsKey(unrootedInputFile.Key)) { _allInputFilePaths.Add(unrootedInputFile.Key, unrootedInputFile.Value); unrootedInputFilePaths.Add(unrootedInputFile.Key, unrootedInputFile.Value); _referenceableModules.Add(module); if (compositeRootPath == null) { compositeRootPath = Path.GetDirectoryName(unrootedInputFile.Value); } } } catch (TypeSystemException.BadImageFormatException) { // Keep calm and carry on. } } CheckManagedCppInputFiles(_allInputFilePaths.Values); _typeSystemContext.InputFilePaths = _allInputFilePaths; _typeSystemContext.ReferenceFilePaths = _referenceFilePaths; if (_typeSystemContext.InputFilePaths.Count == 0) { if (_commandLineOptions.InputFilePaths.Count > 0) { Console.WriteLine(SR.InputWasNotLoadable); return(2); } throw new CommandLineException(SR.NoInputFiles); } foreach (var referenceFile in _referenceFilePaths.Values) { try { EcmaModule module = _typeSystemContext.GetModuleFromPath(referenceFile); _referenceableModules.Add(module); if (_commandLineOptions.InputBubble && _inputbubblereferenceFilePaths.Count == 0) { // In large version bubble mode add reference paths to the compilation group // Consider bubble as large if no explicit bubble references were passed versionBubbleModulesHash.Add(module); } } catch { } // Ignore non-managed pe files } if (_commandLineOptions.InputBubble) { foreach (var referenceFile in _inputbubblereferenceFilePaths.Values) { try { EcmaModule module = _typeSystemContext.GetModuleFromPath(referenceFile); versionBubbleModulesHash.Add(module); } catch { } // Ignore non-managed pe files } } } string systemModuleName = _commandLineOptions.SystemModule ?? DefaultSystemModule; _typeSystemContext.SetSystemModule((EcmaModule)_typeSystemContext.GetModuleForSimpleName(systemModuleName)); CompilerTypeSystemContext typeSystemContext = _typeSystemContext; if (_commandLineOptions.SingleFileCompilation) { var singleCompilationInputFilePaths = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (var inputFile in inputFilePaths) { var singleCompilationVersionBubbleModulesHash = new HashSet <ModuleDesc>(versionBubbleModulesHash); singleCompilationInputFilePaths.Clear(); singleCompilationInputFilePaths.Add(inputFile.Key, inputFile.Value); typeSystemContext.InputFilePaths = singleCompilationInputFilePaths; if (!_commandLineOptions.InputBubble) { bool singleCompilationVersionBubbleIncludesCoreLib = versionBubbleIncludesCoreLib || (String.Compare(inputFile.Key, "System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) == 0); typeSystemContext = new ReadyToRunCompilerContext(targetDetails, genericsMode, singleCompilationVersionBubbleIncludesCoreLib, _typeSystemContext); typeSystemContext.SetSystemModule((EcmaModule)typeSystemContext.GetModuleForSimpleName(systemModuleName)); } RunSingleCompilation(singleCompilationInputFilePaths, instructionSetSupport, compositeRootPath, unrootedInputFilePaths, singleCompilationVersionBubbleModulesHash, typeSystemContext); } } else { RunSingleCompilation(inputFilePaths, instructionSetSupport, compositeRootPath, unrootedInputFilePaths, versionBubbleModulesHash, typeSystemContext); } return(0); }
public RyuJitCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group) : base(new RyuJitNodeFactory(context, group)) { }
private MethodDesc CheckAndParseSingleMethodModeArguments(CompilerTypeSystemContext context) { if (_commandLineOptions.SingleMethodName == null && _commandLineOptions.SingleMethodTypeName == null && _commandLineOptions.SingleMethodGenericArg == null) { return(null); } if (_commandLineOptions.SingleMethodName == null || _commandLineOptions.SingleMethodTypeName == null) { throw new CommandLineException(SR.TypeAndMethodNameNeeded); } TypeDesc owningType = FindType(context, _commandLineOptions.SingleMethodTypeName); // TODO: allow specifying signature to distinguish overloads MethodDesc method = null; bool printMethodList = false; int curIndex = 0; foreach (var searchMethod in owningType.GetMethods()) { if (searchMethod.Name != _commandLineOptions.SingleMethodName) { continue; } curIndex++; if (_commandLineOptions.SingleMethodIndex != 0) { if (curIndex == _commandLineOptions.SingleMethodIndex) { method = searchMethod; break; } } else { if (method == null) { method = searchMethod; } else { printMethodList = true; } } } if (printMethodList) { curIndex = 0; foreach (var searchMethod in owningType.GetMethods()) { if (searchMethod.Name != _commandLineOptions.SingleMethodName) { continue; } curIndex++; Console.WriteLine($"{curIndex} - {searchMethod}"); } throw new CommandLineException(SR.SingleMethodIndexNeeded); } if (method == null) { throw new CommandLineException(string.Format(SR.MethodNotFoundOnType, _commandLineOptions.SingleMethodName, _commandLineOptions.SingleMethodTypeName)); } if (method.HasInstantiation != (_commandLineOptions.SingleMethodGenericArg != null) || (method.HasInstantiation && (method.Instantiation.Length != _commandLineOptions.SingleMethodGenericArg.Count))) { throw new CommandLineException( string.Format(SR.GenericArgCountMismatch, method.Instantiation.Length, _commandLineOptions.SingleMethodName, _commandLineOptions.SingleMethodTypeName)); } if (method.HasInstantiation) { List <TypeDesc> genericArguments = new List <TypeDesc>(); foreach (var argString in _commandLineOptions.SingleMethodGenericArg) { genericArguments.Add(FindType(context, argString)); } method = method.MakeInstantiatedMethod(genericArguments.ToArray()); } return(method); }
protected CompilationModuleGroup(CompilerTypeSystemContext typeSystemContext) { _typeSystemContext = typeSystemContext; }
public MetadataManager(CompilerTypeSystemContext context) { _typeSystemContext = context; }
private TypeDesc FindType(CompilerTypeSystemContext context, string typeName) { ModuleDesc systemModule = context.SystemModule; TypeDesc foundType = systemModule.GetTypeByCustomAttributeTypeName(typeName); if (foundType == null) throw new CommandLineException($"Type '{typeName}' not found"); TypeDesc classLibCanon = systemModule.GetType("System", "__Canon", false); TypeDesc classLibUniCanon = systemModule.GetType("System", "__UniversalCanon", false); return foundType.ReplaceTypesInConstructionOfType( new TypeDesc[] { classLibCanon, classLibUniCanon }, new TypeDesc[] { context.CanonType, context.UniversalCanonType }); }
public ApplicationAssemblyRootProvider(CompilerTypeSystemContext context) { _context = context; }
public MetadataManager(CompilationModuleGroup compilationModuleGroup, CompilerTypeSystemContext typeSystemContext) { _compilationModuleGroup = compilationModuleGroup; _typeSystemContext = typeSystemContext; }
private int Run(string[] args) { InitializeDefaultOptions(); ArgumentSyntax syntax = ParseCommandLine(args); if (_help) { Help(syntax.GetHelpText()); return 1; } if (_inputFilePaths.Count == 0) throw new CommandLineException("No input files specified"); if (_outputFilePath == null) throw new CommandLineException("Output filename must be specified (/out <file>)"); // // Initialize type system context // SharedGenericsMode genericsMode = _useSharedGenerics ? SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled; var typeSystemContext = new CompilerTypeSystemContext(new TargetDetails(_targetArchitecture, _targetOS), genericsMode); typeSystemContext.InputFilePaths = _inputFilePaths; typeSystemContext.ReferenceFilePaths = _referenceFilePaths; typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName)); // // Initialize compilation group and compilation roots // // Single method mode? MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext); CompilationModuleGroup compilationGroup; List<ICompilationRootProvider> compilationRoots = new List<ICompilationRootProvider>(); if (singleMethod != null) { // Compiling just a single method compilationGroup = new SingleMethodCompilationModuleGroup(singleMethod); compilationRoots.Add(new SingleMethodRootProvider(singleMethod)); } else { // Either single file, or multifile library, or multifile consumption. EcmaModule entrypointModule = null; foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (module.PEReader.PEHeaders.IsExe) { if (entrypointModule != null) throw new Exception("Multiple EXE modules"); entrypointModule = module; } compilationRoots.Add(new ExportedMethodsRootProvider(module)); } if (entrypointModule != null) { compilationRoots.Add(new MainMethodRootProvider(entrypointModule)); } if (_multiFile) { List<EcmaModule> inputModules = new List<EcmaModule>(); foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (entrypointModule == null) { // This is a multifile production build - we need to root all methods compilationRoots.Add(new LibraryRootProvider(module)); } inputModules.Add(module); } compilationGroup = new MultiFileCompilationModuleGroup(inputModules); } else { if (entrypointModule == null) throw new Exception("No entrypoint module"); compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule)); // System.Private.Reflection.Execution needs to establish a communication channel with System.Private.CoreLib // at process startup. This is done through an eager constructor that calls into CoreLib and passes it // a callback object. // // Since CoreLib cannot reference anything, the type and it's eager constructor won't be added to the compilation // unless we explictly add it. var refExec = typeSystemContext.GetModuleForSimpleName("System.Private.Reflection.Execution", false); if (refExec != null) { var exec = refExec.GetType("Internal.Reflection.Execution", "ReflectionExecution"); compilationRoots.Add(new SingleMethodRootProvider(exec.GetStaticConstructor())); } compilationGroup = new SingleFileCompilationModuleGroup(); } foreach (var rdXmlFilePath in _rdXmlFilePaths) { compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath)); } } // // Compile // CompilationBuilder builder; if (_isCppCodegen) builder = new CppCodegenCompilationBuilder(typeSystemContext, compilationGroup); else builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup); var logger = _isVerbose ? new Logger(Console.Out, true) : Logger.Null; DependencyTrackingLevel trackingLevel = _dgmlLogFileName == null ? DependencyTrackingLevel.None : (_generateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); ICompilation compilation = builder .UseBackendOptions(_codegenOptions) .UseLogger(logger) .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .ToCompilation(); compilation.Compile(_outputFilePath); if (_dgmlLogFileName != null) compilation.WriteDependencyLog(_dgmlLogFileName); return 0; }
public SingleMethodCompilationModuleGroup(CompilerTypeSystemContext typeSystemContext, MethodDesc method) : base(typeSystemContext) { _method = method; }
private int Run(string[] args) { InitializeDefaultOptions(); ArgumentSyntax syntax = ParseCommandLine(args); if (_help) { Help(syntax.GetHelpText()); return 1; } if (_inputFilePaths.Count == 0) throw new CommandLineException("No input files specified"); if (_options.OutputFilePath == null) throw new CommandLineException("Output filename must be specified (/out <file>)"); // // Initialize type system context // SharedGenericsMode genericsMode = _useSharedGenerics ? SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled; var typeSystemContext = new CompilerTypeSystemContext(new TargetDetails(_targetArchitecture, _targetOS), genericsMode); typeSystemContext.InputFilePaths = _inputFilePaths; typeSystemContext.ReferenceFilePaths = _referenceFilePaths; typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName)); // // Initialize compilation group // // Single method mode? MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext); CompilationModuleGroup compilationGroup; if (singleMethod != null) { compilationGroup = new SingleMethodCompilationModuleGroup(typeSystemContext, singleMethod); } else if (_multiFile) { compilationGroup = new MultiFileCompilationModuleGroup(typeSystemContext); } else { compilationGroup = new SingleFileCompilationModuleGroup(typeSystemContext); } // // Compile // Compilation compilation = new Compilation(_options, typeSystemContext, compilationGroup); compilation.Log = _options.Verbose ? Console.Out : TextWriter.Null; compilation.Compile(); return 0; }
public ReadyToRunCompilerContext(TargetDetails details, SharedGenericsMode genericsMode, bool bubbleIncludesCorelib, CompilerTypeSystemContext oldTypeSystemContext = null) : base(details, genericsMode) { _r2rFieldLayoutAlgorithm = new ReadyToRunMetadataFieldLayoutAlgorithm(); _systemObjectFieldLayoutAlgorithm = new SystemObjectFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm); // Only the Arm64 JIT respects the OS rules for vector type abi currently _vectorFieldLayoutAlgorithm = new VectorFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm, (details.Architecture == TargetArchitecture.ARM64) ? true : bubbleIncludesCorelib); string matchingVectorType = "Unknown"; if (details.MaximumSimdVectorLength == SimdVectorLength.Vector128Bit) { matchingVectorType = "Vector128`1"; } else if (details.MaximumSimdVectorLength == SimdVectorLength.Vector256Bit) { matchingVectorType = "Vector256`1"; } // No architecture has completely stable handling of Vector<T> in the abi (Arm64 may change to SVE) _vectorOfTFieldLayoutAlgorithm = new VectorOfTFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm, _vectorFieldLayoutAlgorithm, matchingVectorType, bubbleIncludesCorelib); // Int128 and UInt128 should be ABI stable on all currently supported platforms _int128FieldLayoutAlgorithm = new Int128FieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm); if (oldTypeSystemContext != null) { InheritOpenModules(oldTypeSystemContext); } }
private MethodDesc CheckAndParseSingleMethodModeArguments(CompilerTypeSystemContext context) { if (_singleMethodName == null && _singleMethodTypeName == null && _singleMethodGenericArgs == null) return null; if (_singleMethodName == null || _singleMethodTypeName == null) throw new CommandLineException("Both method name and type name are required parameters for single method mode"); TypeDesc owningType = FindType(context, _singleMethodTypeName); // TODO: allow specifying signature to distinguish overloads MethodDesc method = owningType.GetMethod(_singleMethodName, null); if (method == null) throw new CommandLineException($"Method '{_singleMethodName}' not found in '{_singleMethodTypeName}'"); if (method.HasInstantiation != (_singleMethodGenericArgs != null) || (method.HasInstantiation && (method.Instantiation.Length != _singleMethodGenericArgs.Count))) { throw new CommandLineException( $"Expected {method.Instantiation.Length} generic arguments for method '{_singleMethodName}' on type '{_singleMethodTypeName}'"); } if (method.HasInstantiation) { List<TypeDesc> genericArguments = new List<TypeDesc>(); foreach (var argString in _singleMethodGenericArgs) genericArguments.Add(FindType(context, argString)); method = method.MakeInstantiatedMethod(genericArguments.ToArray()); } return method; }
private static InteropStubManager NewEmptyInteropStubManager(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup) { // On Project N, the compiler doesn't generate the interop code on the fly return(new EmptyInteropStubManager(compilationModuleGroup, context, null)); }
private int Run(string[] args) { ParseCommandLine(args); if (_help) { Help(); return 1; } if (_inputFilePaths.Count == 0) throw new CommandLineException("No input files specified"); if (_outputPath == null) throw new CommandLineException("Output filename must be specified (/out <file>)"); TargetOS targetOS; #if FXCORE // We could offer this as a command line option, but then we also need to // load a different RyuJIT, so this is a future nice to have... if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) targetOS = TargetOS.Windows; else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) targetOS = TargetOS.Linux; else throw new NotImplementedException(); #else targetOS = TargetOS.Windows; #endif _compilerTypeSystemContext = new CompilerTypeSystemContext(new TargetDetails(TargetArchitecture.X64, targetOS)); _compilerTypeSystemContext.InputFilePaths = _inputFilePaths; _compilerTypeSystemContext.ReferenceFilePaths = _referenceFilePaths; _compilerTypeSystemContext.SetSystemModule(_compilerTypeSystemContext.GetModuleForSimpleName(_systemModuleName)); // For now, we can do single file compilation only // TODO: Multifile SingleFileCompilation(); return 0; }
private int Run(string[] args) { InitializeDefaultOptions(); ArgumentSyntax syntax = ParseCommandLine(args); if (_help) { Help(syntax.GetHelpText()); return(1); } if (_outputFilePath == null) { throw new CommandLineException("Output filename must be specified (/out <file>)"); } // // Set target Architecture and OS // if (_targetArchitectureStr != null) { if (_targetArchitectureStr.Equals("x86", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.X86; } else if (_targetArchitectureStr.Equals("x64", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.X64; } else if (_targetArchitectureStr.Equals("arm", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM; } else if (_targetArchitectureStr.Equals("armel", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM; } else if (_targetArchitectureStr.Equals("arm64", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.ARM64; } else if (_targetArchitectureStr.Equals("wasm", StringComparison.OrdinalIgnoreCase)) { _targetArchitecture = TargetArchitecture.Wasm32; _isWasmCodegen = true; } else { throw new CommandLineException("Target architecture is not supported"); } } if (_targetOSStr != null) { if (_targetOSStr.Equals("windows", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.Windows; } else if (_targetOSStr.Equals("linux", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.Linux; } else if (_targetOSStr.Equals("osx", StringComparison.OrdinalIgnoreCase)) { _targetOS = TargetOS.OSX; } else { throw new CommandLineException("Target OS is not supported"); } } if (_isWasmCodegen) { _targetArchitecture = TargetArchitecture.Wasm32; } InstructionSetSupportBuilder instructionSetSupportBuilder = new InstructionSetSupportBuilder(_targetArchitecture); // The runtime expects certain baselines that the codegen can assume as well. if ((_targetArchitecture == TargetArchitecture.X86) || (_targetArchitecture == TargetArchitecture.X64)) { instructionSetSupportBuilder.AddSupportedInstructionSet("sse"); instructionSetSupportBuilder.AddSupportedInstructionSet("sse2"); } else if (_targetArchitecture == TargetArchitecture.ARM64) { instructionSetSupportBuilder.AddSupportedInstructionSet("base"); instructionSetSupportBuilder.AddSupportedInstructionSet("neon"); } if (_instructionSet != null) { List <string> instructionSetParams = new List <string>(); // Normalize instruction set format to include implied +. string[] instructionSetParamsInput = _instructionSet.Split(','); for (int i = 0; i < instructionSetParamsInput.Length; i++) { string instructionSet = instructionSetParamsInput[i]; if (String.IsNullOrEmpty(instructionSet)) { throw new CommandLineException("Instruction set must not be empty"); } char firstChar = instructionSet[0]; if ((firstChar != '+') && (firstChar != '-')) { instructionSet = "+" + instructionSet; } instructionSetParams.Add(instructionSet); } Dictionary <string, bool> instructionSetSpecification = new Dictionary <string, bool>(); foreach (string instructionSetSpecifier in instructionSetParams) { string instructionSet = instructionSetSpecifier.Substring(1, instructionSetSpecifier.Length - 1); bool enabled = instructionSetSpecifier[0] == '+' ? true : false; if (enabled) { if (!instructionSetSupportBuilder.AddSupportedInstructionSet(instructionSet)) { throw new CommandLineException($"Unrecognized instruction set '{instructionSet}'"); } } else { if (!instructionSetSupportBuilder.RemoveInstructionSetSupport(instructionSet)) { throw new CommandLineException($"Unrecognized instruction set '{instructionSet}'"); } } } } instructionSetSupportBuilder.ComputeInstructionSetFlags(out var supportedInstructionSet, out var unsupportedInstructionSet, (string specifiedInstructionSet, string impliedInstructionSet) => throw new CommandLineException(String.Format("Unsupported combination of instruction sets: {0}/{1}", specifiedInstructionSet, impliedInstructionSet))); InstructionSetSupportBuilder optimisticInstructionSetSupportBuilder = new InstructionSetSupportBuilder(_targetArchitecture); // Optimistically assume some instruction sets are present. if ((_targetArchitecture == TargetArchitecture.X86) || (_targetArchitecture == TargetArchitecture.X64)) { // We set these hardware features as enabled always, as most // of hardware in the wild supports them. Note that we do not indicate support for AVX, or any other // instruction set which uses the VEX encodings as the presence of those makes otherwise acceptable // code be unusable on hardware which does not support VEX encodings, as well as emulators that do not // support AVX instructions. // // The compiler is able to generate runtime IsSupported checks for the following instruction sets. optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("ssse3"); optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("aes"); optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("pclmul"); optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("lzcnt"); // NOTE: we don't optimistically enable SSE4.1/SSE4.2 because RyuJIT can opportunistically use // these instructions in e.g. optimizing Math.Round or Vector<T> operations without IsSupported guards. // If SSE4.2 was enabled, we can also opportunistically enable POPCNT Debug.Assert(InstructionSet.X64_SSE42 == InstructionSet.X86_SSE42); if (supportedInstructionSet.HasInstructionSet(InstructionSet.X64_SSE42)) { optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("popcnt"); } // If AVX was enabled, we can opportunistically enable FMA/BMI Debug.Assert(InstructionSet.X64_AVX == InstructionSet.X86_AVX); if (supportedInstructionSet.HasInstructionSet(InstructionSet.X64_AVX)) { optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("fma"); optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("bmi1"); optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("bmi2"); } } optimisticInstructionSetSupportBuilder.ComputeInstructionSetFlags(out var optimisticInstructionSet, out _, (string specifiedInstructionSet, string impliedInstructionSet) => throw new NotSupportedException()); optimisticInstructionSet.Remove(unsupportedInstructionSet); optimisticInstructionSet.Add(supportedInstructionSet); var instructionSetSupport = new InstructionSetSupport(supportedInstructionSet, unsupportedInstructionSet, optimisticInstructionSet, InstructionSetSupportBuilder.GetNonSpecifiableInstructionSetsForArch(_targetArchitecture), _targetArchitecture); bool supportsReflection = !_disableReflection && _systemModuleName == DefaultSystemModule; // // Initialize type system context // SharedGenericsMode genericsMode = SharedGenericsMode.CanonicalReferenceTypes; var simdVectorLength = (_isCppCodegen || _isWasmCodegen) ? SimdVectorLength.None : instructionSetSupport.GetVectorTSimdVector(); var targetAbi = _isCppCodegen ? TargetAbi.CppCodegen : TargetAbi.CoreRT; var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, targetAbi, simdVectorLength); CompilerTypeSystemContext typeSystemContext = new CompilerTypeSystemContext(targetDetails, genericsMode, supportsReflection ? DelegateFeature.All : 0); // // TODO: To support our pre-compiled test tree, allow input files that aren't managed assemblies since // some tests contain a mixture of both managed and native binaries. // // See: https://github.com/dotnet/corert/issues/2785 // // When we undo this this hack, replace this foreach with // typeSystemContext.InputFilePaths = _inputFilePaths; // Dictionary <string, string> inputFilePaths = new Dictionary <string, string>(); foreach (var inputFile in _inputFilePaths) { try { var module = typeSystemContext.GetModuleFromPath(inputFile.Value); inputFilePaths.Add(inputFile.Key, inputFile.Value); } catch (TypeSystemException.BadImageFormatException) { // Keep calm and carry on. } } typeSystemContext.InputFilePaths = inputFilePaths; typeSystemContext.ReferenceFilePaths = _referenceFilePaths; if (!typeSystemContext.InputFilePaths.ContainsKey(_systemModuleName) && !typeSystemContext.ReferenceFilePaths.ContainsKey(_systemModuleName)) { throw new CommandLineException($"System module {_systemModuleName} does not exists. Make sure that you specify --systemmodule"); } typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(_systemModuleName)); if (typeSystemContext.InputFilePaths.Count == 0) { throw new CommandLineException("No input files specified"); } // // Initialize compilation group and compilation roots // // Single method mode? MethodDesc singleMethod = CheckAndParseSingleMethodModeArguments(typeSystemContext); CompilationModuleGroup compilationGroup; List <ICompilationRootProvider> compilationRoots = new List <ICompilationRootProvider>(); if (singleMethod != null) { // Compiling just a single method compilationGroup = new SingleMethodCompilationModuleGroup(singleMethod); compilationRoots.Add(new SingleMethodRootProvider(singleMethod)); } else { // Either single file, or multifile library, or multifile consumption. EcmaModule entrypointModule = null; bool systemModuleIsInputModule = false; foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (module.PEReader.PEHeaders.IsExe) { if (entrypointModule != null) { throw new Exception("Multiple EXE modules"); } entrypointModule = module; } if (module == typeSystemContext.SystemModule) { systemModuleIsInputModule = true; } compilationRoots.Add(new ExportedMethodsRootProvider(module)); } if (entrypointModule != null) { compilationRoots.Add(new MainMethodRootProvider(entrypointModule, CreateInitializerList(typeSystemContext))); compilationRoots.Add(new RuntimeConfigurationRootProvider(_runtimeOptions)); compilationRoots.Add(new ExpectedIsaFeaturesRootProvider(instructionSetSupport)); } if (_multiFile) { List <EcmaModule> inputModules = new List <EcmaModule>(); foreach (var inputFile in typeSystemContext.InputFilePaths) { EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); if (entrypointModule == null) { // This is a multifile production build - we need to root all methods compilationRoots.Add(new LibraryRootProvider(module)); } inputModules.Add(module); } compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules); } else { if (entrypointModule == null && !_nativeLib) { throw new Exception("No entrypoint module"); } if (!systemModuleIsInputModule) { compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule)); } compilationGroup = new SingleFileCompilationModuleGroup(); } if (_nativeLib) { // Set owning module of generated native library startup method to compiler generated module, // to ensure the startup method is included in the object file during multimodule mode build compilationRoots.Add(new NativeLibraryInitializerRootProvider(typeSystemContext.GeneratedAssembly, CreateInitializerList(typeSystemContext))); compilationRoots.Add(new RuntimeConfigurationRootProvider(_runtimeOptions)); compilationRoots.Add(new ExpectedIsaFeaturesRootProvider(instructionSetSupport)); } if (_rdXmlFilePaths.Count > 0) { Console.WriteLine("Warning: RD.XML processing will change before release (https://github.com/dotnet/corert/issues/5001)"); } foreach (var rdXmlFilePath in _rdXmlFilePaths) { compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath)); } } // // Compile // CompilationBuilder builder; if (_isWasmCodegen) { builder = new WebAssemblyCodegenCompilationBuilder(typeSystemContext, compilationGroup); } else if (_isCppCodegen) { builder = new CppCodegenCompilationBuilder(typeSystemContext, compilationGroup); } else { builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup); } string compilationUnitPrefix = _multiFile ? System.IO.Path.GetFileNameWithoutExtension(_outputFilePath) : ""; builder.UseCompilationUnitPrefix(compilationUnitPrefix); PInvokeILEmitterConfiguration pinvokePolicy; if (!_isCppCodegen && !_isWasmCodegen) { pinvokePolicy = new ConfigurablePInvokePolicy(typeSystemContext.Target); } else { pinvokePolicy = new DirectPInvokePolicy(); } RemovedFeature removedFeatures = 0; foreach (string feature in _removedFeatures) { if (feature == "EventSource") { removedFeatures |= RemovedFeature.Etw; } else if (feature == "FrameworkStrings") { removedFeatures |= RemovedFeature.FrameworkResources; } else if (feature == "Globalization") { removedFeatures |= RemovedFeature.Globalization; } else if (feature == "Comparers") { removedFeatures |= RemovedFeature.Comparers; } else if (feature == "SerializationGuard") { removedFeatures |= RemovedFeature.SerializationGuard; } else if (feature == "XmlNonFileStream") { removedFeatures |= RemovedFeature.XmlDownloadNonFileStream; } } ILProvider ilProvider = new CoreRTILProvider(); if (removedFeatures != 0) { ilProvider = new RemovingILProvider(ilProvider, removedFeatures); } var stackTracePolicy = _emitStackTraceData ? (StackTraceEmissionPolicy) new EcmaMethodStackTraceEmissionPolicy() : new NoStackTraceEmissionPolicy(); MetadataBlockingPolicy mdBlockingPolicy; ManifestResourceBlockingPolicy resBlockingPolicy; UsageBasedMetadataGenerationOptions metadataGenerationOptions = UsageBasedMetadataGenerationOptions.IteropILScanning; if (supportsReflection) { mdBlockingPolicy = _noMetadataBlocking ? (MetadataBlockingPolicy) new NoMetadataBlockingPolicy() : new BlockedInternalsBlockingPolicy(typeSystemContext); resBlockingPolicy = (removedFeatures & RemovedFeature.FrameworkResources) != 0 ? new FrameworkStringResourceBlockingPolicy() : (ManifestResourceBlockingPolicy) new NoManifestResourceBlockingPolicy(); metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic; if (_completeTypesMetadata) { metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.CompleteTypesOnly; } if (_scanReflection) { metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.ReflectionILScanning; } if (_rootAllApplicationAssemblies) { metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.FullUserAssemblyRooting; } } else { mdBlockingPolicy = new FullyBlockedMetadataBlockingPolicy(); resBlockingPolicy = new FullyBlockedManifestResourceBlockingPolicy(); } DynamicInvokeThunkGenerationPolicy invokeThunkGenerationPolicy = new DefaultDynamicInvokeThunkGenerationPolicy(); MetadataManager metadataManager = new UsageBasedMetadataManager( compilationGroup, typeSystemContext, mdBlockingPolicy, resBlockingPolicy, _metadataLogFileName, stackTracePolicy, invokeThunkGenerationPolicy, ilProvider, metadataGenerationOptions); InteropStateManager interopStateManager = new InteropStateManager(typeSystemContext.GeneratedAssembly); InteropStubManager interopStubManager = new UsageBasedInteropStubManager(interopStateManager, pinvokePolicy); // Unless explicitly opted in at the command line, we enable scanner for retail builds by default. // We don't do this for CppCodegen and Wasm, because those codegens are behind. // We also don't do this for multifile because scanner doesn't simulate inlining (this would be // fixable by using a CompilationGroup for the scanner that has a bigger worldview, but // let's cross that bridge when we get there). bool useScanner = _useScanner || (_optimizationMode != OptimizationMode.None && !_isCppCodegen && !_isWasmCodegen && !_multiFile); useScanner &= !_noScanner; builder.UseILProvider(ilProvider); ILScanResults scanResults = null; if (useScanner) { ILScannerBuilder scannerBuilder = builder.GetILScannerBuilder() .UseCompilationRoots(compilationRoots) .UseMetadataManager(metadataManager) .UseSingleThread(enable: _singleThreaded) .UseInteropStubManager(interopStubManager); if (_scanDgmlLogFileName != null) { scannerBuilder.UseDependencyTracking(_generateFullScanDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); } IILScanner scanner = scannerBuilder.ToILScanner(); scanResults = scanner.Scan(); metadataManager = ((UsageBasedMetadataManager)metadataManager).ToAnalysisBasedMetadataManager(); interopStubManager = scanResults.GetInteropStubManager(interopStateManager, pinvokePolicy); } var logger = new Logger(Console.Out, _isVerbose); DebugInformationProvider debugInfoProvider = _enableDebugInfo ? (_ilDump == null ? new DebugInformationProvider() : new ILAssemblyGeneratingMethodDebugInfoProvider(_ilDump, new EcmaOnlyDebugInformationProvider())) : new NullDebugInformationProvider(); DependencyTrackingLevel trackingLevel = _dgmlLogFileName == null ? DependencyTrackingLevel.None : (_generateFullDgmlLog ? DependencyTrackingLevel.All : DependencyTrackingLevel.First); compilationRoots.Add(metadataManager); compilationRoots.Add(interopStubManager); builder .UseInstructionSetSupport(instructionSetSupport) .UseBackendOptions(_codegenOptions) .UseMethodBodyFolding(enable: _methodBodyFolding) .UseSingleThread(enable: _singleThreaded) .UseMetadataManager(metadataManager) .UseInteropStubManager(interopStubManager) .UseLogger(logger) .UseDependencyTracking(trackingLevel) .UseCompilationRoots(compilationRoots) .UseOptimizationMode(_optimizationMode) .UseDebugInfoProvider(debugInfoProvider); if (scanResults != null) { // If we have a scanner, feed the vtable analysis results to the compilation. // This could be a command line switch if we really wanted to. builder.UseVTableSliceProvider(scanResults.GetVTableLayoutInfo()); // If we have a scanner, feed the generic dictionary results to the compilation. // This could be a command line switch if we really wanted to. builder.UseGenericDictionaryLayoutProvider(scanResults.GetDictionaryLayoutInfo()); // If we feed any outputs of the scanner into the compilation, it's essential // we use scanner's devirtualization manager. It prevents optimizing codegens // from accidentally devirtualizing cases that can never happen at runtime // (e.g. devirtualizing a method on a type that never gets allocated). builder.UseDevirtualizationManager(scanResults.GetDevirtualizationManager()); } ICompilation compilation = builder.ToCompilation(); ObjectDumper dumper = _mapFileName != null ? new ObjectDumper(_mapFileName) : null; CompilationResults compilationResults = compilation.Compile(_outputFilePath, dumper); if (_exportsFile != null) { ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, _exportsFile); foreach (var compilationRoot in compilationRoots) { if (compilationRoot is ExportedMethodsRootProvider provider) { defFileWriter.AddExportedMethods(provider.ExportedMethods); } } defFileWriter.EmitExportedMethods(); } if (_dgmlLogFileName != null) { compilationResults.WriteDependencyLog(_dgmlLogFileName); } if (scanResults != null) { if (_scanDgmlLogFileName != null) { scanResults.WriteDependencyLog(_scanDgmlLogFileName); } // If the scanner and compiler don't agree on what to compile, the outputs of the scanner might not actually be usable. // We are going to check this two ways: // 1. The methods and types generated during compilation are a subset of method and types scanned // 2. The methods and types scanned are a subset of methods and types compiled (this has a chance to hold for unoptimized builds only). // Check that methods and types generated during compilation are a subset of method and types scanned bool scanningFail = false; DiffCompilationResults(ref scanningFail, compilationResults.CompiledMethodBodies, scanResults.CompiledMethodBodies, "Methods", "compiled", "scanned", method => !(method.GetTypicalMethodDefinition() is EcmaMethod) || method.Name == "ThrowPlatformNotSupportedException" || method.Name == "ThrowArgumentOutOfRangeException"); DiffCompilationResults(ref scanningFail, compilationResults.ConstructedEETypes, scanResults.ConstructedEETypes, "EETypes", "compiled", "scanned", type => !(type.GetTypeDefinition() is EcmaType)); // If optimizations are enabled, the results will for sure not match in the other direction due to inlining, etc. // But there's at least some value in checking the scanner doesn't expand the universe too much in debug. if (_optimizationMode == OptimizationMode.None) { // Check that methods and types scanned are a subset of methods and types compiled // If we find diffs here, they're not critical, but still might be causing a Size on Disk regression. bool dummy = false; // We additionally skip methods in SIMD module because there's just too many intrisics to handle and IL scanner // doesn't expand them. They would show up as noisy diffs. DiffCompilationResults(ref dummy, scanResults.CompiledMethodBodies, compilationResults.CompiledMethodBodies, "Methods", "scanned", "compiled", method => !(method.GetTypicalMethodDefinition() is EcmaMethod) || method.OwningType.IsIntrinsic); DiffCompilationResults(ref dummy, scanResults.ConstructedEETypes, compilationResults.ConstructedEETypes, "EETypes", "scanned", "compiled", type => !(type.GetTypeDefinition() is EcmaType)); } if (scanningFail) { throw new Exception("Scanning failure"); } } if (debugInfoProvider is IDisposable) { ((IDisposable)debugInfoProvider).Dispose(); } return(0); }
public CppCodegenCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group) : base(context, group, new CoreRTNameMangler(new CppNodeMangler(), true)) { }
public MetadataManager(CompilerTypeSystemContext typeSystemContext, MetadataBlockingPolicy blockingPolicy) { _typeSystemContext = typeSystemContext; _blockingPolicy = blockingPolicy; }
private TypeDesc FindType(CompilerTypeSystemContext context, string typeName) { TypeDesc foundType = context.SystemModule.GetTypeByCustomAttributeTypeName(typeName); if (foundType == null) throw new CommandLineException($"Type '{typeName}' not found"); return foundType; }