mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-18 00:11:01 +00:00
Adjust maximum memory pages hard limit for the pooling instantiation strategy (#11482)
* Run `sc-executor-wasmtime` unit tests for all instantiation strategies * Adjust maximum memory pages hard limit for the pooling instantiation strategy
This commit is contained in:
Generated
+1
@@ -8278,6 +8278,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
"parity-wasm 0.42.2",
|
"parity-wasm 0.42.2",
|
||||||
|
"paste 1.0.6",
|
||||||
"sc-allocator",
|
"sc-allocator",
|
||||||
"sc-executor-common",
|
"sc-executor-common",
|
||||||
"sc-runtime-test",
|
"sc-runtime-test",
|
||||||
|
|||||||
@@ -37,3 +37,4 @@ wat = "1.0"
|
|||||||
sc-runtime-test = { version = "2.0.0", path = "../runtime-test" }
|
sc-runtime-test = { version = "2.0.0", path = "../runtime-test" }
|
||||||
sp-io = { version = "6.0.0", path = "../../../primitives/io" }
|
sp-io = { version = "6.0.0", path = "../../../primitives/io" }
|
||||||
tempfile = "3.3.0"
|
tempfile = "3.3.0"
|
||||||
|
paste = "1.0"
|
||||||
|
|||||||
@@ -341,6 +341,21 @@ fn common_config(semantics: &Semantics) -> std::result::Result<wasmtime::Config,
|
|||||||
);
|
);
|
||||||
|
|
||||||
if use_pooling {
|
if use_pooling {
|
||||||
|
const WASM_PAGE_SIZE: u64 = 65536;
|
||||||
|
const MAX_WASM_PAGES: u64 = 0x10000;
|
||||||
|
|
||||||
|
let memory_pages = if let Some(max_memory_size) = semantics.max_memory_size {
|
||||||
|
let max_memory_size = max_memory_size as u64;
|
||||||
|
let mut pages = max_memory_size / WASM_PAGE_SIZE;
|
||||||
|
if max_memory_size % WASM_PAGE_SIZE != 0 {
|
||||||
|
pages += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cmp::min(MAX_WASM_PAGES, pages)
|
||||||
|
} else {
|
||||||
|
MAX_WASM_PAGES
|
||||||
|
};
|
||||||
|
|
||||||
config.allocation_strategy(wasmtime::InstanceAllocationStrategy::Pooling {
|
config.allocation_strategy(wasmtime::InstanceAllocationStrategy::Pooling {
|
||||||
strategy: wasmtime::PoolingAllocationStrategy::ReuseAffinity,
|
strategy: wasmtime::PoolingAllocationStrategy::ReuseAffinity,
|
||||||
|
|
||||||
@@ -353,7 +368,7 @@ fn common_config(semantics: &Semantics) -> std::result::Result<wasmtime::Config,
|
|||||||
// memory_pages: 2070
|
// memory_pages: 2070
|
||||||
size: 64 * 1024,
|
size: 64 * 1024,
|
||||||
table_elements: 2048,
|
table_elements: 2048,
|
||||||
memory_pages: 4096,
|
memory_pages,
|
||||||
|
|
||||||
// We can only have a single of those.
|
// We can only have a single of those.
|
||||||
tables: 1,
|
tables: 1,
|
||||||
|
|||||||
@@ -24,6 +24,54 @@ use crate::InstantiationStrategy;
|
|||||||
|
|
||||||
type HostFunctions = sp_io::SubstrateHostFunctions;
|
type HostFunctions = sp_io::SubstrateHostFunctions;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! test_wasm_execution {
|
||||||
|
(@no_legacy_instance_reuse $method_name:ident) => {
|
||||||
|
paste::item! {
|
||||||
|
#[test]
|
||||||
|
fn [<$method_name _recreate_instance_cow>]() {
|
||||||
|
$method_name(
|
||||||
|
InstantiationStrategy::RecreateInstanceCopyOnWrite
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn [<$method_name _recreate_instance_vanilla>]() {
|
||||||
|
$method_name(
|
||||||
|
InstantiationStrategy::RecreateInstance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn [<$method_name _pooling_cow>]() {
|
||||||
|
$method_name(
|
||||||
|
InstantiationStrategy::PoolingCopyOnWrite
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn [<$method_name _pooling_vanilla>]() {
|
||||||
|
$method_name(
|
||||||
|
InstantiationStrategy::Pooling
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($method_name:ident) => {
|
||||||
|
test_wasm_execution!(@no_legacy_instance_reuse $method_name);
|
||||||
|
|
||||||
|
paste::item! {
|
||||||
|
#[test]
|
||||||
|
fn [<$method_name _legacy_instance_reuse>]() {
|
||||||
|
$method_name(
|
||||||
|
InstantiationStrategy::LegacyInstanceReuse
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
struct RuntimeBuilder {
|
struct RuntimeBuilder {
|
||||||
code: Option<String>,
|
code: Option<String>,
|
||||||
instantiation_strategy: InstantiationStrategy,
|
instantiation_strategy: InstantiationStrategy,
|
||||||
@@ -36,12 +84,10 @@ struct RuntimeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RuntimeBuilder {
|
impl RuntimeBuilder {
|
||||||
/// Returns a new builder that won't use the fast instance reuse mechanism, but instead will
|
fn new(instantiation_strategy: InstantiationStrategy) -> Self {
|
||||||
/// create a new runtime instance each time.
|
|
||||||
fn new_on_demand() -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
code: None,
|
code: None,
|
||||||
instantiation_strategy: InstantiationStrategy::RecreateInstance,
|
instantiation_strategy,
|
||||||
canonicalize_nans: false,
|
canonicalize_nans: false,
|
||||||
deterministic_stack: false,
|
deterministic_stack: false,
|
||||||
extra_heap_pages: 1024,
|
extra_heap_pages: 1024,
|
||||||
@@ -128,9 +174,9 @@ impl RuntimeBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
test_wasm_execution!(test_nan_canonicalization);
|
||||||
fn test_nan_canonicalization() {
|
fn test_nan_canonicalization(instantiation_strategy: InstantiationStrategy) {
|
||||||
let mut builder = RuntimeBuilder::new_on_demand().canonicalize_nans(true);
|
let mut builder = RuntimeBuilder::new(instantiation_strategy).canonicalize_nans(true);
|
||||||
let runtime = builder.build();
|
let runtime = builder.build();
|
||||||
|
|
||||||
let mut instance = runtime.new_instance().expect("failed to instantiate a runtime");
|
let mut instance = runtime.new_instance().expect("failed to instantiate a runtime");
|
||||||
@@ -166,11 +212,11 @@ fn test_nan_canonicalization() {
|
|||||||
assert_eq!(res, CANONICAL_NAN_BITS);
|
assert_eq!(res, CANONICAL_NAN_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
test_wasm_execution!(test_stack_depth_reaching);
|
||||||
fn test_stack_depth_reaching() {
|
fn test_stack_depth_reaching(instantiation_strategy: InstantiationStrategy) {
|
||||||
const TEST_GUARD_PAGE_SKIP: &str = include_str!("test-guard-page-skip.wat");
|
const TEST_GUARD_PAGE_SKIP: &str = include_str!("test-guard-page-skip.wat");
|
||||||
|
|
||||||
let mut builder = RuntimeBuilder::new_on_demand()
|
let mut builder = RuntimeBuilder::new(instantiation_strategy)
|
||||||
.use_wat(TEST_GUARD_PAGE_SKIP.to_string())
|
.use_wat(TEST_GUARD_PAGE_SKIP.to_string())
|
||||||
.deterministic_stack(true);
|
.deterministic_stack(true);
|
||||||
|
|
||||||
@@ -186,33 +232,46 @@ fn test_stack_depth_reaching() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
test_wasm_execution!(test_max_memory_pages_imported_memory_without_precompilation);
|
||||||
fn test_max_memory_pages_imported_memory_without_precompilation() {
|
fn test_max_memory_pages_imported_memory_without_precompilation(
|
||||||
test_max_memory_pages(true, false);
|
instantiation_strategy: InstantiationStrategy,
|
||||||
|
) {
|
||||||
|
test_max_memory_pages(instantiation_strategy, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
test_wasm_execution!(test_max_memory_pages_exported_memory_without_precompilation);
|
||||||
fn test_max_memory_pages_exported_memory_without_precompilation() {
|
fn test_max_memory_pages_exported_memory_without_precompilation(
|
||||||
test_max_memory_pages(false, false);
|
instantiation_strategy: InstantiationStrategy,
|
||||||
|
) {
|
||||||
|
test_max_memory_pages(instantiation_strategy, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
test_wasm_execution!(@no_legacy_instance_reuse test_max_memory_pages_imported_memory_with_precompilation);
|
||||||
fn test_max_memory_pages_imported_memory_with_precompilation() {
|
fn test_max_memory_pages_imported_memory_with_precompilation(
|
||||||
test_max_memory_pages(true, true);
|
instantiation_strategy: InstantiationStrategy,
|
||||||
|
) {
|
||||||
|
test_max_memory_pages(instantiation_strategy, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
test_wasm_execution!(@no_legacy_instance_reuse test_max_memory_pages_exported_memory_with_precompilation);
|
||||||
fn test_max_memory_pages_exported_memory_with_precompilation() {
|
fn test_max_memory_pages_exported_memory_with_precompilation(
|
||||||
test_max_memory_pages(false, true);
|
instantiation_strategy: InstantiationStrategy,
|
||||||
|
) {
|
||||||
|
test_max_memory_pages(instantiation_strategy, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_max_memory_pages(import_memory: bool, precompile_runtime: bool) {
|
fn test_max_memory_pages(
|
||||||
|
instantiation_strategy: InstantiationStrategy,
|
||||||
|
import_memory: bool,
|
||||||
|
precompile_runtime: bool,
|
||||||
|
) {
|
||||||
fn try_instantiate(
|
fn try_instantiate(
|
||||||
max_memory_size: Option<usize>,
|
max_memory_size: Option<usize>,
|
||||||
wat: String,
|
wat: String,
|
||||||
|
instantiation_strategy: InstantiationStrategy,
|
||||||
precompile_runtime: bool,
|
precompile_runtime: bool,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut builder = RuntimeBuilder::new_on_demand()
|
let mut builder = RuntimeBuilder::new(instantiation_strategy)
|
||||||
.use_wat(wat)
|
.use_wat(wat)
|
||||||
.max_memory_size(max_memory_size)
|
.max_memory_size(max_memory_size)
|
||||||
.precompile_runtime(precompile_runtime);
|
.precompile_runtime(precompile_runtime);
|
||||||
@@ -265,6 +324,7 @@ fn test_max_memory_pages(import_memory: bool, precompile_runtime: bool) {
|
|||||||
*/
|
*/
|
||||||
memory(64511, None, import_memory)
|
memory(64511, None, import_memory)
|
||||||
),
|
),
|
||||||
|
instantiation_strategy,
|
||||||
precompile_runtime,
|
precompile_runtime,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -288,6 +348,7 @@ fn test_max_memory_pages(import_memory: bool, precompile_runtime: bool) {
|
|||||||
// 1 initial, max is not specified.
|
// 1 initial, max is not specified.
|
||||||
memory(1, None, import_memory)
|
memory(1, None, import_memory)
|
||||||
),
|
),
|
||||||
|
instantiation_strategy,
|
||||||
precompile_runtime,
|
precompile_runtime,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -309,6 +370,7 @@ fn test_max_memory_pages(import_memory: bool, precompile_runtime: bool) {
|
|||||||
// Max is 2048.
|
// Max is 2048.
|
||||||
memory(1, Some(2048), import_memory)
|
memory(1, Some(2048), import_memory)
|
||||||
),
|
),
|
||||||
|
instantiation_strategy,
|
||||||
precompile_runtime,
|
precompile_runtime,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -342,6 +404,7 @@ fn test_max_memory_pages(import_memory: bool, precompile_runtime: bool) {
|
|||||||
// Zero starting pages.
|
// Zero starting pages.
|
||||||
memory(0, None, import_memory)
|
memory(0, None, import_memory)
|
||||||
),
|
),
|
||||||
|
instantiation_strategy,
|
||||||
precompile_runtime,
|
precompile_runtime,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -375,6 +438,7 @@ fn test_max_memory_pages(import_memory: bool, precompile_runtime: bool) {
|
|||||||
// Initial=1, meaning after heap pages mount the total will be already 1025.
|
// Initial=1, meaning after heap pages mount the total will be already 1025.
|
||||||
memory(1, None, import_memory)
|
memory(1, None, import_memory)
|
||||||
),
|
),
|
||||||
|
instantiation_strategy,
|
||||||
precompile_runtime,
|
precompile_runtime,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user