diff --git a/crates/cranelift/src/func_environ.rs b/crates/cranelift/src/func_environ.rs index ee0b15b76493..b6565bdef447 100644 --- a/crates/cranelift/src/func_environ.rs +++ b/crates/cranelift/src/func_environ.rs @@ -299,7 +299,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> { /// reference count. /// /// The new reference count is returned. - fn mutate_extenref_ref_count( + fn mutate_externref_ref_count( &mut self, builder: &mut FunctionBuilder, externref: ir::Value, @@ -1036,7 +1036,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m // * store the reference into the bump table at `*next`, // * and finally increment the `next` bump finger. builder.switch_to_block(no_gc_block); - self.mutate_extenref_ref_count(builder, elem, 1); + self.mutate_externref_ref_count(builder, elem, 1); builder.ins().store(ir::MemFlags::trusted(), elem, next, 0); let new_next = builder @@ -1159,7 +1159,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m .brnz(value_is_null, check_current_elem_block, &[]); builder.ins().jump(inc_ref_count_block, &[]); builder.switch_to_block(inc_ref_count_block); - self.mutate_extenref_ref_count(builder, value, 1); + self.mutate_externref_ref_count(builder, value, 1); builder.ins().jump(check_current_elem_block, &[]); // Grab the current element from the table, and store the new @@ -1193,7 +1193,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m builder.ins().jump(continue_block, &[]); builder.switch_to_block(dec_ref_count_block); - let prev_ref_count = self.mutate_extenref_ref_count(builder, current_elem, -1); + let prev_ref_count = self.mutate_externref_ref_count(builder, current_elem, -1); let one = builder.ins().iconst(pointer_type, 1); builder .ins() diff --git a/crates/environ/src/vmoffsets.rs b/crates/environ/src/vmoffsets.rs index eca046a31582..d30f6b924481 100644 --- a/crates/environ/src/vmoffsets.rs +++ b/crates/environ/src/vmoffsets.rs @@ -7,6 +7,7 @@ // interrupts: *const VMInterrupts, // externref_activations_table: *mut VMExternRefActivationsTable, // store: *mut dyn Store, +// builtins: *mut VMBuiltinFunctionsArray, // signature_ids: *const VMSharedSignatureIndex, // imported_functions: [VMFunctionImport; module.num_imported_functions], // imported_tables: [VMTableImport; module.num_imported_tables], @@ -16,7 +17,6 @@ // memories: [VMMemoryDefinition; module.num_defined_memories], // globals: [VMGlobalDefinition; module.num_defined_globals], // anyfuncs: [VMCallerCheckedAnyfunc; module.num_imported_functions + module.num_defined_functions], -// builtins: *mut VMBuiltinFunctionsArray, // } use crate::{ @@ -74,6 +74,7 @@ pub struct VMOffsets
{ epoch_ptr: u32, externref_activations_table: u32, store: u32, + builtin_functions: u32, signature_ids: u32, imported_functions: u32, imported_tables: u32, @@ -83,7 +84,6 @@ pub struct VMOffsets
{
defined_memories: u32,
defined_globals: u32,
defined_anyfuncs: u32,
- builtin_functions: u32,
size: u32,
}
@@ -172,6 +172,7 @@ impl {
epoch_ptr: 0,
externref_activations_table: 0,
store: 0,
+ builtin_functions: 0,
signature_ids: 0,
imported_functions: 0,
imported_tables: 0,
@@ -181,103 +182,67 @@ impl {
defined_memories: 0,
defined_globals: 0,
defined_anyfuncs: 0,
- builtin_functions: 0,
size: 0,
};
- ret.interrupts = 0;
- ret.epoch_ptr = ret
- .interrupts
- .checked_add(u32::from(ret.ptr.size()))
- .unwrap();
- ret.externref_activations_table = ret
- .epoch_ptr
- .checked_add(u32::from(ret.ptr.size()))
- .unwrap();
- ret.store = ret
- .externref_activations_table
- .checked_add(u32::from(ret.ptr.size()))
- .unwrap();
- ret.signature_ids = ret
- .store
- .checked_add(u32::from(ret.ptr.size() * 2))
- .unwrap();
- ret.imported_functions = ret
- .signature_ids
- .checked_add(u32::from(ret.ptr.size()))
- .unwrap();
- ret.imported_tables = ret
- .imported_functions
- .checked_add(
- ret.num_imported_functions
- .checked_mul(u32::from(ret.size_of_vmfunction_import()))
- .unwrap(),
- )
- .unwrap();
- ret.imported_memories = ret
- .imported_tables
- .checked_add(
- ret.num_imported_tables
- .checked_mul(u32::from(ret.size_of_vmtable_import()))
- .unwrap(),
- )
- .unwrap();
- ret.imported_globals = ret
- .imported_memories
- .checked_add(
- ret.num_imported_memories
- .checked_mul(u32::from(ret.size_of_vmmemory_import()))
- .unwrap(),
- )
- .unwrap();
- ret.defined_tables = ret
- .imported_globals
- .checked_add(
- ret.num_imported_globals
- .checked_mul(u32::from(ret.size_of_vmglobal_import()))
- .unwrap(),
- )
- .unwrap();
- ret.defined_memories = ret
- .defined_tables
- .checked_add(
- ret.num_defined_tables
- .checked_mul(u32::from(ret.size_of_vmtable_definition()))
- .unwrap(),
- )
- .unwrap();
- ret.defined_globals = align(
- ret.defined_memories
- .checked_add(
- ret.num_defined_memories
- .checked_mul(u32::from(ret.size_of_vmmemory_definition()))
- .unwrap(),
- )
- .unwrap(),
- 16,
- );
- ret.defined_anyfuncs = ret
- .defined_globals
- .checked_add(
- ret.num_defined_globals
- .checked_mul(u32::from(ret.size_of_vmglobal_definition()))
- .unwrap(),
- )
- .unwrap();
- ret.builtin_functions = ret
- .defined_anyfuncs
- .checked_add(
- ret.num_imported_functions
- .checked_add(ret.num_defined_functions)
- .unwrap()
- .checked_mul(u32::from(ret.size_of_vmcaller_checked_anyfunc()))
- .unwrap(),
- )
- .unwrap();
- ret.size = ret
- .builtin_functions
- .checked_add(u32::from(ret.pointer_size()))
- .unwrap();
+ // Convenience functions for checked addition and multiplication.
+ // As side effect this reduces binary size by using only a single
+ // `#[track_caller]` location for each function instead of one for
+ // each individual invocation.
+ #[inline]
+ fn cadd(count: u32, size: u32) -> u32 {
+ count.checked_add(size).unwrap()
+ }
+
+ #[inline]
+ fn cmul(count: u32, size: u8) -> u32 {
+ count.checked_mul(u32::from(size)).unwrap()
+ }
+
+ let mut next_field_offset = 0;
+
+ macro_rules! fields {
+ (size($field:ident) = $size:expr, $($rest:tt)*) => {
+ ret.$field = next_field_offset;
+ next_field_offset = cadd(next_field_offset, u32::from($size));
+ fields!($($rest)*);
+ };
+ (align($align:literal), $($rest:tt)*) => {
+ next_field_offset = align(next_field_offset, $align);
+ fields!($($rest)*);
+ };
+ () => {};
+ }
+
+ fields! {
+ size(interrupts) = ret.ptr.size(),
+ size(epoch_ptr) = ret.ptr.size(),
+ size(externref_activations_table) = ret.ptr.size(),
+ size(store) = ret.ptr.size() * 2,
+ size(builtin_functions) = ret.pointer_size(),
+ size(signature_ids) = ret.ptr.size(),
+ size(imported_functions)
+ = cmul(ret.num_imported_functions, ret.size_of_vmfunction_import()),
+ size(imported_tables)
+ = cmul(ret.num_imported_tables, ret.size_of_vmtable_import()),
+ size(imported_memories)
+ = cmul(ret.num_imported_memories, ret.size_of_vmmemory_import()),
+ size(imported_globals)
+ = cmul(ret.num_imported_globals, ret.size_of_vmglobal_import()),
+ size(defined_tables)
+ = cmul(ret.num_defined_tables, ret.size_of_vmtable_definition()),
+ size(defined_memories)
+ = cmul(ret.num_defined_memories, ret.size_of_vmmemory_definition()),
+ align(16),
+ size(defined_globals)
+ = cmul(ret.num_defined_globals, ret.size_of_vmglobal_definition()),
+ size(defined_anyfuncs) = cmul(
+ cadd(ret.num_imported_functions, ret.num_defined_functions),
+ ret.size_of_vmcaller_checked_anyfunc(),
+ ),
+ }
+
+ ret.size = next_field_offset;
return ret;
}