Do not compute debug names of reflection objects (#86880)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Tue, 30 May 2023 05:45:14 +0000 (14:45 +0900)
committerGitHub <noreply@github.com>
Tue, 30 May 2023 05:45:14 +0000 (14:45 +0900)
We're spending 5% of Stage2 app startup computing debug names.

This code originates from .NET Native where we had a "release mode with developer experience mode enabled" mode that tried to make troubleshooting trimming issues easier. One of the things it did was providing names of things in the debugger. Since we lack compiler support for this, developer experience mode is always enabled right now.

Since in .NET 5+ people are not supposed to troubleshoot trimming issues in the debugger, this mode doesn't make much sense (we also don't have a managed debugger to surface the `DebuggerDisplay` anyway)

src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceState.cs [deleted file]
src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs

diff --git a/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceState.cs b/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceState.cs
deleted file mode 100644 (file)
index 78a8de1..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-
-namespace System.Runtime.CompilerServices
-{
-    internal static class DeveloperExperienceState
-    {
-        public static bool DeveloperExperienceModeEnabled
-        {
-            get
-            {
-                return true;  // ILC will rewrite to this "return false" if run with "/buildType:ret"
-            }
-        }
-    }
-}
index 945077f..3ba50b4 100644 (file)
     <Compile Include="$(CompilerCommonPath)\Internal\LowLevelLinq\LowLevelEnumerable.ToArray.cs">
       <Link>Internal\LowLevelLinq\LowLevelEnumerable.ToArray.cs</Link>
     </Compile>
-    <Compile Include="$(AotCommonPath)\System\Runtime\CompilerServices\DeveloperExperienceState.cs">
-      <Link>System\Runtime\CompilerServices\DeveloperExperienceState.cs</Link>
-    </Compile>
     <Compile Include="$(CompilerCommonPath)\Internal\Runtime\CanonTypeKind.cs">
       <Link>Internal\Runtime\CanonTypeKind.cs</Link>
     </Compile>
index da4d374..8b0ba5c 100644 (file)
@@ -18,7 +18,6 @@ namespace System.Reflection.Runtime.EventInfos
     //
     // The runtime's implementation of EventInfo's
     //
-    [DebuggerDisplay("{_debugName}")]
     internal abstract partial class RuntimeEventInfo : EventInfo
     {
         protected RuntimeEventInfo(RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)
@@ -120,18 +119,13 @@ namespace System.Reflection.Runtime.EventInfos
 
         protected RuntimeEventInfo WithDebugName()
         {
-            bool populateDebugNames = DeveloperExperienceState.DeveloperExperienceModeEnabled;
 #if DEBUG
-            populateDebugNames = true;
-#endif
-            if (!populateDebugNames)
-                return this;
-
             if (_debugName == null)
             {
                 _debugName = "Constructing..."; // Protect against any inadvertent reentrancy.
                 _debugName = MetadataName;
             }
+#endif
             return this;
         }
 
@@ -174,6 +168,8 @@ namespace System.Reflection.Runtime.EventInfos
         private volatile MethodInfo _lazyAdder;
         private volatile MethodInfo _lazyRemover;
 
+#if DEBUG
         private string _debugName;
+#endif
     }
 }
index 58dd95e..e0e7058 100644 (file)
@@ -22,7 +22,6 @@ namespace System.Reflection.Runtime.FieldInfos
     //
     // The Runtime's implementation of fields.
     //
-    [DebuggerDisplay("{_debugName}")]
     internal abstract partial class RuntimeFieldInfo : FieldInfo
     {
         //
@@ -229,18 +228,13 @@ namespace System.Reflection.Runtime.FieldInfos
 
         protected RuntimeFieldInfo WithDebugName()
         {
-            bool populateDebugNames = DeveloperExperienceState.DeveloperExperienceModeEnabled;
 #if DEBUG
-            populateDebugNames = true;
-#endif
-            if (!populateDebugNames)
-                return this;
-
             if (_debugName == null)
             {
                 _debugName = "Constructing..."; // Protect against any inadvertent reentrancy.
                 _debugName = MetadataName;
             }
+#endif
             return this;
         }
 
@@ -264,6 +258,8 @@ namespace System.Reflection.Runtime.FieldInfos
 
         private volatile Type _lazyFieldType;
 
+#if DEBUG
         private string _debugName;
+#endif
     }
 }
