perf(codegen): share numeric guards across dynamic add trees - #8675
perf(codegen): share numeric guards across dynamic add trees#8675proggeramlug wants to merge 2 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ape guards (#8682) Lands three reviewed PRs as one squash: #8674, #8675, #8676. - #8674: compress array forwarding chains (`clean_arr_ptr` multi-hop walk). - #8675: share numeric guards across dynamic add trees. - #8676: pack monomorphic method shape guards. These three were authored as a stack on top of #8672, but their contents touch disjoint files, so they are cherry-picked onto main on their own. #8672 is NOT included: it defines its own `is_bound_native_method_closure_value` (true for any bound native-module export with a non-empty module name), which #8662 superseded on main with the strictly narrower `is_bound_native_constructor_closure_value` (gated on explicit constructor metadata). Those predicates have different truth sets, so the substitution is a behavioural change at every call site and is left to the author to rebase. Also splits `array/tests.rs`, which #8674 pushed over the 2000-line cap, into an `array/forwarding_tests.rs` sibling. Pure relocation. Version bump not included per maintainer policy. Co-authored-by: Ralph Küpper <ralph@skelpo.com>
|
Landed on Your branch was stacked on #8672, but the contents touch disjoint files, so this commit was cherry-picked onto Validated on the merged result: 9 ratchet gates + One adjustment: #8674's new test pushed |
Summary
+trees with at least three leavesfaddarmjs_dynamic_string_or_number_addtree as the cold arm for strings, BigInt, Symbols, and object coercionWhy
Accumulator expressions such as
sum += row.x + row.ycommonly reach codegen with all three leaves boxed asAny, especially across callback and interface boundaries. Lowering each+node independently then calls the full dynamic addition helper twice even when all runtime values are numbers.The compiler already has a guarded numeric-tree lowering that evaluates leaves once and reconstructs the source tree in both arms. This change admits fully dynamic trees only when they have three or more leaves, which is the first point where one shared guard can replace multiple dynamic helpers.
This PR is stacked on #8674 (which is stacked on #8672). Please review/merge those first; this PR contains only commit
ed9d86bcerelative to its base, followed by the required changelog fragment.Correctness
cargo fmt --all -- --checkfadds and retains two dynamic helpers in the cold armcargo test -p perry-codegen --lib: 1,191 passed, 0 failed, 1 ignoredSymbol.toPrimitiveordering in both associativitiesPERRY_GC_FORCE_EVACUATE=1 PERRY_GC_VERIFY_EVACUATION=1codehz/ecscomprehensive suite: 7/7 passed with exact 50,005,000 accumulation checksumfadds on the numeric arm and both original dynamic-helper calls on the cold armThe exact committed compiler emitted the same
__textSHA-256 as the benchmarked artifact (b19ad70a31fa27d93f26e50bf1d140e5d577ebc9a0c256b3a9d762855f9fc90a).Performance
Apple M1 Mac mini on AC power. Each cohort followed a 60-sample quiet-host gate with every sample at or below 25% active CPU, used
taskpolicy -t 0 -l 0, and alternated process order.Against the exact #8674 code (
repeat=64), 11 accumulation pairs measured:All 22 processes passed the 7/7 suite oracle and exact checksum. A separate three-pair read-only regression check was neutral at the paired median (-0.033%, 1/3 wins); this optimization does not target that callback.
This is a measured incremental improvement, not a claim of Node parity. The remaining gap is dominated by the guarded ECS loop body and indirect boxed callback boundary.