next.js
f491bdfa - make `TaskInput::is_resolved` inlinable everywhere (#94213)

Commit
19 hours ago
make `TaskInput::is_resolved` inlinable everywhere (#94213) ## What Removes the `ArgMeta::is_resolved` function-pointer field and the 592 monomorphized `closure#3` trampolines it generated. The `TaskInput::is_resolved` check that runs on the synchronous fast path of every turbo-tasks function call now happens at the macro-generated callsite on the concrete tuple type, before erasure into `&dyn StackDynTaskInputs`. For trait calls with `filter_owned`, the check is fused into the filter functor so the filter and the resolved-check monomorphize together. ## Why The `is_resolved` method is almost always trivial after optimization but putting it behind an opaque function pointer means we always pay a small code size and perf cost. Inlining actually saves bothr `Vc` field. Bonus rename: `OwnedStackDynTaskInputs` → `BoxedDynTaskInputs`. The \"Stack\" was the trait, not the storage — the inner value is a `Box<dyn DynTaskInputs>` on the heap. ## Hot-path microcheck The synchronous wrapper for a representative 6-input turbo function (`directory_tree_to_loader_tree`) now performs the entire `is_resolved` check as ~15 register-only ARM instructions inlined into the caller — three `cmp/csel/tbnz` chains testing the discriminant byte of each `Vc<...>` input. The four trivially-resolved inputs (`FileSystemPath`, `RcStr`, `AppPage`, `AppPath`) contribute zero instructions because their `is_resolved` constant-folded to `true`. No indirect call, no downcast trampoline. ## Code-size impact Release `next-swc.darwin-arm64.node`, macOS aarch64, vs the `temporary` branch this PR is stacked on: | Metric | prior (temporary) | this PR | Δ bytes | Δ % | | --- | ---: | ---: | ---: | ---: | | Raw `.node` | 124,217,280 | 123,845,712 | −371,568 | −0.30% | | Stripped (`strip -x`) | 84,013,136 | 83,880,384 | −132,752 | −0.16% | | Stripped + gzip -9 | 28,898,920 | 28,887,624 | −11,296 | −0.04% | <!-- NEXT_JS_LLM_PR -->
Author
Parents
Loading