Here's a quick comparison vs Graal, which is the same thing but for the HotSpot JVM.
Java 9+ has Java-side interfaces for extending the compiler called JVMCI. So you don't need the deep hacking with the C++ vtables and other such mangling, that I guess could be quite fragile in the face of future changes to the runtime. There's a clean plugin API to let you write a compiler entirely in managed code. You can drop it in as a JAR, set some command line flags, and it'll be used.
HotSpot has an interpreter (written in C++ for now). The CLR never did, instead it uses a model where all code is compiled on first access. This means Graal avoids the re-entrancy issues that Alexandre solves with a counter in a TLS slot. Instead Graal is invoked asynchronously whilst the main program continues to run. And Graal is itself interpreted until it warms up, at which point it starts to compile itself.
The ICorJitCompiler interface the .NET JIT has to implement is much simpler than the HotSpot equivalent:
http://lafo.ssw.uni-linz.ac.at/javadoc/graalvm/jdk.internal....
Whilst the compile method is kind of the same, the CompilationResult structure is far harder to fill out. That's because HotSpot heavily uses de-optimisation to make things go fast, so the compiler isn't just responsible for production of machine code but also de-optimisation metadata. That metadata enables converting stack frames of optimised code back into interpreter stack frames and is quite complex to produce, in fact it affects the design of the whole compiler. It's also required to produce safepoint metadata, GC pointer maps and more.
http://lafo.ssw.uni-linz.ac.at/javadoc/graalvm/jdk.internal....
There's also an additional reflection API that provides access to things that the compiler needs, like raw bytecodes.
The author says finally
The benefits to have a Managed JIT wouldn’t be visible in short-term or even medium-term while it could open many possibilities in the long run, but for a project of the - legacy - size of .NET, this is probably too much to ask.
But is it too much to ask? Java not only has Graal but Project Metropolis, the goal of which is to explore conversion of HotSpot into Java. HotSpot is older and more complex than the CLR, but apparently they don't consider it impossible. And SubstrateVM is the spiritual successor to Jikes; a JVM written entirely in Java, using magic methods and classes to model pointer arithmetic for the garbage collector and the compiler in AOT mode to produce the final binary image.
The real issue is not .NET's size or legacy, but rather, Microsoft's level of investment in it and/or their strategic choices. The .NET team are paying a heavy price for the lack of investment into portability in recent years, and have been frequently distracted by the many re-spins and backwards compatibility breaks. They have also tended to push complexity and performance into the C# language rather than the runtime. Perhaps in hindsight the Java approach has worked out with less tech debt and a better path to the future.