From 3c4ea3f8f4fcb688194f5f1e501ab01642d4bdf4 Mon Sep 17 00:00:00 2001 From: Mike Voorhees Date: Fri, 12 Feb 2021 13:51:43 -0500 Subject: [PATCH] Add ModuleDefinition.ImmediateRead (#713) We are going to use this to do a multi stage load in parallel. We will be able to greatly reduce our load times using this new API. The way it's going to work is Stage 1 - In parallel, load the assemblies with ReadingMode.Deferred. Stage 2 - Populate our AssemblyResolver with a cache of all read assemblies. Stage 3 - In parallel, call ImmediateRead. What I really want is an API to load everything in stage 3. I found that ImmediateRead does not load method bodies. I don't know if/how you want want something like this exposed via the public API. For now I'm iterating the data model and forcing things to load that ImmediateRead did not cover. --- Mono.Cecil/ModuleDefinition.cs | 9 +++++++++ Test/Mono.Cecil.Tests/ModuleTests.cs | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs index a18969bdb..8fb35a540 100644 --- a/Mono.Cecil/ModuleDefinition.cs +++ b/Mono.Cecil/ModuleDefinition.cs @@ -928,6 +928,15 @@ public IMetadataTokenProvider LookupToken (MetadataToken token) { return Read (token, (t, reader) => reader.LookupToken (t)); } + + public void ImmediateRead () + { + if (!HasImage) + return; + ReadingMode = ReadingMode.Immediate; + var moduleReader = new ImmediateModuleReader (Image); + moduleReader.ReadModule (this, resolve_attributes: true); + } readonly object module_lock = new object(); diff --git a/Test/Mono.Cecil.Tests/ModuleTests.cs b/Test/Mono.Cecil.Tests/ModuleTests.cs index 5e4bee736..5af2a65d7 100644 --- a/Test/Mono.Cecil.Tests/ModuleTests.cs +++ b/Test/Mono.Cecil.Tests/ModuleTests.cs @@ -283,6 +283,27 @@ public void OpenModuleDeferred () } } + + [Test] + public void OpenModuleDeferredAndThenPerformImmediateRead () + { + using (var module = GetResourceModule ("hello.exe", ReadingMode.Deferred)) { + Assert.AreEqual (ReadingMode.Deferred, module.ReadingMode); + module.ImmediateRead (); + Assert.AreEqual (ReadingMode.Immediate, module.ReadingMode); + } + } + + [Test] + public void ImmediateReadDoesNothingForModuleWithNoImage () + { + using (var module = new ModuleDefinition ()) { + var initialReadingMode = module.ReadingMode; + module.ImmediateRead (); + Assert.AreEqual (initialReadingMode, module.ReadingMode); + } + } + [Test] public void OwnedStreamModuleFileName () {