Integration of changes in shared files from runtimelab/NativeAOT (#61655)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Fri, 19 Nov 2021 14:29:38 +0000 (23:29 +0900)
committerGitHub <noreply@github.com>
Fri, 19 Nov 2021 14:29:38 +0000 (06:29 -0800)
12 files changed:
src/coreclr/gc/gcload.cpp
src/coreclr/jit/importer.cpp
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs
src/coreclr/tools/Common/Compiler/DevirtualizationManager.cs
src/coreclr/tools/Common/Compiler/DisplayNameHelpers.cs
src/coreclr/tools/Common/Compiler/Logger.cs
src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageContainer.cs
src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageOrigin.cs
src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/README.md
src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs
src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs

index 0549ca8..12cc857 100644 (file)
@@ -78,10 +78,12 @@ GC_Initialize(
     // various components may want to query the current configuration.
     GCConfig::Initialize();
 
+#ifndef FEATURE_REDHAWK // GCToOSInterface is initialized directly
     if (!GCToOSInterface::Initialize())
     {
         return E_FAIL;
     }
+#endif
 
     IGCHandleManager* handleManager = CreateGCHandleManager();
     if (handleManager == nullptr)
index 8f6e467..0435cee 100644 (file)
@@ -20902,6 +20902,14 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall*           call,
         return;
     }
 
+    // Delegate Invoke method doesn't have a body and gets special cased instead.
+    // Don't even bother trying to inline it.
+    if (call->IsDelegateInvoke())
+    {
+        inlineResult.NoteFatal(InlineObservation::CALLEE_HAS_NO_BODY);
+        return;
+    }
+
     // Tail recursion elimination takes precedence over inlining.
     // TODO: We may want to do some of the additional checks from fgMorphCall
     // here to reduce the chance we don't inline a call that won't be optimized
index 1dc0fd8..fa0828f 100644 (file)
@@ -193,6 +193,12 @@ namespace ILCompiler
                 if (oldModuleData == null)
                 {
                     peReader = OpenPEFile(filePath, out mappedViewAccessor);
+
+#if !READYTORUN
+                if (peReader.HasMetadata && (peReader.PEHeaders.CorHeader.Flags & (CorFlags.ILLibrary | CorFlags.ILOnly)) == 0)
+                    throw new NotSupportedException($"Error: C++/CLI is not supported: '{filePath}'");
+#endif
+
                     pdbReader = PortablePdbSymbolReader.TryOpenEmbedded(peReader, GetMetadataStringDecoder()) ?? OpenAssociatedSymbolFile(filePath, peReader);
                 }
                 else
index 455f6b4..17135f6 100644 (file)
@@ -174,6 +174,12 @@ namespace ILCompiler.DependencyAnalysis.X64
             Builder.EmitByte(0xC3);
         }
 
+        public void EmitCompareToZero(Register reg)
+        {
+            AddrMode rexAddrMode = new AddrMode(Register.RegDirect | reg, null, 0, 0, AddrModeSize.Int64);
+            EmitIndirInstructionSize(0x84, reg, ref rexAddrMode);
+        }
+
         public void EmitZeroReg(Register reg)
         {
             // High 32 bits get cleared automatically when using 32bit registers
index aba4134..f7bd609 100644 (file)
@@ -201,5 +201,16 @@ namespace ILCompiler
 
             return impl;
         }
+
+#if !READYTORUN
+        /// <summary>
+        /// Gets a value indicating whether it might be possible to obtain a constructed type data structure for the given type.
+        /// </summary>
+        /// <remarks>
+        /// This is a bit of a hack, but devirtualization manager has a global view of all allocated types
+        /// so it can answer this question.
+        /// </remarks>
+        public virtual bool CanConstructType(TypeDesc type) => true;
+#endif
     }
 }
index 674d54a..b1faf0d 100644 (file)
@@ -1,6 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System;
 using System.Text;
 
 using Internal.TypeSystem;
