JIT Compiling Code in 5μs
JIT compilation for databases is being revisited with ultra-fast “copy-and-patch” approaches that can generate machine code in microseconds, avoiding the heavy latency of LLVM while still yielding sizable speedups over interpretation. Commenters weigh these performance gains against security concerns around relaxing strict W^X policies, the complexity and attack surface of JITs (especially for untrusted inputs), and the limited domains where JIT is worth the added portability and maintenance burden. Several point to lighter-weight JIT frameworks, manual JIT techniques in languages like Common Lisp, and even LLM-assisted code generation as ways to make specialized JITs more practical.
Security of JIT and W^X
- One side argues JIT is inherently less secure because it requires writable and executable memory, undermining strict W^X policies and enabling more powerful exploits.
- Others counter that modern JITs typically allocate RW pages, write code, then flip them to RX, so W^X is preserved per mapping.
- There’s debate over whether this has “system-wide implications” or is just a per-process hardening choice; some say the OS already has to manage such permissions, others stress that permitting dynamic code execution increases the impact of bugs.
- Examples are cited of platforms that heavily restrict JIT (iOS, GrapheneOS) and of techniques like bytecode verification and hardware memory tagging to make JIT safer.
- Several comments note that JITs increase attack surface for the host process (especially when running untrusted input, like browsers or DB queries), but do not grant new capabilities beyond what the process already has.
- ROP and similar techniques are invoked to argue that if a process can execute any code, arbitrary code execution is effectively possible with or without JIT.
JIT design, performance, and LLVM vs lightweight approaches
- Multiple comments emphasize that LLVM-based JITs have high latency and can be inappropriate for workloads needing very fast compilation (e.g., Postgres queries).
- Lightweight JIT approaches—copy-and-patch templates, small libraries (e.g., SLJIT, GNU Lightning, AsmJit), or custom backends—trade fewer optimizations for much lower compile time.
- Benchmarks discussed in linked posts show that simple JITs can achieve meaningful speedups over interpretation with negligible compile time, while LLVM can spend tens of milliseconds compiling.
- Database-focused comments stress that query-plan optimization (e.g., join ordering) matters far more than JIT; Postgres’s current JIT granularity (per expression, not pipeline) is seen as a fundamental limitation.
Is template-based codegen “real” JIT?
- Some dismiss the approach as “just assembly templates,” but others push back that:
- Non-optimizing compilers are still compilers.
- Copy-and-patch is a standard, legitimate JIT technique.
- Examples are given where very simple codegens (no register allocation, heavy stack use) are only a few times slower than highly optimized -O3 binaries, yet much faster than interpreters.
Common Lisp and manual JIT
- Common Lisp implementations are discussed as a middle ground:
- Some compile all code eagerly; others support bytecode plus optional native compilation.
evaland compile-on-load are framed as a form of JIT.- There are toggles to switch between interpreter and compiler for REPL use, trading compile time vs execution speed.
- A “manual JIT” style—explicitly choosing what to compile for speed—is praised as a practical and simpler compromise.
AI’s role in writing JITs and complex systems
- Opinions sharply diverge:
- Some say current models produce poor code in complex domains, suitable mainly for boilerplate, CRUD, wiring APIs, and simple bug-finding.
- Others report large productivity gains using AI to scaffold complex components (including JITs), turning a week of work into hours, provided a competent engineer decomposes tasks and reviews output.
- There’s debate over:
- How much domain expertise is still required (many say “a lot”).
- Whether AI-generated code quality is objectively bad or just stylistically different.
- The risk of non-expert users shipping superficially decent but fragile AI-written code.
Other applications and observations
- Commenters suggest using similar stencil-based JIT ideas for firewalls and on-the-fly eBPF generation.
- Regex engines, historical BASIC and Lisp systems, and modern DBMSs are mentioned as classic or natural domains for JIT.
- The thread also briefly touches on formally verified interpreters and signed static binaries as an extreme security alternative to JIT and native code.