Skip to content
Instruction Dispatch & The Main Loop
step 1/3

Reading — step 1 of 3

Efficient Dispatch and Global Variables

~2 min readBytecode Virtual Machine

Instruction Dispatch & The Main Loop

The dispatch loop is the most performance-critical part of the VM. Every optimization here multiplies across every instruction executed.

Dispatch Strategies

Switch Dispatch

The simplest approach — a switch statement on the opcode:

while true:
    switch code[ip++]:
        case OP_ADD: ...
        case OP_SUB: ...

This is what CPython, Lua, and our VM use. It is straightforward but the CPU branch predictor struggles because every iteration jumps to a different case.

Computed Goto (Threaded Code)

In C, you can use GCC's &&label extension to create a table of label addresses:

void* dispatch_table[] = { &&op_add, &&op_sub, ... };
goto *dispatch_table[code[ip++]];
op_add: { ... goto *dispatch_table[code[ip++]]; }

Each instruction dispatches directly to the next, avoiding the switch overhead. CPython and Lua both use this when available. It is typically 15-25% faster than switch dispatch.

Global Variables

We add three instructions for globals:

OP_DEFINE_GLOBAL  // define a new global variable
OP_GET_GLOBAL     // read a global variable
OP_SET_GLOBAL     // write to a global variable

Globals are stored in a hash table (name to value). The operand is an index into the constant pool where the variable name (a string) is stored.

Local Variables

Local variables use the stack directly — no hash table lookup needed:

OP_GET_LOCAL   // read local at stack slot [operand]
OP_SET_LOCAL   // write local at stack slot [operand]

Since we know the stack layout at compile time, local variable access is O(1) — just index into the stack. This is a major performance win over globals.

String Interning

To make string comparison O(1), we intern strings: ensure each unique string exists only once in memory. Two interned strings are equal if and only if their pointers are equal — no character-by-character comparison needed.

Lua interns all strings. Java interns string literals and strings explicitly interned via String.intern(). CPython interns short strings and identifiers.

Your Task

Optimize the dispatch loop, implement global and local variable instructions, and add string interning for fast comparison.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…