From cbc5eb729862b0de00aa2e46424a602dcbec899d Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Thu, 14 Oct 2021 05:55:15 -0700 Subject: [PATCH] Improve multi-assembly support (#69) - Add handling of field references - Implement multi-assembly support for the command line iltrim - Small change based on PR feedback - Improve the tests --- .../tools/ILTrim/ILTrim.Exe/ILTrim.csproj | 1 + .../tools/ILTrim/ILTrim.Exe/Program.cs | 19 ++++++++++++++----- .../MultiAssembly/Dependencies/Dep.cs | 5 ++++- .../MultiAssembly/MultiAssembly.cs | 7 ++++++- .../ILTrim/DependencyAnalysis/NodeFactory.cs | 9 +++++++-- .../TokenBased/MemberReferenceNode.cs | 18 +++++++++++++----- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/coreclr/tools/ILTrim/ILTrim.Exe/ILTrim.csproj b/src/coreclr/tools/ILTrim/ILTrim.Exe/ILTrim.csproj index 87dd0c08973..91d6e987372 100644 --- a/src/coreclr/tools/ILTrim/ILTrim.Exe/ILTrim.csproj +++ b/src/coreclr/tools/ILTrim/ILTrim.Exe/ILTrim.csproj @@ -1,5 +1,6 @@ + exe $(NetCoreAppToolCurrent) true x64;x86 diff --git a/src/coreclr/tools/ILTrim/ILTrim.Exe/Program.cs b/src/coreclr/tools/ILTrim/ILTrim.Exe/Program.cs index d74bae4b595..4477d32289e 100644 --- a/src/coreclr/tools/ILTrim/ILTrim.Exe/Program.cs +++ b/src/coreclr/tools/ILTrim/ILTrim.Exe/Program.cs @@ -12,14 +12,23 @@ public class Program static void Main(string[] args) { var inputPath = args[0]; - using var output = File.Create("out.exe"); int i = 1; List referencePaths = new(); - while (args.Length > i && args[i] == "-r") { - referencePaths.Add (args[i+1]); - i += 2; + List trimPaths = new(); + while (args.Length > i) { + if (args[i] == "-r") + { + referencePaths.Add(args[i + 1]); + i += 2; + } + else if (args[i] == "-t") + { + trimPaths.Add(args[i + 1]); + i += 2; + } } - Trimmer.TrimAssembly(inputPath, output, referencePaths); + + Trimmer.TrimAssembly(inputPath, trimPaths, Directory.GetCurrentDirectory(), referencePaths); } } } diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/Dependencies/Dep.cs b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/Dependencies/Dep.cs index 868d4cf773c..dbf19ccecea 100644 --- a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/Dependencies/Dep.cs +++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/Dependencies/Dep.cs @@ -8,4 +8,7 @@ public static void Kept() public static void Trimmed() { } -} \ No newline at end of file + + public static int KeptField; + public static int TrimmedField; +} diff --git a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/MultiAssembly.cs b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/MultiAssembly.cs index fa44c66c381..089588ef5a6 100644 --- a/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/MultiAssembly.cs +++ b/src/coreclr/tools/ILTrim/ILTrim.Tests.Cases/MultiAssembly/MultiAssembly.cs @@ -1,15 +1,20 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.MultiAssembly { [SetupLinkerAction ("link", "Dep")] [SetupCompileBefore("Dep.dll", new[] { "Dependencies/Dep.cs" })] + + [KeptMemberInAssembly("Dep.dll", typeof(DepClass), "Kept()")] + [KeptMemberInAssembly("Dep.dll", typeof(DepClass), nameof(DepClass.KeptField))] public class MultiAssembly { public static void Main() { DepClass.Kept(); + DepClass.KeptField = 0; } } -} \ No newline at end of file +} diff --git a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/NodeFactory.cs index 331d6e39a88..796eed91597 100644 --- a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/NodeFactory.cs @@ -17,11 +17,11 @@ namespace ILTrim.DependencyAnalysis /// public sealed class NodeFactory { - public IReadOnlySet TrimAssemblies { get; } + IReadOnlySet _trimAssemblies { get; } public NodeFactory(IEnumerable trimAssemblies) { - TrimAssemblies = new HashSet(trimAssemblies); + _trimAssemblies = new HashSet(trimAssemblies); } /// @@ -232,6 +232,11 @@ public GenericParameterConstraintNode GenericParameterConstraint(EcmaModule modu return _genericParameterConstraints.GetOrAdd(new HandleKey(module, handle)); } + public bool IsModuleTrimmed(EcmaModule module) + { + return _trimAssemblies.Contains(module.Assembly.GetName().Name); + } + private struct HandleKey : IEquatable> where T : struct, IEquatable { public readonly EcmaModule Module; diff --git a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/TokenBased/MemberReferenceNode.cs b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/TokenBased/MemberReferenceNode.cs index 7f039a1c809..6447c360542 100644 --- a/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/TokenBased/MemberReferenceNode.cs +++ b/src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/TokenBased/MemberReferenceNode.cs @@ -27,13 +27,21 @@ public override IEnumerable GetStaticDependencies(NodeFacto DependencyList dependencies = new DependencyList(); - if (methodOrFieldDef is EcmaMethod method) + switch (methodOrFieldDef) { - if (factory.TrimAssemblies.Contains(method.Module.Assembly.GetName().Name)) - { - dependencies.Add(factory.GetNodeForToken(method.Module, method.Handle), "Target method def of member reference"); - } + case EcmaMethod method: + if (factory.IsModuleTrimmed(method.Module)) + { + dependencies.Add(factory.GetNodeForToken(method.Module, method.Handle), "Target method def of member reference"); + } + break; + case EcmaField field: + if (factory.IsModuleTrimmed(field.Module)) + { + dependencies.Add(factory.GetNodeForToken(field.Module, field.Handle), "Target field def of member reference"); + } + break; } if (!memberRef.Parent.IsNil)