Switch to pooling copy-on-write instantiation strategy for WASM (#11232)

* Switch to pooling copy-on-write instantiation strategy for WASM

* Fix benchmark compilation

* Fix `cargo fmt`

* Fix compilation of another benchmark I've missed

* Cleanups according to review comments

* Move `max_memory_size` to `Semantics`

* Set `memory_guaranteed_dense_image_size` to `max_memory_size`

* Rename `wasm_instantiation_strategy` to `wasmtime_instantiation_strategy`

* Update the doc-comments regarding the instantiation strategy

* Extend the integration tests to test every instantiation strategy

* Don't drop the temporary directory until the runtime is dropped in benchmarks

* Don't drop the temporary directory until the runtime is dropped in tests
This commit is contained in:
Koute
2022-05-19 16:32:53 +09:00
committed by GitHub
parent b3b7b4ddc7
commit dd854c16e2
21 changed files with 726 additions and 236 deletions
@@ -38,7 +38,13 @@ fn memory_consumption_compiled() {
// For that we make a series of runtime calls, probing the RSS for the VMA matching the linear
// memory. After the call we expect RSS to be equal to 0.
let runtime = mk_test_runtime(WasmExecutionMethod::Compiled, 1024);
let runtime = mk_test_runtime(
WasmExecutionMethod::Compiled {
instantiation_strategy:
sc_executor_wasmtime::InstantiationStrategy::LegacyInstanceReuse,
},
1024,
);
let mut instance = runtime.new_instance().unwrap();
let heap_base = instance
@@ -54,8 +54,42 @@ macro_rules! test_wasm_execution {
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled>]() {
$method_name(WasmExecutionMethod::Compiled);
fn [<$method_name _compiled_recreate_instance_cow>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstanceCopyOnWrite
});
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_recreate_instance_vanilla>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstance
});
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_pooling_cow>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::PoolingCopyOnWrite
});
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_pooling_vanilla>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::Pooling
});
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_legacy_instance_reuse>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::LegacyInstanceReuse
});
}
}
};
@@ -88,14 +122,82 @@ macro_rules! test_wasm_execution_sandbox {
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_host_executor>]() {
$method_name(WasmExecutionMethod::Compiled, "_host");
fn [<$method_name _compiled_pooling_cow_host_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::PoolingCopyOnWrite
}, "_host");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_embedded_executor>]() {
$method_name(WasmExecutionMethod::Compiled, "_embedded");
fn [<$method_name _compiled_pooling_cow_embedded_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::PoolingCopyOnWrite
}, "_embedded");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_pooling_vanilla_host_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::Pooling
}, "_host");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_pooling_vanilla_embedded_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::Pooling
}, "_embedded");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_recreate_instance_cow_host_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstanceCopyOnWrite
}, "_host");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_recreate_instance_cow_embedded_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstanceCopyOnWrite
}, "_embedded");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_recreate_instance_vanilla_host_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstance
}, "_host");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_recreate_instance_vanilla_embedded_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstance
}, "_embedded");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_legacy_instance_reuse_host_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::LegacyInstanceReuse
}, "_host");
}
#[test]
#[cfg(feature = "wasmtime")]
fn [<$method_name _compiled_legacy_instance_reuse_embedded_executor>]() {
$method_name(WasmExecutionMethod::Compiled {
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::LegacyInstanceReuse
}, "_embedded");
}
}
};
@@ -153,7 +255,7 @@ fn call_not_existing_function(wasm_method: WasmExecutionMethod) {
let expected = match wasm_method {
WasmExecutionMethod::Interpreted => "Trap: Host(Other(\"Function `missing_external` is only a stub. Calling a stub is not allowed.\"))",
#[cfg(feature = "wasmtime")]
WasmExecutionMethod::Compiled => "call to a missing function env:missing_external"
WasmExecutionMethod::Compiled { .. } => "call to a missing function env:missing_external"
};
assert_eq!(error.message, expected);
},
@@ -173,7 +275,7 @@ fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) {
let expected = match wasm_method {
WasmExecutionMethod::Interpreted => "Trap: Host(Other(\"Function `yet_another_missing_external` is only a stub. Calling a stub is not allowed.\"))",
#[cfg(feature = "wasmtime")]
WasmExecutionMethod::Compiled => "call to a missing function env:yet_another_missing_external"
WasmExecutionMethod::Compiled { .. } => "call to a missing function env:yet_another_missing_external"
};
assert_eq!(error.message, expected);
},
@@ -473,7 +575,9 @@ fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) {
match err {
#[cfg(feature = "wasmtime")]
Error::AbortedDueToTrap(error) if wasm_method == WasmExecutionMethod::Compiled => {
Error::AbortedDueToTrap(error)
if matches!(wasm_method, WasmExecutionMethod::Compiled { .. }) =>
{
assert_eq!(
error.message,
r#"host code panicked while being called by the runtime: Failed to allocate memory: "Allocator ran out of space""#
@@ -807,7 +911,7 @@ fn unreachable_intrinsic(wasm_method: WasmExecutionMethod) {
let expected = match wasm_method {
WasmExecutionMethod::Interpreted => "Trap: Unreachable",
#[cfg(feature = "wasmtime")]
WasmExecutionMethod::Compiled => "wasm trap: wasm `unreachable` instruction executed",
WasmExecutionMethod::Compiled { .. } => "wasm trap: wasm `unreachable` instruction executed",
};
assert_eq!(error.message, expected);
},