Part of #378. Each item gets its own issue, and B2 its own ADR, before implementation. The ordering will be re-ranked after the A items land and the per-request census is re-run.
- B1: kwargs without a Hash.
- Today every kwargs call does
op_new_hash, then hash-literal dedup, then SipHash, then intern, and only then unpacks. That costs 370 ns versus 19 ns on CRuby.
- CRuby passes keywords positionally via the call-info
kw_arg list and allocates only for **opts.
- B2: 8-byte Copy
Value.
Value is a 16-byte enum holding Rc (Str, Class), so even an Int push/pop runs the clone/drop glue.
- In the empty-loop profile,
drop_glue, Value::clone and Vec::push account for about 25% and the Vm::run dispatch for about 20%. This is the root of the ~4× base step cost.
- Candidates are NaN-boxing or a tagged pointer, with Str/Class moved behind heap ids. Needs an ADR; co-design with the C value representation.
- B3: call-site cache holding the resolved method plus a call handler.
- Skip the
do_call cascade on a hit, along the lines of CRuby's vm_call_handler.
- Replace
&*name == "..." string compares and runtime intern on hot paths with precomputed SymIds.
- B4: Proc-free yield and frame elision.
yield costs 224 ns versus 27 ns on CRuby.
- ADR 0037 measured −21..34% per call for the frameless zero-arg tier; extend that approach.
Target: the Rails hello world bench within 1.5× of CRuby interp.
Part of #378. Each item gets its own issue, and B2 its own ADR, before implementation. The ordering will be re-ranked after the A items land and the per-request census is re-run.
op_new_hash, then hash-literal dedup, then SipHash, then intern, and only then unpacks. That costs 370 ns versus 19 ns on CRuby.kw_arglist and allocates only for**opts.Value.Valueis a 16-byte enum holdingRc(Str, Class), so even anIntpush/pop runs the clone/drop glue.drop_glue,Value::cloneandVec::pushaccount for about 25% and theVm::rundispatch for about 20%. This is the root of the ~4× base step cost.do_callcascade on a hit, along the lines of CRuby'svm_call_handler.&*name == "..."string compares and runtimeinternon hot paths with precomputed SymIds.yieldcosts 224 ns versus 27 ns on CRuby.Target: the Rails hello world bench within 1.5× of CRuby interp.