37.7. Bytecode Design

This section offers some insight into bytecode design in the form
of questions and answers.

37.7.1. When to add a new bytecode?

Question:

Does it make sense to define a new bytecode instruction for
RESTART-CASE? Why? Why not?

Answer: Is it speed critical?

RESTART-CASE is a glorified LET binding
for SYSTEM::*ACTIVE-RESTARTS* and could well profit
from a separate bytecode: it would make it non-consing[3].
(Remember that RESTARTs have dynamic extent and therefore do not
really need to be heap allocated.)

The reason HANDLER-BIND has its own bytecodes and
RESTART-CASE does not is that HANDLER-BIND can occur in inner
computation loops, whereas RESTART-CASE occurs only as part of
user-interface programming and therefore not in inner loops where its
consing could hurt much.

Why are the arguments pushed onto the STACK, just to be popped off of
it during the JMPTAIL?
Why not a sequence of LOAD,
STORE and
SKIP instructions
followed by a JMP?

Answer: This is a shortcut for the most common use

Using JMPTAIL requires 3
instructions, JMP requires more.
When JMPTAIL needs to be called, we
usually have some stuff close to the top of the STACK which will
become the new arguments, and some junk between these new arguments
and the closure object. JMPTAIL
removes the junk. JMPTAIL is a
convenient shortcut which shortens the bytecode - because typically
one would really have to clean-up the STACK by hand or make the
calculations in src/compiler.lisp
more complicated.