Step 07 · Beyond LLJIT — lazy, tiered, remote

LLJIT covers ~80 % of JIT use cases. ORC gives you more when you need it.

Lazy compilation

LLLazyJIT (a sibling of LLJIT) wraps each function in a stub. The function isn't compiled until the stub is hit, which dramatically reduces start-up time for big modules where only a fraction of code runs.

Tiering

A real engine like V8 starts cold code in an interpreter, then re-compiles hot functions with full optimisations, then patches the call sites. Build this on ORC by:

  1. Tier-1: compile with OptimizationLevel::O0 immediately.
  2. Use sampling or counters in the runtime to find hot functions.
  3. Submit a fresh module for those functions with O3 to a compile-thread.
  4. Use ORC's JITLink re-defining a symbol to atomically swap the entry point.

Remote / out-of-process JIT

OrcRemoteTargetClient lets you compile in one process and execute in another (or on a different machine). Great for embedded targets or sandboxing untrusted code.

Caching

ObjectCache plugs into the IR-compile layer to memoise compiled objects across runs — perfect for shell-style use of the JIT where the same script is launched repeatedly.

What we won't tackle in this curriculum

The integration with debuggers (GDB/LLDB JIT interface), profilers (VTune), and deopt/inline-cache machinery (V8/HotSpot-style ICs) deserve a course of their own. cp-12 leaves you with a working foundation; adding any one of the above is a focused, incremental exercise on top of jit::runMain.