Skip to content

Commit 001f5de

Browse files
authored
perf(turbo-tasks): Use the type information we already have for all ResolvedVc casts, expose synchronous versions of functions (#75055)
We already have type information for `ResolvedVc`, so we can avoid going through the codepath in `Vc`, which can fail and requires a cell read. I did this for sidecasts in #74844 to unblock synchronous graph traversals. This does the same for the rest of the functions. I expect any perf impact to be pretty small (casting isn't a particularly hot codepath), but it's also an easy change to make, and (once callsites are migrated) will lead to a nicer API. Right now I'm continuing to expose the async fallible versions of these functions. I'll port the callsites (looks like there's 92 of them) to the synchronous infallible version in a later PR.
1 parent 5de5b9a commit 001f5de

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

turbopack/crates/turbo-tasks/src/raw_vc.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ impl RawVc {
292292
}
293293
}
294294

295-
/// For a type that's already resolved, synchronously check if it implements a trait using the
295+
/// For a cell that's already resolved, synchronously check if it implements a trait using the
296296
/// type information in `RawVc::TaskCell` (we don't actualy need to read the cell!).
297297
pub(crate) fn resolved_has_trait(&self, trait_id: TraitTypeId) -> bool {
298298
match self {
@@ -302,6 +302,15 @@ impl RawVc {
302302
_ => unreachable!("resolved_has_trait must be called with a RawVc::TaskCell"),
303303
}
304304
}
305+
306+
/// For a cell that's already resolved, synchronously check if it is a given type using the type
307+
/// information in `RawVc::TaskCell` (we don't actualy need to read the cell!).
308+
pub(crate) fn resolved_is_type(&self, type_id: ValueTypeId) -> bool {
309+
match self {
310+
RawVc::TaskCell(_task_id, cell_id) => cell_id.type_id == type_id,
311+
_ => unreachable!("resolved_is_type must be called with a RawVc::TaskCell"),
312+
}
313+
}
305314
}
306315

307316
impl CollectiblesSource for RawVc {

turbopack/crates/turbo-tasks/src/vc/resolved.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,22 @@ where
255255
where
256256
K: Upcast<T> + VcValueTrait + ?Sized,
257257
{
258-
Ok(Vc::try_resolve_downcast(this.node)
259-
.await?
260-
.map(|node| ResolvedVc { node }))
258+
// TODO: Expose a synchronous API instead of this async one that returns `Result<Option<_>>`
259+
Ok(Self::try_downcast_sync(this))
260+
}
261+
262+
/// Attempts to downcast the given `ResolvedVc<Box<dyn T>>` to a `ResolvedVc<K>`, where `K`
263+
/// is of the form `Box<dyn L>`, and `L` is a value trait.
264+
///
265+
/// Returns `None` if the underlying value type is not a `K`.
266+
///
267+
/// See also: [`Vc::try_resolve_downcast`].
268+
pub fn try_downcast_sync<K>(this: Self) -> Option<ResolvedVc<K>>
269+
where
270+
K: Upcast<T> + VcValueTrait + ?Sized,
271+
{
272+
// this is just a more type-safe version of a sidecast
273+
Self::try_sidecast_sync(this)
261274
}
262275

263276
/// Attempts to downcast the given `Vc<Box<dyn T>>` to a `Vc<K>`, where `K` is a value type.
@@ -269,9 +282,28 @@ where
269282
where
270283
K: Upcast<T> + VcValueType,
271284
{
272-
Ok(Vc::try_resolve_downcast_type(this.node)
273-
.await?
274-
.map(|node| ResolvedVc { node }))
285+
// TODO: Expose a synchronous API instead of this async one that returns `Result<Option<_>>`
286+
Ok(Self::try_downcast_type_sync(this))
287+
}
288+
289+
/// Attempts to downcast the given `Vc<Box<dyn T>>` to a `Vc<K>`, where `K` is a value type.
290+
///
291+
/// Returns `None` if the underlying value type is not a `K`.
292+
///
293+
/// See also: [`Vc::try_resolve_downcast_type`].
294+
pub fn try_downcast_type_sync<K>(this: Self) -> Option<ResolvedVc<K>>
295+
where
296+
K: Upcast<T> + VcValueType,
297+
{
298+
let raw_vc = this.node.node;
299+
raw_vc
300+
.resolved_is_type(<K as VcValueType>::get_value_type_id())
301+
.then_some(ResolvedVc {
302+
node: Vc {
303+
node: raw_vc,
304+
_t: PhantomData,
305+
},
306+
})
275307
}
276308
}
277309

0 commit comments

Comments
 (0)