From 2e8ed8838baa5f94983766ba26c67c390514d4f3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 1 Nov 2024 23:15:32 -0500 Subject: [PATCH] Deduplicate some code related to `Tunables` (#9540) Generate the `Option`-field struct based on the definition of `Tunables` itself instead of duplicating the listed fields in `config.rs`. Additionally auto-generate methods to debug-format and configure `Tunables` instead of requiring more duplicated macros as well. --- crates/environ/src/tunables.rs | 160 ++++++++++++++++++++++----------- crates/wasmtime/src/config.rs | 65 +------------- 2 files changed, 111 insertions(+), 114 deletions(-) diff --git a/crates/environ/src/tunables.rs b/crates/environ/src/tunables.rs index 142b9c172ea..ca46268c3fb 100644 --- a/crates/environ/src/tunables.rs +++ b/crates/environ/src/tunables.rs @@ -1,74 +1,130 @@ -use core::fmt; - use anyhow::{anyhow, bail, Result}; +use core::fmt; use serde_derive::{Deserialize, Serialize}; use target_lexicon::{PointerWidth, Triple}; -/// Tunable parameters for WebAssembly compilation. -#[derive(Clone, Hash, Serialize, Deserialize, Debug)] -pub struct Tunables { - /// The garbage collector implementation to use, which implies the layout of - /// GC objects and barriers that must be emitted in Wasm code. - pub collector: Option, +macro_rules! define_tunables { + ( + $(#[$outer_attr:meta])* + pub struct $tunables:ident { + $( + $(#[$field_attr:meta])* + pub $field:ident : $field_ty:ty, + )* + } + + pub struct $config_tunables:ident { + ... + } + ) => { + $(#[$outer_attr])* + pub struct $tunables { + $( + $(#[$field_attr])* + pub $field: $field_ty, + )* + } + + /// Optional tunable configuration options used in `wasmtime::Config` + #[derive(Default, Clone)] + #[allow(missing_docs)] + pub struct $config_tunables { + $(pub $field: Option<$field_ty>,)* + } + + impl $config_tunables { + /// Formats configured fields into `f`. + pub fn format(&self, f: &mut fmt::DebugStruct<'_,'_>) { + $( + if let Some(val) = &self.$field { + f.field(stringify!($field), val); + } + )* + } + + /// Configure the `Tunables` provided. + pub fn configure(&self, tunables: &mut Tunables) { + $( + if let Some(val) = self.$field { + tunables.$field = val; + } + )* + } + } + }; +} - /// For static heaps, the size in bytes of virtual memory reservation for - /// the heap. - pub static_memory_reservation: u64, +define_tunables! { + /// Tunable parameters for WebAssembly compilation. + #[derive(Clone, Hash, Serialize, Deserialize, Debug)] + pub struct Tunables { + /// The garbage collector implementation to use, which implies the layout of + /// GC objects and barriers that must be emitted in Wasm code. + pub collector: Option, - /// The size, in bytes, of the guard page region for linear memories. - pub memory_guard_size: u64, + /// For static heaps, the size in bytes of virtual memory reservation for + /// the heap. + pub static_memory_reservation: u64, - /// The size, in bytes, of reserved memory at the end of a "dynamic" memory, - /// before the guard page, that memory can grow into. This is intended to - /// amortize the cost of `memory.grow` in the same manner that `Vec` has - /// space not in use to grow into. - pub dynamic_memory_growth_reserve: u64, + /// The size, in bytes, of the guard page region for linear memories. + pub memory_guard_size: u64, - /// Whether or not to generate native DWARF debug information. - pub generate_native_debuginfo: bool, + /// The size, in bytes, of reserved memory at the end of a "dynamic" memory, + /// before the guard page, that memory can grow into. This is intended to + /// amortize the cost of `memory.grow` in the same manner that `Vec` has + /// space not in use to grow into. + pub dynamic_memory_growth_reserve: u64, - /// Whether or not to retain DWARF sections in compiled modules. - pub parse_wasm_debuginfo: bool, + /// Whether or not to generate native DWARF debug information. + pub generate_native_debuginfo: bool, - /// Whether or not fuel is enabled for generated code, meaning that fuel - /// will be consumed every time a wasm instruction is executed. - pub consume_fuel: bool, + /// Whether or not to retain DWARF sections in compiled modules. + pub parse_wasm_debuginfo: bool, - /// Whether or not we use epoch-based interruption. - pub epoch_interruption: bool, + /// Whether or not fuel is enabled for generated code, meaning that fuel + /// will be consumed every time a wasm instruction is executed. + pub consume_fuel: bool, - /// Whether or not to treat the static memory bound as the maximum for - /// unbounded heaps. - pub static_memory_bound_is_maximum: bool, + /// Whether or not we use epoch-based interruption. + pub epoch_interruption: bool, - /// Whether or not linear memory allocations will have a guard region at the - /// beginning of the allocation in addition to the end. - pub guard_before_linear_memory: bool, + /// Whether or not to treat the static memory bound as the maximum for + /// unbounded heaps. + pub static_memory_bound_is_maximum: bool, - /// Whether to initialize tables lazily, so that instantiation is fast but - /// indirect calls are a little slower. If false, tables are initialized - /// eagerly from any active element segments that apply to them during - /// instantiation. - pub table_lazy_init: bool, + /// Whether or not linear memory allocations will have a guard region at the + /// beginning of the allocation in addition to the end. + pub guard_before_linear_memory: bool, - /// Indicates whether an address map from compiled native code back to wasm - /// offsets in the original file is generated. - pub generate_address_map: bool, + /// Whether to initialize tables lazily, so that instantiation is fast but + /// indirect calls are a little slower. If false, tables are initialized + /// eagerly from any active element segments that apply to them during + /// instantiation. + pub table_lazy_init: bool, - /// Flag for the component module whether adapter modules have debug - /// assertions baked into them. - pub debug_adapter_modules: bool, + /// Indicates whether an address map from compiled native code back to wasm + /// offsets in the original file is generated. + pub generate_address_map: bool, - /// Whether or not lowerings for relaxed simd instructions are forced to - /// be deterministic. - pub relaxed_simd_deterministic: bool, + /// Flag for the component module whether adapter modules have debug + /// assertions baked into them. + pub debug_adapter_modules: bool, - /// Whether or not Wasm functions target the winch abi. - pub winch_callable: bool, + /// Whether or not lowerings for relaxed simd instructions are forced to + /// be deterministic. + pub relaxed_simd_deterministic: bool, - /// Whether or not the host will be using native signals (e.g. SIGILL, - /// SIGSEGV, etc) to implement traps. - pub signals_based_traps: bool, + /// Whether or not Wasm functions target the winch abi. + pub winch_callable: bool, + + /// Whether or not the host will be using native signals (e.g. SIGILL, + /// SIGSEGV, etc) to implement traps. + pub signals_based_traps: bool, + } + + pub struct ConfigTunables { + ... + } } impl Tunables { diff --git a/crates/wasmtime/src/config.rs b/crates/wasmtime/src/config.rs index 1d051415ede..22ad0a46a4d 100644 --- a/crates/wasmtime/src/config.rs +++ b/crates/wasmtime/src/config.rs @@ -11,7 +11,7 @@ use std::path::Path; use wasmparser::WasmFeatures; #[cfg(feature = "cache")] use wasmtime_cache::CacheConfig; -use wasmtime_environ::Tunables; +use wasmtime_environ::{ConfigTunables, Tunables}; #[cfg(feature = "runtime")] use crate::memory::MemoryCreator; @@ -145,24 +145,6 @@ pub struct Config { pub(crate) detect_host_feature: Option Option>, } -#[derive(Default, Clone)] -struct ConfigTunables { - static_memory_reservation: Option, - memory_guard_size: Option, - dynamic_memory_growth_reserve: Option, - generate_native_debuginfo: Option, - parse_wasm_debuginfo: Option, - consume_fuel: Option, - epoch_interruption: Option, - static_memory_bound_is_maximum: Option, - guard_before_linear_memory: Option, - table_lazy_init: Option, - generate_address_map: Option, - debug_adapter_modules: Option, - relaxed_simd_deterministic: Option, - signals_based_traps: Option, -} - /// User-provided configuration for the compiler. #[cfg(any(feature = "cranelift", feature = "winch"))] #[derive(Debug, Clone)] @@ -1916,36 +1898,7 @@ impl Config { None => Tunables::default_host(), }; - macro_rules! set_fields { - ($($field:ident)*) => ( - let ConfigTunables { - $($field,)* - } = &self.tunables; - - $( - if let Some(e) = $field { - tunables.$field = *e; - } - )* - ) - } - - set_fields! { - static_memory_reservation - memory_guard_size - dynamic_memory_growth_reserve - generate_native_debuginfo - parse_wasm_debuginfo - consume_fuel - epoch_interruption - static_memory_bound_is_maximum - guard_before_linear_memory - table_lazy_init - generate_address_map - debug_adapter_modules - relaxed_simd_deterministic - signals_based_traps - } + self.tunables.configure(&mut tunables); // If we're going to compile with winch, we must use the winch calling convention. #[cfg(any(feature = "cranelift", feature = "winch"))] @@ -2318,7 +2271,6 @@ impl Default for Config { impl fmt::Debug for Config { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut f = f.debug_struct("Config"); - f.field("debug_info", &self.tunables.generate_native_debuginfo); // Not every flag in WasmFeatures can be enabled as part of creating // a Config. This impl gives a complete picture of all WasmFeatures @@ -2339,18 +2291,7 @@ impl fmt::Debug for Config { f.field("compiler_config", &self.compiler_config); } - if let Some(enable) = self.tunables.parse_wasm_debuginfo { - f.field("parse_wasm_debuginfo", &enable); - } - if let Some(size) = self.tunables.static_memory_reservation { - f.field("static_memory_maximum_reservation", &size); - } - if let Some(size) = self.tunables.memory_guard_size { - f.field("memory_guard_size", &size); - } - if let Some(enable) = self.tunables.guard_before_linear_memory { - f.field("guard_before_linear_memory", &enable); - } + self.tunables.format(&mut f); f.finish() } }