diff options
author | Michal Strehovsky <michals@microsoft.com> | 2018-07-23 10:23:45 +0300 |
---|---|---|
committer | Michal Strehovsky <michals@microsoft.com> | 2018-07-23 10:23:45 +0300 |
commit | 045a28051c6b85b82fe42e944fcb2267768ebbe2 (patch) | |
tree | 007e9d069f087ef48bb6270ccc710a555cef7d1a /src/ILCompiler.Compiler | |
parent | 67ea31d51ad529912b00ad8bc7a29aa9621413db (diff) |
Make generic composition details relative addresses
I'm looking at size regressions between .NET Native 1.7 and the current mainline branch. A thing that stood out is universally bigger EETypes. A contributor to this was getting rid of GenericInstanceDescs between 1.7 and 2.0 and replacing them by direct references to generic composition details from the EEType. Size-wise, this was mostly a wash, but we can actually do better - these new fields are not critical to be pointer-sized.
This change turns them into relative pointers. This saves 33 kB on a hello world app. I expect around 100 kB savings on the UWP People app based on my back-of-the-envelope calculation.
Project N baggage:
1. Update pntestcl build configuration to compile it with a C# compiler that is not 8 years old
2. Disable metadata validation transform on class libraries. This is hitting what appears to be a CCI metadata validator bug (Validator.cs:796) where it thinks a modified type should have the same interned key as the unmodified version of it. The act of resolving a modified type strips off the modifier. This ticks off the validator.
3. Fix a Reducer bug where it wasn't marking non-interface constraints as necessary. The C# unmanaged constraint is expressed as [modreq UnmanagedType] ValueType. We were not marking UnmanagedType as necessary.
4. Update checked in binder because this is a file format change
[tfs-changeset: 1708263]
Diffstat (limited to 'src/ILCompiler.Compiler')
7 files changed, 50 insertions, 20 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs index 9d07fac1f..1d2c7832d 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs @@ -846,7 +846,11 @@ namespace ILCompiler.DependencyAnalysis { if (_type.HasInstantiation && !_type.IsTypeDefinition) { - objData.EmitPointerRelocOrIndirectionReference(factory.NecessaryTypeSymbol(_type.GetTypeDefinition())); + IEETypeNode typeDefNode = factory.NecessaryTypeSymbol(_type.GetTypeDefinition()); + if (factory.Target.SupportsRelativePointers) + objData.EmitRelativeRelocOrIndirectionReference(typeDefNode); + else + objData.EmitPointerRelocOrIndirectionReference(typeDefNode); GenericCompositionDetails details; if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType) @@ -864,7 +868,11 @@ namespace ILCompiler.DependencyAnalysis else details = new GenericCompositionDetails(_type); - objData.EmitPointerReloc(factory.GenericComposition(details)); + ISymbolNode compositionNode = factory.GenericComposition(details); + if (factory.Target.SupportsRelativePointers) + objData.EmitReloc(compositionNode, RelocType.IMAGE_REL_BASED_RELPTR32); + else + objData.EmitPointerReloc(compositionNode); } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs index 1f2d1f3f0..570974205 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs @@ -69,7 +69,7 @@ namespace ILCompiler.DependencyAnalysis dataBuilder.AddSymbol(this); // +1 for SyncBlock (in CoreRT static size already includes EEType) - Debug.Assert(factory.Target.Abi == TargetAbi.CoreRT); + Debug.Assert(factory.Target.Abi == TargetAbi.CoreRT || factory.Target.Abi == TargetAbi.CppCodegen); int totalSize = (_gcMap.Size + 1) * _target.PointerSize; // We only need to check for containsPointers because ThreadStatics are always allocated diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs index 247d1e9a1..39d886e5e 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs @@ -65,7 +65,7 @@ namespace ILCompiler.DependencyAnalysis } dependencyList.Add(factory.GCStaticsRegion, "GCStatics Region"); - if (factory.Target.Abi == TargetAbi.CoreRT) + if (factory.Target.Abi != TargetAbi.ProjectN) { dependencyList.Add(GetGCStaticEETypeNode(factory), "GCStatic EEType"); if (_preInitFieldInfos != null) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionExtensions.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionExtensions.cs new file mode 100644 index 000000000..9265f94f8 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionExtensions.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Internal.Runtime; +using Internal.TypeSystem; + +using Debug = System.Diagnostics.Debug; + +namespace ILCompiler.DependencyAnalysis +{ + static class IndirectionExtensions + { + /// <summary> + /// Use this api to generate a reloc to a symbol that may be an indirection cell or not as a pointer + /// </summary> + /// <param name="symbol">symbol to reference</param> + /// <param name="indirectionBit">value to OR in to the reloc to represent to runtime code that this pointer is an indirection. Defaults to IndirectionConstants.IndirectionCellPointer</param> + /// <param name="delta">Delta from symbol start for value</param> + public static void EmitPointerRelocOrIndirectionReference(ref this ObjectDataBuilder builder, ISymbolNode symbol, int delta = 0, int indirectionBit = IndirectionConstants.IndirectionCellPointer) + { + if (symbol.RepresentsIndirectionCell) + delta |= indirectionBit; + + builder.EmitReloc(symbol, (builder.TargetPointerSize == 8) ? RelocType.IMAGE_REL_BASED_DIR64 : RelocType.IMAGE_REL_BASED_HIGHLOW, delta); + } + + public static void EmitRelativeRelocOrIndirectionReference(ref this ObjectDataBuilder builder, ISymbolNode symbol, int delta = 0, int indirectionBit = IndirectionConstants.IndirectionCellPointer) + { + if (symbol.RepresentsIndirectionCell) + delta = delta | indirectionBit; + + builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_RELPTR32, delta); + } + } +} diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectDataBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectDataBuilder.cs index b42c3e382..29fc23f98 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectDataBuilder.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectDataBuilder.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using Internal.TypeSystem; -using Internal.Runtime; using Debug = System.Diagnostics.Debug; @@ -293,20 +292,6 @@ namespace ILCompiler.DependencyAnalysis EmitReloc(symbol, (_target.PointerSize == 8) ? RelocType.IMAGE_REL_BASED_DIR64 : RelocType.IMAGE_REL_BASED_HIGHLOW, delta); } - /// <summary> - /// Use this api to generate a reloc to a symbol that may be an indirection cell or not as a pointer - /// </summary> - /// <param name="symbol">symbol to reference</param> - /// <param name="indirectionBit">value to OR in to the reloc to represent to runtime code that this pointer is an indirection. Defaults to IndirectionConstants.IndirectionCellPointer</param> - /// <param name="delta">Delta from symbol start for value</param> - public void EmitPointerRelocOrIndirectionReference(ISymbolNode symbol, int indirectionBit = IndirectionConstants.IndirectionCellPointer, int delta = 0) - { - if (symbol.RepresentsIndirectionCell) - delta |= indirectionBit; - - EmitReloc(symbol, (_target.PointerSize == 8) ? RelocType.IMAGE_REL_BASED_DIR64 : RelocType.IMAGE_REL_BASED_HIGHLOW, delta); - } - public ObjectNode.ObjectData ToObjectData() { #if DEBUG diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs index 89a479939..80c497e2c 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs @@ -20,7 +20,7 @@ namespace ILCompiler.DependencyAnalysis public ThreadStaticsNode(MetadataType type, NodeFactory factory) { - Debug.Assert(factory.Target.Abi == TargetAbi.CoreRT); + Debug.Assert(factory.Target.Abi == TargetAbi.CoreRT || factory.Target.Abi == TargetAbi.CppCodegen); _type = type; } diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj index 6b8cd40df..05f3c956f 100644 --- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj +++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj @@ -102,6 +102,7 @@ <Compile Include="Compiler\DependencyAnalysis\DefaultConstructorMapNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\ExternSymbolsImportedNodeProvider.cs" /> <Compile Include="Compiler\DependencyAnalysis\ExternSymbolsWithIndirectionImportedNodeProvider.cs" /> + <Compile Include="Compiler\DependencyAnalysis\IndirectionExtensions.cs" /> <Compile Include="Compiler\DependencyAnalysis\MrtImportImportedNodeProvider.cs" /> <Compile Include="Compiler\DependencyAnalysis\MrtImports.cs" /> <Compile Include="Compiler\DependencyAnalysis\MrtProcessedExportAddressTableNode.cs" /> |