Repository navigation
perf(interp): faster named calls and looped tail calls - #55
Merged
Merged
Conversation
Exact-arity INTERP-to-INTERP named and closure calls go through InterpreterExecute without copying VmFunction or entering GuardJitEntry. CALLNAME uses string_view on the success path. return f(...) emits TAIL/TAILNAME. Common exact-arity no-box self tails reuse the current frame in place; mutual, vararg, Multi, and cross-template cases use a generic fallback and a TLS trampoline so C-stack depth stays one. Tests cover self, mutual, vararg, upvalue, multi-return, deep tails, and error locations.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #55 +/- ##
==========================================
- Coverage 89.77% 89.73% -0.04%
==========================================
Files 125 125
Lines 27317 27554 +237
==========================================
+ Hits 24523 24725 +202
- Misses 2794 2829 +35 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR speeds up interpreter calls in two related ways, landed together:
Direct INTERP call fast paths. Exact-arity INTERP-to-INTERP named and closure calls go through
InterpreterExecute/InterpExecuteInContextwithout copyingVmFunctionor enteringGuardJitEntry/ an extraLuaLocScope.Vm::FindFunction(std::string_view)returns a pointer into the function table.CALLNAME/CallByNameArgstakestring_viewand no longer heap-allocatestd::stringon the success path (allocation remains on error paths).Looped tail calls.
return f(...)(not parenthesizedreturn (f(...))) emitsTAIL/TAILNAME. The common exact-arity, non-vararg, no-box self-tail reuses the current frame in place (inst.c = kTailSelfExact, no name lookup). Mutual recursion, vararg, Multi, JIT/native callees, and no-box→boxed or root-frame growth use a generic fallback and a TLS trampoline so C-stack depth stays one. NormalCALL/CALLNAMEdo not pay a per-tail setup cost.Semantics / tests
New fixtures and cases cover self, mutual, vararg, upvalue, multi-return, deep INTERP tails (
n=100000), and tail error locations (TailErr.boomline 6,call_missingline 13, including deep INTERPn=20000). File-level functions cannot be reassigned, which is what allows self-TAILNAMEto skip the name lookup.Locally, 562 related unit tests (
test_basic,closure,runtime,vm_cvar_call,test_native,algo,jitter,exception) passed under an addr2line bwrap stub used only to keep Boost.Stacktrace throw-heavy tests from hanging on symbolization. This is not a claim that the full suite or CI is green.Measurements
Comparable Release, same harness,
debug_mode=false,min_time=0.3s, 3 sequential reps, median Time ns/call. Three libraries (master at49c63c7, call-opt alone, and this combined change) viaLD_LIBRARY_PATH. No concurrent compile during the run. INTERP TailRec at large n ran in a forked child so C-stack overflow is recorded as a crash rather than killing the driver.master → this PR (combined call-opt + tail):
Tradeoff versus call-opt alone (not an unqualified all-path speedup): the combined change is about 4% slower on EmptyCall and about 11% slower on non-tail Recursion than the call-opt-only intermediate (EmptyCall 538246 → 559517; Recursion 1165972 → 1298006). The residual is likely interpreter loop code layout. There is no new public opt-in flag; tail is on by default because of the tail-call wins and stack safety below.
TailRec INTERP (self tail):
Notes
Default
CompileConfig/debug_modeand unrelated caches are unchanged.