mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-01 13:37:23 +00:00
wasm-executor: Support growing the memory (#12520)
* As always, start with something :P * Add support for max_heap_pages * Add support for wasmtime * Make it compile * Fix compilation * Copy wrongly merged code * Fix compilation * Some fixes * Fix * Get stuff working * More work * More fixes * ... * More * FIXEs * Switch wasmi to use `RuntimeBlob` like wasmtime * Removed unused stuff * Cleanup * More cleanups * Introduce `CallContext` * Fixes * More fixes * Add builder for creating the `WasmExecutor` * Adds some docs * FMT * First round of feedback. * Review feedback round 2 * More fixes * Fix try-runtime * Update client/executor/wasmtime/src/instance_wrapper.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/executor/common/src/wasm_runtime.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/executor/common/src/runtime_blob/runtime_blob.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/executor/common/src/wasm_runtime.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/allocator/src/freeing_bump.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Update client/allocator/src/freeing_bump.rs Co-authored-by: Koute <koute@users.noreply.github.com> * Feedback round 3 * FMT * Review comments --------- Co-authored-by: Koute <koute@users.noreply.github.com>
This commit is contained in:
@@ -24,7 +24,7 @@ use codec::{Decode, Encode};
|
||||
use sc_executor_common::{
|
||||
error::{Error, WasmError},
|
||||
runtime_blob::RuntimeBlob,
|
||||
wasm_runtime::WasmModule,
|
||||
wasm_runtime::{HeapAllocStrategy, WasmModule},
|
||||
};
|
||||
use sc_runtime_test::wasm_binary_unwrap;
|
||||
use sp_core::{
|
||||
@@ -52,11 +52,13 @@ macro_rules! test_wasm_execution {
|
||||
paste::item! {
|
||||
#[test]
|
||||
fn [<$method_name _interpreted>]() {
|
||||
let _ = sp_tracing::try_init_simple();
|
||||
$method_name(WasmExecutionMethod::Interpreted);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn [<$method_name _compiled_recreate_instance_cow>]() {
|
||||
let _ = sp_tracing::try_init_simple();
|
||||
$method_name(WasmExecutionMethod::Compiled {
|
||||
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstanceCopyOnWrite
|
||||
});
|
||||
@@ -64,6 +66,7 @@ macro_rules! test_wasm_execution {
|
||||
|
||||
#[test]
|
||||
fn [<$method_name _compiled_recreate_instance_vanilla>]() {
|
||||
let _ = sp_tracing::try_init_simple();
|
||||
$method_name(WasmExecutionMethod::Compiled {
|
||||
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::RecreateInstance
|
||||
});
|
||||
@@ -71,6 +74,7 @@ macro_rules! test_wasm_execution {
|
||||
|
||||
#[test]
|
||||
fn [<$method_name _compiled_pooling_cow>]() {
|
||||
let _ = sp_tracing::try_init_simple();
|
||||
$method_name(WasmExecutionMethod::Compiled {
|
||||
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::PoolingCopyOnWrite
|
||||
});
|
||||
@@ -78,6 +82,7 @@ macro_rules! test_wasm_execution {
|
||||
|
||||
#[test]
|
||||
fn [<$method_name _compiled_pooling_vanilla>]() {
|
||||
let _ = sp_tracing::try_init_simple();
|
||||
$method_name(WasmExecutionMethod::Compiled {
|
||||
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::Pooling
|
||||
});
|
||||
@@ -85,6 +90,7 @@ macro_rules! test_wasm_execution {
|
||||
|
||||
#[test]
|
||||
fn [<$method_name _compiled_legacy_instance_reuse>]() {
|
||||
let _ = sp_tracing::try_init_simple();
|
||||
$method_name(WasmExecutionMethod::Compiled {
|
||||
instantiation_strategy: sc_executor_wasmtime::InstantiationStrategy::LegacyInstanceReuse
|
||||
});
|
||||
@@ -474,7 +480,10 @@ fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) {
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_test_runtime(wasm_method: WasmExecutionMethod, pages: u64) -> Arc<dyn WasmModule> {
|
||||
fn mk_test_runtime(
|
||||
wasm_method: WasmExecutionMethod,
|
||||
pages: HeapAllocStrategy,
|
||||
) -> Arc<dyn WasmModule> {
|
||||
let blob = RuntimeBlob::uncompress_if_needed(wasm_binary_unwrap())
|
||||
.expect("failed to create a runtime blob out of test runtime");
|
||||
|
||||
@@ -490,7 +499,8 @@ fn mk_test_runtime(wasm_method: WasmExecutionMethod, pages: u64) -> Arc<dyn Wasm
|
||||
|
||||
test_wasm_execution!(returns_mutable_static);
|
||||
fn returns_mutable_static(wasm_method: WasmExecutionMethod) {
|
||||
let runtime = mk_test_runtime(wasm_method, 1024);
|
||||
let runtime =
|
||||
mk_test_runtime(wasm_method, HeapAllocStrategy::Dynamic { maximum_pages: Some(1024) });
|
||||
|
||||
let mut instance = runtime.new_instance().unwrap();
|
||||
let res = instance.call_export("returns_mutable_static", &[0]).unwrap();
|
||||
@@ -505,7 +515,8 @@ fn returns_mutable_static(wasm_method: WasmExecutionMethod) {
|
||||
|
||||
test_wasm_execution!(returns_mutable_static_bss);
|
||||
fn returns_mutable_static_bss(wasm_method: WasmExecutionMethod) {
|
||||
let runtime = mk_test_runtime(wasm_method, 1024);
|
||||
let runtime =
|
||||
mk_test_runtime(wasm_method, HeapAllocStrategy::Dynamic { maximum_pages: Some(1024) });
|
||||
|
||||
let mut instance = runtime.new_instance().unwrap();
|
||||
let res = instance.call_export("returns_mutable_static_bss", &[0]).unwrap();
|
||||
@@ -530,9 +541,12 @@ fn restoration_of_globals(wasm_method: WasmExecutionMethod) {
|
||||
//
|
||||
// The fixture performs 2 allocations of 768KB and this theoretically gives 1536KB, however, due
|
||||
// to our allocator algorithm there are inefficiencies.
|
||||
const REQUIRED_MEMORY_PAGES: u64 = 32;
|
||||
const REQUIRED_MEMORY_PAGES: u32 = 32;
|
||||
|
||||
let runtime = mk_test_runtime(wasm_method, REQUIRED_MEMORY_PAGES);
|
||||
let runtime = mk_test_runtime(
|
||||
wasm_method,
|
||||
HeapAllocStrategy::Static { extra_pages: REQUIRED_MEMORY_PAGES },
|
||||
);
|
||||
let mut instance = runtime.new_instance().unwrap();
|
||||
|
||||
// On the first invocation we allocate approx. 768KB (75%) of stack and then trap.
|
||||
@@ -546,7 +560,7 @@ fn restoration_of_globals(wasm_method: WasmExecutionMethod) {
|
||||
|
||||
test_wasm_execution!(interpreted_only heap_is_reset_between_calls);
|
||||
fn heap_is_reset_between_calls(wasm_method: WasmExecutionMethod) {
|
||||
let runtime = mk_test_runtime(wasm_method, 1024);
|
||||
let runtime = mk_test_runtime(wasm_method, HeapAllocStrategy::Static { extra_pages: 1024 });
|
||||
let mut instance = runtime.new_instance().unwrap();
|
||||
|
||||
let heap_base = instance
|
||||
@@ -651,6 +665,15 @@ fn wasm_tracing_should_work(wasm_method: WasmExecutionMethod) {
|
||||
assert_eq!(len, 2);
|
||||
}
|
||||
|
||||
test_wasm_execution!(allocate_two_gigabyte);
|
||||
fn allocate_two_gigabyte(wasm_method: WasmExecutionMethod) {
|
||||
let runtime = mk_test_runtime(wasm_method, HeapAllocStrategy::Dynamic { maximum_pages: None });
|
||||
|
||||
let mut instance = runtime.new_instance().unwrap();
|
||||
let res = instance.call_export("allocate_two_gigabyte", &[0]).unwrap();
|
||||
assert_eq!(10 * 1024 * 1024 * 205, u32::decode(&mut &res[..]).unwrap());
|
||||
}
|
||||
|
||||
test_wasm_execution!(memory_is_cleared_between_invocations);
|
||||
fn memory_is_cleared_between_invocations(wasm_method: WasmExecutionMethod) {
|
||||
// This is based on the code generated by compiling a runtime *without*
|
||||
@@ -713,7 +736,7 @@ fn memory_is_cleared_between_invocations(wasm_method: WasmExecutionMethod) {
|
||||
|
||||
let runtime = crate::wasm_runtime::create_wasm_runtime_with_code::<HostFunctions>(
|
||||
wasm_method,
|
||||
1024,
|
||||
HeapAllocStrategy::Dynamic { maximum_pages: Some(1024) },
|
||||
RuntimeBlob::uncompress_if_needed(&binary[..]).unwrap(),
|
||||
true,
|
||||
None,
|
||||
|
||||
Reference in New Issue
Block a user