pub struct JitVmGuard { /* private fields */ }Expand description
P11-S5c — RAII guard pinning the active Vm (and optional closure)
pointer for JIT-emitted Rust helper calls.
§v2.0 Track J sub-step J-D — real RAII rebind
Prior to J-D, this guard’s drop was a deliberate no-op: the
dispatcher always re-installed JIT_VM / JIT_CL on every
enter_jit call, so the previous-dispatch values would simply be
overwritten on the next entry. That trick saved 2 TLS writes per
dispatch (~5-10 cycles each on arm64) — measurable on fib_28’s
434k dispatches (~1.5 ms aggregate).
Track J Option B targets cross-thread Vm move under
feature = "send" (J-E flip). Once a Vm parks on thread A, moves
to thread B, and dispatches there, the per-thread JIT_VM slot on
thread B is null/stale at entry — enter_jit installs it fine on
the way in, but on the way out the no-op drop left stale Vm
pointers behind for any nested JIT entry (Lua-from-Rust-from-
JIT call chains, e.g. metamethod dispatch under a JIT’d op). With
nested entries restoring an outer Vm pointer becomes load-bearing.
J-D therefore turns the guard into a real RAII: enter_jit
captures the prior (JIT_VM, JIT_CL) values into the guard, and
Drop restores them. The cost is the 2 TLS writes we previously
elided per dispatch. The single-thread-no-nesting case is
semantically equivalent: prior values restored on exit are the
same null/stale ones the next enter_jit would overwrite anyway;
no observable behavior change for existing call sites.
NullJitBackend::enter keeps the no-op shape via
noop_jit_guard — its guard has restore = None.
Debug-mode assertions still catch misuse via current_jit_vm’s
is_null check IF a helper runs outside enter_jit (would happen
only if some bug calls a helper symbol from interp code, which
never happens by design).