Skip to content

Commit fb7a42c

Browse files
committed
Devirtualize some trait calls
1 parent 3c46980 commit fb7a42c

File tree

7 files changed

+137
-19
lines changed

7 files changed

+137
-19
lines changed

turbopack/crates/turbo-tasks-macros/src/func.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -561,22 +561,37 @@ impl TurboFn<'_> {
561561
let inputs = self.exposed_input_idents();
562562
let persistence = self.persistence_with_this();
563563
parse_quote! {
564-
{
565-
#assertions
566-
let inputs = std::boxed::Box::new((#(#inputs,)*));
567-
let this = #converted_this;
568-
let persistence = #persistence;
569-
static TRAIT_METHOD: turbo_tasks::macro_helpers::Lazy<&'static turbo_tasks::TraitMethod> =
570-
turbo_tasks::macro_helpers::Lazy::new(|| #trait_type_ident.get(stringify!(#ident)));
571-
<#output as turbo_tasks::task::TaskOutput>::try_from_raw_vc(
564+
{
565+
#assertions
566+
let inputs = std::boxed::Box::new((#(#inputs,)*));
567+
let this = #converted_this;
568+
let persistence = #persistence;
569+
static TRAIT_METHOD: turbo_tasks::macro_helpers::Lazy<&'static turbo_tasks::TraitMethod> =
570+
turbo_tasks::macro_helpers::Lazy::new(|| #trait_type_ident.get(stringify!(#ident)));
571+
static DEVIRTUALIZED: turbo_tasks::macro_helpers::Lazy<Option<&'static turbo_tasks::macro_helpers::NativeFunction>> =
572+
turbo_tasks::macro_helpers::Lazy::new(|| turbo_tasks::registry::get_devirtualized_trait_impl(*TRAIT_METHOD));
573+
574+
// Perform direct calls to devirtualized trait methods.
575+
// ideally we would call directly to the outer implementation function on the only implementation
576+
<#output as turbo_tasks::task::TaskOutput>::try_from_raw_vc(match *DEVIRTUALIZED {
577+
Some(f) => {
578+
turbo_tasks::devirtualized_trait_call(
579+
f,
580+
this,
581+
inputs as std::boxed::Box<dyn turbo_tasks::MagicAny>,
582+
persistence,
583+
)
584+
}
585+
None => {
572586
turbo_tasks::trait_call(
573587
*TRAIT_METHOD,
574588
this,
575589
inputs as std::boxed::Box<dyn turbo_tasks::MagicAny>,
576590
persistence,
577591
)
578-
)
579-
}
592+
}
593+
})
594+
}
580595
}
581596
}
582597

turbopack/crates/turbo-tasks-testing/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,15 @@ impl TurboTasksCallApi for VcStorage {
119119
) -> RawVc {
120120
unreachable!()
121121
}
122-
122+
fn devirtualized_trait_call(
123+
&self,
124+
__trait_impl: &'static turbo_tasks::macro_helpers::NativeFunction,
125+
_this: RawVc,
126+
_arg: Box<dyn MagicAny>,
127+
_persistence: TaskPersistence,
128+
) -> RawVc {
129+
unreachable!()
130+
}
123131
fn run(
124132
&self,
125133
_future: Pin<Box<dyn Future<Output = Result<()>> + Send + 'static>>,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ pub use key_value_pair::KeyValuePair;
107107
pub use magic_any::MagicAny;
108108
pub use manager::{
109109
CurrentCellRef, ReadConsistency, ReadTracking, TaskPersistence, TurboTasks, TurboTasksApi,
110-
TurboTasksBackendApi, TurboTasksCallApi, Unused, UpdateInfo, dynamic_call, emit, mark_finished,
111-
mark_root, mark_session_dependent, mark_stateful, prevent_gc, run, run_once,
112-
run_once_with_reason, trait_call, turbo_tasks, turbo_tasks_scope,
110+
TurboTasksBackendApi, TurboTasksCallApi, Unused, UpdateInfo, devirtualized_trait_call,
111+
dynamic_call, emit, mark_finished, mark_root, mark_session_dependent, mark_stateful,
112+
prevent_gc, run, run_once, run_once_with_reason, trait_call, turbo_tasks, turbo_tasks_scope,
113113
};
114114
pub use output::OutputContent;
115115
pub use raw_vc::{CellId, RawVc, ReadRawVcFuture, ResolveTypeError};

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

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,13 @@ pub trait TurboTasksCallApi: Sync + Send {
7373
arg: Box<dyn MagicAny>,
7474
persistence: TaskPersistence,
7575
) -> RawVc;
76-
76+
fn devirtualized_trait_call(
77+
&self,
78+
trait_impl: &'static NativeFunction,
79+
this: RawVc,
80+
arg: Box<dyn MagicAny>,
81+
persistence: TaskPersistence,
82+
) -> RawVc;
7783
fn run(
7884
&self,
7985
future: Pin<Box<dyn Future<Output = Result<()>> + Send + 'static>>,
@@ -656,6 +662,17 @@ impl<B: Backend + 'static> TurboTasks<B> {
656662
self.schedule_local_task(task_type, persistence)
657663
}
658664

665+
pub fn devirtualized_trait_call(
666+
&self,
667+
trait_impl: &'static NativeFunction,
668+
this: RawVc,
669+
arg: Box<dyn MagicAny>,
670+
persistence: TaskPersistence,
671+
) -> RawVc {
672+
let arg = trait_impl.arg_meta.filter_owned(arg);
673+
return self.dynamic_call(trait_impl, Some(this), arg, persistence);
674+
}
675+
659676
pub fn trait_call(
660677
&self,
661678
trait_method: &'static TraitMethod,
@@ -1183,7 +1200,15 @@ impl<B: Backend + 'static> TurboTasksCallApi for TurboTasks<B> {
11831200
) -> RawVc {
11841201
self.trait_call(trait_method, this, arg, persistence)
11851202
}
1186-
1203+
fn devirtualized_trait_call(
1204+
&self,
1205+
trait_impl: &'static NativeFunction,
1206+
this: RawVc,
1207+
arg: Box<dyn MagicAny>,
1208+
persistence: TaskPersistence,
1209+
) -> RawVc {
1210+
self.devirtualized_trait_call(trait_impl, this, arg, persistence)
1211+
}
11871212
#[track_caller]
11881213
fn run(
11891214
&self,
@@ -1579,6 +1604,15 @@ pub fn trait_call(
15791604
) -> RawVc {
15801605
with_turbo_tasks(|tt| tt.trait_call(trait_method, this, arg, persistence))
15811606
}
1607+
/// Calls [`TurboTasks::devirtualized_trait_call`] for the current turbo tasks instance.
1608+
pub fn devirtualized_trait_call(
1609+
trait_impl: &'static NativeFunction,
1610+
this: RawVc,
1611+
arg: Box<dyn MagicAny>,
1612+
persistence: TaskPersistence,
1613+
) -> RawVc {
1614+
with_turbo_tasks(|tt| tt.devirtualized_trait_call(trait_impl, this, arg, persistence))
1615+
}
15821616

15831617
pub fn turbo_tasks() -> Arc<dyn TurboTasksApi> {
15841618
TURBO_TASKS.with(|arc| arc.clone())

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

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use once_cell::sync::Lazy;
55
use rustc_hash::{FxHashMap, FxHashSet};
66

77
use crate::{
8-
TraitType, ValueType,
8+
TraitMethod, TraitType, ValueType,
99
id::{FunctionId, TraitTypeId, ValueTypeId},
1010
macro_helpers::CollectableFunction,
1111
native_function::NativeFunction,
@@ -171,6 +171,56 @@ static TRAITS: Lazy<Registry<TraitType>> = Lazy::new(|| {
171171
Registry::new_from_items(all_traits)
172172
});
173173

174+
static DEVIRTUALIZED_TRAIT_METHODS: Lazy<FxHashMap<&'static TraitMethod, &'static NativeFunction>> =
175+
Lazy::new(|| {
176+
#[derive(Default)]
177+
enum Impls {
178+
#[default]
179+
None,
180+
One(&'static NativeFunction),
181+
MoreThanOne,
182+
}
183+
impl Impls {
184+
fn push(&mut self, func: &'static NativeFunction) {
185+
let new = match self {
186+
Impls::None => Impls::One(func),
187+
Impls::One(_) => Impls::MoreThanOne,
188+
Impls::MoreThanOne => Impls::MoreThanOne,
189+
};
190+
*self = new;
191+
}
192+
}
193+
let mut trait_method_to_impls = FxHashMap::default();
194+
for tt in &TRAITS.id_to_item {
195+
for (_, tm) in &tt.methods {
196+
trait_method_to_impls
197+
.insert(tm, tm.default_method.map(Impls::One).unwrap_or(Impls::None));
198+
}
199+
}
200+
for value in &VALUES.id_to_item {
201+
for (tm, nf) in &value.trait_methods {
202+
trait_method_to_impls.entry(tm).or_default().push(nf);
203+
}
204+
}
205+
206+
trait_method_to_impls
207+
.into_iter()
208+
.filter_map(|(k, v)| {
209+
if let Impls::One(f) = v {
210+
Some((k, f))
211+
} else {
212+
None
213+
}
214+
})
215+
.collect()
216+
});
217+
218+
pub fn get_devirtualized_trait_impl(
219+
trait_method: &'static TraitMethod,
220+
) -> Option<&'static NativeFunction> {
221+
DEVIRTUALIZED_TRAIT_METHODS.get(trait_method).copied()
222+
}
223+
174224
pub fn get_trait_type_id(trait_type: &'static TraitType) -> TraitTypeId {
175225
TRAITS.get_id(trait_type)
176226
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub struct ValueType {
3434
/// Set of traits available
3535
traits: AutoSet<TraitTypeId>,
3636
/// List of trait methods available
37-
trait_methods: AutoMap<&'static TraitMethod, &'static NativeFunction>,
37+
pub(crate) trait_methods: AutoMap<&'static TraitMethod, &'static NativeFunction>,
3838

3939
/// Functors for serialization
4040
any_serialization: Option<(AnySerializationFn, AnyDeserializeSeed)>,

turbopack/crates/turbopack-core/src/ident.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::Result;
44
use once_cell::sync::Lazy;
55
use regex::Regex;
66
use serde::{Deserialize, Serialize};
7-
use turbo_rcstr::RcStr;
7+
use turbo_rcstr::{RcStr, rcstr};
88
use turbo_tasks::{
99
NonLocalValue, ReadRef, ResolvedVc, TaskInput, ValueToString, Vc, trace::TraceRawVcs,
1010
};
@@ -104,6 +104,17 @@ impl AssetIdent {
104104
}
105105
}
106106

107+
#[turbo_tasks::value]
108+
struct TestStruct {}
109+
110+
#[turbo_tasks::value_impl]
111+
impl ValueToString for TestStruct {
112+
#[turbo_tasks::function]
113+
fn to_string(self: Vc<Self>) -> Vc<RcStr> {
114+
Vc::cell(rcstr!("huh"))
115+
}
116+
}
117+
107118
#[turbo_tasks::value_impl]
108119
impl AssetIdent {
109120
#[turbo_tasks::function]

0 commit comments

Comments
 (0)