From 12645282fe2f4b194f3c96524efbf07cc55a514c Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Sun, 2 Oct 2022 14:07:02 +0200 Subject: [PATCH 1/3] Implement `Clone` and `Default` for `Config` --- client/executor/wasmtime/src/runtime.rs | 62 +++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index 5925a1792aef2..40f93c4b30f3c 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -544,6 +544,7 @@ pub struct Semantics { pub max_memory_size: Option, } +#[derive(Clone)] pub struct Config { /// The WebAssembly standard requires all imports of an instantiated module to be resolved, /// otherwise, the instantiation fails. If this option is set to `true`, then this behavior is @@ -558,6 +559,67 @@ pub struct Config { pub semantics: Semantics, } +// Memory configuration +// +// When Substrate Runtime is instantiated, a number of WASM pages are allocated for the Substrate +// Runtime instance's linear memory. The exact number of pages is a sum of whatever the WASM blob +// itself requests (by default at least enough to hold the data section as well as have some space +// left for the stack; this is, of course, overridable at link time when compiling the runtime) +// plus the number of pages specified in the `extra_heap_pages` passed to the executor. +// +// By default, rustc (or `lld` specifically) should allocate 1 MiB for the shadow stack, or 16 pages. +// The data section for runtimes are typically rather small and can fit in a single digit number of +// WASM pages, so let's say an extra 16 pages. Thus let's assume that 32 pages or 2 MiB are used for +// these needs by default. +const DEFAULT_HEAP_PAGES_ESTIMATE: u64 = 32; +const EXTRA_HEAP_PAGES: u64 = 2048; + +/// The number of bytes devoted for the stack during wasm execution of a PVF. +const NATIVE_STACK_MAX: u32 = 256 * 1024 * 1024; + +impl Default for Config { + fn default() -> Self { + Config { + allow_missing_func_imports: true, + cache_path: None, + semantics: Semantics { + extra_heap_pages: EXTRA_HEAP_PAGES, + + // NOTE: This is specified in bytes, so we multiply by WASM page size. + max_memory_size: Some(((DEFAULT_HEAP_PAGES_ESTIMATE + EXTRA_HEAP_PAGES) * 65536) as usize), + + instantiation_strategy: + InstantiationStrategy::RecreateInstanceCopyOnWrite, + + // Enable deterministic stack limit to pin down the exact number of items the wasmtime stack + // can contain before it traps with stack overflow. + // + // Here is how the values below were chosen. + // + // At the moment of writing, the default native stack size limit is 1 MiB. Assuming a logical item + // (see the docs about the field and the instrumentation algorithm) is 8 bytes, 1 MiB can + // fit 2x 65536 logical items. + // + // Since reaching the native stack limit is undesirable, we halve the logical item limit and + // also increase the native 256x. This hopefully should preclude wasm code from reaching + // the stack limit set by the wasmtime. + deterministic_stack_limit: Some(DeterministicStackLimit { + logical_max: 65536, + native_stack_max: NATIVE_STACK_MAX, + }), + canonicalize_nans: true, + // Rationale for turning the multi-threaded compilation off is to make the preparation time + // easily reproducible and as deterministic as possible. + // + // Currently the prepare queue doesn't distinguish between precheck and prepare requests. + // On the one hand, it simplifies the code, on the other, however, slows down compile times + // for execute requests. This behavior may change in future. + parallel_compilation: false, + }, + } + } +} + enum CodeSupplyMode<'a> { /// The runtime is instantiated using the given runtime blob. Fresh(RuntimeBlob), From cc0c4fc81df569b7b2d3c37017eb67a6a7881025 Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Sun, 2 Oct 2022 18:10:47 +0200 Subject: [PATCH 2/3] `cargo fmt` --- client/executor/wasmtime/src/runtime.rs | 41 +++++++++++++------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index 40f93c4b30f3c..fdd7ef41c6054 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -567,10 +567,10 @@ pub struct Config { // left for the stack; this is, of course, overridable at link time when compiling the runtime) // plus the number of pages specified in the `extra_heap_pages` passed to the executor. // -// By default, rustc (or `lld` specifically) should allocate 1 MiB for the shadow stack, or 16 pages. -// The data section for runtimes are typically rather small and can fit in a single digit number of -// WASM pages, so let's say an extra 16 pages. Thus let's assume that 32 pages or 2 MiB are used for -// these needs by default. +// By default, rustc (or `lld` specifically) should allocate 1 MiB for the shadow stack, or 16 +// pages. The data section for runtimes are typically rather small and can fit in a single digit +// number of WASM pages, so let's say an extra 16 pages. Thus let's assume that 32 pages or 2 MiB +// are used for these needs by default. const DEFAULT_HEAP_PAGES_ESTIMATE: u64 = 32; const EXTRA_HEAP_PAGES: u64 = 2048; @@ -586,34 +586,35 @@ impl Default for Config { extra_heap_pages: EXTRA_HEAP_PAGES, // NOTE: This is specified in bytes, so we multiply by WASM page size. - max_memory_size: Some(((DEFAULT_HEAP_PAGES_ESTIMATE + EXTRA_HEAP_PAGES) * 65536) as usize), + max_memory_size: Some( + ((DEFAULT_HEAP_PAGES_ESTIMATE + EXTRA_HEAP_PAGES) * 65536) as usize, + ), - instantiation_strategy: - InstantiationStrategy::RecreateInstanceCopyOnWrite, + instantiation_strategy: InstantiationStrategy::RecreateInstanceCopyOnWrite, - // Enable deterministic stack limit to pin down the exact number of items the wasmtime stack - // can contain before it traps with stack overflow. + // Enable deterministic stack limit to pin down the exact number of items the + // wasmtime stack can contain before it traps with stack overflow. // // Here is how the values below were chosen. // - // At the moment of writing, the default native stack size limit is 1 MiB. Assuming a logical item - // (see the docs about the field and the instrumentation algorithm) is 8 bytes, 1 MiB can - // fit 2x 65536 logical items. + // At the moment of writing, the default native stack size limit is 1 MiB. Assuming + // a logical item (see the docs about the field and the instrumentation algorithm) + // is 8 bytes, 1 MiB can fit 2x 65536 logical items. // - // Since reaching the native stack limit is undesirable, we halve the logical item limit and - // also increase the native 256x. This hopefully should preclude wasm code from reaching - // the stack limit set by the wasmtime. + // Since reaching the native stack limit is undesirable, we halve the logical item + // limit and also increase the native 256x. This hopefully should preclude wasm code + // from reaching the stack limit set by the wasmtime. deterministic_stack_limit: Some(DeterministicStackLimit { logical_max: 65536, native_stack_max: NATIVE_STACK_MAX, }), canonicalize_nans: true, - // Rationale for turning the multi-threaded compilation off is to make the preparation time - // easily reproducible and as deterministic as possible. + // Rationale for turning the multi-threaded compilation off is to make the + // preparation time easily reproducible and as deterministic as possible. // - // Currently the prepare queue doesn't distinguish between precheck and prepare requests. - // On the one hand, it simplifies the code, on the other, however, slows down compile times - // for execute requests. This behavior may change in future. + // Currently the prepare queue doesn't distinguish between precheck and prepare + // requests. On the one hand, it simplifies the code, on the other, however, slows + // down compile times for execute requests. This behavior may change in future. parallel_compilation: false, }, } From 1a35808cb2c05d1cefe02c6e372f0b951d2e7a04 Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Wed, 5 Oct 2022 16:12:59 +0200 Subject: [PATCH 3/3] Remove default config implementation --- client/executor/wasmtime/src/runtime.rs | 62 ------------------------- 1 file changed, 62 deletions(-) diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index fdd7ef41c6054..e3509351022bc 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -559,68 +559,6 @@ pub struct Config { pub semantics: Semantics, } -// Memory configuration -// -// When Substrate Runtime is instantiated, a number of WASM pages are allocated for the Substrate -// Runtime instance's linear memory. The exact number of pages is a sum of whatever the WASM blob -// itself requests (by default at least enough to hold the data section as well as have some space -// left for the stack; this is, of course, overridable at link time when compiling the runtime) -// plus the number of pages specified in the `extra_heap_pages` passed to the executor. -// -// By default, rustc (or `lld` specifically) should allocate 1 MiB for the shadow stack, or 16 -// pages. The data section for runtimes are typically rather small and can fit in a single digit -// number of WASM pages, so let's say an extra 16 pages. Thus let's assume that 32 pages or 2 MiB -// are used for these needs by default. -const DEFAULT_HEAP_PAGES_ESTIMATE: u64 = 32; -const EXTRA_HEAP_PAGES: u64 = 2048; - -/// The number of bytes devoted for the stack during wasm execution of a PVF. -const NATIVE_STACK_MAX: u32 = 256 * 1024 * 1024; - -impl Default for Config { - fn default() -> Self { - Config { - allow_missing_func_imports: true, - cache_path: None, - semantics: Semantics { - extra_heap_pages: EXTRA_HEAP_PAGES, - - // NOTE: This is specified in bytes, so we multiply by WASM page size. - max_memory_size: Some( - ((DEFAULT_HEAP_PAGES_ESTIMATE + EXTRA_HEAP_PAGES) * 65536) as usize, - ), - - instantiation_strategy: InstantiationStrategy::RecreateInstanceCopyOnWrite, - - // Enable deterministic stack limit to pin down the exact number of items the - // wasmtime stack can contain before it traps with stack overflow. - // - // Here is how the values below were chosen. - // - // At the moment of writing, the default native stack size limit is 1 MiB. Assuming - // a logical item (see the docs about the field and the instrumentation algorithm) - // is 8 bytes, 1 MiB can fit 2x 65536 logical items. - // - // Since reaching the native stack limit is undesirable, we halve the logical item - // limit and also increase the native 256x. This hopefully should preclude wasm code - // from reaching the stack limit set by the wasmtime. - deterministic_stack_limit: Some(DeterministicStackLimit { - logical_max: 65536, - native_stack_max: NATIVE_STACK_MAX, - }), - canonicalize_nans: true, - // Rationale for turning the multi-threaded compilation off is to make the - // preparation time easily reproducible and as deterministic as possible. - // - // Currently the prepare queue doesn't distinguish between precheck and prepare - // requests. On the one hand, it simplifies the code, on the other, however, slows - // down compile times for execute requests. This behavior may change in future. - parallel_compilation: false, - }, - } - } -} - enum CodeSupplyMode<'a> { /// The runtime is instantiated using the given runtime blob. Fresh(RuntimeBlob),