XCX 4.0 — The Performance & Architecture Update


The biggest XCX release yet. A ground-up JIT rewrite, new VM value representation, zero-copy JSON, arena allocator, and a fully reworked REPL — all delivering up to 27× speedup in benchmarks.


PERFORMANCE — BENCHMARK RESULTS

Benchmark XCX 3.1 reference XCX 4.0 JIT Improvement


____________________________________

|Benchmark| xcx 3.1| xcx 4.0 | Improvment |

|--------------------------------------------------|

|Loop 100M| 520ms | 119ms | 4.37× |

|--------------------------------------------------|

|Fib(30) | 45ms | 14.28ms |3.15× |

|--------------------------------------------------|

|Sieve 100K |5ms | 2.55ms | 1.96× |

|--------------------------------------------------|

|JSON 1000×100| 112ms | 22.74ms | 4.92×|

|____________________________________|


WHAT'S NEW


[JIT] Tracing JIT — fully rewritten (Cranelift)

From 1780-line monolith to 20-file architecture with type inference, liveness analysis, NaN-boxing, tiered compilation, and fused loop opcodes. Hot paths detected after 50 visits; 7-argument trace signature.


[VM] New value representation — two-word struct

Replaced NaN-boxed single 64-bit word with explicit {bits, tag} struct (16 bytes). JIT registers still use NaN-boxing internally via pack/unpack adapters. Added TAG_CLOSURE and TAG_ARENA.


[perf] New perf module

High-resolution monotonic timer — perf.ms(), perf.us(), perf.ns(). Unlike date.now(), values are guaranteed monotonic and unaffected by NTP/DST.


[JSON] Zero-copy JSON engine

Internal JsonVal type replaces serde_json::Value. Objects use Vec-based linear search (faster than hashing at small sizes). Direct buffer writes, no intermediate allocations. 112ms -> 22.74ms.


[VM] Arena allocator

Per-thread bump allocator (TAG_ARENA) — 4KB chunks, no Arc/RwLock overhead, no destructors. Eliminates reference counting cost for temporary values.


[REPL] REPL fully reworked (crossterm)

Rebuilt on top of crossterm. Features free multiline editing via arrow keys without mode switching, explicit !exec command for triggering script execution, and an updated welcome screen/help menu.


[Fix] While loop JIT path fix

Shadowing bug in compile_while caused < operator to always fall through to LessEqual path — dedicated JIT optimization was never used.


[Fix] Type inference at CFG join points

Merge logic incorrectly absorbed types into Unknown for unvisited blocks. Introduced visited: Vec<bool> — JIT now emits more native Cranelift ops instead of polymorphic FFI calls.


[Fix] Table Literal Limit Resolution

Fixed compiler register overflow when declaring large table literals (exceeding 255 cells). Introduced a selective compilation strategy via new TableBegin and TableInitRow opcodes, recycling VM registers per row incrementally. The mechanism activates automatically for matrices larger than 200 cells, maintaining fast paths for small data.


[CLI] New CLI flags

--no-jit disables JIT globally.


[arch] Codebase modularization

19 -> 269 Rust files. ~18K -> ~35K lines. Largest file is 1172 lines. Compiler split into 25+ modules; VM divided into core/, frame/, value/, object/, trace/.


[linux] Linux build parity

The Linux version successfully passes all core tests verified on Windows. However, it may still exhibit isolated OS-specific edge-cases and issues not present on Windows. Performance metrics show a slight variance, generally fluctuating by +-5-7% compared to Windows builds.


[infra] Closure infrastructure (internal)

ClosureObj with upvalue cells, new opcodes MakeClosure/CloseUpvalue/LoadUpvalue/StoreUpvalue. XCX syntax does not yet expose closures — infrastructure ready for 5.0.