index c34c75a..8b5ff9b 100644 (file)
@@ -20,7 +20,6 @@ namespace System.Reflection.Runtime.MethodInfos
     //
     // Abstract base class for RuntimeNamedMethodInfo, RuntimeConstructedGenericMethodInfo.
     //
-    [DebuggerDisplay("{_debugName}")]
     internal abstract partial class RuntimeMethodInfo : MethodInfo
     {
         protected RuntimeMethodInfo()
@@ -447,21 +446,18 @@ namespace System.Reflection.Runtime.MethodInfos
 
         protected RuntimeMethodInfo WithDebugName()
         {
-            bool populateDebugNames = DeveloperExperienceState.DeveloperExperienceModeEnabled;
 #if DEBUG
-            populateDebugNames = true;
-#endif
-            if (!populateDebugNames)
-                return this;
-
             if (_debugName == null)
             {
                 _debugName = "Constructing..."; // Protect against any inadvertent reentrancy.
                 _debugName = RuntimeName;
             }
+#endif
             return this;
         }
 
+#if DEBUG
         private string _debugName;
+#endif
     }
 }
index 50ea6c7..b9eec1e 100644 (file)
@@ -22,7 +22,6 @@ namespace System.Reflection.Runtime.PropertyInfos
     //
     // The runtime's implementation of PropertyInfo's
     //
-    [DebuggerDisplay("{_debugName}")]
     internal abstract partial class RuntimePropertyInfo : PropertyInfo
     {
         //
@@ -272,18 +271,13 @@ namespace System.Reflection.Runtime.PropertyInfos
 
         protected RuntimePropertyInfo WithDebugName()
         {
-            bool populateDebugNames = DeveloperExperienceState.DeveloperExperienceModeEnabled;
 #if DEBUG
-            populateDebugNames = true;
-#endif
-            if (!populateDebugNames)
-                return this;
-
             if (_debugName == null)
             {
                 _debugName = "Constructing..."; // Protect against any inadvertent reentrancy.
                 _debugName = MetadataName;
             }
+#endif
             return this;
         }
 
@@ -350,6 +344,8 @@ namespace System.Reflection.Runtime.PropertyInfos
 
         private volatile Type _lazyPropertyType;
 
+#if DEBUG
         private string _debugName;
+#endif
     }
 }
index 74ad46c..7adc679 100644 (file)
@@ -32,7 +32,6 @@ namespace System.Reflection.Runtime.TypeInfos
     //   - Overrides many "NotImplemented" members in TypeInfo with abstracts so failure to implement
     //     shows up as build error.
     //
-    [DebuggerDisplay("{_debugName}")]
     internal abstract partial class RuntimeTypeInfo : RuntimeType, ICloneable
     {
         protected RuntimeTypeInfo()
@@ -731,21 +730,16 @@ namespace System.Reflection.Runtime.TypeInfos
         // Note: This can be (and is) called multiple times. We do not do this work in the constructor as calling ToString()
         // in the constructor causes some serious recursion issues.
         //
-        internal void EstablishDebugName()
+        internal RuntimeTypeInfo EstablishDebugName()
         {
-            bool populateDebugNames = DeveloperExperienceState.DeveloperExperienceModeEnabled;
 #if DEBUG
-            populateDebugNames = true;
-#endif
-            if (!populateDebugNames)
-                return;
-
             if (_debugName == null)
             {
                 _debugName = "Constructing..."; // Protect against any inadvertent reentrancy.
                 _debugName = ToString() ?? "";
             }
-            return;
+#endif
+            return this;
         }
 
         //
@@ -884,6 +878,8 @@ namespace System.Reflection.Runtime.TypeInfos
 
         private volatile TypeClassification _lazyClassification;
 
+#if DEBUG
         private string _debugName;
+#endif
     }
 }