diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ManifestMetadataTableNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ManifestMetadataTableNode.cs index a021c4c83fd93d..26ac359f10f6ec 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ManifestMetadataTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ManifestMetadataTableNode.cs @@ -27,7 +27,7 @@ public interface ISignatureEmitter void MaterializeSignature(); } - public class ManifestMetadataTableNode : HeaderTableNode + public class ManifestMetadataTableNode : HeaderTableNode, IDisposable { /// /// Map from simple assembly names to their module indices. The map gets prepopulated @@ -329,5 +329,10 @@ internal byte[] GetManifestAssemblyMvidTableData() } return manifestAssemblyMvidTable; } + + public void Dispose() + { + _modulesWhichMustBeIndexable = null; + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index 46e547ed9bab5f..fa51077ac5204e 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -977,7 +977,11 @@ public ISymbolNode GetFieldRvaData(FieldDesc field) public override void Dispose() { - Array.Clear(_corInfoImpls); + // Workaround for https://github.com/dotnet/runtime/issues/23103. + // ManifestMetadataTable.Dispose() allows to break circular reference + // ConcurrentBag -> EcmaModule -> EcmaAssembly -> ReadyToRunCompilerContext -> ... -> ConcurrentBag. + // This circular reference along with #23103 prevents objects from being collected by GC. + _nodeFactory.ManifestMetadataTable.Dispose(); } public string GetReproInstructions(MethodDesc method)