JT said:
So I'm not completely in cloud cuckoo land. Phew!
The Java Virtual Machine Specification is a precise document
on the meaning of bytecodes. So JIT compilers simply
attempt to produce native binaries that have the same behavior
as the bytecode.
I don't see how the JVMS prevents that.
See below
No. The byte code is the native machine code of the JVM.
The JIT does not compile to to the VM's machine language.
In fact, the JIT always compiles to the CPU's machine language.
Why?
Why I dont understand how you can go "lower" than the VM's machine code:
I'm handicapped by not knowing the design/architecture of the actual
JVM, so even though the best way to explain my difficulty would be to do
so in terms of the actual JVM instructions, I will do the next best
thing, and try to do it in terms of a simpler and entirely mythical
virtual machine.
Lets suppose I have a string handling virtual machine. Its got a string
store and it has two native operations (among others, but we're just
interested in showing why I think its not possible to get "below"
the virtual machines own virtual machine language. Your mission
impossible, should you choose to accept it is to expose the flaw
in how I'm thinking.
The two operations are "Head" which returns the first (zeroth) character
of the string, and "Tail" which returns the substring consisting of the
string that remains after removing the first (Zeroth) character. Gee,
sounds like Lisp car and cons, but "never mind".
So the "byte" code for "Head" is x01 and the byte code for "Tail" is
x02. The implementation of the string virtual machine on a particular
hardware platform consists of the native hardware machine instructions
that make the internal structures of the VM (implemented of course as
"real" structures built out of real memory and real registers and all that.
I suppose in one sense, you can say that the "compilation" of the byte
code x01 and/or x02 is the set of machine instructions used to implement
that part of the string virtual machine in the real hardware.
Compilation of the byte code would be nothing more or less than
re-implementing a portion of the string virtual machine. So that makes
no sense to me, as presumably you've done it right the first time when
you implemented the string virtual machine for that hardware in the
first place.
Are you saying that the vm is dynamically re-implementation at run time?
Another way to see my difficulty is to imagine that a virtual machine
instruction changes the internal state of the virtual machine in some
"Atomic" way. No single native machine instruction can do that, because
the native instructions change the state of the real machine, not the
state of the virtual machine. A small change in state of the virtual
machine involves lots of "non atomic" changes in the state of the
underlying real machine. The implementation of the virtual machine runs
lots of native operating instructions to acheive that effect, but those
instructions are determined when you implement the virtual machine, not
dynamically at run time. Unless of course I'm all wet and what you're
really doing is in fact dynamically re-writing the JVM implementation
which seems a bit mind boggling to me.
The JVM itself has full access to the Operating System
that the JVM is running on. Whenever you have native methods
(eg. some of the GUI methods and the IO methods...), the JVM
will have to invoke the corresponding services from the Operating
System.
Er, yes. A fixed set of instructions determined at implementation time,
for each JVM machine instruction. Or is that not so?
So, a JVM could invoke a JIT to translate frequently-executed code
into a suitable binary format that the OS can execute.
Which means that the implementation of any given Java machine language
primitive is dynamically altered at run time. Eek! Can that be true?
You dont? The native hardware instructions that find the head of a
string are re-invented every time somebody does the "head" operation?
Can that be right?
(And as you noted, there are many