A couple of people have asked me to explain what I mean by “the C++ interpreter” and why bits of it are written in assembler. Here is a brief summary:
- OpenJDK is the implementation of the Java platform of Sun Microsystems.
- Hotspot is the Java virtual machine of OpenJDK.
- Hotspot comprises two interpreters and two JITs.
- A running instance of Hotspot comprises one interpreter optionally supplemented by one JIT.
- The interpreters are the template interpreter (aka the asm interpreter) and the C++ interpreter (aka the bytecode interpreter).
- The JITs are client (aka compiler 1 aka C1) and server (aka compiler 2 aka C2).
The point of intersection between the two interpreters and the two JITs is method dispatch. Every method in Hotspot is defined by a
methodOop, and each
methodOop has a method entry* which is the address of the code that will execute the method. Different methods have different entries, depending upon whether they are native or not, synchronized or not, JIT-compiled or not, etc etc, but every method is invoked the same way: you put the address of the
methodOop in one register, the address of the parameters in another, then jump to the method entry. The way the C++ interpreter differs from the template interpreter is that in the template interpreter everything is done in assembler whereas in the C++ interpreter the non-native entries simply** call
BytecodeInterpreter::run(). The C++ interpreter’s entries are therefore much smaller and so easier to port. But they are still written in assembler.
* This is a slight lie: they have two.
** ha ha ha ha ha!