diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2dd97611788..f5f25ca7338 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -123,6 +123,10 @@ jobs: run: | # fast benchmark tests before long run cargo test -p "pallet-*" --features runtime-benchmarks,runtime-benchmarks-checkers --locked ${{ matrix.profiles.flags }} bench + # check `multivalue` proposal works + RUSTFLAGS="--cfg force_wasmer_cranelift_i_know_what_i_do" \ + cargo test -p pallet-gear --features runtime-benchmarks,runtime-benchmarks-checkers --locked ${{ matrix.profiles.flags }} \ + benchmarking::bench_instr_call_indirect_per_result -- --exact - name: "Test: Benchmarks in WASM" # unoptimized benchmarks take a few hours to run diff --git a/Cargo.lock b/Cargo.lock index 316d978a531..bb118ec3c99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2722,13 +2722,43 @@ dependencies = [ "libc", ] +[[package]] +name = "cranelift-bforest" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" +dependencies = [ + "cranelift-entity 0.91.1", +] + [[package]] name = "cranelift-bforest" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1277fbfa94bc82c8ec4af2ded3e639d49ca5f7f3c7eeab2c66accd135ece4e70" dependencies = [ - "cranelift-entity", + "cranelift-entity 0.95.1", +] + +[[package]] +name = "cranelift-codegen" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" +dependencies = [ + "arrayvec 0.7.4", + "bumpalo", + "cranelift-bforest 0.91.1", + "cranelift-codegen-meta 0.91.1", + "cranelift-codegen-shared 0.91.1", + "cranelift-egraph", + "cranelift-entity 0.91.1", + "cranelift-isle 0.91.1", + "gimli 0.26.2", + "log", + "regalloc2 0.5.1", + "smallvec", + "target-lexicon", ] [[package]] @@ -2738,11 +2768,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6e8c31ad3b2270e9aeec38723888fe1b0ace3bea2b06b3f749ccf46661d3220" dependencies = [ "bumpalo", - "cranelift-bforest", - "cranelift-codegen-meta", - "cranelift-codegen-shared", - "cranelift-entity", - "cranelift-isle", + "cranelift-bforest 0.95.1", + "cranelift-codegen-meta 0.95.1", + "cranelift-codegen-shared 0.95.1", + "cranelift-entity 0.95.1", + "cranelift-isle 0.95.1", "gimli 0.27.3", "hashbrown 0.13.2", "log", @@ -2751,21 +2781,56 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cranelift-codegen-meta" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" +dependencies = [ + "cranelift-codegen-shared 0.91.1", +] + [[package]] name = "cranelift-codegen-meta" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ac5ac30d62b2d66f12651f6b606dbdfd9c2cfd0908de6b387560a277c5c9da" dependencies = [ - "cranelift-codegen-shared", + "cranelift-codegen-shared 0.95.1", ] +[[package]] +name = "cranelift-codegen-shared" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + [[package]] name = "cranelift-codegen-shared" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd82b8b376247834b59ed9bdc0ddeb50f517452827d4a11bccf5937b213748b8" +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity 0.91.1", + "fxhash", + "hashbrown 0.12.3", + "indexmap 1.9.3", + "log", + "smallvec", +] + +[[package]] +name = "cranelift-entity" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" + [[package]] name = "cranelift-entity" version = "0.95.1" @@ -2775,18 +2840,36 @@ dependencies = [ "serde", ] +[[package]] +name = "cranelift-frontend" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" +dependencies = [ + "cranelift-codegen 0.91.1", + "log", + "smallvec", + "target-lexicon", +] + [[package]] name = "cranelift-frontend" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a25d9d0a0ae3079c463c34115ec59507b4707175454f0eee0891e83e30e82d" dependencies = [ - "cranelift-codegen", + "cranelift-codegen 0.95.1", "log", "smallvec", "target-lexicon", ] +[[package]] +name = "cranelift-isle" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" + [[package]] name = "cranelift-isle" version = "0.95.1" @@ -2799,7 +2882,7 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb6b03e0e03801c4b3fd8ce0758a94750c07a44e7944cc0ffbf0d3f2e7c79b00" dependencies = [ - "cranelift-codegen", + "cranelift-codegen 0.95.1", "libc", "target-lexicon", ] @@ -2810,9 +2893,9 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff3220489a3d928ad91e59dd7aeaa8b3de18afb554a6211213673a71c90737ac" dependencies = [ - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", + "cranelift-codegen 0.95.1", + "cranelift-entity 0.95.1", + "cranelift-frontend 0.95.1", "itertools 0.10.5", "log", "smallvec", @@ -6517,6 +6600,7 @@ version = "1.7.0" dependencies = [ "derive_more 0.99.18", "enum-iterator 1.5.0", + "gear-wasm", "gwasm-instrument", "wasmparser-nostd", "wat", @@ -13089,6 +13173,18 @@ dependencies = [ "syn 2.0.71", ] +[[package]] +name = "regalloc2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" +dependencies = [ + "fxhash", + "log", + "slice-group-by", + "smallvec", +] + [[package]] name = "regalloc2" version = "0.6.1" @@ -19055,6 +19151,7 @@ dependencies = [ "tracing", "wasm-bindgen", "wasmer-compiler", + "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", "wasmer-types", @@ -19103,6 +19200,25 @@ dependencies = [ "xxhash-rust", ] +[[package]] +name = "wasmer-compiler-cranelift" +version = "4.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3352014573750327646a690d32774312b0e8b7920e7e8ba00c0449eac18390" +dependencies = [ + "cranelift-codegen 0.91.1", + "cranelift-entity 0.91.1", + "cranelift-frontend 0.91.1", + "gimli 0.26.2", + "more-asserts", + "rayon", + "smallvec", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", +] + [[package]] name = "wasmer-compiler-singlepass" version = "4.3.5" @@ -19463,9 +19579,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1cefde0cce8cb700b1b21b6298a3837dba46521affd7b8c38a9ee2c869eee04" dependencies = [ "anyhow", - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", + "cranelift-codegen 0.95.1", + "cranelift-entity 0.95.1", + "cranelift-frontend 0.95.1", "cranelift-native", "cranelift-wasm", "gimli 0.27.3", @@ -19485,7 +19601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd041e382ef5aea1b9fc78442394f1a4f6d676ce457e7076ca4cb3f397882f8b" dependencies = [ "anyhow", - "cranelift-codegen", + "cranelift-codegen 0.95.1", "cranelift-native", "gimli 0.27.3", "object 0.30.4", @@ -19500,7 +19616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a990198cee4197423045235bf89d3359e69bd2ea031005f4c2d901125955c949" dependencies = [ "anyhow", - "cranelift-entity", + "cranelift-entity 0.95.1", "gimli 0.27.3", "indexmap 1.9.3", "log", @@ -19603,7 +19719,7 @@ version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f" dependencies = [ - "cranelift-entity", + "cranelift-entity 0.95.1", "serde", "thiserror", "wasmparser 0.102.0", diff --git a/Cargo.toml b/Cargo.toml index e87e3bc6bd9..8874d1977fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,9 @@ homepage = "https://gear-tech.io" repository = "https://github.com/gear-tech/gear" rust-version = "1.81" +[workspace.lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(loom)', 'cfg(fuzz)', 'cfg(force_wasmer_cranelift_i_know_what_i_do)'] } + [workspace] resolver = "2" @@ -554,9 +557,6 @@ fs4 = "0.11.1" # utils/gear-wasmer bytes = "1.8.0" # utils/gear-wasmer-cache loom = "0.7.2" # utils/gear-wasmer-cache -[workspace.lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(loom)', 'cfg(fuzz)'] } - [profile.dev.package.corosensei] opt-level = 3 @@ -592,9 +592,10 @@ debug = true [patch.crates-io] # sp-io = { version = "38.0.0", git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409" } # sp-application-crypto = { version = "38.0.0", git = "https://github.com/gear-tech/polkadot-sdk.git", branch = "gear-polkadot-stable2409" } + +# these patched dependecies force their `sign_ext` feature to be used by Substrate dependencies parity-wasm = { version = "0.45.0", git = "https://github.com/gear-tech/parity-wasm", branch = "v0.45.0-sign-ext" } wasmi-validation = { version = "0.5.0", git = "https://github.com/gear-tech/wasmi", branch = "v0.13.2-sign-ext" } -# wasm-instrument = { version = "0.3.0", git = "https://github.com/gear-tech/wasm-instrument", branch = "v0.3.0-sign-ext" } wasm-instrument = { version = "0.4.0", git = "https://github.com/gear-tech/wasm-instrument", branch = "v0.4.0-sign-ext" } # TODO: remove after https://github.com/BLAKE3-team/BLAKE3/pull/230 diff --git a/core/src/gas_metering/rules.rs b/core/src/gas_metering/rules.rs index c2a6a5b2275..b41d65a5da1 100644 --- a/core/src/gas_metering/rules.rs +++ b/core/src/gas_metering/rules.rs @@ -183,7 +183,7 @@ impl Rules for CustomConstantCostRules { /// This type provides real gas cost of instructions on pallet-gear. pub struct ScheduleRules<'a> { schedule: &'a Schedule, - params: Vec, + funcs: Vec<(u32, u32)>, } impl Schedule { @@ -191,13 +191,13 @@ impl Schedule { pub fn rules(&self, module: &Module) -> impl Rules + '_ { ScheduleRules { schedule: self, - params: module + funcs: module .type_section() .iter() .flat_map(|section| section.types()) .map(|func| { let Type::Function(func) = func; - func.params().len() as u32 + (func.params().len() as u32, func.results().len() as u32) }) .collect(), } @@ -211,6 +211,7 @@ impl<'a> Rules for ScheduleRules<'a> { let w = &self.schedule.instruction_weights; let max_params = self.schedule.limits.parameters; + let max_results = self.schedule.limits.results; let weight = match *instruction { End | Unreachable | Return | Else | Block(_) | Loop(_) | Nop | Drop => 0, @@ -240,7 +241,16 @@ impl<'a> Rules for ScheduleRules<'a> { GetGlobal(_) => w.global_get, SetGlobal(_) => w.global_set, CurrentMemory(_) => w.memory_current, - CallIndirect(idx, _) => *self.params.get(idx as usize).unwrap_or(&max_params), + CallIndirect(idx, _) => { + let (params, results) = self + .funcs + .get(idx as usize) + .copied() + .unwrap_or((max_params, max_results)); + w.call_indirect + .saturating_add(w.call_indirect_per_param.saturating_mul(params)) + .saturating_add(w.call_indirect_per_result.saturating_mul(results)) + } BrTable(ref data) => w .br_table .saturating_add(w.br_table_per_entry.saturating_mul(data.table.len() as u32)), diff --git a/core/src/gas_metering/schedule.rs b/core/src/gas_metering/schedule.rs index 997b9e89a72..ad83c613200 100644 --- a/core/src/gas_metering/schedule.rs +++ b/core/src/gas_metering/schedule.rs @@ -117,6 +117,8 @@ pub struct Limits { #[doc = " is not weight metered its costs must be static (via this limit) and included in"] #[doc = " the costs of the instructions that cause them (call, call_indirect)."] pub parameters: u32, + #[doc = " Maximum numbers of parameters a function can have."] + pub results: u32, #[doc = " Maximum number of memory pages allowed for a program."] pub memory_pages: u16, #[doc = " Maximum number of elements allowed in a table."] @@ -150,6 +152,7 @@ impl Default for Limits { globals: 256, locals: 1024, parameters: 128, + results: 128, memory_pages: 32768, table_size: 4096, table_number: 100, @@ -212,6 +215,7 @@ pub struct InstructionWeights { pub call: u32, pub call_indirect: u32, pub call_indirect_per_param: u32, + pub call_indirect_per_result: u32, pub call_per_local: u32, pub local_get: u32, pub local_set: u32, @@ -305,6 +309,7 @@ impl Default for InstructionWeights { call: 5506, call_indirect: 24900, call_indirect_per_param: 1308, + call_indirect_per_result: 1104, call_per_local: 0, local_get: 714, local_set: 1386, diff --git a/gcli/src/meta/executor.rs b/gcli/src/meta/executor.rs index 30151506c11..15df66fea62 100644 --- a/gcli/src/meta/executor.rs +++ b/gcli/src/meta/executor.rs @@ -21,7 +21,9 @@ //! is because they are for the on-chain environment data. use anyhow::{anyhow, Context, Result}; -use wasmer::{Engine, FunctionEnv, Imports, Instance, Memory, MemoryType, Module, Store}; +use wasmer::{ + Engine, FunctionEnv, Imports, Instance, Memory, MemoryType, Module, Singlepass, Store, +}; /// HostState for the WASM executor #[derive(Default)] @@ -37,7 +39,7 @@ pub fn call_metadata(wasm: &[u8]) -> Result> { /// Executes the WASM code. fn execute(wasm: &[u8], method: &str) -> Result> { - let engine = Engine::default(); + let engine = Engine::from(Singlepass::default()); let module = Module::new(&engine, wasm).unwrap(); let mut store = Store::new(engine); diff --git a/gsdk/src/metadata/generated.rs b/gsdk/src/metadata/generated.rs index 738654544e0..7718ad911f6 100644 --- a/gsdk/src/metadata/generated.rs +++ b/gsdk/src/metadata/generated.rs @@ -3080,6 +3080,7 @@ pub mod runtime_types { pub call: ::core::primitive::u32, pub call_indirect: ::core::primitive::u32, pub call_indirect_per_param: ::core::primitive::u32, + pub call_indirect_per_result: ::core::primitive::u32, pub call_per_local: ::core::primitive::u32, pub local_get: ::core::primitive::u32, pub local_set: ::core::primitive::u32, @@ -3160,6 +3161,7 @@ pub mod runtime_types { pub globals: ::core::primitive::u32, pub locals: ::core::primitive::u32, pub parameters: ::core::primitive::u32, + pub results: ::core::primitive::u32, pub memory_pages: ::core::primitive::u16, pub table_size: ::core::primitive::u32, pub table_number: ::core::primitive::u32, diff --git a/pallets/gear/Cargo.toml b/pallets/gear/Cargo.toml index f7a15effebf..7e35290a532 100644 --- a/pallets/gear/Cargo.toml +++ b/pallets/gear/Cargo.toml @@ -9,12 +9,12 @@ homepage.workspace = true repository.workspace = true readme = "README.md" -[lints] -workspace = true - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] +[lints] +workspace = true + [dependencies] parity-scale-codec = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] } diff --git a/pallets/gear/src/benchmarking/code.rs b/pallets/gear/src/benchmarking/code.rs index b7030653c4b..f2bfc02732f 100644 --- a/pallets/gear/src/benchmarking/code.rs +++ b/pallets/gear/src/benchmarking/code.rs @@ -90,7 +90,7 @@ pub struct ModuleDefinition { pub aux_body: Option, /// The amount of I64 arguments the aux function should have. pub aux_arg_num: u32, - pub aux_res: Option, + pub aux_res: Vec, /// Create a table containing function pointers. pub table: Option, /// Create a type section with the specified amount of types. @@ -231,8 +231,8 @@ where for _ in 0..def.aux_arg_num { signature = signature.with_param(ValueType::I64); } - if let Some(res) = def.aux_res { - signature = signature.with_result(res); + for ty in def.aux_res { + signature = signature.with_result(ty); } program = signature.build().with_body(body).build(); } @@ -634,6 +634,8 @@ pub mod body { /// Insert a SetGlobal with a random offset in [low, high). /// (low, high) RandomSetGlobal(u32, u32), + /// Insert the specified amount of Drop. + DropRepeated(usize), } pub fn write_access_all_pages_instrs( @@ -726,6 +728,7 @@ pub mod body { DynInstr::RandomSetGlobal(low, high) => { vec![Instruction::SetGlobal(rng.gen_range(*low..*high))] } + DynInstr::DropRepeated(num) => vec![Instruction::Drop; *num], }); head.extend(instr_iter); head diff --git a/pallets/gear/src/benchmarking/mod.rs b/pallets/gear/src/benchmarking/mod.rs index f565967b93b..45f0958bd11 100644 --- a/pallets/gear/src/benchmarking/mod.rs +++ b/pallets/gear/src/benchmarking/mod.rs @@ -1769,7 +1769,7 @@ benchmarks! { let r in 0 .. INSTR_BENCHMARK_BATCHES; let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { aux_body: Some(body::from_instructions(vec![Instruction::I64Const(0x7ffffffff3ffffff)])), - aux_res: Some(ValueType::I64), + aux_res: vec![ValueType::I64], handle_body: Some(body::repeated(r * INSTR_BENCHMARK_BATCH_SIZE, &[ Instruction::Call(OFFSET_AUX), Instruction::Drop, @@ -1840,6 +1840,36 @@ benchmarks! { sbox.invoke(); } + instr_call_indirect_per_result { + let r in 0 .. T::Schedule::get().limits.results; + + #[cfg(not(force_wasmer_cranelift_i_know_what_i_do))] + let _ = r; + + #[cfg(force_wasmer_cranelift_i_know_what_i_do)] + let mut sbox = { + let num_elements = T::Schedule::get().limits.table_size; + Sandbox::from(&WasmModule::::from(ModuleDefinition { + aux_body: Some(body::repeated_dyn(r, vec![RandomI64(0, num_elements as i64)])), + aux_res: vec![ValueType::I64; r as usize], + handle_body: Some(body::repeated_dyn(INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI32(0, num_elements as i32), + Regular(Instruction::CallIndirect(r.min(1), 0)), // aux signature: 1 or 0 + DropRepeated(r as usize), + ])), + table: Some(TableSegment { + num_elements, + function_index: OFFSET_AUX, + init_elements: Default::default(), + }), + .. Default::default() + })) + }; + }: { + #[cfg(force_wasmer_cranelift_i_know_what_i_do)] + sbox.invoke(); + } + // w_per_local = w_bench instr_call_per_local { let l in 0 .. T::Schedule::get().limits.locals; diff --git a/pallets/gear/src/schedule.rs b/pallets/gear/src/schedule.rs index 026773af3a0..a6b0b702870 100644 --- a/pallets/gear/src/schedule.rs +++ b/pallets/gear/src/schedule.rs @@ -190,6 +190,9 @@ pub struct Limits { /// the costs of the instructions that cause them (call, call_indirect). pub parameters: u32, + /// Maximum numbers of parameters a function can have. + pub results: u32, + /// Maximum number of memory pages allowed for a program. pub memory_pages: u16, @@ -275,6 +278,7 @@ pub struct InstructionWeights { pub call: u32, pub call_indirect: u32, pub call_indirect_per_param: u32, + pub call_indirect_per_result: u32, pub call_per_local: u32, pub local_get: u32, pub local_set: u32, @@ -831,6 +835,7 @@ impl Default for Limits { globals: 256, locals: 1024, parameters: 128, + results: 128, memory_pages: MAX_WASM_PAGES_AMOUNT, // 4k function pointers (This is in count not bytes). table_size: 4096, @@ -878,6 +883,7 @@ impl Default for InstructionWeights { call: cost_instr::(W::::instr_call, 2), call_indirect: cost_instr::(W::::instr_call_indirect, 1), call_indirect_per_param: cost_instr::(W::::instr_call_indirect_per_param, 1), + call_indirect_per_result: cost_instr::(W::::instr_call_indirect_per_result, 1), call_per_local: cost_instr::(W::::instr_call_per_local, 1), local_get: cost_instr::(W::::instr_local_get, 0), local_set: cost_instr::(W::::instr_local_set, 1), @@ -1401,7 +1407,7 @@ impl From> for InstantiationCosts { struct ScheduleRules<'a, T: Config> { schedule: &'a Schedule, - params: Vec, + funcs: Vec<(u32, u32)>, } impl<'a, T: Config> Rules for ScheduleRules<'a, T> { @@ -1411,6 +1417,7 @@ impl<'a, T: Config> Rules for ScheduleRules<'a, T> { let w = &self.schedule.instruction_weights; let max_params = self.schedule.limits.parameters; + let max_results = self.schedule.limits.results; let weight = match *instruction { End | Unreachable | Return | Else | Block(_) | Loop(_) | Nop | Drop => 0, @@ -1440,7 +1447,16 @@ impl<'a, T: Config> Rules for ScheduleRules<'a, T> { GetGlobal(_) => w.global_get, SetGlobal(_) => w.global_set, CurrentMemory(_) => w.memory_current, - CallIndirect(idx, _) => *self.params.get(idx as usize).unwrap_or(&max_params), + CallIndirect(idx, _) => { + let (params, results) = self + .funcs + .get(idx as usize) + .copied() + .unwrap_or((max_params, max_results)); + w.call_indirect + .saturating_add(w.call_indirect_per_param.saturating_mul(params)) + .saturating_add(w.call_indirect_per_result.saturating_mul(results)) + } BrTable(ref data) => w .br_table .saturating_add(w.br_table_per_entry.saturating_mul(data.table.len() as u32)), @@ -1532,13 +1548,13 @@ impl Schedule { pub fn rules(&self, module: &Module) -> impl Rules + '_ { ScheduleRules { schedule: self, - params: module + funcs: module .type_section() .iter() .flat_map(|section| section.types()) .map(|func| { let Type::Function(func) = func; - func.params().len() as u32 + (func.params().len() as u32, func.results().len() as u32) }) .collect(), } diff --git a/pallets/gear/src/weights.rs b/pallets/gear/src/weights.rs index b7b8fe10972..260e7925550 100644 --- a/pallets/gear/src/weights.rs +++ b/pallets/gear/src/weights.rs @@ -147,6 +147,7 @@ pub trait WeightInfo { fn instr_call(r: u32, ) -> Weight; fn instr_call_indirect(r: u32, ) -> Weight; fn instr_call_indirect_per_param(p: u32, ) -> Weight; + fn instr_call_indirect_per_result(r: u32, ) -> Weight; fn instr_call_per_local(l: u32, ) -> Weight; fn instr_local_get(r: u32, ) -> Weight; fn instr_local_set(r: u32, ) -> Weight; @@ -1372,6 +1373,16 @@ impl WeightInfo for SubstrateWeight { // Standard Error: 10_999 .saturating_add(Weight::from_parts(685_687 * 110 / 100 /* Adjust slope weight by 10 percent (Patched by script) */, 0).saturating_mul(p.into())) } + /// The range of component `r` is `[0, 128]`. + fn instr_call_indirect_per_result(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(8_845_563, 0) + // Standard Error: 2_496 + .saturating_add(Weight::from_parts(652_462, 0).saturating_mul(r.into())) + } /// The range of component `l` is `[0, 1024]`. fn instr_call_per_local(_l: u32, ) -> Weight { // Proof Size summary in bytes: @@ -3313,6 +3324,16 @@ impl WeightInfo for () { // Standard Error: 10_999 .saturating_add(Weight::from_parts(685_687 * 110 / 100 /* Adjust slope weight by 10 percent (Patched by script) */, 0).saturating_mul(p.into())) } + /// The range of component `r` is `[0, 128]`. + fn instr_call_indirect_per_result(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(8_845_563, 0) + // Standard Error: 2_496 + .saturating_add(Weight::from_parts(652_462, 0).saturating_mul(r.into())) + } /// The range of component `l` is `[0, 1024]`. fn instr_call_per_local(_l: u32, ) -> Weight { // Proof Size summary in bytes: diff --git a/runtime/vara/src/tests.rs b/runtime/vara/src/tests.rs index 9aab1c15c2e..b95afcf2640 100644 --- a/runtime/vara/src/tests.rs +++ b/runtime/vara/src/tests.rs @@ -146,6 +146,7 @@ fn instruction_weights_heuristics_test() { call_per_local: 0, call_indirect: 22_100, call_indirect_per_param: 1_000, + call_indirect_per_result: 1_000, local_get: 900, local_set: 1_900, diff --git a/runtime/vara/src/weights/pallet_gear.rs b/runtime/vara/src/weights/pallet_gear.rs index 43150ed2677..1d3000e4f8b 100644 --- a/runtime/vara/src/weights/pallet_gear.rs +++ b/runtime/vara/src/weights/pallet_gear.rs @@ -147,6 +147,7 @@ pub trait WeightInfo { fn instr_call(r: u32, ) -> Weight; fn instr_call_indirect(r: u32, ) -> Weight; fn instr_call_indirect_per_param(p: u32, ) -> Weight; + fn instr_call_indirect_per_result(r: u32, ) -> Weight; fn instr_call_per_local(l: u32, ) -> Weight; fn instr_local_get(r: u32, ) -> Weight; fn instr_local_set(r: u32, ) -> Weight; @@ -1372,6 +1373,16 @@ impl pallet_gear::WeightInfo for SubstrateWeight { // Standard Error: 10_999 .saturating_add(Weight::from_parts(685_687 * 110 / 100 /* Adjust slope weight by 10 percent (Patched by script) */, 0).saturating_mul(p.into())) } + /// The range of component `r` is `[0, 128]`. + fn instr_call_indirect_per_result(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(8_845_563, 0) + // Standard Error: 2_496 + .saturating_add(Weight::from_parts(652_462, 0).saturating_mul(r.into())) + } /// The range of component `l` is `[0, 1024]`. fn instr_call_per_local(_l: u32, ) -> Weight { // Proof Size summary in bytes: @@ -3313,6 +3324,16 @@ impl WeightInfo for () { // Standard Error: 10_999 .saturating_add(Weight::from_parts(685_687 * 110 / 100 /* Adjust slope weight by 10 percent (Patched by script) */, 0).saturating_mul(p.into())) } + /// The range of component `r` is `[0, 128]`. + fn instr_call_indirect_per_result(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(8_845_563, 0) + // Standard Error: 2_496 + .saturating_add(Weight::from_parts(652_462, 0).saturating_mul(r.into())) + } /// The range of component `l` is `[0, 1024]`. fn instr_call_per_local(_l: u32, ) -> Weight { // Proof Size summary in bytes: diff --git a/sandbox/sandbox/Cargo.toml b/sandbox/sandbox/Cargo.toml index 57f5fa61b36..caa661601ee 100644 --- a/sandbox/sandbox/Cargo.toml +++ b/sandbox/sandbox/Cargo.toml @@ -14,10 +14,12 @@ rust-version.workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] +[lints] +workspace = true + [dependencies] codec.workspace = true log.workspace = true -wasmer = { workspace = true, optional = true } wasmer-types = { workspace = true, optional = true } wasmer-vm = { workspace = true, optional = true } wasmer-compiler = { workspace = true, optional = true } @@ -28,6 +30,12 @@ sp-wasm-interface-common.workspace = true gear-sandbox-interface.workspace = true gear-sandbox-env.workspace = true +[target.'cfg(not(force_wasmer_cranelift_i_know_what_i_do))'.dependencies] +wasmer = { workspace = true, optional = true } + +[target.'cfg(force_wasmer_cranelift_i_know_what_i_do)'.dependencies] +wasmer = { workspace = true, optional = true, features = ["cranelift"] } + [dev-dependencies] assert_matches = "1.3.0" wat = "1.0" diff --git a/sandbox/sandbox/src/embedded_executor.rs b/sandbox/sandbox/src/embedded_executor.rs index 92fec1d85f3..0fe01e5ad4c 100644 --- a/sandbox/sandbox/src/embedded_executor.rs +++ b/sandbox/sandbox/src/embedded_executor.rs @@ -204,7 +204,12 @@ impl Store { impl SandboxStore for Store { fn new(state: T) -> Self { - let mut engine = Engine::from(wasmer::Singlepass::new()); + #[cfg(force_wasmer_cranelift_i_know_what_i_do)] + let compiler = wasmer::Cranelift::new(); + #[cfg(not(force_wasmer_cranelift_i_know_what_i_do))] + let compiler = wasmer::Singlepass::new(); + + let mut engine = Engine::from(compiler); let tunables = CustomTunables::for_target(engine.target()) // make stack size bigger for fuzzer .with_wasm_stack_size(16 * 1024 * 1024); diff --git a/utils/regression-analysis/src/main.rs b/utils/regression-analysis/src/main.rs index 772c4953ee5..28aaaf3c306 100644 --- a/utils/regression-analysis/src/main.rs +++ b/utils/regression-analysis/src/main.rs @@ -399,6 +399,7 @@ fn weights(kind: WeightsKind, input_file: PathBuf, output_file: PathBuf) { call, call_indirect, call_indirect_per_param, + call_indirect_per_result, call_per_local, local_get, local_set, diff --git a/utils/wasm-instrument/Cargo.toml b/utils/wasm-instrument/Cargo.toml index 29980941751..e05cd631283 100644 --- a/utils/wasm-instrument/Cargo.toml +++ b/utils/wasm-instrument/Cargo.toml @@ -17,6 +17,10 @@ gwasm-instrument = { workspace = true, features = ["sign_ext"] } derive_more.workspace = true enum-iterator.workspace = true +# TODO: remove when tooling is updated +# forcely enable features in transitive dependencies like `gwasm-instrument` +gear-wasm = { version = "0.45.1", default-features = false, features = ["sign_ext", "multi_value"] } + [dev-dependencies] wasmparser.workspace = true wat.workspace = true @@ -26,4 +30,5 @@ default = ["std"] std = [ "gwasm-instrument/std", "wasmparser/std", + "gear-wasm/std", ]