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)
+++ /dev/null
-// 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"
- }
- }
- }
-}
<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>
//
// The runtime's implementation of EventInfo's
//
- [DebuggerDisplay("{_debugName}")]
internal abstract partial class RuntimeEventInfo : EventInfo
{
protected RuntimeEventInfo(RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)
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;
}
private volatile MethodInfo _lazyAdder;
private volatile MethodInfo _lazyRemover;
+#if DEBUG
private string _debugName;
+#endif
}
}
//
// The Runtime's implementation of fields.
//
- [DebuggerDisplay("{_debugName}")]
internal abstract partial class RuntimeFieldInfo : FieldInfo
{
//
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;
}
private volatile Type _lazyFieldType;
+#if DEBUG
private string _debugName;
+#endif
}
}
//
// Abstract base class for RuntimeNamedMethodInfo, RuntimeConstructedGenericMethodInfo.
//
- [DebuggerDisplay("{_debugName}")]
internal abstract partial class RuntimeMethodInfo : MethodInfo
{
protected RuntimeMethodInfo()
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
}
}
//
// The runtime's implementation of PropertyInfo's
//
- [DebuggerDisplay("{_debugName}")]
internal abstract partial class RuntimePropertyInfo : PropertyInfo
{
//
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;
}
private volatile Type _lazyPropertyType;
+#if DEBUG
private string _debugName;
+#endif
}
}
// - 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()
// 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;
}
//
private volatile TypeClassification _lazyClassification;
+#if DEBUG
private string _debugName;
+#endif
}
}