Elide/ Architecture

Architecture · memory safety

Memory-safe semantics, optimized.

Elide carries memory-safety checks from the interpreter into optimized machine code, giving guest languages one foundation for safety and performance.2

Walkthrough

Share a memory-safe foundation across languages

Elide gives its guest languages Truffle's shared managed execution model 1 2. Truffle supports JavaScript through GraalJS, Python through GraalPy, JVM bytecode through Espresso, and WebAssembly through GraalWasm.15 Bounds checks and garbage collection give these language implementations a common foundation for memory safety.2

Optimize code without duplicating its safety rules

Graal specializes the interpreter for each guest program, reusing its checked semantics in optimized machine code.2 5 The compiler must preserve those semantics through optimization and code generation.17 This reduces duplicated correctness rules across a language’s interpreter and optimizer.2

Precompile the engine, specialize guest execution

Native Image compiles reachable Engine code ahead of time, reducing the host code included in the executable.4 18 At run time, partial evaluation specializes guest execution while preserving interpreter behavior.5 Changing assumptions return execution to the interpreter for renewed specialization.6

Build safety into guest optimization

V8’s in-process sandbox aims to contain corruption within its heap sandbox, protecting the surrounding application.3 16 Truffle addresses semantic duplication by deriving guest optimizations from checked interpreter behavior.2 Elide chooses that shared foundation for memory safety across its guest languages.15

Make native ownership explicit

Rust owns Elide’s native entry, which calls the Native Image Engine through a C ABI.1 That hand-off records pointer lifetimes and thread ownership.7 Native libraries and extension interfaces belong to the trusted integration layer, with explicit memory and resource ownership contracts.8 17

Test native paths and reinforce their boundaries

Elide’s sanitizer test builds detect errors in instrumented paths during testing.11 12 21 Optional protections include Native Image control-flow integrity (CFI), hardware-backed memory protection domains, and mimalloc's secure allocator mode.13 14 19 Compiler and linker hardening reinforce the C integration.9 10

JavaScriptPythonJVMWasmmanaged interpreter model checked memory · GCJavaScriptPythonJVMWasmmanaged interpreter model checked memory · GCinterpreter language rulesguest program known behaviorpartial evaluation specialize the rulesmachine code derived behaviorassumption changes → return to interpreter interpreter language rulesguest program known behaviorpartial evaluation specialize the rulesmachine code derived behaviorassumption changes → interpreter
image build reachability · ahead of time run time partial evaluationentryruntimehttpTruffleJSPythonunusedunusedunusednative Engine image reachable code onlyAddintdoublestringobjectprofile: int + intmachine code the int path only
V8 · containmentEmbedder processV8 heap sandboxJS · Wasm heapguarded sandbox boundarynative process memoryGraal · derivememory-safe interpreter one set of rulespartial evaluation specializemachine code same guest semanticsV8 · containmentEmbedder processV8 heap sandboxJS · Wasm heapnative process memoryGraal · derivememory-safe interpreter one set of rulespartial evaluation specializemachine code same guest semantics
Host OS
C dependencies
CLI parsing crate
Rust entry · FFI
C ABI entry
Native Image Engine
JS
Py
JVM
Wasm
Application
Rust → Engine · C ABI boundary
Runtime hardeningOptional CFI · MPK
mimalloc secure mode
C compiler · linker flags
Sanitizer test buildsDetect memory errors
Check executed paths
Selected per target
Mike Hearn

“The core idea is to automatically transform the code of your interpreter to create individual JIT compiled user methods.”

Mike Hearn · GraalVM Team
Writing Truly Memory Safe JIT Compilers · 2024

In practice

One foundation, explicit boundaries

Elide reuses checked interpreter semantics across languages and optimization tiers.2 15 Graal and the Native Image runtime preserve those semantics; Rust and native libraries provide system integration.1 17 18 At a native boundary, the caller must supply valid memory and the callee must respect its bounds and lifetime.7 8 Python native extensions run with native authority.17 20

Memory safety governs valid memory access.2 Application permissions, resource budgets, and tenant isolation have their own policies and boundaries.22 This composition lets Elide combine managed guest execution with native services, while using sanitizer validation and optional hardening to reinforce the interfaces between them.1 11 13 19

Sources

  1. packages/entry/bin/main.rs:325-343,509-543; packages/cli/main/dev/elide/Entry.kt:549-592 — establishes the Rust C-ABI declaration and call, and the Kotlin @CEntryPoint implementation.
  2. GraalVM blog, “Writing Truly Memory Safe JIT Compilers” — describes Java Truffle interpreters, partial evaluation, and deriving compiled code from interpreter semantics.
  3. V8, “The V8 Sandbox” § The V8 (Heap) Sandbox — describes heap containment, sandbox-relative pointers, and external-pointer-table indirection.
  4. GraalVM Native Image § Native Image and Third-Party Libraries — defines Native Image’s closed-world static reachability analysis.
  5. GraalVM, “Host Compilation for Interpreter Java code” § Host Compilation for Interpreter Java code — distinguishes host and guest compilation and describes partial evaluation and Native Image reachability for runtime-compilable Truffle methods.
  6. GraalVM, “Optimizing Truffle Interpreters” § Debugging Deoptimizations — documents deoptimization from compiled Truffle code back to the interpreter.
  7. packages/entry/bin/main.rs:408-429 — documents the raw-pointer lifetime and ownership invariants for the Engine input hand-off.
  8. Native bridge string ownership — returns a Rust-owned C string and defines the matching release operation and pointer contract.
  9. crates/builder/src/lib.rs:42-58,794-820 — establishes the C hardening and control-flow-protection flags used by the C-build helper.
  10. tools/settings.mts:107-112,497-507,1617-1620 — establishes Linux C and linker options forwarded to Native Image, including RELRO and immediate binding.
  11. tools/strict.mts:6-21,27-64,128-197 — establishes the sanitizer set, per-target validation, and AddressSanitizer default for strict mode.
  12. tools/builder/cargo.mts:510-559,616-624; Cargo.toml:56-66 — establishes strict-mode Rust flags, the strict Cargo profile, and -Zbuild-std use.
  13. GraalVM SDK, Isolates.ProtectionDomain — documents Native Image isolate protection domains backed by a MemoryProtectionKeyProvider and underlying MPK hardware.
  14. mimalloc, “Building” § Linux, macOS, BSD, etc. — documents its secure build with guard pages and encrypted free lists.
  15. GraalVM, “Languages” — lists JavaScript, Python, JVM languages, and WebAssembly among the languages implemented on GraalVM and Truffle.
  16. V8 sandbox README — defines the in-process sandbox boundary, the memory it contains, and its assumed attacker model.
  17. GraalVM Security Guide § Security Model — treats correct instruction execution as the runtime’s security contract; native access and sandboxing have separate authority rules.
  18. Native Image Basics § Static Analysis — includes reachable code in the image and bundles runtime support, including garbage collection and threading.
  19. GraalVM 25.3 release notes § Native Image — documents optional CFI: software checks for indirect branches on AMD64 and pointer authentication for return addresses on AArch64.
  20. GraalPy, Embedding Native Extensions — native extensions require native access and execute with native authority; polyglot restrictions on Python code do not constrain native extensions.
  21. Clang, AddressSanitizer § Introduction and Usage — describes compiler instrumentation and runtime detection when instrumented code executes.
  22. GraalVM, Sandboxing § Sandbox Policies and Sharing Execution Engines — defines host-access restrictions, resource budgets, and separate engine boundaries for different trust domains.