fix(wasmtime):Config methods should be idempotent (#4252)
This commit refactored `Config` to use a seperate `CompilerConfig` field instead of operating on `CompilerBuilder` directly to make all its methods idempotent. Fixes #4189
This commit is contained in:
11
RELEASES.md
11
RELEASES.md
@@ -8,6 +8,17 @@ Unreleased.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
* The `Config::strategy`, `Config::cranelift_flag_enable`, `Config::cranelift_flag_set`
|
||||||
|
and `Config::profiler` APIs now return `&mut Self` instead of `Result<&mut Self>`
|
||||||
|
since the validation is deferred until `Engine::new`.
|
||||||
|
[#4252](https://github.com/bytecodealliance/wasmtime/pull/4252)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* A refactor of `Config` was made to fix an issue that the order of calls to `Config`
|
||||||
|
matters now, which may lead to unexpected behavior.
|
||||||
|
[#4252](https://github.com/bytecodealliance/wasmtime/pull/4252)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
## 0.38.0
|
## 0.38.0
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ WASMTIME_CONFIG_PROP(void, wasm_memory64, bool)
|
|||||||
* If the compilation strategy selected could not be enabled then an error is
|
* If the compilation strategy selected could not be enabled then an error is
|
||||||
* returned.
|
* returned.
|
||||||
*/
|
*/
|
||||||
WASMTIME_CONFIG_PROP(wasmtime_error_t*, strategy, wasmtime_strategy_t)
|
WASMTIME_CONFIG_PROP(void, strategy, wasmtime_strategy_t)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Configures whether Cranelift's debug verifier is enabled.
|
* \brief Configures whether Cranelift's debug verifier is enabled.
|
||||||
@@ -238,7 +238,7 @@ WASMTIME_CONFIG_PROP(void, cranelift_opt_level, wasmtime_opt_level_t)
|
|||||||
*
|
*
|
||||||
* This setting in #WASMTIME_PROFILING_STRATEGY_NONE by default.
|
* This setting in #WASMTIME_PROFILING_STRATEGY_NONE by default.
|
||||||
*/
|
*/
|
||||||
WASMTIME_CONFIG_PROP(wasmtime_error_t*, profiler, wasmtime_profiling_strategy_t)
|
WASMTIME_CONFIG_PROP(void, profiler, wasmtime_profiling_strategy_t)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Configures the maximum size for memory to be considered "static"
|
* \brief Configures the maximum size for memory to be considered "static"
|
||||||
|
|||||||
@@ -103,13 +103,12 @@ pub extern "C" fn wasmtime_config_wasm_memory64_set(c: &mut wasm_config_t, enabl
|
|||||||
pub extern "C" fn wasmtime_config_strategy_set(
|
pub extern "C" fn wasmtime_config_strategy_set(
|
||||||
c: &mut wasm_config_t,
|
c: &mut wasm_config_t,
|
||||||
strategy: wasmtime_strategy_t,
|
strategy: wasmtime_strategy_t,
|
||||||
) -> Option<Box<wasmtime_error_t>> {
|
) {
|
||||||
use wasmtime_strategy_t::*;
|
use wasmtime_strategy_t::*;
|
||||||
let result = c.config.strategy(match strategy {
|
c.config.strategy(match strategy {
|
||||||
WASMTIME_STRATEGY_AUTO => Strategy::Auto,
|
WASMTIME_STRATEGY_AUTO => Strategy::Auto,
|
||||||
WASMTIME_STRATEGY_CRANELIFT => Strategy::Cranelift,
|
WASMTIME_STRATEGY_CRANELIFT => Strategy::Cranelift,
|
||||||
});
|
});
|
||||||
handle_result(result, |_cfg| {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -145,13 +144,12 @@ pub extern "C" fn wasmtime_config_cranelift_opt_level_set(
|
|||||||
pub extern "C" fn wasmtime_config_profiler_set(
|
pub extern "C" fn wasmtime_config_profiler_set(
|
||||||
c: &mut wasm_config_t,
|
c: &mut wasm_config_t,
|
||||||
strategy: wasmtime_profiling_strategy_t,
|
strategy: wasmtime_profiling_strategy_t,
|
||||||
) -> Option<Box<wasmtime_error_t>> {
|
) {
|
||||||
use wasmtime_profiling_strategy_t::*;
|
use wasmtime_profiling_strategy_t::*;
|
||||||
let result = c.config.profiler(match strategy {
|
c.config.profiler(match strategy {
|
||||||
WASMTIME_PROFILING_STRATEGY_NONE => ProfilingStrategy::None,
|
WASMTIME_PROFILING_STRATEGY_NONE => ProfilingStrategy::None,
|
||||||
WASMTIME_PROFILING_STRATEGY_JITDUMP => ProfilingStrategy::JitDump,
|
WASMTIME_PROFILING_STRATEGY_JITDUMP => ProfilingStrategy::JitDump,
|
||||||
});
|
});
|
||||||
handle_result(result, |_cfg| {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -260,20 +260,20 @@ impl CommonOptions {
|
|||||||
.cranelift_debug_verifier(self.enable_cranelift_debug_verifier)
|
.cranelift_debug_verifier(self.enable_cranelift_debug_verifier)
|
||||||
.debug_info(self.debug_info)
|
.debug_info(self.debug_info)
|
||||||
.cranelift_opt_level(self.opt_level())
|
.cranelift_opt_level(self.opt_level())
|
||||||
.profiler(pick_profiling_strategy(self.jitdump, self.vtune)?)?
|
.profiler(pick_profiling_strategy(self.jitdump, self.vtune)?)
|
||||||
.cranelift_nan_canonicalization(self.enable_cranelift_nan_canonicalization);
|
.cranelift_nan_canonicalization(self.enable_cranelift_nan_canonicalization);
|
||||||
|
|
||||||
self.enable_wasm_features(&mut config);
|
self.enable_wasm_features(&mut config);
|
||||||
|
|
||||||
for name in &self.cranelift_enable {
|
for name in &self.cranelift_enable {
|
||||||
unsafe {
|
unsafe {
|
||||||
config.cranelift_flag_enable(name)?;
|
config.cranelift_flag_enable(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name, value) in &self.cranelift_set {
|
for (name, value) in &self.cranelift_set {
|
||||||
unsafe {
|
unsafe {
|
||||||
config.cranelift_flag_set(name, value)?;
|
config.cranelift_flag_set(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use cranelift_codegen::settings::{self, Configurable, SetError};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use wasmtime_environ::{CompilerBuilder, Setting, SettingKind};
|
use wasmtime_environ::{CompilerBuilder, Setting, SettingKind};
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Builder {
|
struct Builder {
|
||||||
flags: settings::Builder,
|
flags: settings::Builder,
|
||||||
isa_flags: isa::Builder,
|
isa_flags: isa::Builder,
|
||||||
@@ -55,10 +54,6 @@ impl CompilerBuilder for Builder {
|
|||||||
self.isa_flags.triple()
|
self.isa_flags.triple()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone(&self) -> Box<dyn CompilerBuilder> {
|
|
||||||
Box::new(Clone::clone(self))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn target(&mut self, target: target_lexicon::Triple) -> Result<()> {
|
fn target(&mut self, target: target_lexicon::Triple) -> Result<()> {
|
||||||
self.isa_flags = isa::lookup(target)?;
|
self.isa_flags = isa::lookup(target)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ pub enum CompileError {
|
|||||||
/// This is used in Wasmtime to separate compiler implementations, currently
|
/// This is used in Wasmtime to separate compiler implementations, currently
|
||||||
/// mostly used to separate Cranelift from Wasmtime itself.
|
/// mostly used to separate Cranelift from Wasmtime itself.
|
||||||
pub trait CompilerBuilder: Send + Sync + fmt::Debug {
|
pub trait CompilerBuilder: Send + Sync + fmt::Debug {
|
||||||
/// Like the `Clone` trait, but for the boxed trait object.
|
|
||||||
fn clone(&self) -> Box<dyn CompilerBuilder>;
|
|
||||||
|
|
||||||
/// Sets the target of compilation to the target specified.
|
/// Sets the target of compilation to the target specified.
|
||||||
fn target(&mut self, target: target_lexicon::Triple) -> Result<()>;
|
fn target(&mut self, target: target_lexicon::Triple) -> Result<()>;
|
||||||
|
|
||||||
|
|||||||
@@ -421,8 +421,7 @@ impl Config {
|
|||||||
|
|
||||||
if self.wasmtime.force_jump_veneers {
|
if self.wasmtime.force_jump_veneers {
|
||||||
unsafe {
|
unsafe {
|
||||||
cfg.cranelift_flag_set("wasmtime_linkopt_force_jump_veneer", "true")
|
cfg.cranelift_flag_set("wasmtime_linkopt_force_jump_veneer", "true");
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,8 +430,7 @@ impl Config {
|
|||||||
cfg.cranelift_flag_set(
|
cfg.cranelift_flag_set(
|
||||||
"wasmtime_linkopt_padding_between_functions",
|
"wasmtime_linkopt_padding_between_functions",
|
||||||
&pad.to_string(),
|
&pad.to_string(),
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,7 +656,7 @@ impl CodegenSettings {
|
|||||||
config.target(target).unwrap();
|
config.target(target).unwrap();
|
||||||
for (key, value) in flags {
|
for (key, value) in flags {
|
||||||
unsafe {
|
unsafe {
|
||||||
config.cranelift_flag_set(key, value).unwrap();
|
config.cranelift_flag_set(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,18 @@ use crate::memory::MemoryCreator;
|
|||||||
use crate::trampoline::MemoryCreatorProxy;
|
use crate::trampoline::MemoryCreatorProxy;
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cmp;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
#[cfg(feature = "cache")]
|
#[cfg(feature = "cache")]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::{
|
||||||
|
cmp,
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
};
|
||||||
use wasmparser::WasmFeatures;
|
use wasmparser::WasmFeatures;
|
||||||
#[cfg(feature = "cache")]
|
#[cfg(feature = "cache")]
|
||||||
use wasmtime_cache::CacheConfig;
|
use wasmtime_cache::CacheConfig;
|
||||||
use wasmtime_environ::{CompilerBuilder, Tunables};
|
use wasmtime_environ::Tunables;
|
||||||
use wasmtime_jit::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
|
use wasmtime_jit::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
|
||||||
use wasmtime_runtime::{InstanceAllocator, OnDemandInstanceAllocator, RuntimeMemoryCreator};
|
use wasmtime_runtime::{InstanceAllocator, OnDemandInstanceAllocator, RuntimeMemoryCreator};
|
||||||
|
|
||||||
@@ -79,14 +82,18 @@ impl Default for ModuleVersionStrategy {
|
|||||||
/// and customize its behavior.
|
/// and customize its behavior.
|
||||||
///
|
///
|
||||||
/// This structure exposed a builder-like interface and is primarily consumed by
|
/// This structure exposed a builder-like interface and is primarily consumed by
|
||||||
/// [`Engine::new()`](crate::Engine::new)
|
/// [`Engine::new()`](crate::Engine::new).
|
||||||
|
///
|
||||||
|
/// The validation of `Config` is deferred until the engine is being built, thus
|
||||||
|
/// a problematic config may cause `Engine::new` to fail.
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
pub(crate) compiler: Box<dyn CompilerBuilder>,
|
compiler_config: CompilerConfig,
|
||||||
pub(crate) tunables: Tunables,
|
pub(crate) tunables: Tunables,
|
||||||
#[cfg(feature = "cache")]
|
#[cfg(feature = "cache")]
|
||||||
pub(crate) cache_config: CacheConfig,
|
pub(crate) cache_config: CacheConfig,
|
||||||
pub(crate) profiler: Arc<dyn ProfilingAgent>,
|
pub(crate) profiling_strategy: ProfilingStrategy,
|
||||||
pub(crate) mem_creator: Option<Arc<dyn RuntimeMemoryCreator>>,
|
pub(crate) mem_creator: Option<Arc<dyn RuntimeMemoryCreator>>,
|
||||||
pub(crate) allocation_strategy: InstanceAllocationStrategy,
|
pub(crate) allocation_strategy: InstanceAllocationStrategy,
|
||||||
pub(crate) max_wasm_stack: usize,
|
pub(crate) max_wasm_stack: usize,
|
||||||
@@ -103,6 +110,54 @@ pub struct Config {
|
|||||||
pub(crate) force_memory_init_memfd: bool,
|
pub(crate) force_memory_init_memfd: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// User-provided configuration for the compiler.
|
||||||
|
#[cfg(compiler)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct CompilerConfig {
|
||||||
|
strategy: Strategy,
|
||||||
|
target: Option<target_lexicon::Triple>,
|
||||||
|
settings: HashMap<String, String>,
|
||||||
|
flags: HashSet<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(compiler)]
|
||||||
|
impl CompilerConfig {
|
||||||
|
fn new(strategy: Strategy) -> Self {
|
||||||
|
Self {
|
||||||
|
strategy,
|
||||||
|
target: None,
|
||||||
|
settings: HashMap::new(),
|
||||||
|
flags: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensures that the key is not set or equals to the given value.
|
||||||
|
/// If the key is not set, it will be set to the given value.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// Returns true if successfully set or already had the given setting
|
||||||
|
/// value, or false if the setting was explicitly set to something
|
||||||
|
/// else previously.
|
||||||
|
fn ensure_setting_unset_or_given(&mut self, k: &str, v: &str) -> bool {
|
||||||
|
if let Some(value) = self.settings.get(k) {
|
||||||
|
if value != v {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.settings.insert(k.to_string(), v.to_string());
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(compiler)]
|
||||||
|
impl Default for CompilerConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(Strategy::Auto)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
/// Creates a new configuration object with the default configuration
|
/// Creates a new configuration object with the default configuration
|
||||||
/// specified.
|
/// specified.
|
||||||
@@ -110,10 +165,10 @@ impl Config {
|
|||||||
let mut ret = Self {
|
let mut ret = Self {
|
||||||
tunables: Tunables::default(),
|
tunables: Tunables::default(),
|
||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
compiler: compiler_builder(Strategy::Auto).unwrap(),
|
compiler_config: CompilerConfig::default(),
|
||||||
#[cfg(feature = "cache")]
|
#[cfg(feature = "cache")]
|
||||||
cache_config: CacheConfig::new_cache_disabled(),
|
cache_config: CacheConfig::new_cache_disabled(),
|
||||||
profiler: Arc::new(NullProfilerAgent),
|
profiling_strategy: ProfilingStrategy::None,
|
||||||
mem_creator: None,
|
mem_creator: None,
|
||||||
allocation_strategy: InstanceAllocationStrategy::OnDemand,
|
allocation_strategy: InstanceAllocationStrategy::OnDemand,
|
||||||
// 512k of stack -- note that this is chosen currently to not be too
|
// 512k of stack -- note that this is chosen currently to not be too
|
||||||
@@ -166,8 +221,8 @@ impl Config {
|
|||||||
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
||||||
pub fn target(&mut self, target: &str) -> Result<&mut Self> {
|
pub fn target(&mut self, target: &str) -> Result<&mut Self> {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
self.compiler
|
self.compiler_config.target =
|
||||||
.target(target_lexicon::Triple::from_str(target).map_err(|e| anyhow::anyhow!(e))?)?;
|
Some(target_lexicon::Triple::from_str(target).map_err(|e| anyhow::anyhow!(e))?);
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
@@ -290,20 +345,6 @@ impl Config {
|
|||||||
/// will always return `None`.
|
/// will always return `None`.
|
||||||
pub fn wasm_backtrace(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_backtrace(&mut self, enable: bool) -> &mut Self {
|
||||||
self.wasm_backtrace = enable;
|
self.wasm_backtrace = enable;
|
||||||
#[cfg(compiler)]
|
|
||||||
{
|
|
||||||
// unwind_info must be enabled when either backtraces or reference types are enabled:
|
|
||||||
self.compiler
|
|
||||||
.set(
|
|
||||||
"unwind_info",
|
|
||||||
if enable || self.features.reference_types {
|
|
||||||
"true"
|
|
||||||
} else {
|
|
||||||
"false"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,8 +548,8 @@ impl Config {
|
|||||||
/// be enabled through this method for appropriate wasm modules.
|
/// be enabled through this method for appropriate wasm modules.
|
||||||
///
|
///
|
||||||
/// This feature gates items such as shared memories and atomic
|
/// This feature gates items such as shared memories and atomic
|
||||||
/// instructions. Note that enabling the threads feature will
|
/// instructions. Note that the threads feature depends on the
|
||||||
/// also enable the bulk memory feature.
|
/// bulk memory feature, which is enabled by default.
|
||||||
///
|
///
|
||||||
/// This is `false` by default.
|
/// This is `false` by default.
|
||||||
///
|
///
|
||||||
@@ -517,13 +558,14 @@ impl Config {
|
|||||||
/// > expected. This should not be enabled in a production setting right
|
/// > expected. This should not be enabled in a production setting right
|
||||||
/// > now.
|
/// > now.
|
||||||
///
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// The validation of this feature are deferred until the engine is being built,
|
||||||
|
/// and thus may cause `Engine::new` fail if the `bulk_memory` feature is disabled.
|
||||||
|
///
|
||||||
/// [threads]: https://github.com/webassembly/threads
|
/// [threads]: https://github.com/webassembly/threads
|
||||||
pub fn wasm_threads(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_threads(&mut self, enable: bool) -> &mut Self {
|
||||||
self.features.threads = enable;
|
self.features.threads = enable;
|
||||||
// The threads proposal depends on the bulk memory proposal
|
|
||||||
if enable {
|
|
||||||
self.wasm_bulk_memory(true);
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,38 +575,18 @@ impl Config {
|
|||||||
/// This feature gates items such as the `externref` and `funcref` types as
|
/// This feature gates items such as the `externref` and `funcref` types as
|
||||||
/// well as allowing a module to define multiple tables.
|
/// well as allowing a module to define multiple tables.
|
||||||
///
|
///
|
||||||
/// Note that enabling the reference types feature will also enable the bulk
|
/// Note that the reference types proposal depends on the bulk memory proposal.
|
||||||
/// memory feature.
|
|
||||||
///
|
///
|
||||||
/// This feature is `true` by default.
|
/// This feature is `true` by default.
|
||||||
///
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// The validation of this feature are deferred until the engine is being built,
|
||||||
|
/// and thus may cause `Engine::new` fail if the `bulk_memory` feature is disabled.
|
||||||
|
///
|
||||||
/// [proposal]: https://github.com/webassembly/reference-types
|
/// [proposal]: https://github.com/webassembly/reference-types
|
||||||
pub fn wasm_reference_types(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_reference_types(&mut self, enable: bool) -> &mut Self {
|
||||||
self.features.reference_types = enable;
|
self.features.reference_types = enable;
|
||||||
|
|
||||||
#[cfg(compiler)]
|
|
||||||
{
|
|
||||||
self.compiler
|
|
||||||
.set("enable_safepoints", if enable { "true" } else { "false" })
|
|
||||||
.unwrap();
|
|
||||||
// unwind_info must be enabled when either backtraces or reference types are enabled:
|
|
||||||
self.compiler
|
|
||||||
.set(
|
|
||||||
"unwind_info",
|
|
||||||
if enable || self.wasm_backtrace {
|
|
||||||
"true"
|
|
||||||
} else {
|
|
||||||
"false"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The reference types proposal depends on the bulk memory proposal.
|
|
||||||
if enable {
|
|
||||||
self.wasm_bulk_memory(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,13 +608,6 @@ impl Config {
|
|||||||
/// [relaxed simd proposal]: https://github.com/WebAssembly/relaxed-simd
|
/// [relaxed simd proposal]: https://github.com/WebAssembly/relaxed-simd
|
||||||
pub fn wasm_simd(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_simd(&mut self, enable: bool) -> &mut Self {
|
||||||
self.features.simd = enable;
|
self.features.simd = enable;
|
||||||
#[cfg(compiler)]
|
|
||||||
{
|
|
||||||
let val = if enable { "true" } else { "false" };
|
|
||||||
self.compiler
|
|
||||||
.set("enable_simd", val)
|
|
||||||
.expect("should be valid flag");
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,6 +619,15 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// This is `true` by default.
|
/// This is `true` by default.
|
||||||
///
|
///
|
||||||
|
/// Feature `reference_types`, which is also `true` by default, requires
|
||||||
|
/// this feature to be enabled. Thus disabling this feature must also disable
|
||||||
|
/// `reference_types` as well using [`wasm_reference_types`](crate::Config::wasm_reference_types).
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Disabling this feature without disabling `reference_types` will cause
|
||||||
|
/// `Engine::new` to fail.
|
||||||
|
///
|
||||||
/// [proposal]: https://github.com/webassembly/bulk-memory-operations
|
/// [proposal]: https://github.com/webassembly/bulk-memory-operations
|
||||||
pub fn wasm_bulk_memory(&mut self, enable: bool) -> &mut Self {
|
pub fn wasm_bulk_memory(&mut self, enable: bool) -> &mut Self {
|
||||||
self.features.bulk_memory = enable;
|
self.features.bulk_memory = enable;
|
||||||
@@ -674,30 +698,30 @@ impl Config {
|
|||||||
/// and its documentation.
|
/// and its documentation.
|
||||||
///
|
///
|
||||||
/// The default value for this is `Strategy::Auto`.
|
/// The default value for this is `Strategy::Auto`.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Some compilation strategies require compile-time options of `wasmtime`
|
|
||||||
/// itself to be set, but if they're not set and the strategy is specified
|
|
||||||
/// here then an error will be returned.
|
|
||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
||||||
pub fn strategy(&mut self, strategy: Strategy) -> Result<&mut Self> {
|
pub fn strategy(&mut self, strategy: Strategy) -> &mut Self {
|
||||||
self.compiler = compiler_builder(strategy)?;
|
self.compiler_config.strategy = strategy;
|
||||||
Ok(self)
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a default profiler based on the profiling strategy chosen.
|
/// Creates a default profiler based on the profiling strategy chosen.
|
||||||
///
|
///
|
||||||
/// Profiler creation calls the type's default initializer where the purpose is
|
/// Profiler creation calls the type's default initializer where the purpose is
|
||||||
/// really just to put in place the type used for profiling.
|
/// really just to put in place the type used for profiling.
|
||||||
pub fn profiler(&mut self, profile: ProfilingStrategy) -> Result<&mut Self> {
|
///
|
||||||
self.profiler = match profile {
|
/// Some [`ProfilingStrategy`] require specific platforms or particular feature
|
||||||
ProfilingStrategy::JitDump => Arc::new(JitDumpAgent::new()?) as Arc<dyn ProfilingAgent>,
|
/// to be enabled, such as `ProfilingStrategy::JitDump` requires the `jitdump`
|
||||||
ProfilingStrategy::VTune => Arc::new(VTuneAgent::new()?) as Arc<dyn ProfilingAgent>,
|
/// feature.
|
||||||
ProfilingStrategy::None => Arc::new(NullProfilerAgent),
|
///
|
||||||
};
|
/// # Errors
|
||||||
Ok(self)
|
///
|
||||||
|
/// The validation of this field is deferred until the engine is being built, and thus may
|
||||||
|
/// cause `Engine::new` fail if the required feature is disabled, or the platform is not
|
||||||
|
/// supported.
|
||||||
|
pub fn profiler(&mut self, profile: ProfilingStrategy) -> &mut Self {
|
||||||
|
self.profiling_strategy = profile;
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configures whether the debug verifier of Cranelift is enabled or not.
|
/// Configures whether the debug verifier of Cranelift is enabled or not.
|
||||||
@@ -712,9 +736,9 @@ impl Config {
|
|||||||
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
||||||
pub fn cranelift_debug_verifier(&mut self, enable: bool) -> &mut Self {
|
pub fn cranelift_debug_verifier(&mut self, enable: bool) -> &mut Self {
|
||||||
let val = if enable { "true" } else { "false" };
|
let val = if enable { "true" } else { "false" };
|
||||||
self.compiler
|
self.compiler_config
|
||||||
.set("enable_verifier", val)
|
.settings
|
||||||
.expect("should be valid flag");
|
.insert("enable_verifier".to_string(), val.to_string());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,9 +757,9 @@ impl Config {
|
|||||||
OptLevel::Speed => "speed",
|
OptLevel::Speed => "speed",
|
||||||
OptLevel::SpeedAndSize => "speed_and_size",
|
OptLevel::SpeedAndSize => "speed_and_size",
|
||||||
};
|
};
|
||||||
self.compiler
|
self.compiler_config
|
||||||
.set("opt_level", val)
|
.settings
|
||||||
.expect("should be valid flag");
|
.insert("opt_level".to_string(), val.to_string());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -751,9 +775,9 @@ impl Config {
|
|||||||
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
||||||
pub fn cranelift_nan_canonicalization(&mut self, enable: bool) -> &mut Self {
|
pub fn cranelift_nan_canonicalization(&mut self, enable: bool) -> &mut Self {
|
||||||
let val = if enable { "true" } else { "false" };
|
let val = if enable { "true" } else { "false" };
|
||||||
self.compiler
|
self.compiler_config
|
||||||
.set("enable_nan_canonicalization", val)
|
.settings
|
||||||
.expect("should be valid flag");
|
.insert("enable_nan_canonicalization".to_string(), val.to_string());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,12 +794,14 @@ impl Config {
|
|||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// This method can fail if the flag's name does not exist.
|
/// The validation of the flags are deferred until the engine is being built, and thus may
|
||||||
|
/// cause `Engine::new` fail if the flag's name does not exist, or the value is not appropriate
|
||||||
|
/// for the flag type.
|
||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
||||||
pub unsafe fn cranelift_flag_enable(&mut self, flag: &str) -> Result<&mut Self> {
|
pub unsafe fn cranelift_flag_enable(&mut self, flag: &str) -> &mut Self {
|
||||||
self.compiler.enable(flag)?;
|
self.compiler_config.flags.insert(flag.to_string());
|
||||||
Ok(self)
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allows settings another Cranelift flag defined by a flag name and value. This allows
|
/// Allows settings another Cranelift flag defined by a flag name and value. This allows
|
||||||
@@ -784,18 +810,26 @@ impl Config {
|
|||||||
/// Since Cranelift flags may be unstable, this method should not be considered to be stable
|
/// Since Cranelift flags may be unstable, this method should not be considered to be stable
|
||||||
/// either; other `Config` functions should be preferred for stability.
|
/// either; other `Config` functions should be preferred for stability.
|
||||||
///
|
///
|
||||||
/// Note that this is marked as unsafe, because setting the wrong flag might break invariants,
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This is marked as unsafe, because setting the wrong flag might break invariants,
|
||||||
/// resulting in execution hazards.
|
/// resulting in execution hazards.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// This method can fail if the flag's name does not exist, or the value is not appropriate for
|
/// The validation of the flags are deferred until the engine is being built, and thus may
|
||||||
/// the flag type.
|
/// cause `Engine::new` fail if the flag's name does not exist, or incompatible with other
|
||||||
|
/// settings.
|
||||||
|
///
|
||||||
|
/// For example, feature `wasm_backtrace` will set `unwind_info` to `true`, but if it's
|
||||||
|
/// manually set to false then it will fail.
|
||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
|
||||||
pub unsafe fn cranelift_flag_set(&mut self, name: &str, value: &str) -> Result<&mut Self> {
|
pub unsafe fn cranelift_flag_set(&mut self, name: &str, value: &str) -> &mut Self {
|
||||||
self.compiler.set(name, value)?;
|
self.compiler_config
|
||||||
Ok(self)
|
.settings
|
||||||
|
.insert(name.to_string(), value.to_string());
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads cache configuration specified at `path`.
|
/// Loads cache configuration specified at `path`.
|
||||||
@@ -1294,6 +1328,16 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validate(&self) -> Result<()> {
|
||||||
|
if self.features.reference_types && !self.features.bulk_memory {
|
||||||
|
bail!("feature 'reference_types' requires 'bulk_memory' to be enabled");
|
||||||
|
}
|
||||||
|
if self.features.threads && !self.features.bulk_memory {
|
||||||
|
bail!("feature 'threads' requires 'bulk_memory' to be enabled");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn build_allocator(&self) -> Result<Box<dyn InstanceAllocator>> {
|
pub(crate) fn build_allocator(&self) -> Result<Box<dyn InstanceAllocator>> {
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
let stack_size = self.async_stack_size;
|
let stack_size = self.async_stack_size;
|
||||||
@@ -1318,12 +1362,59 @@ impl Config {
|
|||||||
)?)),
|
)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(compiler)]
|
pub(crate) fn build_profiler(&self) -> Result<Box<dyn ProfilingAgent>> {
|
||||||
fn compiler_builder(strategy: Strategy) -> Result<Box<dyn CompilerBuilder>> {
|
Ok(match self.profiling_strategy {
|
||||||
match strategy {
|
ProfilingStrategy::JitDump => Box::new(JitDumpAgent::new()?) as Box<dyn ProfilingAgent>,
|
||||||
Strategy::Auto | Strategy::Cranelift => Ok(wasmtime_cranelift::builder()),
|
ProfilingStrategy::VTune => Box::new(VTuneAgent::new()?) as Box<dyn ProfilingAgent>,
|
||||||
|
ProfilingStrategy::None => Box::new(NullProfilerAgent),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(compiler)]
|
||||||
|
pub(crate) fn build_compiler(&mut self) -> Result<Box<dyn wasmtime_environ::Compiler>> {
|
||||||
|
let mut compiler = match self.compiler_config.strategy {
|
||||||
|
Strategy::Auto | Strategy::Cranelift => wasmtime_cranelift::builder(),
|
||||||
|
};
|
||||||
|
if let Some(target) = &self.compiler_config.target {
|
||||||
|
compiler.target(target.clone())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for incompatible compiler options and set required values
|
||||||
|
if self.wasm_backtrace || self.features.reference_types {
|
||||||
|
if !self
|
||||||
|
.compiler_config
|
||||||
|
.ensure_setting_unset_or_given("unwind_info", "true")
|
||||||
|
{
|
||||||
|
bail!("compiler option 'unwind_info' must be enabled when either 'backtraces' or 'reference types' are enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.features.reference_types {
|
||||||
|
if !self
|
||||||
|
.compiler_config
|
||||||
|
.ensure_setting_unset_or_given("enable_safepoints", "true")
|
||||||
|
{
|
||||||
|
bail!("compiler option 'enable_safepoints' must be enabled when 'reference types' is enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.features.simd {
|
||||||
|
if !self
|
||||||
|
.compiler_config
|
||||||
|
.ensure_setting_unset_or_given("enable_simd", "true")
|
||||||
|
{
|
||||||
|
bail!("compiler option 'enable_simd' must be enabled when 'simd' is enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply compiler settings and flags
|
||||||
|
for (k, v) in self.compiler_config.settings.iter() {
|
||||||
|
compiler.set(k, v)?;
|
||||||
|
}
|
||||||
|
for flag in self.compiler_config.flags.iter() {
|
||||||
|
compiler.enable(flag)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
compiler.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1332,7 +1423,7 @@ fn round_up_to_pages(val: u64) -> u64 {
|
|||||||
debug_assert!(page_size.is_power_of_two());
|
debug_assert!(page_size.is_power_of_two());
|
||||||
val.checked_add(page_size - 1)
|
val.checked_add(page_size - 1)
|
||||||
.map(|val| val & !(page_size - 1))
|
.map(|val| val & !(page_size - 1))
|
||||||
.unwrap_or(u64::max_value() / page_size + 1)
|
.unwrap_or(u64::MAX / page_size + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@@ -1341,33 +1432,6 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Config {
|
|
||||||
fn clone(&self) -> Config {
|
|
||||||
Config {
|
|
||||||
#[cfg(compiler)]
|
|
||||||
compiler: self.compiler.clone(),
|
|
||||||
tunables: self.tunables.clone(),
|
|
||||||
#[cfg(feature = "cache")]
|
|
||||||
cache_config: self.cache_config.clone(),
|
|
||||||
profiler: self.profiler.clone(),
|
|
||||||
features: self.features.clone(),
|
|
||||||
mem_creator: self.mem_creator.clone(),
|
|
||||||
allocation_strategy: self.allocation_strategy.clone(),
|
|
||||||
max_wasm_stack: self.max_wasm_stack,
|
|
||||||
wasm_backtrace: self.wasm_backtrace,
|
|
||||||
wasm_backtrace_details_env_used: self.wasm_backtrace_details_env_used,
|
|
||||||
async_support: self.async_support,
|
|
||||||
#[cfg(feature = "async")]
|
|
||||||
async_stack_size: self.async_stack_size,
|
|
||||||
module_version: self.module_version.clone(),
|
|
||||||
parallel_compilation: self.parallel_compilation,
|
|
||||||
memory_init_cow: self.memory_init_cow,
|
|
||||||
memory_guaranteed_dense_image_size: self.memory_guaranteed_dense_image_size,
|
|
||||||
force_memory_init_memfd: self.force_memory_init_memfd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for Config {
|
impl fmt::Debug for Config {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut f = f.debug_struct("Config");
|
let mut f = f.debug_struct("Config");
|
||||||
@@ -1398,7 +1462,7 @@ impl fmt::Debug for Config {
|
|||||||
.field("parallel_compilation", &self.parallel_compilation);
|
.field("parallel_compilation", &self.parallel_compilation);
|
||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
{
|
{
|
||||||
f.field("compiler", &self.compiler);
|
f.field("compiler_config", &self.compiler_config);
|
||||||
}
|
}
|
||||||
f.finish()
|
f.finish()
|
||||||
}
|
}
|
||||||
@@ -1408,7 +1472,7 @@ impl fmt::Debug for Config {
|
|||||||
///
|
///
|
||||||
/// This is used as an argument to the [`Config::strategy`] method.
|
/// This is used as an argument to the [`Config::strategy`] method.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Copy)]
|
||||||
pub enum Strategy {
|
pub enum Strategy {
|
||||||
/// An indicator that the compilation strategy should be automatically
|
/// An indicator that the compilation strategy should be automatically
|
||||||
/// selected.
|
/// selected.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use std::sync::Arc;
|
|||||||
#[cfg(feature = "cache")]
|
#[cfg(feature = "cache")]
|
||||||
use wasmtime_cache::CacheConfig;
|
use wasmtime_cache::CacheConfig;
|
||||||
use wasmtime_environ::FlagValue;
|
use wasmtime_environ::FlagValue;
|
||||||
|
use wasmtime_jit::ProfilingAgent;
|
||||||
use wasmtime_runtime::{debug_builtins, CompiledModuleIdAllocator, InstanceAllocator};
|
use wasmtime_runtime::{debug_builtins, CompiledModuleIdAllocator, InstanceAllocator};
|
||||||
|
|
||||||
/// An `Engine` which is a global context for compilation and management of wasm
|
/// An `Engine` which is a global context for compilation and management of wasm
|
||||||
@@ -43,6 +44,7 @@ struct EngineInner {
|
|||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
compiler: Box<dyn wasmtime_environ::Compiler>,
|
compiler: Box<dyn wasmtime_environ::Compiler>,
|
||||||
allocator: Box<dyn InstanceAllocator>,
|
allocator: Box<dyn InstanceAllocator>,
|
||||||
|
profiler: Box<dyn ProfilingAgent>,
|
||||||
signatures: SignatureRegistry,
|
signatures: SignatureRegistry,
|
||||||
epoch: AtomicU64,
|
epoch: AtomicU64,
|
||||||
unique_id_allocator: CompiledModuleIdAllocator,
|
unique_id_allocator: CompiledModuleIdAllocator,
|
||||||
@@ -55,6 +57,16 @@ struct EngineInner {
|
|||||||
impl Engine {
|
impl Engine {
|
||||||
/// Creates a new [`Engine`] with the specified compilation and
|
/// Creates a new [`Engine`] with the specified compilation and
|
||||||
/// configuration settings.
|
/// configuration settings.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// This method can fail if the `config` is invalid or some
|
||||||
|
/// configurations are incompatible.
|
||||||
|
///
|
||||||
|
/// For example, feature `reference_types` will need to set
|
||||||
|
/// the compiler setting `enable_safepoints` and `unwind_info`
|
||||||
|
/// to `true`, but explicitly disable these two compiler settings
|
||||||
|
/// will cause errors.
|
||||||
pub fn new(config: &Config) -> Result<Engine> {
|
pub fn new(config: &Config) -> Result<Engine> {
|
||||||
// Ensure that wasmtime_runtime's signal handlers are configured. This
|
// Ensure that wasmtime_runtime's signal handlers are configured. This
|
||||||
// is the per-program initialization required for handling traps, such
|
// is the per-program initialization required for handling traps, such
|
||||||
@@ -64,15 +76,22 @@ impl Engine {
|
|||||||
|
|
||||||
let registry = SignatureRegistry::new();
|
let registry = SignatureRegistry::new();
|
||||||
let mut config = config.clone();
|
let mut config = config.clone();
|
||||||
|
config.validate()?;
|
||||||
|
|
||||||
|
#[cfg(compiler)]
|
||||||
|
let compiler = config.build_compiler()?;
|
||||||
|
|
||||||
let allocator = config.build_allocator()?;
|
let allocator = config.build_allocator()?;
|
||||||
allocator.adjust_tunables(&mut config.tunables);
|
allocator.adjust_tunables(&mut config.tunables);
|
||||||
|
let profiler = config.build_profiler()?;
|
||||||
|
|
||||||
Ok(Engine {
|
Ok(Engine {
|
||||||
inner: Arc::new(EngineInner {
|
inner: Arc::new(EngineInner {
|
||||||
#[cfg(compiler)]
|
#[cfg(compiler)]
|
||||||
compiler: config.compiler.build()?,
|
compiler,
|
||||||
config,
|
config,
|
||||||
allocator,
|
allocator,
|
||||||
|
profiler,
|
||||||
signatures: registry,
|
signatures: registry,
|
||||||
epoch: AtomicU64::new(0),
|
epoch: AtomicU64::new(0),
|
||||||
unique_id_allocator: CompiledModuleIdAllocator::new(),
|
unique_id_allocator: CompiledModuleIdAllocator::new(),
|
||||||
@@ -117,6 +136,10 @@ impl Engine {
|
|||||||
self.inner.allocator.as_ref()
|
self.inner.allocator.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn profiler(&self) -> &dyn ProfilingAgent {
|
||||||
|
self.inner.profiler.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "cache")]
|
#[cfg(feature = "cache")]
|
||||||
pub(crate) fn cache_config(&self) -> &CacheConfig {
|
pub(crate) fn cache_config(&self) -> &CacheConfig {
|
||||||
&self.config().cache_config
|
&self.config().cache_config
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ impl Module {
|
|||||||
let module = Arc::new(CompiledModule::from_artifacts(
|
let module = Arc::new(CompiledModule::from_artifacts(
|
||||||
mmap,
|
mmap,
|
||||||
info,
|
info,
|
||||||
&*engine.config().profiler,
|
engine.profiler(),
|
||||||
engine.unique_id_allocator(),
|
engine.unique_id_allocator(),
|
||||||
)?);
|
)?);
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ where
|
|||||||
let mut code_memory = CodeMemory::new(obj);
|
let mut code_memory = CodeMemory::new(obj);
|
||||||
let code = code_memory.publish()?;
|
let code = code_memory.publish()?;
|
||||||
|
|
||||||
register_trampolines(engine.config().profiler.as_ref(), &code.obj);
|
register_trampolines(engine.profiler(), &code.obj);
|
||||||
|
|
||||||
// Extract the host/wasm trampolines from the results of compilation since
|
// Extract the host/wasm trampolines from the results of compilation since
|
||||||
// we know their start/length.
|
// we know their start/length.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ fn create_engine() -> Engine {
|
|||||||
// the generated code at all; it only does extra checking after
|
// the generated code at all; it only does extra checking after
|
||||||
// compilation.
|
// compilation.
|
||||||
unsafe {
|
unsafe {
|
||||||
config.cranelift_flag_enable("regalloc_checker").unwrap();
|
config.cranelift_flag_enable("regalloc_checker");
|
||||||
}
|
}
|
||||||
Engine::new(&config).expect("Could not construct Engine")
|
Engine::new(&config).expect("Could not construct Engine")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fn store_with_padding(padding: usize) -> Result<Store<()>> {
|
|||||||
config.cranelift_flag_set(
|
config.cranelift_flag_set(
|
||||||
"wasmtime_linkopt_padding_between_functions",
|
"wasmtime_linkopt_padding_between_functions",
|
||||||
&padding.to_string(),
|
&padding.to_string(),
|
||||||
)?;
|
);
|
||||||
}
|
}
|
||||||
let engine = Engine::new(&config)?;
|
let engine = Engine::new(&config)?;
|
||||||
Ok(Store::new(&engine, ()))
|
Ok(Store::new(&engine, ()))
|
||||||
@@ -78,7 +78,7 @@ fn mixed() -> Result<()> {
|
|||||||
fn mixed_forced() -> Result<()> {
|
fn mixed_forced() -> Result<()> {
|
||||||
let mut config = Config::new();
|
let mut config = Config::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
config.cranelift_flag_set("wasmtime_linkopt_force_jump_veneer", "true")?;
|
config.cranelift_flag_set("wasmtime_linkopt_force_jump_veneer", "true");
|
||||||
}
|
}
|
||||||
let engine = Engine::new(&config)?;
|
let engine = Engine::new(&config)?;
|
||||||
test_many_call_module(Store::new(&engine, ()))
|
test_many_call_module(Store::new(&engine, ()))
|
||||||
|
|||||||
Reference in New Issue
Block a user