Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reduce amount of code generated by ValueDebugFormat (#8239)
I noticed that `ValueDebugFormat` was pretty common near the top of `cargo llvm-lines`. It looked like this was probably due to the large number of await points inserted into the code. Each await point complicates the state machine that rustc must generate and pass to LLVM. This reduces the number of await points from one per field to one per struct. There's a minor change in behavior as the child fields are awaited concurrently (`join_all`) instead of one-at-a-time. ## Why? Less code generated by macros and passed to LLVM should mean faster compiles and a smaller binary that we're shipping to the user. The total change here is pretty small though, so it's probably not worth benchmarking compile times. ## Testing ``` cargo test -p turbo-tasks-macros-tests ``` ## cargo llvm-lines (sanity check) ``` cargo llvm-lines -p next-swc-napi ``` Before: ``` Lines Copies Function name ----- ------ ------------- 1094257 31851 (TOTAL) ... 1246 (0.1%, 2.2%) 1 (0.0%, 0.0%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` After: ``` Lines Copies Function name ----- ------ ------------- 1088974 31851 (TOTAL) ... 462 (0.0%, 7.7%) 1 (0.0%, 0.3%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` ## Binary size (next-swc, stripped arm64 linux tarball) Before: `188180480 bytes` After: `187443200 bytes` <details> <summary><strong>Example Generated Code (After)</strong> </summary> ```rust // ================================================= // Recursive expansion of the ValueDebugFormat macro // ================================================= impl turbo_tasks::debug::ValueDebugFormat for ComponentsForJs { fn value_debug_format<'a>( &'a self, depth: usize, ) -> turbo_tasks::debug::ValueDebugFormatString<'a> { turbo_tasks::debug::ValueDebugFormatString::Async(Box::pin(async move { if depth == 0 { return Ok(stringify!(ComponentsForJs).to_string()); } use turbo_tasks::debug::{internal::*, ValueDebugFormat}; Ok(format!( "{:#?}", match self { ComponentsForJs { page, layout, error, loading, template, not_found, default, route, metadata, } => FormattingStruct::new_named_async( stringify!(ComponentsForJs), vec![ AsyncFormattingField::new( stringify!(page), turbo_tasks::macro_helpers::value_debug_format_field( page.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(layout), turbo_tasks::macro_helpers::value_debug_format_field( layout.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(error), turbo_tasks::macro_helpers::value_debug_format_field( error.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(loading), turbo_tasks::macro_helpers::value_debug_format_field( loading.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(template), turbo_tasks::macro_helpers::value_debug_format_field( template.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(not_found), turbo_tasks::macro_helpers::value_debug_format_field( not_found.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(default), turbo_tasks::macro_helpers::value_debug_format_field( default.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(route), turbo_tasks::macro_helpers::value_debug_format_field( route.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(metadata), turbo_tasks::macro_helpers::value_debug_format_field( metadata.value_debug_format(depth.saturating_sub(1)) ), ), ], ) .await, } )) })) } } ``` </details>
- Loading branch information