1

How do I guarantee that the CLR's JIT "method" cache has been cleared? Is it simply a matter of starting a new instance of the application, or do you have to re-boot the PC?

It is my understanding the the CLR JIT is process specific, and that this should work.

  1. Foobar.exe is started.
  2. DoWork() is invoked for the first time
    • CLR's JIT compiler converts the intermediate language (for DoWork()) to machine code
    • the generated machine code is cached in-memory for future calls
  3. DoWork() is called again, and existing machine code is used. (i.e. JIT is bypassed)
  4. Terminate Foobar.exe application.
    • there are no instances of Foobar.exe running
  5. Foobar.exe is started again.
  6. DoWork() is invoked for the first time
    • Terminating the previous application, and starting a new instance effectively cleared the JIT "method" cache.
    • CLR's JIT compiler converts the intermediate language (for DoWork()) to machine code
    • the generated machine code is cached in-memory for future calls
  7. DoWork() is called again, and existing machine code is used. (i.e. JIT is bypassed)

Any feedback that can be provided would be greatly appreciated.

Environment

  • Windows IOT Enterprise (LTSC 2019), 64-bit
  • Application currently targeting: .Net library 4.7.2, CLR 4.x
    • <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    • to the best of my knowledge, we are not using .Net core
  • We are not explicitly using NGen

Related Reading

Pressacco
  • 2,815
  • 2
  • 26
  • 45
  • Unless I'm completely mistaken, the JITter produces executable code that gets mapped into the process's non-shared memory (for subsequent execution). Every time the process runs, `DoWork()` will get re-JITted. I'm curious though, why are you asking? – Flydog57 Jan 08 '20 at 19:15
  • Thanks for you feedback Flydog. I am asking because Microsoft fixed an interesting bug in .Net 4.8 CLR JIT, and we are trying to understand how it might impact us. _Addressed the issue where the JIT compiler optimized away a call to the CompareExchange intrinsic operation under specific conditions [638227, clrjit.dll, Bug, Build:3646]_. Unfortunately no further information was provided. – Pressacco Jan 08 '20 at 19:39
  • Which .NET version are you using, is it .NET Core or classic .NET Framework? Because ngen and crossgen can behave differently – Pavel Anikhouski Jan 08 '20 at 19:43
  • This [article](https://blogs.msdn.microsoft.com/abhinaba/2013/12/11/net-loading-native-ngen-images-and-its-interaction-with-the-gac/) can be helpful – Pavel Anikhouski Jan 08 '20 at 19:55
  • Hi Pavel. We are specifically targeting .Net library 4.7.2 (CLR 4.x) via `supportedRuntine` in `app.config`. – Pressacco Jan 08 '20 at 19:59
  • There is no caching unless you ran ngen.exe on the machine. You'd know that, the installer you need is not simple. If you did then the bug wouldn't be fixed if it happened before the machine got the .NET update. – Hans Passant Jan 08 '20 at 20:10
  • Thank you for your feedback Hans. To clarify, are you staying that the sequence of events I listed in my original question is incorrect? – Pressacco Jan 08 '20 at 20:24
  • Hard to comment on, the mental model is leaky. Since it doesn't seem aware of the role that ngen.exe plays, it is quite safe to assume that there is no caching and you don't have a problem at all. Other than the universal "did I do it right" doubt that is associated with threading. Which does tend to have the universal answer "no", Interlocked is not for the faint of heart. – Hans Passant Jan 08 '20 at 20:44

1 Answers1

1

Your understanding is very correct.

Every time the process is started, the JIT emits a new machine code that is used until the process is finished.

However, it's also possible to create a machine code cache, to avoid repetitive jit emission. It's know as NGen