Add methods to the compilation graph without a full Entrypoint (#35879)
authorDavid Wrighton <davidwr@microsoft.com>
Wed, 6 May 2020 20:26:14 +0000 (13:26 -0700)
committerGitHub <noreply@github.com>
Wed, 6 May 2020 20:26:14 +0000 (13:26 -0700)
* Add methods to the compilation graph without a full Entrypoint
- There is quite a lot of content needed to provide an actual entrypoint for a method
- These cases don't actually require the entrypoint, they simple express a desire for the method to be compiled if possible
- This change both reduces the final file size substantially as well as reduces the memory footprint of the compiler

src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/AllMethodsOnTypeNode.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperMethodImport.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs

index 643b35f..7d7e9fd 100644 (file)
@@ -38,9 +38,10 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
 
             foreach (MethodDesc method in Type.GetAllMethods())
             {
-                if (!method.IsGenericMethodDefinition && context.CompilationModuleGroup.VersionsWithMethodBody(method))
+                if (!method.IsGenericMethodDefinition &&
+                    context.CompilationModuleGroup.ContainsMethodBody(method, false))
                 {
-                    dependencies.Add(context.MethodEntrypoint(method), $"Method on type {Type.ToString()}");
+                    dependencies.Add(context.CompiledMethodNode(method), $"Method on type {Type.ToString()}");
                 }
             }
 
index dbf1068..4002bfd 100644 (file)
@@ -47,12 +47,11 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             {
                 // Require compilation of the canonical version for instantiating stubs
                 MethodDesc canonMethod = _method.Method.GetCanonMethodTarget(CanonicalFormKind.Specific);
-                ISymbolNode canonMethodNode = factory.MethodEntrypoint(
-                    new MethodWithToken(canonMethod, _method.Token, constrainedType: null),
-                    isUnboxingStub: false,
-                    isInstantiatingStub: false,
-                    isPrecodeImportRequired: false);
-                yield return new DependencyListEntry(canonMethodNode, "Canonical method for instantiating stub");
+                if (factory.CompilationModuleGroup.ContainsMethodBody(canonMethod, false))
+                {
+                    ISymbolNode canonMethodNode = factory.CompiledMethodNode(canonMethod);
+                    yield return new DependencyListEntry(canonMethodNode, "Canonical method for instantiating stub");
+                }
             }
         }
 
index 9ddbe79..e4b76f7 100644 (file)
@@ -67,15 +67,12 @@ namespace ILCompiler.DependencyAnalysis
             _markingComplete = true;
         }
 
-        public IMethodNode MethodEntrypoint(MethodDesc method)
+        public IMethodNode CompiledMethodNode(MethodDesc method)
         {
             EcmaModule module = ((EcmaMethod)method.GetTypicalMethodDefinition()).Module;
             ModuleToken moduleToken = Resolver.GetModuleTokenForMethod(method, throwIfNotFound: true);
-            return MethodEntrypoint(
-                new MethodWithToken(method, moduleToken, constrainedType: null),
-                isUnboxingStub: false,
-                isInstantiatingStub: false,
-                isPrecodeImportRequired: false);
+
+            return CreateMethodEntrypointNodeHelper(new MethodWithToken(method, moduleToken, constrainedType: null));
         }
 
         private NodeCache<TypeDesc, AllMethodsOnTypeNode> _allMethodsOnType;
@@ -427,7 +424,10 @@ namespace ILCompiler.DependencyAnalysis
                 MethodDesc method = methodNode.Method;
                 MethodWithGCInfo methodCodeNode = methodNode as MethodWithGCInfo;
 #if DEBUG
-                IMethodNode methodNodeDebug = MethodEntrypoint(method);
+                EcmaModule module = ((EcmaMethod)method.GetTypicalMethodDefinition()).Module;
+                ModuleToken moduleToken = Resolver.GetModuleTokenForMethod(method, throwIfNotFound: true);
+
+                IMethodNode methodNodeDebug = MethodEntrypoint(new MethodWithToken(method, moduleToken, constrainedType: null), false, false, false);
                 MethodWithGCInfo methodCodeNodeDebug = methodNodeDebug as MethodWithGCInfo;
                 if (methodCodeNodeDebug == null && methodNodeDebug is LocalMethodImport localMethodImport)
                 {
index a03c94d..3b3f323 100644 (file)
@@ -196,8 +196,11 @@ namespace ILCompiler
             public void AddCompilationRoot(MethodDesc method, string reason)
             {
                 MethodDesc canonMethod = method.GetCanonMethodTarget(CanonicalFormKind.Specific);
-                IMethodNode methodEntryPoint = _factory.MethodEntrypoint(canonMethod);
-                _rootAdder(methodEntryPoint, reason);
+                if (_factory.CompilationModuleGroup.ContainsMethodBody(canonMethod, false))
+                {
+                    IMethodNode methodEntryPoint = _factory.CompiledMethodNode(canonMethod);
+                    _rootAdder(methodEntryPoint, reason);
+                }
             }
         }
     }