diff options
author | Jan Kotas <jkotas@microsoft.com> | 2015-11-19 12:45:51 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2015-11-20 04:41:38 +0300 |
commit | 8e0b6a850a17703e47ce50eb7dcd364e85c78149 (patch) | |
tree | daca7bdad9573c4ce96bbe664f72e20602e43f8c /src/ILCompiler.Compiler | |
parent | 84c21c058b04ed734e5001ad603babd3614fa025 (diff) |
Fixes for Runtime.Base compilation with RyuJIT
- Disambiguate singleton globals by prepending compilation unit prefix to them
- Emit alternate entry for RuntimeExport methods. Fixes #153.
Diffstat (limited to 'src/ILCompiler.Compiler')
9 files changed, 83 insertions, 31 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs index de87016b6..cf0482ec3 100644 --- a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs +++ b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs @@ -228,9 +228,10 @@ namespace ILCompiler if (!_options.IsCppCodeGen) { - _nodeFactory = new NodeFactory(_typeSystemContext); NodeFactory.NameMangler = NameMangler; + _nodeFactory = new NodeFactory(_typeSystemContext); + // Choose which dependency graph implementation to use based on the amount of logging requested. if (_options.DgmlLog == null) { @@ -259,8 +260,7 @@ namespace ILCompiler _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; var nodes = _dependencyGraph.MarkedNodeList; - var mainMethodNode = (_mainMethod != null) ? _nodeFactory.MethodEntrypoint(_mainMethod) : null; - ObjectWriter.EmitObject(OutputPath, nodes, mainMethodNode, _nodeFactory); + ObjectWriter.EmitObject(OutputPath, nodes, _nodeFactory); if (_options.DgmlLog != null) { @@ -290,8 +290,12 @@ namespace ILCompiler private void AddCompilationRoots() { if (_mainMethod != null) + { AddCompilationRoot(_mainMethod, "Main method"); + _nodeFactory.NodeAliases.Add(_nodeFactory.MethodEntrypoint(_mainMethod), "__managed__Main"); + } + foreach (var inputFile in _typeSystemContext.InputFilePaths) { var module = _typeSystemContext.GetModuleFromPath(inputFile.Value); @@ -300,7 +304,12 @@ namespace ILCompiler foreach (var method in type.GetMethods()) { if (method.HasCustomAttribute("System.Runtime", "RuntimeExportAttribute")) + { AddCompilationRoot(method, "Runtime export"); + + string exportName = ((EcmaMethod)method).GetAttributeStringValue("System.Runtime", "RuntimeExportAttribute"); + _nodeFactory.NodeAliases.Add(_nodeFactory.MethodEntrypoint(method), exportName); + } } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs index 208d39d72..948d15cbd 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs @@ -63,7 +63,7 @@ namespace ILCompiler.DependencyAnalysis get { StringBuilder nameBuilder = new StringBuilder(); - nameBuilder.Append("__GCStaticEEType_"); + nameBuilder.Append(NodeFactory.NameMangler.CompilationUnitPrefix + "__GCStaticEEType_"); int totalSize = 0; foreach (int run in _runLengths) { diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs index da2055110..8e2691afb 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs @@ -248,7 +248,7 @@ namespace ILCompiler.DependencyAnalysis } else if (kind == SpecialMethodKind.RuntimeImport) { - return ExternSymbol(((EcmaMethod)method).GetRuntimeImportEntryPointName()); + return ExternSymbol(((EcmaMethod)method).GetAttributeStringValue("System.Runtime", "RuntimeImportAttribute")); } return _methodCode.GetOrAdd(method); @@ -311,12 +311,35 @@ namespace ILCompiler.DependencyAnalysis return _stringIndirectionNodes.GetOrAdd(data); } - public ArrayOfEmbeddedDataNode GCStaticsRegion = new ArrayOfEmbeddedDataNode("__GCStaticRegionStart", "__GCStaticRegionEnd", null); - public ArrayOfEmbeddedDataNode ThreadStaticsRegion = new ArrayOfEmbeddedDataNode("__ThreadStaticRegionStart", "__ThreadStaticRegionEnd", null); - public ArrayOfEmbeddedDataNode StringTable = new ArrayOfEmbeddedDataNode("__str_fixup", "__str_fixup_end", null); + /// <summary> + /// Returns alternative symbol name that object writer should produce for given symbols + /// in addition to the regular one. + /// </summary> + public string GetSymbolAlternateName(ISymbolNode node) + { + string value; + if (!NodeAliases.TryGetValue(node, out value)) + return null; + return value; + } + + public ArrayOfEmbeddedDataNode GCStaticsRegion = new ArrayOfEmbeddedDataNode( + NameMangler.CompilationUnitPrefix + "__GCStaticRegionStart", + NameMangler.CompilationUnitPrefix + "__GCStaticRegionEnd", + null); + public ArrayOfEmbeddedDataNode ThreadStaticsRegion = new ArrayOfEmbeddedDataNode( + NameMangler.CompilationUnitPrefix + "__ThreadStaticRegionStart", + NameMangler.CompilationUnitPrefix + "__ThreadStaticRegionEnd", + null); + public ArrayOfEmbeddedDataNode StringTable = new ArrayOfEmbeddedDataNode( + NameMangler.CompilationUnitPrefix + "__str_fixup", + NameMangler.CompilationUnitPrefix + "__str_fixup_end", + null); public Dictionary<TypeDesc, List<MethodDesc>> VirtualSlots = new Dictionary<TypeDesc, List<MethodDesc>>(); + public Dictionary<ISymbolNode, string> NodeAliases = new Dictionary<ISymbolNode, string>(); + public static NameMangler NameMangler; public void AttachToDependencyGraph(DependencyAnalysisFramework.DependencyAnalyzerBase<NodeFactory> graph) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectWriter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectWriter.cs index 2343c689a..db60b296e 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectWriter.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectWriter.cs @@ -30,7 +30,6 @@ namespace ILCompiler.DependencyAnalysis // We preserved the original order of ISymbolNode[]. private Dictionary<int, List<ISymbolNode>> _offsetToDefSymbol = new Dictionary<int, List<ISymbolNode>>(); - public const string MainEntryNodeName = "__managed__Main"; private const string NativeObjectWriterFileName = "objwriter"; [DllImport(NativeObjectWriterFileName)] @@ -193,7 +192,7 @@ namespace ILCompiler.DependencyAnalysis } } - public void EmitSymbolDefinition(int currentOffset) + public void EmitSymbolDefinition(int currentOffset, NodeFactory factory) { List<ISymbolNode> nodes; if (_offsetToDefSymbol.TryGetValue(currentOffset, out nodes)) @@ -201,6 +200,10 @@ namespace ILCompiler.DependencyAnalysis foreach (var node in nodes) { EmitSymbolDef(node.MangledName); + + string alternateName = factory.GetSymbolAlternateName(node); + if (alternateName != null) + EmitSymbolDef(alternateName); } } } @@ -241,7 +244,7 @@ namespace ILCompiler.DependencyAnalysis Dispose(false); } - public static void EmitObject(string OutputPath, IEnumerable<DependencyNode> nodes, ISymbolNode mainMethodNode, NodeFactory factory) + public static void EmitObject(string OutputPath, IEnumerable<DependencyNode> nodes, NodeFactory factory) { using (ObjectWriter objectWriter = new ObjectWriter(OutputPath)) { @@ -282,11 +285,6 @@ namespace ILCompiler.DependencyAnalysis nextRelocIndex = 0; } - if (mainMethodNode == node) - { - objectWriter.EmitSymbolDef(MainEntryNodeName); - } - // Build symbol definition map. objectWriter.BuildSymbolDefinitionMap(nodeContents.DefinedSymbols); @@ -296,7 +294,7 @@ namespace ILCompiler.DependencyAnalysis for (int i = 0; i < nodeContents.Data.Length; i++) { // Emit symbol definitions if necessary - objectWriter.EmitSymbolDefinition(i); + objectWriter.EmitSymbolDefinition(i, factory); // Emit debug loc info if needed. objectWriter.EmitDebugLocInfo(i); @@ -311,11 +309,6 @@ namespace ILCompiler.DependencyAnalysis bool isPCRelative = false; switch (reloc.RelocType) { - // REVIEW: I believe the JIT is emitting 0x3 instead of 0xA - // for x64, because emitter from x86 is ported for RyuJIT. - // I will consult with Bruce and if he agrees, I will delete - // this "case" duplicated by IMAGE_REL_BASED_DIR64. - case (RelocType)0x03: // IMAGE_REL_BASED_HIGHLOW case RelocType.IMAGE_REL_BASED_DIR64: size = 8; break; @@ -342,7 +335,7 @@ namespace ILCompiler.DependencyAnalysis } // It is possible to have a symbol just after all of the data. - objectWriter.EmitSymbolDefinition(nodeContents.Data.Length); + objectWriter.EmitSymbolDefinition(nodeContents.Data.Length, factory); // The first definition is the main node name string nodeName = objectWriter._offsetToDefSymbol[0][0].MangledName; diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringDataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringDataNode.cs index d1e8ddb30..549437ea8 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringDataNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringDataNode.cs @@ -38,9 +38,9 @@ namespace ILCompiler.DependencyAnalysis get { if (_id.HasValue) - return "__str_table_entry_" + _id.Value.ToString(CultureInfo.InvariantCulture); + return NodeFactory.NameMangler.CompilationUnitPrefix + "__str_table_entry_" + _id.Value.ToString(CultureInfo.InvariantCulture); else - return "__str_table_entry_" + _data; + return NodeFactory.NameMangler.CompilationUnitPrefix + "__str_table_entry_" + _data; } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringIndirectionNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringIndirectionNode.cs index 96bd37b7d..b1393c661 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringIndirectionNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringIndirectionNode.cs @@ -31,9 +31,9 @@ namespace ILCompiler.DependencyAnalysis get { if (base.Offset != 1) - return "__str" + base.Offset.ToString(CultureInfo.InvariantCulture); + return NodeFactory.NameMangler.CompilationUnitPrefix + "__str" + base.Offset.ToString(CultureInfo.InvariantCulture); else - return "__str" + _data; + return NodeFactory.NameMangler.CompilationUnitPrefix + "__str" + _data; } } diff --git a/src/ILCompiler.Compiler/src/Compiler/MethodExtensions.cs b/src/ILCompiler.Compiler/src/Compiler/MethodExtensions.cs index 0e72345c3..642b3021f 100644 --- a/src/ILCompiler.Compiler/src/Compiler/MethodExtensions.cs +++ b/src/ILCompiler.Compiler/src/Compiler/MethodExtensions.cs @@ -19,7 +19,7 @@ namespace ILCompiler internal static class MethodExtensions { - public static string GetRuntimeImportEntryPointName(this EcmaMethod This) + public static string GetAttributeStringValue(this EcmaMethod This, string nameSpace, string name) { var metadataReader = This.MetadataReader; foreach (var attributeHandle in metadataReader.GetMethodDefinition(This.Handle).GetCustomAttributes()) @@ -38,8 +38,8 @@ namespace ILCompiler continue; } - if (metadataReader.StringComparer.Equals(namespaceHandle, "System.Runtime") - && metadataReader.StringComparer.Equals(nameHandle, "RuntimeImportAttribute")) + if (metadataReader.StringComparer.Equals(namespaceHandle, nameSpace) + && metadataReader.StringComparer.Equals(nameHandle, name)) { var constructor = This.Module.GetMethod(attributeCtor); diff --git a/src/ILCompiler.Compiler/src/Compiler/NameMangler.cs b/src/ILCompiler.Compiler/src/Compiler/NameMangler.cs index 6e51ede50..11c3ef474 100644 --- a/src/ILCompiler.Compiler/src/Compiler/NameMangler.cs +++ b/src/ILCompiler.Compiler/src/Compiler/NameMangler.cs @@ -335,5 +335,32 @@ namespace ILCompiler return mangledName; } + + private string _compilationUnixPrefix; + + /// <summary> + /// Prefix to prepend to compilation unit global symbols to make them disambiguated between different .obj files. + /// </summary> + public string CompilationUnitPrefix + { + get + { + if (_compilationUnixPrefix == null) + { + string systemModuleName = ((EcmaModule)_compilation.TypeSystemContext.SystemModule).GetName().Name; + + // TODO: just something to get Runtime.Base compiled + if (systemModuleName != "System.Private.CoreLib") + { + _compilationUnixPrefix = systemModuleName.Replace(".", "_"); + } + else + { + _compilationUnixPrefix = ""; + } + } + return _compilationUnixPrefix; + } + } } } diff --git a/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs b/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs index 3623d4a54..fdcbd67e1 100644 --- a/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs +++ b/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs @@ -264,7 +264,7 @@ namespace ILCompiler.CppCodeGen EcmaMethod ecmaMethod = method as EcmaMethod; string importName = kind == SpecialMethodKind.PInvoke ? - method.GetPInvokeMethodMetadata().Name : ecmaMethod.GetRuntimeImportEntryPointName(); + method.GetPInvokeMethodMetadata().Name : ecmaMethod.GetAttributeStringValue("System.Runtime", "RuntimeImport"); if (importName == null) importName = method.Name; |