Skip to content

X64 - Too many methods JITted on startup for blank console application #85791

Description

@TIHan

Using this example:

namespace HelloWorldStartup
{
    internal class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

The CPU I used was an AMD 7950X.
X64 - With DOTNET_JitDisasmSummary=1 it shows this number of methods (this is with R2R):

   1: JIT compiled System.Runtime.CompilerServices.CastHelpers:StelemRef(System.Array,long,System.Object) [Tier1, IL size=88, code size=93]
   2: JIT compiled System.Runtime.CompilerServices.CastHelpers:LdelemaRef(System.Array,long,ulong) [Tier1, IL size=44, code size=44]
   3: JIT compiled System.SpanHelpers:IndexOfNullCharacter(ulong) [Tier1, IL size=805, code size=391]
   4: JIT compiled System.Guid:TryFormatCore[ushort](System.Span`1[ushort],byref,int) [Tier0, IL size=894, code size=892]
   5: JIT compiled System.Number:UInt32ToDecChars[ushort](ulong,uint) [Tier0, IL size=114, code size=253]
   6: JIT compiled System.ArgumentOutOfRangeException:ThrowIfNegative[int](int,System.String) [Tier0, IL size=22, code size=50]
   7: JIT compiled System.Text.Unicode.Utf16Utility:GetPointerToFirstInvalidChar(ulong,int,byref,byref) [Tier0, IL size=994, code size=1101]
   8: JIT compiled System.Text.Ascii:NarrowUtf16ToAscii(ulong,ulong,ulong) [Tier0, IL size=491, code size=594]
   9: JIT compiled System.SpanHelpers:IndexOfNullByte(ulong) [Tier1, IL size=844, code size=459]
  10: JIT compiled System.PackedSpanHelpers:IndexOf[System.SpanHelpers+DontNegate`1[short]](byref,short,int) [Tier0, IL size=698, code size=1631]
  11: JIT compiled System.PackedSpanHelpers:PackSources(System.Runtime.Intrinsics.Vector256`1[short],System.Runtime.Intrinsics.Vector256`1[short]) [Tier0, IL size=13, code size=52]
  12: JIT compiled System.PackedSpanHelpers:ComputeFirstIndexOverlapped(byref,byref,byref,System.Runtime.Intrinsics.Vector256`1[ubyte]) [Tier0, IL size=52, code size=124]
  13: JIT compiled System.PackedSpanHelpers:FixUpPackedVector256Result(System.Runtime.Intrinsics.Vector256`1[ubyte]) [Tier0, IL size=22, code size=42]
  14: JIT compiled System.SpanHelpers:LastIndexOfValueType[short,System.SpanHelpers+DontNegate`1[short]](byref,short,int) [Tier1, IL size=963, code size=419]
  15: JIT compiled System.Text.Ascii:WidenAsciiToUtf16(ulong,ulong,ulong) [Tier0, IL size=604, code size=1425]
  16: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Level(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
  17: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Message(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
  18: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Task(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
  19: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Opcode(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
  20: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Version(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
  21: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Keywords(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
  22: JIT compiled System.Number:Int64ToHexChars[ushort](ulong,ulong,int,int) [Tier0, IL size=67, code size=252]
  23: JIT compiled System.SpanHelpers:IndexOfAnyInRangeUnsignedNumber[ushort,System.SpanHelpers+DontNegate`1[ushort]](byref,ushort,ushort,int) [Tier0, IL size=142, code size=190]
  24: JIT compiled System.PackedSpanHelpers:IndexOfAnyInRange[System.SpanHelpers+DontNegate`1[short]](byref,short,short,int) [Tier0, IL size=659, code size=1600]
  25: JIT compiled System.SpanHelpers:SequenceCompareTo(byref,int,byref,int) [Tier1, IL size=568, code size=329]
  26: JIT compiled HelloWorldStartup.Program:Main(System.String[]) [Tier0, IL size=1, code size=10]

ARM64:

   1: JIT compiled System.Runtime.CompilerServices.CastHelpers:StelemRef(System.Array,long,System.Object) [Tier1, IL size=88, code size=144]
   2: JIT compiled System.Runtime.CompilerServices.CastHelpers:LdelemaRef(System.Array,long,ulong) [Tier1, IL size=44, code size=88]
   3: JIT compiled System.SpanHelpers:IndexOfNullCharacter(ulong) [Tier1, IL size=492, code size=392]
   4: JIT compiled HelloWorldStartup.Program:Main(System.String[]) [Tier0, IL size=1, code size=20]

Problems identified:

Activity

  1. ghost added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on May 4, 2023
  2. ghost added
    untriagedNew issue has not been triaged by the area owner
    on May 4, 2023
  3. changed the title [-][JIT] X64 - Too many methods JITted on startup for blank console application[/-] [+][Runtime] X64 - Too many methods JITted on startup for blank console application[/+] on May 4, 2023
  4. added and removed
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    runtime-coreclrspecific to the CoreCLR runtime
    on May 4, 2023
  5. changed the title [-][Runtime] X64 - Too many methods JITted on startup for blank console application[/-] [+]X64 - Too many methods JITted on startup for blank console application[/+] on May 4, 2023
  6. EgorBo commented on May 4, 2023

    @EgorBo
    Member

    @MihaZupan can it be caused by SearchValue preinitializations + AVX2?

  7. TIHan commented on May 4, 2023

    @TIHan
    ContributorAuthor
  8. stephentoub commented on May 5, 2023

    @stephentoub
    Member

    Seems like R2R gives up on methods parameterized with static abstract interfaces? Methods like UInt32ToDecChars, ThrowIfNegative, and Int64ToHexChars aren't doing anything with AVX2.

  9. stephentoub commented on May 5, 2023

    @stephentoub
    Member

    I'm curious what's triggering these:

      16: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Level(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
      17: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Message(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
      18: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Task(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
      19: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Opcode(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
      20: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Version(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
      21: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Keywords(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
    

    ?

  10. jkotas commented on May 5, 2023

    @jkotas
    Member

    I'm curious what's triggering these:

    Extensive use of reflection in EventSource

  11. 13 remaining items

  12. stephentoub commented on May 6, 2023

    @stephentoub
    Member

    but no ushort

    It's never used with ushort, only byte and char.

    🤷 trying to find out who is instanciating that

    Did you figure this part out?

  13. EgorBo commented on May 8, 2023

    @EgorBo
    Member

    Did you figure this part out?

    Looks like we have two methods:

    System.Guid.TryFormatCore[System.Char](System.Span`1<Char>, Int32 ByRef, System.ReadOnlySpan`1<Char>)
    System.Guid.TryFormatCore[System.Char](System.Span`1<Char>, Int32 ByRef, Int32)
    

