diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 868ed2b46a..d9f7339588 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -1068,11 +1068,11 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6bea67967505247f54fa2c85cf4f6e0e31c4e5692c9b70e4ae58e339067333" +checksum = "15013642ddda44eebcf61365b2052a23fd8b7314f90ba44aa059ec02643c5139" dependencies = [ - "cranelift-entity 0.76.0", + "cranelift-entity 0.77.0", ] [[package]] @@ -1096,18 +1096,17 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48194035d2752bdd5bdae429e3ab88676e95f52a2b1355a5d4e809f9e39b1d74" +checksum = "298f2a7ed5fdcb062d8e78b7496b0f4b95265d20245f2d0ca88f846dd192a3a3" dependencies = [ - "cranelift-bforest 0.76.0", - "cranelift-codegen-meta 0.76.0", - "cranelift-codegen-shared 0.76.0", - "cranelift-entity 0.76.0", + "cranelift-bforest 0.77.0", + "cranelift-codegen-meta 0.77.0", + "cranelift-codegen-shared 0.77.0", + "cranelift-entity 0.77.0", "gimli 0.25.0", "log 0.4.14", "regalloc", - "serde", "smallvec 1.7.0", "target-lexicon 0.12.0", ] @@ -1124,12 +1123,12 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976efb22fcab4f2cd6bd4e9913764616a54d895c1a23530128d04e03633c555f" +checksum = "5cf504261ac62dfaf4ffb3f41d88fd885e81aba947c1241275043885bc5f0bac" dependencies = [ - "cranelift-codegen-shared 0.76.0", - "cranelift-entity 0.76.0", + "cranelift-codegen-shared 0.77.0", + "cranelift-entity 0.77.0", ] [[package]] @@ -1140,12 +1139,9 @@ checksum = "6759012d6d19c4caec95793f052613e9d4113e925e7f14154defbac0f1d4c938" [[package]] name = "cranelift-codegen-shared" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dabb5fe66e04d4652e434195b45ae65b5c8172d520247b8f66d8df42b2b45dc" -dependencies = [ - "serde", -] +checksum = "1cd2a72db4301dbe7e5a4499035eedc1e82720009fb60603e20504d8691fa9cd" [[package]] name = "cranelift-entity" @@ -1158,9 +1154,9 @@ dependencies = [ [[package]] name = "cranelift-entity" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3329733e4d4b8e91c809efcaa4faee80bf66f20164e3dd16d707346bd3494799" +checksum = "48868faa07cacf948dc4a1773648813c0e453ff9467e800ff10f6a78c021b546" dependencies = [ "serde", ] @@ -1179,11 +1175,11 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279afcc0d3e651b773f94837c3d581177b348c8d69e928104b2e9fccb226f921" +checksum = "351c9d13b4ecd1a536215ec2fd1c3ee9ee8bc31af172abf1e45ed0adb7a931df" dependencies = [ - "cranelift-codegen 0.76.0", + "cranelift-codegen 0.77.0", "log 0.4.14", "smallvec 1.7.0", "target-lexicon 0.12.0", @@ -1191,30 +1187,29 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c04d1fe6a5abb5bb0edc78baa8ef238370fb8e389cc88b6d153f7c3e9680425" +checksum = "6df8b556663d7611b137b24db7f6c8d9a8a27d7f29c7ea7835795152c94c1b75" dependencies = [ - "cranelift-codegen 0.76.0", + "cranelift-codegen 0.77.0", "libc", "target-lexicon 0.12.0", ] [[package]] name = "cranelift-wasm" -version = "0.76.0" +version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d260ad44f6fd2c91f7f5097191a2a9e3edcbb36df1fb787b600dad5ea148ec" +checksum = "7a69816d90db694fa79aa39b89dda7208a4ac74b6f2b8f3c4da26ee1c8bdfc5e" dependencies = [ - "cranelift-codegen 0.76.0", - "cranelift-entity 0.76.0", - "cranelift-frontend 0.76.0", + "cranelift-codegen 0.77.0", + "cranelift-entity 0.77.0", + "cranelift-frontend 0.77.0", "itertools", "log 0.4.14", - "serde", "smallvec 1.7.0", - "thiserror", - "wasmparser 0.79.0", + "wasmparser 0.80.2", + "wasmtime-types", ] [[package]] @@ -7161,7 +7156,6 @@ checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5" dependencies = [ "log 0.4.14", "rustc-hash", - "serde", "smallvec 1.7.0", ] @@ -8626,26 +8620,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scroll" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" -dependencies = [ - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaaae8f38bb311444cfb7f1979af0bc9240d95795f75f9ceddf6a59b79ceffa0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "sct" version = "0.6.0" @@ -11404,15 +11378,15 @@ checksum = "87cc2fe6350834b4e528ba0901e7aa405d78b89dc1fa3145359eb4de0e323fcf" [[package]] name = "wasmparser" -version = "0.79.0" +version = "0.80.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5894be15a559c85779254700e1d35f02f843b5a69152e5c82c626d9fd66c0e" +checksum = "449167e2832691a1bff24cde28d2804e90e09586a448c8e76984792c44334a6b" [[package]] name = "wasmtime" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbb8a082a8ef50f7eeb8b82dda9709ef1e68963ea3c94e45581644dd4041835" +checksum = "899b1e5261e3d3420860dacfb952871ace9d7ba9f953b314f67aaf9f8e2a4d89" dependencies = [ "anyhow", "backtrace", @@ -11423,27 +11397,28 @@ dependencies = [ "lazy_static", "libc", "log 0.4.14", + "object 0.26.0", "paste 1.0.4", "psm", + "rayon", "region", "rustc-demangle", "serde", - "smallvec 1.7.0", "target-lexicon 0.12.0", - "wasmparser 0.79.0", + "wasmparser 0.80.2", "wasmtime-cache", + "wasmtime-cranelift", "wasmtime-environ", "wasmtime-jit", - "wasmtime-profiling", "wasmtime-runtime", "winapi 0.3.9", ] [[package]] name = "wasmtime-cache" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d73391579ca7f24573138ef768b73b2aed5f9d542385c64979b65d60d0912399" +checksum = "e2493b81d7a9935f7af15e06beec806f256bc974a90a843685f3d61f2fc97058" dependencies = [ "anyhow", "base64 0.13.0", @@ -11462,125 +11437,76 @@ dependencies = [ [[package]] name = "wasmtime-cranelift" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81c6f5ae9205382345c7cd7454932a906186836999a2161c385e38a15f52e1fe" -dependencies = [ - "cranelift-codegen 0.76.0", - "cranelift-entity 0.76.0", - "cranelift-frontend 0.76.0", - "cranelift-wasm", - "target-lexicon 0.12.0", - "wasmparser 0.79.0", - "wasmtime-environ", -] - -[[package]] -name = "wasmtime-debug" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c69e08f55e12f15f50b1b533bc3626723e7224254a065de6576934c86258c9e8" +checksum = "99706bacdf5143f7f967d417f0437cce83a724cf4518cb1a3ff40e519d793021" dependencies = [ "anyhow", + "cranelift-codegen 0.77.0", + "cranelift-entity 0.77.0", + "cranelift-frontend 0.77.0", + "cranelift-native", + "cranelift-wasm", "gimli 0.25.0", "more-asserts", "object 0.26.0", "target-lexicon 0.12.0", "thiserror", - "wasmparser 0.79.0", + "wasmparser 0.80.2", "wasmtime-environ", ] [[package]] name = "wasmtime-environ" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005d93174040af37fb8625f891cd9827afdad314261f7ec4ee61ec497d6e9d3c" +checksum = "ac42cb562a2f98163857605f02581d719a410c5abe93606128c59a10e84de85b" dependencies = [ + "anyhow", "cfg-if 1.0.0", - "cranelift-codegen 0.76.0", - "cranelift-entity 0.76.0", - "cranelift-wasm", + "cranelift-entity 0.77.0", "gimli 0.25.0", "indexmap", "log 0.4.14", "more-asserts", + "object 0.26.0", "serde", + "target-lexicon 0.12.0", "thiserror", - "wasmparser 0.79.0", + "wasmparser 0.80.2", + "wasmtime-types", ] [[package]] name = "wasmtime-jit" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bf1dfb213a35d8f21aefae40e597fe72778a907011ffdff7affb029a02af9a" +checksum = "24f46dd757225f29a419be415ea6fb8558df9b0194f07e3a6a9c99d0e14dd534" dependencies = [ "addr2line", "anyhow", + "bincode", "cfg-if 1.0.0", - "cranelift-codegen 0.76.0", - "cranelift-entity 0.76.0", - "cranelift-frontend 0.76.0", - "cranelift-native", - "cranelift-wasm", "gimli 0.25.0", + "libc", "log 0.4.14", "more-asserts", "object 0.26.0", - "rayon", "region", "serde", "target-lexicon 0.12.0", "thiserror", - "wasmparser 0.79.0", - "wasmtime-cranelift", - "wasmtime-debug", + "wasmparser 0.80.2", "wasmtime-environ", - "wasmtime-obj", - "wasmtime-profiling", "wasmtime-runtime", "winapi 0.3.9", ] -[[package]] -name = "wasmtime-obj" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231491878e710c68015228c9f9fc5955fe5c96dbf1485c15f7bed55b622c83c" -dependencies = [ - "anyhow", - "more-asserts", - "object 0.26.0", - "target-lexicon 0.12.0", - "wasmtime-debug", - "wasmtime-environ", -] - -[[package]] -name = "wasmtime-profiling" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21486cfb5255c2069666c1f116f9e949d4e35c9a494f11112fa407879e42198d" -dependencies = [ - "anyhow", - "cfg-if 1.0.0", - "gimli 0.25.0", - "lazy_static", - "libc", - "object 0.26.0", - "scroll", - "serde", - "target-lexicon 0.12.0", - "wasmtime-environ", - "wasmtime-runtime", -] - [[package]] name = "wasmtime-runtime" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ddfdf32e0a20d81f48be9dacd31612bc61de5a174d1356fef806d300f507de" +checksum = "0122215a44923f395487048cb0a1d60b5b32c73aab15cf9364b798dbaff0996f" dependencies = [ "anyhow", "backtrace", @@ -11600,6 +11526,18 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "wasmtime-types" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9b01caf8a204ef634ebac99700e77ba716d3ebbb68a1abbc2ceb6b16dbec9e4" +dependencies = [ + "cranelift-entity 0.77.0", + "serde", + "thiserror", + "wasmparser 0.80.2", +] + [[package]] name = "wast" version = "38.0.0" diff --git a/substrate/client/executor/src/wasm_runtime.rs b/substrate/client/executor/src/wasm_runtime.rs index 4c768b7f9c..c7aa120071 100644 --- a/substrate/client/executor/src/wasm_runtime.rs +++ b/substrate/client/executor/src/wasm_runtime.rs @@ -318,14 +318,15 @@ pub fn create_wasm_runtime_with_code( WasmExecutionMethod::Compiled => sc_executor_wasmtime::create_runtime( blob, sc_executor_wasmtime::Config { - heap_pages: heap_pages as u32, - max_memory_pages: None, + heap_pages, + max_memory_size: None, allow_missing_func_imports, cache_path: cache_path.map(ToOwned::to_owned), semantics: sc_executor_wasmtime::Semantics { fast_instance_reuse: true, deterministic_stack_limit: None, canonicalize_nans: false, + parallel_compilation: true, }, }, host_functions, diff --git a/substrate/client/executor/wasmtime/Cargo.toml b/substrate/client/executor/wasmtime/Cargo.toml index c122b3ab0e..a8ed01c203 100644 --- a/substrate/client/executor/wasmtime/Cargo.toml +++ b/substrate/client/executor/wasmtime/Cargo.toml @@ -23,8 +23,9 @@ sp-wasm-interface = { version = "4.0.0-dev", path = "../../../primitives/wasm-in sp-runtime-interface = { version = "4.0.0-dev", path = "../../../primitives/runtime-interface" } sp-core = { version = "4.0.0-dev", path = "../../../primitives/core" } sc-allocator = { version = "4.0.0-dev", path = "../../allocator" } -wasmtime = { version = "0.29.0", default-features = false, features = [ +wasmtime = { version = "0.30.0", default-features = false, features = [ "cache", + "cranelift", "jitdump", "parallel-compilation", ] } diff --git a/substrate/client/executor/wasmtime/src/imports.rs b/substrate/client/executor/wasmtime/src/imports.rs index a9ef6e1f58..a00ab14263 100644 --- a/substrate/client/executor/wasmtime/src/imports.rs +++ b/substrate/client/executor/wasmtime/src/imports.rs @@ -22,10 +22,9 @@ use crate::{ }; use sc_executor_common::error::WasmError; use sp_wasm_interface::{Function, ValueType}; -use std::any::Any; +use std::{any::Any, convert::TryInto}; use wasmtime::{ - Caller, Extern, ExternType, Func, FuncType, ImportType, Limits, Memory, MemoryType, Module, - Trap, Val, + Caller, Extern, ExternType, Func, FuncType, ImportType, Memory, MemoryType, Module, Trap, Val, }; pub struct Imports { @@ -41,7 +40,7 @@ pub(crate) fn resolve_imports( store: &mut Store, module: &Module, host_functions: &[&'static dyn Function], - heap_pages: u32, + heap_pages: u64, allow_missing_func_imports: bool, ) -> Result { let mut externs = vec![]; @@ -83,7 +82,7 @@ fn import_name<'a, 'b: 'a>(import: &'a ImportType<'b>) -> Result<&'a str, WasmEr fn resolve_memory_import( store: &mut Store, import_ty: &ImportType, - heap_pages: u32, + heap_pages: u64, ) -> Result { let requested_memory_ty = match import_ty.ty() { ExternType::Memory(memory_ty) => memory_ty, @@ -97,8 +96,8 @@ fn resolve_memory_import( // Increment the min (a.k.a initial) number of pages by `heap_pages` and check if it exceeds the // maximum specified by the import. - let initial = requested_memory_ty.limits().min().saturating_add(heap_pages); - if let Some(max) = requested_memory_ty.limits().max() { + let initial = requested_memory_ty.minimum().saturating_add(heap_pages); + if let Some(max) = requested_memory_ty.maximum() { if initial > max { return Err(WasmError::Other(format!( "incremented number of pages by heap_pages (total={}) is more than maximum requested\ @@ -109,7 +108,27 @@ fn resolve_memory_import( } } - let memory_ty = MemoryType::new(Limits::new(initial, requested_memory_ty.limits().max())); + // Note that the return value of `maximum` and `minimum`, while a u64, + // will always fit into a u32 for 32-bit memories. + // 64-bit memories are part of the memory64 proposal for WebAssembly which is not standardized + // yet. + let minimum: u32 = initial.try_into().map_err(|_| { + WasmError::Other(format!( + "minimum number of memory pages ({}) doesn't fit into u32", + initial + )) + })?; + let maximum: Option = match requested_memory_ty.maximum() { + Some(max) => Some(max.try_into().map_err(|_| { + WasmError::Other(format!( + "maximum number of memory pages ({}) doesn't fit into u32", + max + )) + })?), + None => None, + }; + + let memory_ty = MemoryType::new(minimum, maximum); let memory = Memory::new(store, memory_ty).map_err(|e| { WasmError::Other(format!( "failed to create a memory during resolving of memory import: {}", diff --git a/substrate/client/executor/wasmtime/src/instance_wrapper.rs b/substrate/client/executor/wasmtime/src/instance_wrapper.rs index ccfbb912b9..2b8508ee2b 100644 --- a/substrate/client/executor/wasmtime/src/instance_wrapper.rs +++ b/substrate/client/executor/wasmtime/src/instance_wrapper.rs @@ -154,7 +154,7 @@ impl InstanceWrapper { pub fn new( module: &Module, imports: &Imports, - heap_pages: u32, + heap_pages: u64, mut ctx: impl AsContextMut, ) -> Result { let instance = Instance::new(&mut ctx, module, &imports.externs) diff --git a/substrate/client/executor/wasmtime/src/runtime.rs b/substrate/client/executor/wasmtime/src/runtime.rs index a62356357b..bd113c3383 100644 --- a/substrate/client/executor/wasmtime/src/runtime.rs +++ b/substrate/client/executor/wasmtime/src/runtime.rs @@ -77,7 +77,7 @@ struct InstanceCreator { store: Store, module: Arc, imports: Arc, - heap_pages: u32, + heap_pages: u64, } impl InstanceCreator { @@ -130,15 +130,15 @@ pub struct WasmtimeRuntime { impl WasmtimeRuntime { /// Creates the store respecting the set limits. fn new_store(&self) -> Store { - let limits = if let Some(max_memory_pages) = self.config.max_memory_pages { - wasmtime::StoreLimitsBuilder::new().memory_pages(max_memory_pages).build() + let limits = if let Some(max_memory_size) = self.config.max_memory_size { + wasmtime::StoreLimitsBuilder::new().memory_size(max_memory_size).build() } else { Default::default() }; let mut store = Store::new(&self.engine, StoreData { limits, host_state: None }); - if self.config.max_memory_pages.is_some() { + if self.config.max_memory_size.is_some() { store.limiter(|s| &mut s.limits); } @@ -350,6 +350,8 @@ fn common_config(semantics: &Semantics) -> std::result::Result std::result::Result, + pub max_memory_size: Option, /// The WebAssembly standard requires all imports of an instantiated module to be resolved, - /// othewise, the instantiation fails. If this option is set to `true`, then this behavior is + /// otherwise, the instantiation fails. If this option is set to `true`, then this behavior is /// overriden and imports that are requested by the module and not provided by the host /// functions will be resolved using stubs. These stubs will trap upon a call. pub allow_missing_func_imports: bool, diff --git a/substrate/client/executor/wasmtime/src/tests.rs b/substrate/client/executor/wasmtime/src/tests.rs index 2a8bcc0b01..261afba0c6 100644 --- a/substrate/client/executor/wasmtime/src/tests.rs +++ b/substrate/client/executor/wasmtime/src/tests.rs @@ -28,8 +28,8 @@ struct RuntimeBuilder { fast_instance_reuse: bool, canonicalize_nans: bool, deterministic_stack: bool, - heap_pages: u32, - max_memory_pages: Option, + heap_pages: u64, + max_memory_size: Option, } impl RuntimeBuilder { @@ -42,7 +42,7 @@ impl RuntimeBuilder { canonicalize_nans: false, deterministic_stack: false, heap_pages: 1024, - max_memory_pages: None, + max_memory_size: None, } } @@ -58,8 +58,8 @@ impl RuntimeBuilder { self.deterministic_stack = deterministic_stack; } - fn max_memory_pages(&mut self, max_memory_pages: Option) { - self.max_memory_pages = max_memory_pages; + fn max_memory_size(&mut self, max_memory_size: Option) { + self.max_memory_size = max_memory_size; } fn build(self) -> Arc { @@ -82,7 +82,7 @@ impl RuntimeBuilder { blob, crate::Config { heap_pages: self.heap_pages, - max_memory_pages: self.max_memory_pages, + max_memory_size: self.max_memory_size, allow_missing_func_imports: true, cache_path: None, semantics: crate::Semantics { @@ -95,6 +95,7 @@ impl RuntimeBuilder { false => None, }, canonicalize_nans: self.canonicalize_nans, + parallel_compilation: true, }, }, { @@ -171,13 +172,13 @@ fn test_stack_depth_reaching() { #[test] fn test_max_memory_pages() { fn try_instantiate( - max_memory_pages: Option, + max_memory_size: Option, wat: &'static str, ) -> Result<(), Box> { let runtime = { let mut builder = RuntimeBuilder::new_on_demand(); builder.use_wat(wat); - builder.max_memory_pages(max_memory_pages); + builder.max_memory_size(max_memory_size); builder.build() }; let mut instance = runtime.new_instance()?; @@ -185,6 +186,8 @@ fn test_max_memory_pages() { Ok(()) } + const WASM_PAGE_SIZE: usize = 65536; + // check the old behavior if preserved. That is, if no limit is set we allow 4 GiB of memory. try_instantiate( None, @@ -213,9 +216,9 @@ fn test_max_memory_pages() { // max is not specified, therefore it's implied to be 65536 pages (4 GiB). // - // max_memory_pages = 1 (initial) + 1024 (heap_pages) + // max_memory_size = (1 (initial) + 1024 (heap_pages)) * WASM_PAGE_SIZE try_instantiate( - Some(1 + 1024), + Some((1 + 1024) * WASM_PAGE_SIZE), r#" (module @@ -233,7 +236,7 @@ fn test_max_memory_pages() { // max is specified explicitly to 2048 pages. try_instantiate( - Some(1 + 1024), + Some((1 + 1024) * WASM_PAGE_SIZE), r#" (module @@ -251,7 +254,7 @@ fn test_max_memory_pages() { // memory grow should work as long as it doesn't exceed 1025 pages in total. try_instantiate( - Some(0 + 1024 + 25), + Some((0 + 1024 + 25) * WASM_PAGE_SIZE), r#" (module (import "env" "memory" (memory 0)) ;; <- zero starting pages. @@ -280,7 +283,7 @@ fn test_max_memory_pages() { // We start with 1025 pages and try to grow at least one. try_instantiate( - Some(1 + 1024), + Some((1 + 1024) * WASM_PAGE_SIZE), r#" (module (import "env" "memory" (memory 1)) ;; <- initial=1, meaning after heap pages mount the