next.js
db8c86ce - turbo-tasks: inline LazyTail bytes into TaskStorageBox allocation

Commit
65 days ago
turbo-tasks: inline LazyTail bytes into TaskStorageBox allocation `LazyTail` shrinks from 16 B to 8 B by dropping its `NonNull<u8>` field and the explicit unsafe `Send`/`Sync` impls. The byte buffer it described now lives in the same heap allocation as the surrounding `TaskStorageBox`, immediately after the `TaskStorage` head: offset 0: TaskStorage { inline fields, flags, LazyTail (8 B) } offset size_of::<TaskStorage>(): [u8; tail_cap] (payloads in tag order) `TaskStorageBox` switches from a Box<TaskStorage> wrapper to a custom NonNull<TaskStorage> that manages the unified allocation: alloc(head + tail_cap), drop walks the bitmap dispatching per-tag drops then runs the head Drop then deallocs. Realloc on grow updates the box's pointer in-place. Grow-capable lazy mutations move to `impl TaskStorageBox`: - Macro-emitted `set_<name>` and `<name>_mut` for lazy fields. Read / take / get-mut-if-present stay on `TaskStorage`. - `drop_partial`, `decode_meta`, `decode_data`, `clone_snapshot`, `restore_from`, `restore_meta_from`, `restore_data_from`. - Hand-written `init_transient_task` and `decode` wrapper. Read-only / non-grow methods stay on `TaskStorage` and reach the tail via `(self as *const TaskStorage).add(size_of::<TaskStorage>())` arithmetic. `Deref<Target = TaskStorage>` on `TaskStorageBox` lets all callsites keep their `self.typed().<field>()` / `self.typed_mut().<field>()` shape — the auto-deref picks whichever impl the method lives on. Per-tag drop dispatch runs in `TaskStorageBox::drop`; the previous hand-written `Drop for TaskStorage` is gone since stack-constructed `TaskStorage` values now always have `tail_cap == 0` and no live payloads. `size_of::<TaskStorage>()` returns to 128 B (down from 136 B in step 1) because `LazyTail` shrank by 8 B. `size_of::<LazyTail>()` is 8 B. 50 backend tests pass; whole workspace builds.
Author
Committer
Parents
Loading