Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2015-12-27 11:23:48 +0300
committerJan Kotas <jkotas@microsoft.com>2015-12-27 11:24:57 +0300
commite264fcb9c69a6671c4d455b1fa12675b97d9a3e1 (patch)
tree0516086d3e27613f8803e24ab3c3133fa465dc96 /src/ILCompiler
parentbf8670422b294df760e54639c68a40b738ab4eda (diff)
Improve performance of MethodIL provider
- Explicitly use memory mapped files for Ecma metadata reader. System.Reflection.Metadata has heuristic that tries to save virtual address space. This heuristic does not work well for us since it can make IL access very slow (call to OS for each method IL query). Explicitly using memory mapped files gives us reliably the desired performance characteristics. - Implement caching in MethodILProvider. - Refactor command line parsing - move TypeSystemContext instantiation from the driver .exe into the compiler These performance improvements bring hello world native compilation from multiple seconds back to sub second range (with release build of RyuJIT and NGened compiler).
Diffstat (limited to 'src/ILCompiler')
-rw-r--r--src/ILCompiler/desktop/project.json1
-rw-r--r--src/ILCompiler/src/Program.cs111
-rw-r--r--src/ILCompiler/src/project.json3
3 files changed, 42 insertions, 73 deletions
diff --git a/src/ILCompiler/desktop/project.json b/src/ILCompiler/desktop/project.json
index f12cfd123..b9a3083ec 100644
--- a/src/ILCompiler/desktop/project.json
+++ b/src/ILCompiler/desktop/project.json
@@ -6,6 +6,7 @@
"System.Diagnostics.Debug": "4.0.10",
"System.IO": "4.0.10",
"System.IO.FileSystem": "4.0.0",
+ "System.IO.MemoryMappedFiles": "4.0.0-beta-23419",
"System.Collections": "4.0.10",
"System.Text.Encoding": "4.0.10",
"System.Runtime.InteropServices": "4.0.20",
diff --git a/src/ILCompiler/src/Program.cs b/src/ILCompiler/src/Program.cs
index f9c6a206a..d91e44bfc 100644
--- a/src/ILCompiler/src/Program.cs
+++ b/src/ILCompiler/src/Program.cs
@@ -5,11 +5,9 @@ using System;
using System.IO;
using System.Collections.Generic;
using System.Reflection;
-using System.Reflection.Metadata.Ecma335;
using System.Runtime.InteropServices;
using Internal.TypeSystem;
-using Internal.TypeSystem.Ecma;
using Internal.CommandLine;
@@ -17,18 +15,12 @@ namespace ILCompiler
{
internal class Program
{
- private bool _help;
-
- private string _outputPath;
+ private CompilationOptions _options;
private Dictionary<string, string> _inputFilePaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private Dictionary<string, string> _referenceFilePaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- private string _systemModuleName = "System.Private.CoreLib";
-
- private CompilationOptions _options;
-
- private CompilerTypeSystemContext _compilerTypeSystemContext;
+ private bool _help;
private Program()
{
@@ -40,11 +32,38 @@ namespace ILCompiler
Console.WriteLine();
Console.WriteLine("-help Display this usage message (Short form: -?)");
Console.WriteLine("-out Specify output file name");
- Console.WriteLine("-dgmllog Dump dgml log of dependency graph to specified file");
- Console.WriteLine("-fulllog Generate full dependency log graph");
Console.WriteLine("-reference Reference metadata from the specified assembly (Short form: -r)");
}
+ private void InitializeDefaultOptions()
+ {
+ _options = new CompilationOptions();
+
+ _options.InputFilePaths = _inputFilePaths;
+ _options.ReferenceFilePaths = _referenceFilePaths;
+
+ _options.SystemModuleName = "System.Private.CoreLib";
+
+#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))
+ _options.TargetOS = TargetOS.Windows;
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ _options.TargetOS = TargetOS.Linux;
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ _options.TargetOS = TargetOS.OSX;
+ else
+ throw new NotImplementedException();
+#else
+ _options.TargetOS = TargetOS.Windows;
+#endif
+
+ _options.TargetArchitecture = TargetArchitecture.X64;
+ }
+
+ // TODO: Use System.CommandLine for command line parsing
+ // https://github.com/dotnet/corert/issues/568
private void ParseCommandLine(string[] args)
{
var parser = new CommandLineParser(args);
@@ -66,7 +85,7 @@ namespace ILCompiler
case "o":
case "out":
- _outputPath = parser.GetStringValue();
+ _options.OutputFilePath = parser.GetStringValue();
break;
case "dgmllog":
@@ -95,7 +114,7 @@ namespace ILCompiler
break;
case "systemmodule":
- _systemModuleName = parser.GetStringValue();
+ _options.SystemModuleName = parser.GetStringValue();
break;
default:
@@ -104,48 +123,18 @@ namespace ILCompiler
}
}
- private EcmaModule GetEntryPointModule()
- {
- EcmaModule mainModule = null;
- foreach (var inputFile in _inputFilePaths)
- {
- EcmaModule module = _compilerTypeSystemContext.GetModuleFromPath(inputFile.Value);
- if (module.PEReader.PEHeaders.IsExe)
- {
- if (mainModule != null)
- throw new CommandLineException("Multiple entrypoint modules");
- mainModule = module;
- }
- }
- return mainModule;
- }
-
private void SingleFileCompilation()
{
- List<MethodDesc> rootMethods = new List<MethodDesc>();
- MethodDesc entryPointMethod = null;
-
- EcmaModule entryPointModule = GetEntryPointModule();
- if (entryPointModule != null)
- {
- int entryPointToken = entryPointModule.PEReader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress;
- entryPointMethod = entryPointModule.GetMethod(MetadataTokens.EntityHandle(entryPointToken));
- }
-
- Compilation compilation = new Compilation(_compilerTypeSystemContext, _options);
+ Compilation compilation = new Compilation(_options);
compilation.Log = _options.Verbose ? Console.Out : TextWriter.Null;
- compilation.OutputPath = _outputPath;
- if (_options.IsCppCodeGen)
- {
- // Don't set Out when using object writer which is handled by LLVM.
- compilation.Out = new StreamWriter(File.Create(_outputPath));
- }
- compilation.CompileSingleFile(entryPointMethod);
+ compilation.CompileSingleFile();
}
private int Run(string[] args)
{
+ InitializeDefaultOptions();
+
ParseCommandLine(args);
if (_help)
@@ -154,34 +143,12 @@ namespace ILCompiler
return 1;
}
- if (_inputFilePaths.Count == 0)
+ if (_options.InputFilePaths.Count == 0)
throw new CommandLineException("No input files specified");
- if (_outputPath == null)
+ if (_options.OutputFilePath == 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 if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- targetOS = TargetOS.OSX;
- 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();
diff --git a/src/ILCompiler/src/project.json b/src/ILCompiler/src/project.json
index a194def8c..14b5ead41 100644
--- a/src/ILCompiler/src/project.json
+++ b/src/ILCompiler/src/project.json
@@ -6,6 +6,7 @@
"System.Diagnostics.Debug": "4.0.10",
"System.IO": "4.0.10",
"System.IO.FileSystem": "4.0.0",
+ "System.IO.MemoryMappedFiles": "4.0.0-beta-23419",
"System.Collections": "4.0.10",
"System.Text.Encoding": "4.0.10",
"System.Runtime.InteropServices": "4.0.20",
@@ -20,7 +21,7 @@
"System.Reflection.Metadata": "1.0.22",
"System.Runtime.InteropServices.RuntimeInformation": "4.0.0-beta-23409",
"Microsoft.DotNet.RyuJit": "1.0.2-prerelease-00002",
- "Microsoft.DotNet.ObjectWriter": "1.0.3-prerelease-00001",
+ "Microsoft.DotNet.ObjectWriter": "1.0.3-prerelease-00001"
},
"frameworks": {
"dotnet": {