I think you are mixing two different concepts.
At a minimum for Java, the JVM acts like a virtual machine - it is an idealized computer with a relatively high level of assembler (bytecode), which is based on a stack of calls with stack frames. When compiling Java into bytecode, the Java program turns into an (essentially) build program to control this machine.
When Java is actually running on this system, the job of implementing the JVM is to accurately simulate the execution of this machine on a stack basis using any hardware that is actually available. Usually this means that a huge number of stack operations will be implemented using registers when possible, and possibly using other specialized equipment that is not in the Java virtual machine description. The actual information about how this is done is implementation-specific - some implementations can compile it to machine code that does almost everything in the register, while a simpler implementation can simply be compiled into memory operations. For several months I was working on the implementation of the JVM for JavaScript, and in this case we โcompiledโ the code to JS functions, which, in turn, were passed to the JS browser implementation.
The reason for this difference is that Java was designed to easily load and paste (think of applets). In this case, security and portability issues are important. The bytecode had to be checked in some way automatically to exclude certain types of malicious code (for example, buffer overflows). In the same way, whatever format was used, it had to be high enough so that it could be run on various platforms (handheld devices, supercomputers, PCs, etc.). The choice of stack-based JVMs allowed both of these problems to be met simultaneously. This is a high enough level that you can check bytecode to rule out many type errors or read / write uninitialized memory, at a low enough level that the JVM can use tricks, such as compiling to code using registers.
If you are interested in what your particular JVM will do with a specific piece of code, you should take a look at the documentation. Most JVMs have some way to provide you with information on how they execute code. If your question is: โWhy not just bytecode manipulate case-basedโ, the reason is twofold:
- The bytecode has an analogue of registers - each frame of the stack has an additional allocated space for storing temporary values โโand
- There is not such reliable register support as is present in x86 or MIPS, because JVM code must be easily executed on several hardware, and hard coding in a number of registers can complicate the situation.
Hope this helps!
source share