diff options
author | Jb Evain <jbevain@gmail.com> | 2011-10-27 16:53:07 +0400 |
---|---|---|
committer | Jb Evain <jbevain@gmail.com> | 2011-10-27 16:53:07 +0400 |
commit | 8771de6415d3fa5e34b12fd90519a5405c02e8b2 (patch) | |
tree | 0a1707ab3fc77c49d3f5f6f51628089ccffb1d19 /Mono.Cecil | |
parent | ecdd7454b53a4d6b57c9eb2a500b91025a63b401 (diff) |
First pass at a branch with reduced memory usage; Keeps an open handle on the file, dispose your modules
Diffstat (limited to 'Mono.Cecil')
-rw-r--r-- | Mono.Cecil/AssemblyDefinition.cs | 9 | ||||
-rw-r--r-- | Mono.Cecil/AssemblyReader.cs | 46 | ||||
-rw-r--r-- | Mono.Cecil/AssemblyWriter.cs | 3 | ||||
-rw-r--r-- | Mono.Cecil/ModuleDefinition.cs | 14 |
4 files changed, 32 insertions, 40 deletions
diff --git a/Mono.Cecil/AssemblyDefinition.cs b/Mono.Cecil/AssemblyDefinition.cs index f1b5d25..70929b7 100644 --- a/Mono.Cecil/AssemblyDefinition.cs +++ b/Mono.Cecil/AssemblyDefinition.cs @@ -33,7 +33,7 @@ using Mono.Collections.Generic; namespace Mono.Cecil { - public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider { + public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider, IDisposable { AssemblyNameDefinition name; @@ -107,6 +107,13 @@ namespace Mono.Cecil { { } + public void Dispose () + { + var modules = this.Modules; + for (int i = 0; i < modules.Count; i++) + modules [i].Dispose (); + } + #if !READ_ONLY public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleKind kind) { diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs index 72cb480..9b9669c 100644 --- a/Mono.Cecil/AssemblyReader.cs +++ b/Mono.Cecil/AssemblyReader.cs @@ -364,7 +364,6 @@ namespace Mono.Cecil { readonly internal MetadataSystem metadata; internal IGenericContext context; - internal CodeReader code; uint Position { get { return (uint) base.position; } @@ -372,12 +371,11 @@ namespace Mono.Cecil { } public MetadataReader (ModuleDefinition module) - : base (module.Image.MetadataSection.Data) + : base (module.Image.TableHeap.data) { this.image = module.Image; this.module = module; this.metadata = module.MetadataSystem; - this.code = new CodeReader (image.MetadataSection, this); } int GetCodedIndexSize (CodedIndex index) @@ -660,17 +658,9 @@ namespace Mono.Cecil { public MemoryStream GetManagedResourceStream (uint offset) { - var rva = image.Resources.VirtualAddress; - var section = image.GetSectionAtVirtualAddress (rva); - var position = (rva - section.VirtualAddress) + offset; - var buffer = section.Data; - - var length = buffer [position] - | (buffer [position + 1] << 8) - | (buffer [position + 2] << 16) - | (buffer [position + 3] << 24); - - return new MemoryStream (buffer, (int) position + 4, length); + var reader = image.GetReaderAt (image.Resources.VirtualAddress); + reader.Advance ((int) offset); + return new MemoryStream (reader.ReadBytes (reader.ReadInt32 ())); } void PopulateVersionAndFlags (AssemblyNameReference name) @@ -1216,13 +1206,8 @@ namespace Mono.Cecil { byte [] GetFieldInitializeValue (int size, RVA rva) { - var section = image.GetSectionAtVirtualAddress (rva); - if (section == null) - return Empty<byte>.Array; - - var value = new byte [size]; - Buffer.BlockCopy (section.Data, (int) (rva - section.VirtualAddress), value, 0, size); - return value; + var reader = image.GetReaderAt (rva); + return reader.ReadBytes (size); } static int GetFieldTypeSize (TypeReference type) @@ -1980,7 +1965,7 @@ namespace Mono.Cecil { public MethodBody ReadMethodBody (MethodDefinition method) { - return code.ReadMethodBody (method); + return CodeReader.ReadMethodBody (method, this); } public CallSite ReadCallSite (MetadataToken token) @@ -2624,19 +2609,12 @@ namespace Mono.Cecil { } public SignatureReader (uint blob, MetadataReader reader) - : base (reader.buffer) + : base (reader.image.BlobHeap.data) { this.reader = reader; - - MoveToBlob (blob); - - this.sig_length = ReadCompressedUInt32 (); - this.start = (uint) position; - } - - void MoveToBlob (uint blob) - { - position = (int) (reader.image.BlobHeap.Offset + blob); + this.start = blob; + this.position = (int) this.start; + this.sig_length = ReadCompressedUInt32(); } MetadataToken ReadTypeTokenSignature () @@ -3151,7 +3129,7 @@ namespace Mono.Cecil { public bool CanReadMore () { - return position - start < sig_length; + return position - start <= sig_length; } } } diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs index a2d3ffa..9e597ca 100644 --- a/Mono.Cecil/AssemblyWriter.cs +++ b/Mono.Cecil/AssemblyWriter.cs @@ -114,6 +114,9 @@ namespace Mono.Cecil { var writer = ImageWriter.CreateWriter (module, metadata, stream); + if (module.HasImage) + module.Image.Dispose (); + writer.WriteImage (); #if !SILVERLIGHT && !CF diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs index 0d137e0..4e4ef37 100644 --- a/Mono.Cecil/ModuleDefinition.cs +++ b/Mono.Cecil/ModuleDefinition.cs @@ -189,7 +189,7 @@ namespace Mono.Cecil { #endif - public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider { + public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, IDisposable { internal Image Image; internal MetadataSystem MetadataSystem; @@ -439,11 +439,17 @@ namespace Mono.Cecil { this.runtime = image.Runtime; this.architecture = image.Architecture; this.attributes = image.Attributes; - this.fq_name = image.FileName; + this.fq_name = image.Stream.GetFullyQualifiedName (); this.reader = new MetadataReader (this); } + public void Dispose () + { + if (Image != null) + Image.Dispose (); + } + public bool HasTypeReference (string fullName) { return HasTypeReference (string.Empty, fullName); @@ -915,9 +921,7 @@ namespace Mono.Cecil { public static ModuleDefinition ReadModule (string fileName, ReaderParameters parameters) { - using (var stream = GetFileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { - return ReadModule (stream, parameters); - } + return ReadModule (GetFileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read), parameters); } static void CheckStream (object stream) |