Skip to content

Commit

Permalink
Allow preinitializing EventSource (dotnet#101573)
Browse files Browse the repository at this point in the history
We currently don't preinitialize any event sources because they have a finalizer. This is a bit of a problem for places like this: https://github.com/dotnet/runtime/blob/5c01ed22b7468a2bee13b498855dcfcc5ae4da50/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs#L229-L232. We know `IsSupported` is false so we eliminate the branch, but we still need a cctor check because we access a static. The cctor check in a generic method that is instantiated many many many times becomes a death by a thousand papercuts.

Saves 0.7% in size on the stage2 app with EventSource disabled.
  • Loading branch information
MichalStrehovsky authored and michaelgsharp committed May 8, 2024
1 parent 37947de commit 1a838dc
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,14 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack<Method

if (owningType.HasFinalizer)
{
// Finalizer might have observable side effects
return Status.Fail(methodIL.OwningMethod, opcode, "Finalizable class");
// We have a finalizer. There's still a small chance it has been nopped out
// with a feature switch. Check for that.
byte[] finalizerMethodILBytes = _ilProvider.GetMethodIL(owningType.GetFinalizer()).GetILBytes();
if (finalizerMethodILBytes.Length != 1 || finalizerMethodILBytes[0] != (byte)ILOpcode.ret)
{
// Finalizer might have observable side effects
return Status.Fail(methodIL.OwningMethod, opcode, "Finalizable class");
}
}

if (_flowAnnotations.RequiresDataflowAnalysisDueToSignature(ctor))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<assembly fullname="System.Private.CoreLib">
<type fullname="System.Diagnostics.Tracing.EventSource" feature="System.Diagnostics.Tracing.EventSource.IsSupported" featurevalue="false">
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
<method signature="System.Void Finalize()" body="stub" />
<method signature="System.Boolean IsEnabled()" body="stub" value="false" />
<method signature="System.Boolean IsEnabled(System.Diagnostics.Tracing.EventLevel,System.Diagnostics.Tracing.EventKeywords)" body="stub" value="false" />
<method signature="System.Boolean IsEnabled(System.Diagnostics.Tracing.EventLevel,System.Diagnostics.Tracing.EventKeywords,System.Diagnostics.Tracing.EventChannel)" body="stub" value="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,8 @@ public void Dispose()
/// <param name="disposing">True if called from Dispose(), false if called from the finalizer.</param>
protected virtual void Dispose(bool disposing)
{
// NOTE: If !IsSupported, we use ILLink.Substitutions to nop out the finalizer.
// Do not add any code before this line (or you'd need to delete the substitution).
if (!IsSupported)
{
return;
Expand Down Expand Up @@ -1504,6 +1506,7 @@ protected virtual void Dispose(bool disposing)
/// </summary>
~EventSource()
{
// NOTE: we nop out this method body if !IsSupported using ILLink.Substitutions.
this.Dispose(false);
}
#endregion
Expand Down

0 comments on commit 1a838dc

Please sign in to comment.