5
$\begingroup$

What are the pros and cons of ways to implement the LOAD command in a statically typed VM?

There is two ways to implement LOAD command:

For example to load the number 5 of the int32 type:

  1. To create a one command LOAD with type as argument. Like this:

    LOAD int32 5
    
  2. To сreate a custom command for all types. Like this:

    LOAD_INT32 5
    

What are the pros and cons of this two ways?

$\endgroup$
1
  • 1
    $\begingroup$ The JVM has both actually, the former for classes and the latter for primitive types. $\endgroup$
    – Seggan
    May 28, 2023 at 15:23

1 Answer 1

3
$\begingroup$

The main reason you might want to have a single "load" opcode with an argument controlling the type of value loaded, is to reduce the number of distinct opcodes in your bytecode language. If each opcode must fit in one byte, then you can only support 256 different opcodes, so if you need lots of other opcodes then perhaps you could consider replacing all of the different "load" opcodes with a single one that takes an additional argument.

On the other hand, 256 is actually quite a lot, and even if you are running out of 8-bit opcodes, it probably makes sense to look for savings elsewhere, because the "load" opcodes are some of the most-used ones.

There are several disadvantages of having a single "load" opcode which takes the loaded type as an argument:

  • LOAD_INT32 5 takes five bytes (one for the opcode, four for the value), whereas LOAD int32 5 takes six (one for the opcode, one for the type, four for the value). So the size of a compiled program will be a bit bigger in the latter case.
  • LOAD int32 5 and LOAD int64 5 will take up different numbers of bytes for the second argument, so upon seeing the LOAD opcode you don't know how many more bytes are part of this instruction until you've read the first argument. This can significantly increase the complexity of "parsing" the bytecode language.
  • A bytecode interpreter will typically have a big switch statement which branches on the opcode. If the LOAD opcode has a "type" argument, then you will need a second switch on that argument, meaning more opportunities for the branch predictor to miss.
  • If you have a bytecode verifier (i.e. a static checker which ensures that a bytecode program is correct according to certain rules, including some form of type-checking) then it will be simpler to implement if you don't need to look at the arguments to determine the types or stack effects of an instruction. If the effects of each instruction only depend on the opcode, you can implement this as a simple lookup table from opcodes to their effects. (For example, the effects of an ADD_INT32 opcode would be something like pop int32, pop int32, push int32.)
$\endgroup$

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .