From 2364f6b22ee71ffc7dd394a3ee51ef52357878b9 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:54:37 +0100 Subject: [PATCH] gpui2: Type-erase futures. Project2's LLVM IR size is ~20-25% bigger than project1 due to the fact that in gpui2 we call async_task::spawn(_local) with impl Future instead of dyn Future, which leads to quite a few more instantiations of RawTask. LLVM-IR size for project2: | build_type | main | this branch | project1 | | debug | 2617795 | 2022814 | 1817866 | | release | 4439033 | 3715086 | 3314489 | --- crates/gpui2/src/executor.rs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/crates/gpui2/src/executor.rs b/crates/gpui2/src/executor.rs index b6fd5b23180bed5bf852ae99e79a6cb071ac7174..b7e3610283f5ec58fbd61a6d977c02e55efedaaf 100644 --- a/crates/gpui2/src/executor.rs +++ b/crates/gpui2/src/executor.rs @@ -68,7 +68,8 @@ impl Future for Task { } } } - +type AnyLocalFuture = Pin>>; +type AnyFuture = Pin>>; impl BackgroundExecutor { pub fn new(dispatcher: Arc) -> Self { Self { dispatcher } @@ -81,10 +82,16 @@ impl BackgroundExecutor { R: Send + 'static, { let dispatcher = self.dispatcher.clone(); - let (runnable, task) = - async_task::spawn(future, move |runnable| dispatcher.dispatch(runnable)); - runnable.schedule(); - Task::Spawned(task) + fn inner( + dispatcher: Arc, + future: AnyFuture, + ) -> Task { + let (runnable, task) = + async_task::spawn(future, move |runnable| dispatcher.dispatch(runnable)); + runnable.schedule(); + Task::Spawned(task) + } + inner::(dispatcher, Box::pin(future)) } #[cfg(any(test, feature = "test-support"))] @@ -243,11 +250,17 @@ impl ForegroundExecutor { R: 'static, { let dispatcher = self.dispatcher.clone(); - let (runnable, task) = async_task::spawn_local(future, move |runnable| { - dispatcher.dispatch_on_main_thread(runnable) - }); - runnable.schedule(); - Task::Spawned(task) + fn inner( + dispatcher: Arc, + future: AnyLocalFuture, + ) -> Task { + let (runnable, task) = async_task::spawn_local(future, move |runnable| { + dispatcher.dispatch_on_main_thread(runnable) + }); + runnable.schedule(); + Task::Spawned(task) + } + inner::(dispatcher, Box::pin(future)) } }