user53670
user53670

Reputation:

Difference between a bytecode parsed instruction and machine language?

"A bytecode program is normally executed by parsing the instructions one at a time. This kind of bytecode interpreter is very portable. Some systems, called dynamic translators, or "just-in-time" (JIT) compilers, translate bytecode into machine language as necessary at runtime: this makes the virtual machine unportable."

A question about this paragraph is that: After the bytecode gets processed, what's the difference between a parsed instruction and machine language (or machine code)?

Upvotes: 4

Views: 1682

Answers (4)

Norman Ramsey
Norman Ramsey

Reputation: 202655

In a bytecode interpreter, the instruction format is usually designed for very fast "parsing" using shift and mask operators. The interpreter, after "parsing" (I prefer "decoding") the instruction, immediately updates the state of the virtual machine and then begins decoding the next instruction. So after the bytecode gets processed in an interpreter, no remnant remains.

In a JIT compiler, bytes are processed in units larger than a single instruction. The minimum unit is the basic block, but modern JITs will convert larger paths to machine code. This is a translation step, and the output of the translation step is machine code. The original bytecode may remain in memory, but it is not used for implementation—so there is no real difference. (Although it is still typical that the machine code for a JITted virtual machine does different things from the machine code emitted by a native-code compiler.)

Upvotes: 2

sybreon
sybreon

Reputation: 3156

Ultimately it all boils down to machine instructions.

  1. Native App - contains machine instructions that are executed directly.
  2. JIT App - bytecode is compiled into machine instructions and executed.
  3. Translated App - bytecode is translated by a virtual machine that is a Native App.

As you can tell, with #1, you have the least overhead while with #3, you have the most overhead. So, performance should be fastest on #1 and just as fast on #2 after the initial compilation overhead.

Upvotes: 1

Steven
Steven

Reputation: 3928

JIT is different to a byte code interpreter.

Consider the following C function:

int sum() {
   return 5 + 6;
}

This will be compiled directly machine code. The exact instructions on say x86 and ARM processors will be different.

If we wrote a basic bytecode interpreter it might look something like this:

for(;;) {
   switch(*currentInstruction++) {
   case OP_PUSHINT:
      *stack++ = nextInt(currentInstruction);
      break;
   case OP_ADD:
      --stack;
      stack[-1].add(*stack);
      break;
   case OP_RETURN:
      return stack[-1];
   }
}

This can then interpret the following set of instructions:

OP_PUSHINT (5)
OP_PUSHINT (6)
OP_ADD
OP_RETURN

If you compiled the byte code interpreter on both x86 or ARM then you would be able to run the same byte code without doing any further rewriting of the interpreter.

If you wrote a JIT compiler you would need to emit processor specific instructions (machine code) for each supported processor, whereas the byte code interpreter is relying on the C++ compiler to emit the processor specific instructions.

Upvotes: 7

sharptooth
sharptooth

Reputation: 170539

There's no difference - JIT compiler is done exactly for that - it produces machine code that is executed on the hardware.

Upvotes: 1

Related Questions