JIT Compilation
Joule supports just-in-time compilation for interactive development. Instead of producing an executable file, the compiler compiles your code in memory and runs it immediately.
Quick Start
# JIT-compile and run
joulec --jit program.joule
# Watch mode: re-compile on file changes
joulec --watch program.joule
Requirements
JIT mode requires the jit feature flag, which enables the Cranelift JIT backend:
# Build joulec with JIT support
cargo build --release -p joulec --features jit
The feature chain is: jit -> cranelift -> joule-codegen-cranelift + joule-codegen + notify.
How It Works
JIT Mode (--jit)
- Source code is parsed, type-checked, and lowered to MIR (the same pipeline as normal compilation)
- MIR is translated to Cranelift IR
- Cranelift compiles the IR to native machine code in memory
- The
main()function is called directly via a function pointer - The program runs and exits
No intermediate files are produced. No C compiler is invoked. Compilation and execution happen in a single process.
Watch Mode (--watch)
Watch mode extends JIT with file monitoring:
- The source file is JIT-compiled and run (same as
--jit) - The
notifycrate monitors the source file for changes - When the file is saved, a fresh JIT module is created and the program re-runs
- A 50ms debounce prevents multiple re-runs from editor save-rename sequences
Each watch cycle creates a fresh JITModule because Cranelift's JIT module cannot redefine functions. This ensures clean state on every re-run.
Architecture
FunctionTranslator
The FunctionTranslator<'a, M: Module> is generic over the module type:
| Module Type | Mode | Output |
|---|---|---|
ObjectModule | AOT compilation | Object file (.o) |
JITModule | JIT compilation | In-memory executable code |
This means the same translation logic handles both AOT and JIT -- no code duplication.
Runtime Symbols
JIT mode provides runtime symbols that replace the C runtime's functions:
| Symbol | Purpose |
|---|---|
joule_jit_println | Print a string with newline |
joule_jit_print | Print a string without newline |
joule_jit_panic | Panic with a message |
malloc | Memory allocation (libc) |
free | Memory deallocation (libc) |
memcpy | Memory copy (libc) |
These symbols are registered with the JITModule before compilation so that generated code can call them.
PIC Mode
JIT compilation uses position-independent code (PIC) = false, since the code runs in a known memory location. AOT compilation uses PIC = true for shared library compatibility.
Energy Tracking
JIT mode includes full energy tracking. Energy consumed during execution is measured and reported:
$ joulec --jit program.joule
Hello from JIT!
Energy consumed: 0.000123 J
Energy budgets declared with #[energy_budget] are checked at compile time, before JIT execution begins. If a budget is violated, compilation fails and the program does not run.
Limitations
- No persistent output: JIT mode does not produce an executable file. For deployment, use the C backend or AOT Cranelift compilation.
- Single-file: JIT mode currently compiles a single source file. Multi-file projects should use
moddeclarations within the entry file. - Feature gate: JIT support is behind
--features jitto keep the default binary small. Thenotifydependency is only pulled in when JIT is enabled.
Use Cases
Rapid Prototyping
JIT mode eliminates the compile-link-run cycle:
# Edit, save, see results instantly
joulec --watch prototype.joule
Energy Experimentation
Try different algorithms and immediately see their energy impact:
// Try bubble sort
#[energy_budget(max_joules = 0.001)]
fn sort_experiment(data: Vec<i32>) -> Vec<i32> {
bubble_sort(data)
}
joulec --jit experiment.joule
# Change to quicksort, save, see new energy reading
Interactive Testing
Run tests without a full build:
joulec --jit --test tests.joule
Comparison with Other Modes
| Mode | Command | Speed | Output | Use Case |
|---|---|---|---|---|
| JIT | --jit | Fastest | None (runs in memory) | Development |
| Watch | --watch | Fast (re-runs on save) | None | Interactive development |
| C Backend | --emit c | Moderate | .c file | Deployment, bootstrap |
| Cranelift AOT | (default) | Fast | Binary | Development builds |
| LLVM | --features llvm | Slow | Optimized binary | Release builds |