    the latter fails to pick up R2R version, digging further

  14. EgorBo commented on May 8, 2023

    @EgorBo
    Member

    Ah, SVM again:

    Info: Method `[S.P.CoreLib]System.Guid.TryFormatCore<char>(Span`1<char>,int32&,int32)` 
    was not compiled because `SVM` requires runtime JIT
    
  15. stephentoub commented on May 8, 2023

    @stephentoub
    Member

    Ah, SVM again

    Not following... how does that explain why it compiled a ushort version?

  16. EgorBo commented on May 8, 2023

    @EgorBo
    Member

    Ah, SVM again

    Not following... how does that explain why it compiled a ushort version?

    I assume it's just the way it's displayed in the log (char -> ushort) or maybe R2R is smart enough to share a single version for both char and ushort, but the actual reason we see TryFormatCore in JitDisasmSummary is SVM

  17. stephentoub commented on May 8, 2023

    @stephentoub
    Member

    it's just the way it's displayed in the log

    Ok :)

  18. TIHan commented on May 8, 2023

    @TIHan
    ContributorAuthor

    Also, why would those not show up on ARM64... was that also on a different OS and that's impacting what EventSource is doing?

    They will show-up while running a PerfView trace:

    C:\Users\lolti\OneDrive\Desktop\runtime>dotnet HelloWorldStartup.dll
       1: JIT compiled System.Runtime.CompilerServices.CastHelpers:StelemRef(System.Array,long,System.Object) [Tier1, IL size=88, code size=144]
       2: JIT compiled System.Runtime.CompilerServices.CastHelpers:LdelemaRef(System.Array,long,ulong) [Tier1, IL size=44, code size=88]
       3: JIT compiled System.SpanHelpers:IndexOfNullCharacter(ulong) [Tier1, IL size=492, code size=392]
       4: JIT compiled System.ArgumentOutOfRangeException:ThrowIfNegative[int](int,System.String) [Tier0, IL size=22, code size=80]
       5: JIT compiled System.SpanHelpers:IndexOfNullByte(ulong) [Tier1, IL size=581, code size=504]
       6: JIT compiled System.SpanHelpers:NonPackedIndexOfValueType[short,System.SpanHelpers+DontNegate`1[short]](byref,short,int) [Tier1, IL size=843, code size=404]
       7: JIT compiled System.SpanHelpers:LastIndexOfValueType[short,System.SpanHelpers+DontNegate`1[short]](byref,short,int) [Tier1, IL size=819, code size=384]
       8: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Level(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=56]
       9: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Message(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=56]
      10: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Task(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=56]
      11: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Opcode(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=56]
      12: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Version(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=56]
      13: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Keywords(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=56]
      14: JIT compiled System.SpanHelpers:NonPackedIndexOfAnyInRangeUnsignedNumber[ushort,System.SpanHelpers+DontNegate`1[ushort]](byref,ushort,ushort,int) [Tier0, IL size=294, code size=708]
      15: JIT compiled System.SpanHelpers+DontNegate`1[ushort]:NegateIfNeeded(bool) [Tier0, IL size=2, code size=28]
      16: JIT compiled System.SpanHelpers:SequenceCompareTo(byref,int,byref,int) [Tier1, IL size=287, code size=248]
      17: JIT compiled HelloWorldStartup.Program:Main(System.String[]) [Tier0, IL size=1, code size=20]
    
    C:\Users\lolti\OneDrive\Desktop\runtime>dotnet HelloWorldStartup.dll
       1: JIT compiled System.Runtime.CompilerServices.CastHelpers:StelemRef(System.Array,long,System.Object) [Tier1, IL size=88, code size=144]
       2: JIT compiled System.Runtime.CompilerServices.CastHelpers:LdelemaRef(System.Array,long,ulong) [Tier1, IL size=44, code size=88]
       3: JIT compiled System.SpanHelpers:IndexOfNullCharacter(ulong) [Tier1, IL size=492, code size=392]
       4: JIT compiled HelloWorldStartup.Program:Main(System.String[]) [Tier0, IL size=1, code size=20]
    

    The second run is when I didn't do a perf-view trace.

    On my X64 box, even when not running perf-view, the EventSource still gets created, likely from some other program.

  19. added this to the Future milestone on May 18, 2023
  20. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on May 18, 2023
  21. stephentoub commented on Aug 11, 2023

    @stephentoub
    Member

    For the EventSource ones, anyone know why dotnet app.dll wouldn't show those entries but corerun app.dll would?

    My dotnet is from a few weeks ago and my corerun is from a local build, but with an empty Main app, with dotnet app.dll I see:

       1: JIT compiled System.Runtime.CompilerServices.CastHelpers:StelemRef(System.Array,long,System.Object) [Tier1, IL size=88, code size=93]
       2: JIT compiled System.Runtime.CompilerServices.CastHelpers:LdelemaRef(System.Array,long,ulong) [Tier1, IL size=44, code size=44]
       3: JIT compiled System.Guid:TryFormatCore[ushort](System.Span`1[ushort],byref,int) [Tier0, IL size=894, code size=892]
       4: JIT compiled System.Guid:FormatGuidVector128Utf8(System.Guid,bool) [Tier0, IL size=322, code size=584]
       5: JIT compiled System.HexConverter:AsciiToHexVector128(System.Runtime.Intrinsics.Vector128`1[ubyte],System.Runtime.Intrinsics.Vector128`1[ubyte]) [Tier0, IL size=78, code size=359]
       6: JIT compiled System.Runtime.Intrinsics.Vector128:ShuffleUnsafe(System.Runtime.Intrinsics.Vector128`1[ubyte],System.Runtime.Intrinsics.Vector128`1[ubyte]) [Tier0, IL size=41, code size=50]
       7: JIT compiled System.Number:UInt32ToDecChars[ushort](ulong,uint) [Instrumented Tier0, IL size=114, code size=315]
       8: JIT compiled System.ArgumentOutOfRangeException:ThrowIfNegative[int](int,System.String) [Tier0, IL size=22, code size=50]
       9: JIT compiled System.Text.Unicode.Utf16Utility:GetPointerToFirstInvalidChar(ulong,int,byref,byref) [Instrumented Tier0, IL size=994, code size=1296]
      10: JIT compiled System.Text.Ascii:NarrowUtf16ToAscii(ulong,ulong,ulong) [Instrumented Tier0, IL size=558, code size=1384]
      11: JIT compiled System.RuntimeType+RuntimeTypeCache+MemberInfoCache`1[System.__Canon]:AddMethod(System.RuntimeType,long,int) [Instrumented Tier0, IL size=354, code size=1672]
      12: JIT compiled System.SpanHelpers:LastIndexOfValueType[short,System.SpanHelpers+DontNegate`1[short]](byref,short,int) [Instrumented Tier0, IL size=1128, code size=2125]
      13: JIT compiled System.Text.Ascii:WidenAsciiToUtf16(ulong,ulong,ulong) [Instrumented Tier0, IL size=738, code size=1814]
      14: JIT compiled System.PackedSpanHelpers:IndexOf[System.SpanHelpers+DontNegate`1[short]](byref,short,int) [Instrumented Tier0, IL size=977, code size=1912]
      15: JIT compiled System.Number:Int64ToHexChars[ushort](ulong,ulong,int,int) [Instrumented Tier0, IL size=67, code size=313]
      16: JIT compiled System.SpanHelpers:IndexOfAnyInRangeUnsignedNumber[ushort,System.SpanHelpers+DontNegate`1[ushort]](byref,ushort,ushort,int) [Tier0, IL size=142, code size=190]
      17: JIT compiled System.PackedSpanHelpers:IndexOfAnyInRange[System.SpanHelpers+DontNegate`1[short]](byref,short,short,int) [Instrumented Tier0, IL size=972, code size=1810]
      18: JIT compiled Test:Main() [Tier0, IL size=1, code size=6]
    

    and with corerun app.dll I see:

       1: JIT compiled System.Runtime.CompilerServices.CastHelpers:StelemRef(System.Array,long,System.Object) [Tier1, IL size=88, code size=93]
       2: JIT compiled System.Runtime.CompilerServices.CastHelpers:LdelemaRef(System.Array,long,ulong) [Tier1, IL size=44, code size=44]
       3: JIT compiled System.Guid:FormatGuidVector128Utf8(System.Guid,bool) [Tier0, IL size=322, code size=584]
       4: JIT compiled System.HexConverter:AsciiToHexVector128(System.Runtime.Intrinsics.Vector128`1[ubyte],System.Runtime.Intrinsics.Vector128`1[ubyte]) [Tier0, IL size=78, code size=359]
       5: JIT compiled System.Runtime.Intrinsics.Vector128:ShuffleUnsafe(System.Runtime.Intrinsics.Vector128`1[ubyte],System.Runtime.Intrinsics.Vector128`1[ubyte]) [Tier0, IL size=41, code size=50]
       6: JIT compiled System.Text.Unicode.Utf16Utility:GetPointerToFirstInvalidChar(ulong,int,byref,byref) [Instrumented Tier0, IL size=994, code size=1292]
       7: JIT compiled System.RuntimeType+RuntimeTypeCache+MemberInfoCache`1[System.__Canon]:AddMethod(System.RuntimeType,long,int) [Instrumented Tier0, IL size=354, code size=1672]
       8: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Level(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
       9: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Message(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
      10: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Task(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
      11: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Opcode(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=27]
      12: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Version(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
      13: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Keywords(System.Object,System.Object,ulong) [FullOpts, IL size=25, code size=28]
      14: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Level(System.Object,System.Span`1[System.Object]) [FullOpts, IL size=36, code size=40]
      15: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Message(System.Object,System.Span`1[System.Object]) [FullOpts, IL size=26, code size=37]
      16: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Task(System.Object,System.Span`1[System.Object]) [FullOpts, IL size=36, code size=40]
      17: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Opcode(System.Object,System.Span`1[System.Object]) [FullOpts, IL size=36, code size=40]
      18: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Version(System.Object,System.Span`1[System.Object]) [FullOpts, IL size=36, code size=41]
      19: JIT compiled (dynamicClass):InvokeStub_EventAttribute.set_Keywords(System.Object,System.Span`1[System.Object]) [FullOpts, IL size=36, code size=41]
      20: JIT compiled Test:Main() [Tier0, IL size=1, code size=6]
    

    Many of the extraneous entries have been removed due to improvements in corelib, but corerun is showing all of these dynamicClass entries that dotnet isn't. Is it possible this is a regression? Or is there something different between the hosts that would trigger this?

  22. jkotas commented on Aug 11, 2023

    @jkotas
    Member

    My dotnet is from a few weeks ago

    What is your exact dotnet version? I have tried this on .NET 8 P7 bits and I do not see this difference. (I see the event source in both cases.)

    I think it is most likely difference in timing or difference in what kind of event providers get enabled on the machine. The managed providers run asynchronously and the process can be exiting before they get a chance to run in one case, but not in the other case. Also, the Windows monitoring software running in the background can be turning the event providers on - for examble, it can say that corerun.exe is unsigned binary so better to monitor to it in detail.

  23. tannergooding commented on Jul 23, 2026

    @tannergooding
    Member

    Revisited this on current main (.NET 11, win-x64) with a locally-built R2R corelib + testhost, DOTNET_JitDisasmSummary=1:

    Scenario 2023 (X64, this issue) .NET 11 now
    Empty Main() / Main(string[] args), no event session 26 1 (Program:Main)
    Empty, active EventPipe/ETW session +EventSource stubs 14
    Console.WriteLine("Hello world") ~30 28

    The old empty-app noise -- Guid.TryFormatCore, Number.UInt32ToDecChars<ushort>, Int64ToHexChars, ArgumentOutOfRangeException.ThrowIfNegative<T>, and the pile of SpanHelpers/PackedSpanHelpers/Text.Ascii/CastHelpers methods -- is entirely gone. The structural fixes did it:

    The blank app now JITs exactly one method (Program:Main); even the CastHelpers array helpers no longer show with string[] args.

    What remains:

    1. EventSource reflection stubs (InvokeStub_EventAttribute.* + a reflection-cache entry) still get JITted when an event/ETW session is active -- ~12 methods for the empty app. This is environment-dependent and is the item that the EventSource source generator is meant to remove.
    2. The Console.WriteLine case's 28 methods are now all the genuine Console -> ConsolePal -> Kernel32.WriteFile startup path (Tier0), with none of the old generic-math/SVM fallbacks.

    So the core complaint here -- a blank app JITting ~26 methods -- is effectively resolved (down to 1). The remaining startup-JIT is the EventSource reflection cost when tracing is enabled, which is tracked separately. Closing as resolved; the EventSource source generator work can be tracked on its own.

    Note

    Investigation and this write-up were done with the help of GitHub Copilot.

  24. EgorBo commented on Jul 23, 2026

    @EgorBo
    Member

    Checked on linux-x64 - just one method is jitted for a hello world (tested the most recent daily build of SDK):

    1: JIT compiled Program:<Main>$(System.String[]) [Tier0, IL size=11, code size=37]
    
  25. locked and limited conversation to collaborators on Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions