SquirrelFish differs from the previous implementation of the interpreter in that it uses a bytecode based strategy rather than syntax tree-walking interpretation.
SquirrelFish's bytecode engine elegantly eliminates almost all of the overhead of a tree-walking interpreter. First, a bytecode stream exactly describes the operations needed to execute a program. Compiling to bytecode implicitly strips away irrelevant grammatical structure. Second, a bytecode dispatch is a single direct memory read, followed by a single indirect branch. Therefore, executing a bytecode instruction is much faster than visiting a syntax tree node. Third, with the syntax tree gone, the interpreter no longer needs to propagate execution state between syntax tree nodes.
Because the interpreter is now using bytecodes, it can take advantage of all of the optimizations available to bytecode interpreters. This means we can expect further speed improvements in SquirrelFish's future.
Some of the compile-time optimizations we're looking at, now that we have a bytecode representation, include:
- constant folding
- more aggressive copy propagation
- type inference-both exact and speculative
- specialization based on expression context-especially void and boolean context
- peephole optimization
- escape analysis
In their announcement, the SquirrelFish team acknowledged the work of others in this field from whose work their project drew inspiration.
SquirrelFish owes a lot of its design to some of the latest research in the field of efficient virtual machines, including research done by Professor M. Anton Ertl, et al, Professor David Gregg, et al, and the developers of the Lua programming language.
Mike Amundsen May 29, 2015
Ben Linders May 28, 2015