JIT version determining in runtime
Sometimes I want to know used JIT compiler version in my little C# experiments. It is clear that it is possible to determine the version in advance based on the environment. However, sometimes I want to know it in runtime to perform specific code for the current JIT compiler. More formally, I want to get the value from the following enum:
public enum JitVersion
{
Mono, MsX86, MsX64, RyuJit
}
It is easy to detect Mono by existing of the Mono.Runtime
class. Otherwise, we can assume that we work with Microsoft JIT implementation. It is easy to detect JIT-x86 with help of IntPtr.Size == 4
. The challenge is to distinguish JIT-x64 and RyuJIT. Next, I will show how you can do it with help of the bug from my previous post.
First of all, I show a trivial code that helps us to detect the JitVersion.Mono
and JitVersion.MsX86
versions:
public static bool IsMono()
{
return Type.GetType("Mono.Runtime") != null;
}
public static bool IsMsX86()
{
return !IsMono() && IntPtr.Size == 4;
}
Next, we will learn to detect JitVersion.MsX64
. We will use the JIT-x64 sub-expression elimination optimizer bug for this purpose. Note, that you should compile the program with enabled optimizations.
private int bar;
private bool IsMsX64(int step = 1)
{
var value = 0;
for (int i = 0; i < step; i++)
{
bar = i + 10;
for (int j = 0; j < 2 * step; j += step)
value = j + 10;
}
return value == 20 + step;
}
In this post, we work with a limited set of JIT-compiler. Therefore RyuJIT can be identified by the elimination method:
public JitVersion GetJitVersion()
{
if (IsMono())
return JitVersion.Mono;
if (IsMsX86())
return JitVersion.MsX86;
if (IsMsX64())
return JitVersion.MsX64;
return JitVersion.RyuJit;
}
Everything is ready! Let’s write a simple program, which determine the JIT version in runtime:
using System;
class Program
{
public enum JitVersion
{
Mono, MsX86, MsX64, RyuJit
}
public class JitVersionInfo
{
public JitVersion GetJitVersion()
{
if (IsMono())
return JitVersion.Mono;
if (IsMsX86())
return JitVersion.MsX86;
if (IsMsX64())
return JitVersion.MsX64;
return JitVersion.RyuJit;
}
private int bar;
private bool IsMsX64(int step = 1)
{
var value = 0;
for (int i = 0; i < step; i++)
{
bar = i + 10;
for (int j = 0; j < 2 * step; j += step)
value = j + 10;
}
return value == 20 + step;
}
public static bool IsMono()
{
return Type.GetType("Mono.Runtime") != null;
}
public static bool IsMsX86()
{
return !IsMono() && IntPtr.Size == 4;
}
}
static void Main()
{
Console.WriteLine("Current JIT version: " + new JitVersionInfo().GetJitVersion());
}
}
The class is ready to use! The complete code is also available on Gist: JitVersionInfo.cs.
Notes
- Method of distinguish MsX64 and RyuJIT works only with enabled optimizations.
- The approach works with a limited set of JIT versions, you can have troubles with non-standard .NET versions.
- Miguel have promised that Mono 4 will work on CoreCLR which means RyuJIT.