diff --git a/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs b/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs index 5e62ef34cea..d3ce3de8d3c 100644 --- a/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs +++ b/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs @@ -26,14 +26,16 @@ public MultiFileCompilationModuleGroup(TypeSystemContext context, IEnumerable @@ -125,7 +127,7 @@ public override bool ShouldPromoteToFullType(TypeDesc type) public override bool PresenceOfEETypeImpliesAllMethodsOnType(TypeDesc type) { - return (type.HasInstantiation || type.IsArray) && ShouldProduceFullVTable(type) && + return (type.HasInstantiation || type.IsArray) && ShouldProduceFullVTable(type) && type.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Any); } } diff --git a/src/ILCompiler.ReadyToRun/src/Compiler/ReadyToRunSingleAssemblyCompilationModuleGroup.cs b/src/ILCompiler.ReadyToRun/src/Compiler/ReadyToRunSingleAssemblyCompilationModuleGroup.cs new file mode 100644 index 00000000000..dc83eea83fd --- /dev/null +++ b/src/ILCompiler.ReadyToRun/src/Compiler/ReadyToRunSingleAssemblyCompilationModuleGroup.cs @@ -0,0 +1,121 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +using ILCompiler.DependencyAnalysis; +using Internal.TypeSystem; +using Internal.TypeSystem.Ecma; + +namespace ILCompiler +{ + public class ReadyToRunSingleAssemblyCompilationModuleGroup : CompilationModuleGroup + { + private HashSet _compilationModuleSet; + + public ReadyToRunSingleAssemblyCompilationModuleGroup(TypeSystemContext context, IEnumerable compilationModuleSet) + { + _compilationModuleSet = new HashSet(compilationModuleSet); + + // The fake assembly that holds compiler generated types is part of the compilation. + _compilationModuleSet.Add(context.GeneratedAssembly); + } + + public sealed override bool ContainsType(TypeDesc type) + { + if (type is EcmaType ecmaType) + { + return IsModuleInCompilationGroup(ecmaType.EcmaModule); + } + if (type is InstantiatedType instantiatedType) + { + return ContainsType(instantiatedType.GetTypeDefinition()); + } + return true; + } + + public sealed override bool ContainsTypeDictionary(TypeDesc type) + { + return ContainsType(type); + } + + public sealed override bool ContainsMethodBody(MethodDesc method, bool unboxingStub) + { + if (method.HasInstantiation) + return true; + + return ContainsType(method.OwningType); + } + + public sealed override bool ContainsMethodDictionary(MethodDesc method) + { + Debug.Assert(method.GetCanonMethodTarget(CanonicalFormKind.Specific) != method); + return ContainsMethodBody(method, false); + } + + public sealed override ExportForm GetExportTypeForm(TypeDesc type) + { + return ExportForm.None; + } + + public sealed override ExportForm GetExportTypeFormDictionary(TypeDesc type) + { + return ExportForm.None; + } + + public sealed override ExportForm GetExportMethodForm(MethodDesc method, bool unboxingStub) + { + return ExportForm.None; + } + + public override ExportForm GetExportMethodDictionaryForm(MethodDesc method) + { + return ExportForm.None; + } + + private bool IsModuleInCompilationGroup(EcmaModule module) + { + return _compilationModuleSet.Contains(module); + } + + public sealed override bool IsSingleFileCompilation + { + get + { + return false; + } + } + + public sealed override bool ShouldReferenceThroughImportTable(TypeDesc type) + { + return false; + } + + public override bool CanHaveReferenceThroughImportTable + { + get + { + return false; + } + } + + public override bool ShouldProduceFullVTable(TypeDesc type) + { + return ConstructedEETypeNode.CreationAllowed(type); + } + + public override bool ShouldPromoteToFullType(TypeDesc type) + { + return ShouldProduceFullVTable(type); + } + + public override bool PresenceOfEETypeImpliesAllMethodsOnType(TypeDesc type) + { + return (type.HasInstantiation || type.IsArray) && ShouldProduceFullVTable(type) && + type.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Any); + } + } +} diff --git a/src/ILCompiler.ReadyToRun/src/ILCompiler.ReadyToRun.csproj b/src/ILCompiler.ReadyToRun/src/ILCompiler.ReadyToRun.csproj index f6ab9cbe43b..22862b0da4b 100644 --- a/src/ILCompiler.ReadyToRun/src/ILCompiler.ReadyToRun.csproj +++ b/src/ILCompiler.ReadyToRun/src/ILCompiler.ReadyToRun.csproj @@ -62,6 +62,7 @@ + diff --git a/src/ILCompiler/src/Program.cs b/src/ILCompiler/src/Program.cs index e19671dc153..f142742b01e 100644 --- a/src/ILCompiler/src/Program.cs +++ b/src/ILCompiler/src/Program.cs @@ -360,7 +360,7 @@ private int Run(string[] args) } } - if (_multiFile) + if (_multiFile || _isReadyToRunCodeGen) { List inputModules = new List(); @@ -376,7 +376,14 @@ private int Run(string[] args) inputModules.Add(module); } - compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules); + if (_isReadyToRunCodeGen) + { + compilationGroup = new ReadyToRunSingleAssemblyCompilationModuleGroup(typeSystemContext, inputModules); + } + else + { + compilationGroup = new MultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules); + } } else {