From fce4afa4b8dccb9876efaf7be1079569f0c6795d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 20 Apr 2026 18:35:24 -0700 Subject: [PATCH] Fill out `MAY_REQUIRE_REALLOC` for more types This is an relatively impactful optimization to the performance of futures/streams when transferring data from the host to the guest, so fill this out for more types get the optimization to fire more. This was found during some improvement of wasi-libc where some code paths weren't getting hit, but they should,, and this is required to have that work out. --- crates/component-macro/src/component.rs | 11 +++++++++++ crates/wasmtime/src/runtime/component/func/typed.rs | 7 +++++++ .../wasmtime/src/runtime/component/resources/any.rs | 1 + .../wasmtime/src/runtime/component/resources/host.rs | 1 + .../src/runtime/component/resources/host_dynamic.rs | 1 + .../src/runtime/component/resources/host_static.rs | 1 + 6 files changed, 22 insertions(+) diff --git a/crates/component-macro/src/component.rs b/crates/component-macro/src/component.rs index 3a408dd83fbb..a9f693bd5462 100644 --- a/crates/component-macro/src/component.rs +++ b/crates/component-macro/src/component.rs @@ -359,6 +359,7 @@ fn expand_record_for_component_type( let mut lower_field_declarations = TokenStream::new(); let mut abi_list = TokenStream::new(); let mut unique_types = HashSet::new(); + let mut may_require_realloc = TokenStream::new(); for (index, syn::Field { ident, ty, .. }) in fields.iter().enumerate() { let generic = format_ident!("T{}", index); @@ -371,6 +372,9 @@ fn expand_record_for_component_type( abi_list.extend(quote!( <#ty as #wt::component::ComponentType>::ABI, )); + may_require_realloc.extend(quote!( + <#ty as #wt::component::ComponentType>::MAY_REQUIRE_REALLOC || + )); unique_types.insert(ty); } @@ -408,6 +412,7 @@ fn expand_record_for_component_type( const ABI: #internal::CanonicalAbiInfo = #internal::CanonicalAbiInfo::record_static(&[#abi_list]); + const MAY_REQUIRE_REALLOC: bool = #may_require_realloc false; #[inline] fn typecheck( @@ -961,6 +966,7 @@ impl Expander for ComponentTypeExpander { let mut lower_generic_args = TokenStream::new(); let mut abi_list = TokenStream::new(); let mut unique_types = HashSet::new(); + let mut may_require_realloc = TokenStream::new(); for (index, VariantCase { attrs, ident, ty }) in cases.iter().enumerate() { let rename = find_rename(attrs)?; @@ -969,6 +975,9 @@ impl Expander for ComponentTypeExpander { if let Some(ty) = ty { abi_list.extend(quote!(Some(<#ty as #wt::component::ComponentType>::ABI),)); + may_require_realloc.extend(quote!( + <#ty as #wt::component::ComponentType>::MAY_REQUIRE_REALLOC || + )); case_names_and_checks.extend( quote!((#name, Some(<#ty as #wt::component::ComponentType>::typecheck)),), @@ -1032,6 +1041,7 @@ impl Expander for ComponentTypeExpander { const ABI: #internal::CanonicalAbiInfo = #internal::CanonicalAbiInfo::variant_static(&[#abi_list]); + const MAY_REQUIRE_REALLOC: bool = #may_require_realloc false; } unsafe impl #impl_generics #internal::ComponentVariant for #name #ty_generics #where_clause { @@ -1093,6 +1103,7 @@ impl Expander for ComponentTypeExpander { const ABI: #internal::CanonicalAbiInfo = #internal::CanonicalAbiInfo::enum_(#cases_len); + const MAY_REQUIRE_REALLOC: bool = false; } unsafe impl #internal::ComponentVariant for #name { diff --git a/crates/wasmtime/src/runtime/component/func/typed.rs b/crates/wasmtime/src/runtime/component/func/typed.rs index 26502343504e..c986ca815ce6 100644 --- a/crates/wasmtime/src/runtime/component/func/typed.rs +++ b/crates/wasmtime/src/runtime/component/func/typed.rs @@ -959,6 +959,7 @@ macro_rules! forward_type_impls { type Lower = <$b as ComponentType>::Lower; const ABI: CanonicalAbiInfo = <$b as ComponentType>::ABI; + const MAY_REQUIRE_REALLOC: bool = <$b as ComponentType>::MAY_REQUIRE_REALLOC; #[inline] fn typecheck(ty: &InterfaceType, types: &InstanceType<'_>) -> Result<()> { @@ -1193,6 +1194,7 @@ macro_rules! floats { type Lower = ValRaw; const ABI: CanonicalAbiInfo = CanonicalAbiInfo::$abi; + const MAY_REQUIRE_REALLOC: bool = false; fn typecheck(ty: &InterfaceType, _types: &InstanceType<'_>) -> Result<()> { match ty { @@ -1310,6 +1312,7 @@ unsafe impl ComponentType for bool { type Lower = ValRaw; const ABI: CanonicalAbiInfo = CanonicalAbiInfo::SCALAR1; + const MAY_REQUIRE_REALLOC: bool = false; fn typecheck(ty: &InterfaceType, _types: &InstanceType<'_>) -> Result<()> { match ty { @@ -1376,6 +1379,7 @@ unsafe impl ComponentType for char { type Lower = ValRaw; const ABI: CanonicalAbiInfo = CanonicalAbiInfo::SCALAR4; + const MAY_REQUIRE_REALLOC: bool = false; fn typecheck(ty: &InterfaceType, _types: &InstanceType<'_>) -> Result<()> { match ty { @@ -2534,6 +2538,7 @@ where type Lower = TupleLower<::Lower, T::Lower>; const ABI: CanonicalAbiInfo = CanonicalAbiInfo::variant_static(&[None, Some(T::ABI)]); + const MAY_REQUIRE_REALLOC: bool = T::MAY_REQUIRE_REALLOC; fn typecheck(ty: &InterfaceType, types: &InstanceType<'_>) -> Result<()> { match ty { @@ -2675,6 +2680,7 @@ where type Lower = ResultLower; const ABI: CanonicalAbiInfo = CanonicalAbiInfo::variant_static(&[Some(T::ABI), Some(E::ABI)]); + const MAY_REQUIRE_REALLOC: bool = T::MAY_REQUIRE_REALLOC || E::MAY_REQUIRE_REALLOC; fn typecheck(ty: &InterfaceType, types: &InstanceType<'_>) -> Result<()> { match ty { @@ -3032,6 +3038,7 @@ macro_rules! impl_component_ty_for_tuples { const ABI: CanonicalAbiInfo = CanonicalAbiInfo::record_static(&[ $($t::ABI),* ]); + const MAY_REQUIRE_REALLOC: bool = false $(|| $t::MAY_REQUIRE_REALLOC)*; const IS_RUST_UNIT_TYPE: bool = { let mut _is_unit = true; diff --git a/crates/wasmtime/src/runtime/component/resources/any.rs b/crates/wasmtime/src/runtime/component/resources/any.rs index 4d5d7c800590..17c933f134d1 100644 --- a/crates/wasmtime/src/runtime/component/resources/any.rs +++ b/crates/wasmtime/src/runtime/component/resources/any.rs @@ -272,6 +272,7 @@ impl ResourceAny { unsafe impl ComponentType for ResourceAny { const ABI: CanonicalAbiInfo = CanonicalAbiInfo::SCALAR4; + const MAY_REQUIRE_REALLOC: bool = false; type Lower = ::Lower; diff --git a/crates/wasmtime/src/runtime/component/resources/host.rs b/crates/wasmtime/src/runtime/component/resources/host.rs index ed0d067b17b8..e1d363c696b4 100644 --- a/crates/wasmtime/src/runtime/component/resources/host.rs +++ b/crates/wasmtime/src/runtime/component/resources/host.rs @@ -312,6 +312,7 @@ where D: PartialEq + Send + Sync + Copy + 'static, { const ABI: CanonicalAbiInfo = CanonicalAbiInfo::SCALAR4; + const MAY_REQUIRE_REALLOC: bool = false; type Lower = ::Lower; diff --git a/crates/wasmtime/src/runtime/component/resources/host_dynamic.rs b/crates/wasmtime/src/runtime/component/resources/host_dynamic.rs index c3491b3ba2ae..72b9d4c69ea8 100644 --- a/crates/wasmtime/src/runtime/component/resources/host_dynamic.rs +++ b/crates/wasmtime/src/runtime/component/resources/host_dynamic.rs @@ -144,6 +144,7 @@ impl ResourceDynamic { } unsafe impl ComponentType for ResourceDynamic { + const MAY_REQUIRE_REALLOC: bool = false; const ABI: CanonicalAbiInfo = HostResource::::ABI; type Lower = crate::ValRaw; diff --git a/crates/wasmtime/src/runtime/component/resources/host_static.rs b/crates/wasmtime/src/runtime/component/resources/host_static.rs index 2d45813c0f6e..a85cfefa0ff7 100644 --- a/crates/wasmtime/src/runtime/component/resources/host_static.rs +++ b/crates/wasmtime/src/runtime/component/resources/host_static.rs @@ -217,6 +217,7 @@ where unsafe impl ComponentType for Resource { const ABI: CanonicalAbiInfo = HostResource::, ()>::ABI; + const MAY_REQUIRE_REALLOC: bool = false; type Lower = crate::ValRaw; fn typecheck(ty: &InterfaceType, types: &InstanceType<'_>) -> Result<()> {