SBCL's original "interpreter" is %simple-eval, which just calls the compiler. SB!EVAL was added sometime around 2008, but as you point out it is not used unless you set evaluator-mode to something other than :compile. The default code path goes through %simple-eval and the compiler. I have been using SBCL since before SB!EVAL was added, and I have never used the interpreter.
> ECL has three ways to run code: an interpreter, a byte code engine and a Lisp-to-C compiler
The confusing thing about ECL is that someone decided to call their bytecode VM an "interpreter." ECL has no interpreter - eval_nontrivial_form just calls the bytecode compiler.
All that is irrelevant to the fact that ECL uses GCC as a JIT.
> In theory one could use a JIT to compile the byte codes to native code at runtime.
Which would be completely pointless because GCC (or clang or MVCC, but the original question was about libgccjit) is already there and does better optimization.
> Some experiments of improving CLOS speed at runtime (similar to what Julia does) might be considered to be a moral equivalent of a JIT
Like half of the PCL is devoted to various kinds of caching that are in fact adaptive optimization. It is not a big step from that to inline caching. But again, why would you do that when you don't need to?
https://github.com/guicho271828/inlined-generic-function https://github.com/marcoheisig/fast-generic-functions
There is a reason Mozilla went from tracing (TraceMonkey) to inline caching (JägerMonkey) to type specialization (IonMonkey). JavaScript JITs have moved closer to Lisp compilers, not vice-versa.
I have covered other misconceptions that you have listed elsewhere in this thread.