From 3310ff32c7b32bd09fdeb00a3b79d9dda12b7ce7 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Mon, 23 Oct 2017 10:19:26 -0700 Subject: [PATCH] ProjectX: Set the canonical unboxing stub as the template method for GVMs of structs For GVMs that use the canonical implementation, if their owning types are structs, the canonical template should be the unboxing stub instead of the real target. However, the template signature should not have the IsUnboxingStub set because all template lookups performed at runtime are performed with this flag not set, since it can't always be conveniently computed for a concrete method before looking up its template. [tfs-changeset: 1678892] --- .../NativeLayoutVertexNode.cs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs index 74bd816f081..aa50c9e5fa3 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs @@ -98,11 +98,6 @@ public enum MethodEntryFlags { CreateInstantiatedSignature = 1, SaveEntryPoint = 2, - /// - /// IsUnboxingStub is not set for template methods (all template lookups performed at runtime are done with this flag not set, - /// since it can't always be conveniently computed for a concrete method before looking up its template). - /// - DisableUnboxingStub = 4 } protected readonly MethodDesc _method; @@ -226,9 +221,8 @@ private Vertex GetContainingTypeVertex(NodeFactory factory) protected virtual IMethodNode GetMethodEntrypointNode(NodeFactory factory, out bool unboxingStub) { - unboxingStub = (_flags & MethodEntryFlags.DisableUnboxingStub) != 0 ? false : _method.OwningType.IsValueType && !_method.Signature.IsStatic; + unboxingStub = _method.OwningType.IsValueType && !_method.Signature.IsStatic; IMethodNode methodEntryPointNode = factory.MethodEntrypoint(_method, unboxingStub); - return methodEntryPointNode; } } @@ -672,7 +666,7 @@ internal sealed class NativeLayoutTemplateMethodSignatureVertexNode : NativeLayo protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateMethodSignatureVertexNode_" + factory.NameMangler.GetMangledMethodName(_method); public NativeLayoutTemplateMethodSignatureVertexNode(NodeFactory factory, MethodDesc method) - : base(factory, method, MethodEntryFlags.CreateInstantiatedSignature | MethodEntryFlags.SaveEntryPoint | MethodEntryFlags.DisableUnboxingStub) + : base(factory, method, MethodEntryFlags.CreateInstantiatedSignature | (method.IsVirtual ? MethodEntryFlags.SaveEntryPoint : 0)) { } @@ -683,8 +677,19 @@ public override Vertex WriteVertex(NodeFactory factory) Vertex methodEntryVertex = base.WriteVertex(factory); return SetSavedVertex(factory.MetadataManager.NativeLayoutInfo.TemplatesSection.Place(methodEntryVertex)); } - } + protected override IMethodNode GetMethodEntrypointNode(NodeFactory factory, out bool unboxingStub) + { + // Only GVM templates need entry points. + Debug.Assert(_method.IsVirtual); + unboxingStub = _method.OwningType.IsValueType; + IMethodNode methodEntryPointNode = factory.MethodEntrypoint(_method, unboxingStub); + // Note: We don't set the IsUnboxingStub flag on template methods (all template lookups performed at runtime are performed with this flag not set, + // since it can't always be conveniently computed for a concrete method before looking up its template) + unboxingStub = false; + return methodEntryPointNode; + } + } public sealed class NativeLayoutDictionarySignatureNode : NativeLayoutSavedVertexNode {