Optimize some functions in the wiggle crate (#5566)
* wiggle: Inline some trivial functions This commit marks a number of functions in wiggle as `#[inline]` as they're otherwise trivial, mostly returning constants. This comes out of some work I looked at recently with Andrew where some of these functions showed up in profiles when they shouldn't. * wiggle: Optimize the `GuestMemory` for shared memory This commit implements a minor optimization to the `GuestMemory` implementation for Wasmtime to skip most methods if a shared memory is in play. Shared memories never get borrowed and this can be used to internally skip some borrow-checker methods. * wiggle: Optimize `GuestPtr::to_vec` This commit replaces the safe implementation of `GuestPtr::to_vec` with an unsafe implementation. The purpose of this is to speed up the function when used with shared memory which otherwise performs a bunch of atomic reads for types like `u8` which does validation-per-element and isn't vectorizable. On a benchmark I was helping Andrew with this sped up the host code enough to the point that guest code dwarfed the execution time. * Fix build
This commit is contained in:
@@ -42,6 +42,7 @@ pub(super) fn define_flags(
|
||||
|
||||
impl TryFrom<#repr> for #ident {
|
||||
type Error = wiggle::GuestError;
|
||||
#[inline]
|
||||
fn try_from(value: #repr) -> Result<Self, wiggle::GuestError> {
|
||||
if #repr::from(!#ident::all()) & value != 0 {
|
||||
Err(wiggle::GuestError::InvalidFlagValue(stringify!(#ident)))
|
||||
@@ -53,22 +54,26 @@ pub(super) fn define_flags(
|
||||
|
||||
impl TryFrom<#abi_repr> for #ident {
|
||||
type Error = wiggle::GuestError;
|
||||
#[inline]
|
||||
fn try_from(value: #abi_repr) -> Result<Self, wiggle::GuestError> {
|
||||
#ident::try_from(#repr::try_from(value)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<#ident> for #repr {
|
||||
#[inline]
|
||||
fn from(e: #ident) -> #repr {
|
||||
e.bits
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> wiggle::GuestType<'a> for #ident {
|
||||
#[inline]
|
||||
fn guest_size() -> u32 {
|
||||
#repr::guest_size()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn guest_align() -> usize {
|
||||
#repr::guest_align()
|
||||
}
|
||||
|
||||
@@ -14,29 +14,34 @@ pub(super) fn define_handle(name: &witx::Id, h: &witx::HandleDatatype) -> TokenS
|
||||
pub struct #ident(u32);
|
||||
|
||||
impl #ident {
|
||||
#[inline]
|
||||
pub unsafe fn inner(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<#ident> for u32 {
|
||||
#[inline]
|
||||
fn from(e: #ident) -> u32 {
|
||||
e.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<#ident> for i32 {
|
||||
#[inline]
|
||||
fn from(e: #ident) -> i32 {
|
||||
e.0 as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for #ident {
|
||||
#[inline]
|
||||
fn from(e: u32) -> #ident {
|
||||
#ident(e)
|
||||
}
|
||||
}
|
||||
impl From<i32> for #ident {
|
||||
#[inline]
|
||||
fn from(e: i32) -> #ident {
|
||||
#ident(e as u32)
|
||||
}
|
||||
@@ -49,18 +54,22 @@ pub(super) fn define_handle(name: &witx::Id, h: &witx::HandleDatatype) -> TokenS
|
||||
}
|
||||
|
||||
impl<'a> wiggle::GuestType<'a> for #ident {
|
||||
#[inline]
|
||||
fn guest_size() -> u32 {
|
||||
#size
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn guest_align() -> usize {
|
||||
#align
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read(location: &wiggle::GuestPtr<'a, #ident>) -> Result<#ident, wiggle::GuestError> {
|
||||
Ok(#ident(u32::read(&location.cast())?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write(location: &wiggle::GuestPtr<'_, Self>, val: Self) -> Result<(), wiggle::GuestError> {
|
||||
u32::write(&location.cast(), val.0)
|
||||
}
|
||||
|
||||
@@ -87,10 +87,12 @@ pub(super) fn define_struct(name: &witx::Id, s: &witx::RecordDatatype) -> TokenS
|
||||
}
|
||||
|
||||
impl<'a> wiggle::GuestType<'a> for #ident #struct_lifetime {
|
||||
#[inline]
|
||||
fn guest_size() -> u32 {
|
||||
#size
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn guest_align() -> usize {
|
||||
#align
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ pub(super) fn define_variant(
|
||||
quote! {
|
||||
impl TryFrom<#tag_ty> for #ident {
|
||||
type Error = wiggle::GuestError;
|
||||
#[inline]
|
||||
fn try_from(value: #tag_ty) -> Result<#ident, wiggle::GuestError> {
|
||||
match value {
|
||||
#(#tryfrom_repr_cases),*,
|
||||
@@ -90,6 +91,7 @@ pub(super) fn define_variant(
|
||||
|
||||
impl TryFrom<#abi_ty> for #ident {
|
||||
type Error = wiggle::GuestError;
|
||||
#[inline]
|
||||
fn try_from(value: #abi_ty) -> Result<#ident, wiggle::GuestError> {
|
||||
#ident::try_from(#tag_ty::try_from(value)?)
|
||||
}
|
||||
@@ -107,6 +109,7 @@ pub(super) fn define_variant(
|
||||
});
|
||||
quote! {
|
||||
impl From<#ident> for #tag_ty {
|
||||
#[inline]
|
||||
fn from(v: #ident) -> #tag_ty {
|
||||
match v {
|
||||
#(#from_repr_cases),*,
|
||||
@@ -148,10 +151,12 @@ pub(super) fn define_variant(
|
||||
#enum_from
|
||||
|
||||
impl<'a> wiggle::GuestType<'a> for #ident #enum_lifetime {
|
||||
#[inline]
|
||||
fn guest_size() -> u32 {
|
||||
#size
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn guest_align() -> usize {
|
||||
#align
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user