JIT version determining in runtime

by Andrey Akinshin · 2015-02-28

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.