Remove null value from Opcode #18
Description
After the Rust language designers carefully removed nulls from the language, I went and added my own. It turns out that Option<T>
is often larger than T
, and tables with 32-bit or smaller entries can double in size when using Option<T>
.
C-like Opcode
enum
The Opcode
enum in the generated opcodes.rs
file contains an explicit null value:
pub enum Opcode {
/// An invalid opcode.
NotAnOpcode,
/// `jump EBB, args`. (Jump)
Jump,
/// `brz c, EBB, args`. (Branch)
/// Type inferred from `c`.
Brz,
...
}
With the current opcodes, Opcode
is a single byte, but Option<Opcode>
is two bytes. We use the explicit null to indicate the empty slots in a precomputed hash table:
const OPCODE_HASH_TABLE: [Opcode; 128] = [
Opcode::Imul,
Opcode::Fsub,
Opcode::IconcatLohi,
Opcode::Sshr,
Opcode::Fmaxnum,
Opcode::NotAnOpcode,
Opcode::Nearest,
...
}
This table would double in size if we used Option<Opcode>
. Since this table is only used by the parser when mapping strings to opcodes, perhaps we should just bite the bullet and use an Option<Opcode>
here. Hopefully, the Rust compiler will soon learn how to represent this sum type efficiently. It's one of the easier nested enum optimizations.
Encoding tables also use NotAnOpcode
currently. These tables are more critical to keep small, but there may be an alternative representation of the empty slots.