From e79f72bb0006c24c34e1728da6b950fd9b96e532 Mon Sep 17 00:00:00 2001 From: jbevain Date: Tue, 2 Mar 2010 14:52:06 +0000 Subject: [PATCH] 2010-03-02 Jb Evain Merge the MonoTouch Linker branch. * Mono.Linker/LinkContext.cs: Allow creation with a custom resolver. * Mono.Linker/AssemblyResolver.cs: Allow creation with a custom assembly cache. * Mono.Linker.Steps/ResolveFromAssemblyStep.cs: - Mark fields for copied assemblied. - Now can take an assembly directly. * Mono.Linker.Steps/SweepStep.cs * Mono.Linker.Steps/CleanStep.cs: Optimizations. git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/mcs@152840 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- tools/linker/ChangeLog | 18 ++++++++++ tools/linker/Mono.Linker.Steps/CleanStep.cs | 40 ++++++++++++++------- .../Mono.Linker.Steps/ResolveFromAssemblyStep.cs | 23 ++++++++++-- tools/linker/Mono.Linker.Steps/SweepStep.cs | 41 +++++++++++++++++----- tools/linker/Mono.Linker/AssemblyResolver.cs | 9 +++-- tools/linker/Mono.Linker/LinkContext.cs | 9 +++-- 6 files changed, 113 insertions(+), 27 deletions(-) diff --git a/tools/linker/ChangeLog b/tools/linker/ChangeLog index a91370619b..2c185b04d0 100644 --- a/tools/linker/ChangeLog +++ b/tools/linker/ChangeLog @@ -1,3 +1,21 @@ +2010-03-02 Jb Evain + + Merge the MonoTouch Linker branch. + + * Mono.Linker/LinkContext.cs: + Allow creation with a custom resolver. + + * Mono.Linker/AssemblyResolver.cs: + Allow creation with a custom assembly cache. + + * Mono.Linker.Steps/ResolveFromAssemblyStep.cs: + - Mark fields for copied assemblied. + - Now can take an assembly directly. + + * Mono.Linker.Steps/SweepStep.cs + * Mono.Linker.Steps/CleanStep.cs: + Optimizations. + 2010-02-01 Jb Evain * MarkStep.cs: SoapHeader can either take a field or a property. diff --git a/tools/linker/Mono.Linker.Steps/CleanStep.cs b/tools/linker/Mono.Linker.Steps/CleanStep.cs index ae6095477a..fabe022ca0 100644 --- a/tools/linker/Mono.Linker.Steps/CleanStep.cs +++ b/tools/linker/Mono.Linker.Steps/CleanStep.cs @@ -49,14 +49,17 @@ namespace Mono.Linker.Steps { static void CleanMemberReferences (ModuleDefinition module) { - foreach (MemberReference reference in new ArrayList (module.MemberReferences)) { + var references = module.MemberReferences; + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; GenericInstanceType git = reference.DeclaringType as GenericInstanceType; if (git == null) continue; foreach (TypeReference arg in git.GenericArguments) if (!CheckType (module, arg)) - module.MemberReferences.Remove (reference); + references.RemoveAt (i--); } } @@ -75,16 +78,23 @@ namespace Mono.Linker.Steps { static void CleanType (TypeDefinition type) { - CleanNestedTypes (type); - CleanProperties (type); - CleanEvents (type); + if (type.HasNestedTypes) + CleanNestedTypes (type); + if (type.HasProperties) + CleanProperties (type); + if (type.HasEvents) + CleanEvents (type); } static void CleanNestedTypes (TypeDefinition type) { - foreach (TypeDefinition nested in new ArrayList (type.NestedTypes)) - if (!type.Module.Types.Contains (nested)) - type.NestedTypes.Remove (nested); + var nested_types = type.NestedTypes; + + for (int i = 0; i < nested_types.Count; i++) { + var nested_type = nested_types [i]; + if (!type.Module.Types.Contains (nested_type)) + nested_types.RemoveAt (i--); + } } static MethodDefinition CheckMethod (TypeDefinition type, MethodDefinition method) @@ -97,13 +107,16 @@ namespace Mono.Linker.Steps { static void CleanEvents (TypeDefinition type) { - foreach (EventDefinition evt in new ArrayList (type.Events)) { + var events = type.Events; + + for (int i = 0; i < events.Count; i++) { + var evt = events [i]; evt.AddMethod = CheckMethod (type, evt.AddMethod); evt.InvokeMethod = CheckMethod (type, evt.InvokeMethod); evt.RemoveMethod = CheckMethod (type, evt.RemoveMethod); if (!IsEventUsed (evt)) - type.Events.Remove (evt); + events.RemoveAt (i--); } } @@ -114,12 +127,15 @@ namespace Mono.Linker.Steps { static void CleanProperties (TypeDefinition type) { - foreach (PropertyDefinition prop in new ArrayList (type.Properties)) { + var properties = type.Properties; + + for (int i = 0; i < properties.Count; i++) { + var prop = properties [i]; prop.GetMethod = CheckMethod (type, prop.GetMethod); prop.SetMethod = CheckMethod (type, prop.SetMethod); if (!IsPropertyUsed (prop)) - type.Properties.Remove (prop); + properties.RemoveAt (i--); } } diff --git a/tools/linker/Mono.Linker.Steps/ResolveFromAssemblyStep.cs b/tools/linker/Mono.Linker.Steps/ResolveFromAssemblyStep.cs index 5cb5614b2b..37e707d72e 100644 --- a/tools/linker/Mono.Linker.Steps/ResolveFromAssemblyStep.cs +++ b/tools/linker/Mono.Linker.Steps/ResolveFromAssemblyStep.cs @@ -33,16 +33,27 @@ namespace Mono.Linker.Steps { public class ResolveFromAssemblyStep : ResolveStep { - string _assembly; + AssemblyDefinition _assembly; + string _file; public ResolveFromAssemblyStep (string assembly) { + _file = assembly; + } + + public ResolveFromAssemblyStep (AssemblyDefinition assembly) + { _assembly = assembly; } public override void Process (LinkContext context) { - AssemblyDefinition assembly = context.Resolve (_assembly); + if (_assembly != null) { + context.SafeLoadSymbols (_assembly); + context.Resolver.CacheAssembly (_assembly); + } + + AssemblyDefinition assembly = _assembly ?? context.Resolve (_file); switch (assembly.Kind) { case AssemblyKind.Dll: @@ -61,6 +72,8 @@ namespace Mono.Linker.Steps { foreach (TypeDefinition type in assembly.MainModule.Types) { Annotations.Mark (type); + if (type.HasFields) + MarkFields (type.Fields); if (type.HasMethods) MarkMethods (type.Methods); if (type.HasConstructors) @@ -76,6 +89,12 @@ namespace Mono.Linker.Steps { MarkMethod (assembly.EntryPoint, MethodAction.Parse); } + static void MarkFields (ICollection fields) + { + foreach (FieldDefinition field in fields) + Annotations.Mark (field); + } + static void MarkMethods (ICollection methods) { foreach (MethodDefinition method in methods) diff --git a/tools/linker/Mono.Linker.Steps/SweepStep.cs b/tools/linker/Mono.Linker.Steps/SweepStep.cs index 736f43de6f..d5fe17db91 100644 --- a/tools/linker/Mono.Linker.Steps/SweepStep.cs +++ b/tools/linker/Mono.Linker.Steps/SweepStep.cs @@ -33,11 +33,15 @@ using Mono.Cecil; namespace Mono.Linker.Steps { - public class SweepStep : BaseStep { + public class SweepStep : IStep { - protected override void ProcessAssembly (AssemblyDefinition assembly) + AssemblyDefinition [] assemblies; + + public void Process (LinkContext context) { - SweepAssembly (assembly); + assemblies = context.GetAssemblies (); + foreach (var assembly in assemblies) + SweepAssembly (assembly); } void SweepAssembly (AssemblyDefinition assembly) @@ -50,13 +54,18 @@ namespace Mono.Linker.Steps { return; } - foreach (TypeDefinition type in Clone (assembly.MainModule.Types)) { + var types = assembly.MainModule.Types; + var cloned_types = Clone (types); + + types.Clear (); + + foreach (TypeDefinition type in cloned_types) { if (Annotations.IsMarked (type)) { SweepType (type); + types.Add (type); continue; } - assembly.MainModule.Types.Remove (type); SweepReferences (assembly, type); } } @@ -75,7 +84,7 @@ namespace Mono.Linker.Steps { void SweepReferences (AssemblyDefinition target) { - foreach (var assembly in Context.GetAssemblies ()) + foreach (var assembly in assemblies) SweepReferences (assembly, target); } @@ -84,7 +93,7 @@ namespace Mono.Linker.Steps { var references = assembly.MainModule.AssemblyReferences; for (int i = 0; i < references.Count; i++) { var reference = references [i]; - if (reference.FullName != target.Name.FullName) + if (!AreSameReference (reference, target.Name)) continue; references.RemoveAt (i); @@ -99,7 +108,7 @@ namespace Mono.Linker.Steps { void SweepReferences (AssemblyDefinition assembly, TypeDefinition type) { - foreach (AssemblyDefinition asm in Context.GetAssemblies ()) { + foreach (AssemblyDefinition asm in assemblies) { ModuleDefinition module = asm.MainModule; if (!module.TypeReferences.Contains (type)) continue; @@ -128,7 +137,7 @@ namespace Mono.Linker.Steps { if (reference == null) return false; - return assembly.Name.FullName == reference.FullName; + return AreSameReference (assembly.Name, reference); } static void SweepType (TypeDefinition type) @@ -149,5 +158,19 @@ namespace Mono.Linker.Steps { if (!Annotations.IsMarked ((IAnnotationProvider) list [i])) list.RemoveAt (i--); } + + static bool AreSameReference (AssemblyNameReference a, AssemblyNameReference b) + { + if (a == b) + return true; + + if (a.Name != b.Name) + return false; + + if (a.Version != b.Version) + return false; + + return true; + } } } diff --git a/tools/linker/Mono.Linker/AssemblyResolver.cs b/tools/linker/Mono.Linker/AssemblyResolver.cs index 5d7ee7c705..f203638e99 100644 --- a/tools/linker/Mono.Linker/AssemblyResolver.cs +++ b/tools/linker/Mono.Linker/AssemblyResolver.cs @@ -35,15 +35,20 @@ namespace Mono.Linker { public class AssemblyResolver : BaseAssemblyResolver { - Hashtable _assemblies; + IDictionary _assemblies; public IDictionary AssemblyCache { get { return _assemblies; } } public AssemblyResolver () + : this (new Hashtable ()) { - _assemblies = new Hashtable (); + } + + public AssemblyResolver (IDictionary assembly_cache) + { + _assemblies = assembly_cache; } public override AssemblyDefinition Resolve (AssemblyNameReference name) diff --git a/tools/linker/Mono.Linker/LinkContext.cs b/tools/linker/Mono.Linker/LinkContext.cs index c87095b5fd..4873df001b 100644 --- a/tools/linker/Mono.Linker/LinkContext.cs +++ b/tools/linker/Mono.Linker/LinkContext.cs @@ -71,9 +71,14 @@ namespace Mono.Linker { } public LinkContext (Pipeline pipeline) + : this (pipeline, new AssemblyResolver ()) + { + } + + public LinkContext (Pipeline pipeline, AssemblyResolver resolver) { _pipeline = pipeline; - _resolver = new AssemblyResolver (); + _resolver = resolver; _actions = new Hashtable (); _parameters = new Hashtable (); } @@ -124,7 +129,7 @@ namespace Mono.Linker { return assembly; } - void SafeLoadSymbols (AssemblyDefinition assembly) + public void SafeLoadSymbols (AssemblyDefinition assembly) { if (!_linkSymbols) return; -- 2.11.4.GIT