@@ -11,6 +12,21 @@ namespace ILCompiler
 {
     internal static class DisplayNameHelpers
     {
+        public static string GetDisplayName(this TypeSystemEntity entity)
+        {
+            return entity switch
+            {
+                MethodDesc method => method.GetDisplayName(),
+                FieldDesc field => field.GetDisplayName(),
+                TypeDesc type => type.GetDisplayName(),
+#if !READYTORUN
+                PropertyPseudoDesc property => property.GetDisplayName(),
+                EventPseudoDesc @event => @event.GetDisplayName(),
+#endif
+                _ => throw new InvalidOperationException(),
+            };
+        }
+
         public static string GetDisplayName(this MethodDesc method)
         {
             var sb = new StringBuilder();
index b75435c..af84d21 100644 (file)
@@ -94,13 +94,23 @@ namespace ILCompiler
 
         internal bool IsWarningSuppressed(int code, MessageOrigin origin)
         {
+            // This is causing too much noise
+            // https://github.com/dotnet/runtimelab/issues/1591
+            if (code == 2110 || code == 2111 || code == 2113 || code == 2115)
+                return true;
+
             if (_suppressedWarnings.Contains(code))
                 return true;
 
             IEnumerable<CustomAttributeValue<TypeDesc>> suppressions = null;
 
             // TODO: Suppressions with different scopes
-            
+
+            if (origin.MemberDefinition is TypeDesc type)
+            {
+                var ecmaType = type.GetTypeDefinition() as EcmaType;
+                suppressions = ecmaType?.GetDecodedCustomAttributes("System.Diagnostics.CodeAnalysis", "UnconditionalSuppressMessageAttribute");
+            }
 
             if (origin.MemberDefinition is MethodDesc method)
             {
index 7977343..f0a4afd 100644 (file)
@@ -1,8 +1,9 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
 using System.Text;
 using Mono.Cecil;
@@ -40,7 +41,7 @@ namespace Mono.Linker
                /// Create an error message.
                /// </summary>
                /// <param name="text">Humanly readable message describing the error</param>
-               /// <param name="code">Unique error ID. Please see https://github.com/mono/linker/blob/main/docs/error-codes.md
+               /// <param name="code">Unique error ID. Please see https://github.com/dotnet/linker/blob/main/docs/error-codes.md
                /// for the list of errors and possibly add a new one</param>
                /// <param name="subcategory">Optionally, further categorize this error</param>
                /// <param name="origin">Filename, line, and column where the error was found</param>
@@ -80,7 +81,7 @@ namespace Mono.Linker
                /// </summary>
                /// <param name="context">Context with the relevant warning suppression info.</param>
                /// <param name="text">Humanly readable message describing the warning</param>
-               /// <param name="code">Unique warning ID. Please see https://github.com/mono/linker/blob/main/docs/error-codes.md
+               /// <param name="code">Unique warning ID. Please see https://github.com/dotnet/linker/blob/main/docs/error-codes.md
                /// for the list of warnings and possibly add a new one</param>
                /// /// <param name="origin">Filename or member where the warning is coming from</param>
                /// <param name="subcategory">Optionally, further categorize this warning</param>
@@ -140,14 +141,31 @@ namespace Mono.Linker
                        return new MessageContainer (MessageCategory.Warning, text, code, subcategory, origin);
                }
 
+               public bool IsWarningMessage ([NotNullWhen (true)] out int? code)
+               {
+                       code = null;
+
+                       if (Category is MessageCategory.Warning or MessageCategory.WarningAsError) {
+                               // Warning messages always have a code.
+                               code = Code!;
+                               return true;
+                       }
+
+                       return false;
+               }
+
                static bool TryLogSingleWarning (LinkContext context, int code, MessageOrigin origin, string subcategory)
                {
                        if (subcategory != MessageSubCategory.TrimAnalysis)
                                return false;
 
-                       Debug.Assert (origin.MemberDefinition != null);
-                       var declaringType = origin.MemberDefinition?.DeclaringType ?? (origin.MemberDefinition as TypeDefinition);
-                       var assembly = declaringType.Module.Assembly;
+                       Debug.Assert (origin.Provider != null);
+                       var assembly = origin.Provider switch {
+                               AssemblyDefinition asm => asm,
+                               TypeDefinition type => type.Module.Assembly,
+                               IMemberDefinition member => member.DeclaringType.Module.Assembly,
+                               _ => throw new NotSupportedException ()
+                       };
 
                        Debug.Assert (assembly != null);
                        if (assembly == null)
@@ -228,17 +246,22 @@ namespace Mono.Linker
                                sb.Append (" ")
                                        .Append (cat)
                                        .Append (" IL")
-                                       .Append (Code.Value.ToString ("D4"))
+                                       // Warning and error messages always have a code.
+                                       .Append (Code!.Value.ToString ("D4"))
                                        .Append (": ");
                        } else {
                                sb.Append (" ");
                        }
 
-                       if (Origin?.MemberDefinition != null) {
-                               if (Origin?.MemberDefinition is MethodDefinition method)
+                       if (Origin?.Provider != null) {
+                               if (Origin?.Provider is MethodDefinition method)
                                        sb.Append (method.GetDisplayName ());
+                               else if (Origin?.Provider is IMemberDefinition member)
+                                       sb.Append (member.FullName);
+                               else if (Origin?.Provider is AssemblyDefinition assembly)
+                                       sb.Append (assembly.Name.Name);
                                else
-                                       sb.Append (Origin?.MemberDefinition.FullName);
+                                       throw new NotSupportedException ();
 
                                sb.Append (": ");
                        }
index 3642167..84357b2 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
+using System.Diagnostics;
 using System.Linq;
 using System.Text;
 using Mono.Cecil;
@@ -13,10 +14,14 @@ namespace Mono.Linker
        {
 #nullable enable
                public string? FileName { get; }
-               public IMemberDefinition? MemberDefinition { get; }
-
-               readonly IMemberDefinition _suppressionContextMember;
-               public IMemberDefinition? SuppressionContextMember { get => _suppressionContextMember ?? MemberDefinition; }
+               public ICustomAttributeProvider? Provider { get; }
+               readonly ICustomAttributeProvider _suppressionContextMember;
+               public ICustomAttributeProvider? SuppressionContextMember {
+                       get {
+                               Debug.Assert (_suppressionContextMember == null || _suppressionContextMember is IMemberDefinition || _suppressionContextMember is AssemblyDefinition);
+                               return _suppressionContextMember ?? Provider;
+                       }
+               }
 #nullable disable
                public int SourceLine { get; }
                public int SourceColumn { get; }
@@ -24,8 +29,13 @@ namespace Mono.Linker
 
                const int HiddenLineNumber = 0xfeefee;
 
-               public MessageOrigin (IMemberDefinition memberDefinition)
-                       : this (memberDefinition, null)
+               public MessageOrigin (IMemberDefinition memberDefinition, int? ilOffset = null)
+                       : this (memberDefinition as ICustomAttributeProvider, ilOffset)
+               {
+               }
+
+               public MessageOrigin (ICustomAttributeProvider provider)
+                       : this (provider, null)
                {
                }
 
@@ -34,31 +44,43 @@ namespace Mono.Linker
                        FileName = fileName;
                        SourceLine = sourceLine;
                        SourceColumn = sourceColumn;
-                       MemberDefinition = null;
+                       Provider = null;
                        _suppressionContextMember = null;
                        ILOffset = null;
                }
 
-               public MessageOrigin (IMemberDefinition memberDefinition, int? ilOffset)
-                       : this (memberDefinition, ilOffset, null)
+               public MessageOrigin (ICustomAttributeProvider provider, int? ilOffset)
+                       : this (provider, ilOffset, null)
                {
                }
 
-               public MessageOrigin (IMemberDefinition memberDefinition, int? ilOffset, IMemberDefinition suppressionContextMember)
+               public MessageOrigin (ICustomAttributeProvider provider, int? ilOffset, ICustomAttributeProvider suppressionContextMember)
                {
+                       Debug.Assert (provider == null || provider is IMemberDefinition || provider is AssemblyDefinition);
+                       Debug.Assert (suppressionContextMember == null || suppressionContextMember is IMemberDefinition || provider is AssemblyDefinition);
                        FileName = null;
-                       MemberDefinition = memberDefinition;
+                       Provider = provider;
                        _suppressionContextMember = suppressionContextMember;
                        SourceLine = 0;
                        SourceColumn = 0;
                        ILOffset = ilOffset;
                }
 
+               public MessageOrigin (MessageOrigin other, IMemberDefinition suppressionContextMember)
+               {
+                       FileName = other.FileName;
+                       Provider = other.Provider;
+                       _suppressionContextMember = suppressionContextMember;
+                       SourceLine = other.SourceLine;
+                       SourceColumn = other.SourceColumn;
+                       ILOffset = other.ILOffset;
+               }
+
                public override string ToString ()
                {
                        int sourceLine = SourceLine, sourceColumn = SourceColumn;
                        string fileName = FileName;
-                       if (MemberDefinition is MethodDefinition method &&
+                       if (Provider is MethodDefinition method &&
                                method.DebugInformation.HasSequencePoints) {
                                var offset = ILOffset ?? 0;
                                SequencePoint correspondingSequencePoint = method.DebugInformation.SequencePoints
@@ -94,20 +116,24 @@ namespace Mono.Linker
                }
 
                public bool Equals (MessageOrigin other) =>
-                       (FileName, MemberDefinition, SourceLine, SourceColumn, ILOffset) == (other.FileName, other.MemberDefinition, other.SourceLine, other.SourceColumn, other.ILOffset);
+                       (FileName, Provider, SourceLine, SourceColumn, ILOffset) == (other.FileName, other.Provider, other.SourceLine, other.SourceColumn, other.ILOffset);
 
                public override bool Equals (object obj) => obj is MessageOrigin messageOrigin && Equals (messageOrigin);
-               public override int GetHashCode () => (FileName, MemberDefinition, SourceLine, SourceColumn).GetHashCode ();
+               public override int GetHashCode () => (FileName, Provider, SourceLine, SourceColumn).GetHashCode ();
                public static bool operator == (MessageOrigin lhs, MessageOrigin rhs) => lhs.Equals (rhs);
                public static bool operator != (MessageOrigin lhs, MessageOrigin rhs) => !lhs.Equals (rhs);
 
                public int CompareTo (MessageOrigin other)
                {
-                       if (MemberDefinition != null && other.MemberDefinition != null) {
-                               TypeDefinition thisTypeDef = (MemberDefinition as TypeDefinition) ?? MemberDefinition.DeclaringType;
-                               TypeDefinition otherTypeDef = (other.MemberDefinition as TypeDefinition) ?? other.MemberDefinition.DeclaringType;
-                               int result = (thisTypeDef?.Module?.Assembly?.Name?.Name, thisTypeDef?.Name, MemberDefinition?.Name).CompareTo
-                                       ((otherTypeDef?.Module?.Assembly?.Name?.Name, otherTypeDef?.Name, other.MemberDefinition?.Name));
+                       if (Provider != null && other.Provider != null) {
+                               var thisMember = Provider as IMemberDefinition;
+                               var otherMember = other.Provider as IMemberDefinition;
+                               TypeDefinition thisTypeDef = (Provider as TypeDefinition) ?? (Provider as IMemberDefinition)?.DeclaringType;
+                               TypeDefinition otherTypeDef = (other.Provider as TypeDefinition) ?? (other.Provider as IMemberDefinition)?.DeclaringType;
+                               var thisAssembly = thisTypeDef?.Module.Assembly ?? Provider as AssemblyDefinition;
+                               var otherAssembly = otherTypeDef?.Module.Assembly ?? other.Provider as AssemblyDefinition;
+                               int result = (thisAssembly.Name.Name, thisTypeDef?.Name, thisMember?.Name).CompareTo
+                                       ((otherAssembly.Name.Name, otherTypeDef?.Name, otherMember?.Name));
                                if (result != 0)
                                        return result;
 
@@ -115,7 +141,7 @@ namespace Mono.Linker
                                        return ILOffset.Value.CompareTo (other.ILOffset);
 
                                return ILOffset == null ? (other.ILOffset == null ? 0 : 1) : -1;
-                       } else if (MemberDefinition == null && other.MemberDefinition == null) {
+                       } else if (Provider == null && other.Provider == null) {
                                if (FileName != null && other.FileName != null) {
                                        return string.Compare (FileName, other.FileName);
                                } else if (FileName == null && other.FileName == null) {
@@ -125,7 +151,7 @@ namespace Mono.Linker
                                return (FileName == null) ? 1 : -1;
                        }
 
-                       return (MemberDefinition == null) ? 1 : -1;
+                       return (Provider == null) ? 1 : -1;
                }
        }
 }
index b894c9d..8833326 100644 (file)
@@ -1 +1 @@
-Sources from the mono/linker repo at commit 012efef292663aa38f9047896942cdcc8765b8e0.
\ No newline at end of file
+Sources from the dotnet/linker repo at commit c0567db0b9088e2ad4144cd0fe2a985611ec28f0.
index eee208c..434f9a9 100644 (file)
@@ -84,6 +84,7 @@ namespace Internal.Runtime
         ThreadStaticIndex = 210,
         LoopHijackFlag = 211,
         ImportAddressTables = 212,
+        ModuleInitializerList = 213,
 
         // Sections 300 - 399 are reserved for RhFindBlob backwards compatibility
         ReadonlyBlobRegionStart = 300,
index b23de8a..6315463 100644 (file)
@@ -1283,25 +1283,38 @@ namespace Internal.JitInterface
                 methodWithTokenDecl = new MethodWithToken(decl, declToken, null, false, null, devirtualizedMethodOwner: decl.OwningType);
             }
             MethodWithToken methodWithTokenImpl;
+#endif
 
             if (decl == originalImpl)
             {
+#if READYTORUN
                 methodWithTokenImpl = methodWithTokenDecl;
+#endif
                 if (info->pResolvedTokenVirtualMethod != null)
                 {
                     info->resolvedTokenDevirtualizedMethod = *info->pResolvedTokenVirtualMethod;
                 }
                 else
                 {
-                    info->resolvedTokenDevirtualizedMethod = CreateResolvedTokenFromMethod(this, decl, methodWithTokenDecl);
+                    info->resolvedTokenDevirtualizedMethod = CreateResolvedTokenFromMethod(this, decl
+#if READYTORUN
+                        , methodWithTokenDecl
+#endif
+                        );
                 }
                 info->resolvedTokenDevirtualizedUnboxedMethod = default(CORINFO_RESOLVED_TOKEN);
             }
             else
             {
+#if READYTORUN
                 methodWithTokenImpl = new MethodWithToken(nonUnboxingImpl, resolver.GetModuleTokenForMethod(nonUnboxingImpl.GetTypicalMethodDefinition()), null, unboxingStub, null, devirtualizedMethodOwner: impl.OwningType);
+#endif
 
-                info->resolvedTokenDevirtualizedMethod = CreateResolvedTokenFromMethod(this, impl, methodWithTokenImpl);
+                info->resolvedTokenDevirtualizedMethod = CreateResolvedTokenFromMethod(this, impl
+#if READYTORUN
+                    , methodWithTokenImpl
+#endif
+                    );
 
                 if (unboxingStub)
                 {
@@ -1315,6 +1328,7 @@ namespace Internal.JitInterface
                 }
             }
 
+#if READYTORUN
             // Testing has not shown that concerns about virtual matching are significant
             // Only generate verification for builds with the stress mode enabled
             if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout)
@@ -1322,9 +1336,6 @@ namespace Internal.JitInterface
                 ISymbolNode virtualResolutionNode = _compilation.SymbolNodeFactory.CheckVirtualFunctionOverride(methodWithTokenDecl, objType, methodWithTokenImpl);
                 _methodCodeNode.Fixups.Add(virtualResolutionNode);
             }
-#else
-            info->resolvedTokenDevirtualizedMethod = default(CORINFO_RESOLVED_TOKEN);
-            info->resolvedTokenDevirtualizedUnboxedMethod = default(CORINFO_RESOLVED_TOKEN);
 #endif
             info->detail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_SUCCESS;
             info->devirtualizedMethod = ObjectToHandle(impl);
@@ -1333,9 +1344,21 @@ namespace Internal.JitInterface
 
             return true;
 
+            static CORINFO_RESOLVED_TOKEN CreateResolvedTokenFromMethod(CorInfoImpl jitInterface, MethodDesc method
 #if READYTORUN
-            static CORINFO_RESOLVED_TOKEN CreateResolvedTokenFromMethod(CorInfoImpl jitInterface, MethodDesc method, MethodWithToken methodWithToken)
+                , MethodWithToken methodWithToken
+#endif
+                )
             {
+#if !READYTORUN
+                MethodDesc unboxedMethodDesc = method.IsUnboxingThunk() ? method.GetUnboxedMethod() : method;
+                var methodWithToken = new
+                {
+                    Method = unboxedMethodDesc,
+                    OwningType = unboxedMethodDesc.OwningType,
+                };
+#endif
+
                 CORINFO_RESOLVED_TOKEN result = default(CORINFO_RESOLVED_TOKEN);
                 MethodILScope scope = jitInterface._compilation.GetMethodIL(methodWithToken.Method);
                 if (scope == null)
@@ -1344,19 +1367,22 @@ namespace Internal.JitInterface
                 }
                 result.tokenScope = jitInterface.ObjectToHandle(scope);
                 result.tokenContext = jitInterface.contextFromMethod(method);
+#if READYTORUN
                 result.token = methodWithToken.Token.Token;
                 if (methodWithToken.Token.TokenType != CorTokenType.mdtMethodDef)
                 {
                     Debug.Assert(false); // This should never happen, but we protect against total failure with the throw below.
                     throw new RequiresRuntimeJitException("Attempt to devirtualize and unable to create token for devirtualized method");
                 }
+#else
+                result.token = (mdToken)0x06BAAAAD;
+#endif
                 result.tokenType = CorInfoTokenKind.CORINFO_TOKENKIND_DevirtualizedMethod;
                 result.hClass = jitInterface.ObjectToHandle(methodWithToken.OwningType);
                 result.hMethod = jitInterface.ObjectToHandle(method);
 
                 return result;
             }
-#endif
         }
 
         private CORINFO_METHOD_STRUCT_* getUnboxedEntry(CORINFO_METHOD_STRUCT_* ftn, ref bool requiresInstMethodTableArg)
@@ -3791,7 +3817,11 @@ namespace Internal.JitInterface
                 }
                 else
                 {
-                    ComputeJitPgoInstrumentationSchema(ObjectToHandle, pgoResultsSchemas, out var nativeSchemas, out var instrumentationData);
+                    ComputeJitPgoInstrumentationSchema(ObjectToHandle, pgoResultsSchemas, out var nativeSchemas, out var instrumentationData
+#if !READYTORUN
+                        , _compilation.CanConstructType
+#endif
+                        );
 
                     pgoResults.pInstrumentationData = (byte*)GetPin(instrumentationData);
                     pgoResults.countSchemaItems = (uint)nativeSchemas.Length;