The VM interpreter is generated from assembly code snippets that calls this class when something complex need to be done.
Hotspot is written in C++ and objects shared by Java and the VM can be seen either in Java or in C++ because they have a Java header and a C++ header.
Classloading is done lazily in Java so you can not preload classes until the first time you see it. If you see a non loaded class in the JITed code, you have to jump back into the interpreter and re-generate the assembly code later.
OSR stands for on stack replacement which means that while you are interpreting a loop, you decide to JIT its body.
Biased locking is a way to implement monitor/lock if those locks are used only by one thread, you biased the lock to that thread, which is slightly more efficient.
The stack contains stack frames of different kinds Java, C, adapters (assembly stubs between the 2 JITs and the interpreter which obviously doesn't use the same calling convention) but you have a common way to iterate on them.
All Hotspot GCs are generational so you have to hold every pointers (Java reference) into Handles (box known by the GC) because the GC may decide to move the objects while the C++ code hold them.
Obviously, all this mechanisms make sense but managing the complexity of all of them working together is insane.