Skip to content

Commit 0f508f2

Browse files
Allow preinitializing EventSource (#101573)
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.
1 parent 99dd60d commit 0f508f2

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -533,8 +533,14 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack<Method
533533

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

540546
if (_flowAnnotations.RequiresDataflowAnalysisDueToSignature(ctor))

src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<assembly fullname="System.Private.CoreLib">
33
<type fullname="System.Diagnostics.Tracing.EventSource" feature="System.Diagnostics.Tracing.EventSource.IsSupported" featurevalue="false">
44
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
5+
<method signature="System.Void Finalize()" body="stub" />
56
<method signature="System.Boolean IsEnabled()" body="stub" value="false" />
67
<method signature="System.Boolean IsEnabled(System.Diagnostics.Tracing.EventLevel,System.Diagnostics.Tracing.EventKeywords)" body="stub" value="false" />
78
<method signature="System.Boolean IsEnabled(System.Diagnostics.Tracing.EventLevel,System.Diagnostics.Tracing.EventKeywords,System.Diagnostics.Tracing.EventChannel)" body="stub" value="false" />

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs

+3
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,8 @@ public void Dispose()
14611461
/// <param name="disposing">True if called from Dispose(), false if called from the finalizer.</param>
14621462
protected virtual void Dispose(bool disposing)
14631463
{
1464+
// NOTE: If !IsSupported, we use ILLink.Substitutions to nop out the finalizer.
1465+
// Do not add any code before this line (or you'd need to delete the substitution).
14641466
if (!IsSupported)
14651467
{
14661468
return;
@@ -1504,6 +1506,7 @@ protected virtual void Dispose(bool disposing)
15041506
/// </summary>
15051507
~EventSource()
15061508
{
1509+
// NOTE: we nop out this method body if !IsSupported using ILLink.Substitutions.
15071510
this.Dispose(false);
15081511
}
15091512
#endregion

0 commit comments

Comments
 (0)