From e2d13b0f35dc2d249b15368eb1825087990e9fc3 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Thu, 7 Sep 2023 18:15:58 +0800 Subject: [PATCH 01/10] allocator-v1 --- Cargo.lock | 21 +++++++ Cargo.toml | 1 + .../bin/node-template/runtime/Cargo.toml | 5 ++ substrate/bin/node-template/runtime/build.rs | 1 + .../bin/node-template/runtime/src/lib.rs | 2 + substrate/primitives/allocator-v1/Cargo.toml | 33 ++++++++++ .../primitives/allocator-v1/src/config.rs | 61 +++++++++++++++++++ substrate/primitives/allocator-v1/src/lib.rs | 30 +++++++++ 8 files changed, 154 insertions(+) create mode 100644 substrate/primitives/allocator-v1/Cargo.toml create mode 100644 substrate/primitives/allocator-v1/src/config.rs create mode 100644 substrate/primitives/allocator-v1/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 2fff57879891..83590ccd2e82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7589,6 +7589,15 @@ dependencies = [ "value-bag", ] +[[package]] +name = "lol_alloc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36aabc32b791f1a506e0bb90e0fa03e983500549d7b1f2dad45b5fc20ef45974" +dependencies = [ + "spin 0.9.8", +] + [[package]] name = "lru" version = "0.8.1" @@ -8492,6 +8501,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", + "sp-allocator-v1", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -16677,6 +16687,14 @@ dependencies = [ "sha-1 0.9.8", ] +[[package]] +name = "sp-allocator-v1" +version = "7.0.0" +dependencies = [ + "lol_alloc", + "sp-io", +] + [[package]] name = "sp-api" version = "4.0.0-dev" @@ -17665,6 +17683,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spinners" diff --git a/Cargo.toml b/Cargo.toml index 4db27b98e907..e7fa687af7f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -369,6 +369,7 @@ members = [ "substrate/frame/utility", "substrate/frame/vesting", "substrate/frame/whitelist", + "substrate/primitives/allocator-v1", "substrate/primitives/api", "substrate/primitives/api/proc-macro", "substrate/primitives/api/test", diff --git a/substrate/bin/node-template/runtime/Cargo.toml b/substrate/bin/node-template/runtime/Cargo.toml index 65d0cfca59c4..84bac0aa17db 100644 --- a/substrate/bin/node-template/runtime/Cargo.toml +++ b/substrate/bin/node-template/runtime/Cargo.toml @@ -26,6 +26,7 @@ frame-try-runtime = { path = "../../../frame/try-runtime", default-features = fa pallet-timestamp = { path = "../../../frame/timestamp", default-features = false} pallet-transaction-payment = { path = "../../../frame/transaction-payment", default-features = false} frame-executive = { path = "../../../frame/executive", default-features = false} +sp-allocator-v1 = { default-features = false, path = "../../../primitives/allocator-v1" } sp-api = { path = "../../../primitives/api", default-features = false} sp-block-builder = { path = "../../../primitives/block-builder", default-features = false} sp-consensus-aura = { path = "../../../primitives/consensus/aura", default-features = false} @@ -56,6 +57,9 @@ substrate-wasm-builder = { path = "../../../utils/wasm-builder", optional = true [features] default = [ "std" ] +allocator-v1 = [ + "sp-allocator-v1/allocator-v1", +] std = [ "codec/std", "frame-benchmarking?/std", @@ -74,6 +78,7 @@ std = [ "pallet-transaction-payment-rpc-runtime-api/std", "pallet-transaction-payment/std", "scale-info/std", + "sp-allocator-v1/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", diff --git a/substrate/bin/node-template/runtime/build.rs b/substrate/bin/node-template/runtime/build.rs index c03d618535be..3f1d9bfc455d 100644 --- a/substrate/bin/node-template/runtime/build.rs +++ b/substrate/bin/node-template/runtime/build.rs @@ -5,6 +5,7 @@ fn main() { .with_current_project() .export_heap_base() .import_memory() + .enable_feature("allocator-v1") .build(); } } diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 216be9588bca..e69bed704efb 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -6,6 +6,8 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +extern crate sp_allocator_v1; + use pallet_grandpa::AuthorityId as GrandpaId; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; diff --git a/substrate/primitives/allocator-v1/Cargo.toml b/substrate/primitives/allocator-v1/Cargo.toml new file mode 100644 index 000000000000..75573f2b3d01 --- /dev/null +++ b/substrate/primitives/allocator-v1/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "sp-allocator-v1" +version = "7.0.0" +authors = ["Parity Technologies "] +edition = "2021" +license = "Apache-2.0" +homepage = "https://substrate.io" +repository = "https://github.com/paritytech/substrate/" +description = "I/O for Substrate runtimes" +documentation = "https://docs.rs/sp-io" +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +lol_alloc = { version = "0.4", optional = true } + +# not used just enable feature +sp-io = { path = "../io", default-features = false } + +[features] +default = ["std"] +std = [ + "sp-io/std", +] + +allocator-v1 = [ + "lol_alloc", + "sp-io/disable_allocator", + "sp-io/disable_panic_handler", + "sp-io/disable_oom", +] diff --git a/substrate/primitives/allocator-v1/src/config.rs b/substrate/primitives/allocator-v1/src/config.rs new file mode 100644 index 000000000000..2d834aafffdb --- /dev/null +++ b/substrate/primitives/allocator-v1/src/config.rs @@ -0,0 +1,61 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use core::alloc::GlobalAlloc; +use lol_alloc::{AssumeSingleThreaded, FreeListAllocator}; + +#[global_allocator] +pub static ALLOCATOR: AssumeSingleThreaded = + unsafe { AssumeSingleThreaded::new(FreeListAllocator::new()) }; + +#[no_mangle] +unsafe fn alloc(size: usize) -> *mut u8 { + ALLOCATOR.alloc(core::alloc::Layout::array::(size).unwrap()) +} + +#[no_mangle] +unsafe fn dealloc(ptr: *mut u8, size: usize) { + ALLOCATOR.dealloc(ptr, core::alloc::Layout::array::(size).unwrap()) +} + +#[no_mangle] +unsafe fn realloc(ptr: *mut u8, size: usize, new_size: usize) -> *mut u8 { + ALLOCATOR.realloc(ptr, core::alloc::Layout::array::(size).unwrap(), new_size) +} + +// TODO: maybe it's better to rename this crate to `sp-runtime-abi`. +/// The dummy function represents the version of runtime ABI. +#[no_mangle] +fn v1() { + // nop +} + +// TODO +/// A default panic handler for WASM environment. +#[cfg(all(not(feature = "disable_panic_handler"), not(feature = "std")))] +#[panic_handler] +#[no_mangle] +pub fn panic(_info: &core::panic::PanicInfo) -> ! { + core::arch::wasm32::unreachable() +} + +/// A default OOM handler for WASM environment. +#[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))] +#[alloc_error_handler] +pub fn oom(_layout: core::alloc::Layout) -> ! { + core::arch::wasm32::unreachable() +} diff --git a/substrate/primitives/allocator-v1/src/lib.rs b/substrate/primitives/allocator-v1/src/lib.rs new file mode 100644 index 000000000000..db25ff91abb6 --- /dev/null +++ b/substrate/primitives/allocator-v1/src/lib.rs @@ -0,0 +1,30 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! # V1 spec about runtime abi +//! +//! Export the `alloc`/`dealloc`/`realloc` primitive functions inside the runtime to host. +//! +//! In runtime crate, must use the following sp-io features: +//! - disable_allocator +//! - disable_panic_handler +//! - disable_oom +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(enable_alloc_error_handler, feature(alloc_error_handler))] + +#[cfg(all(feature = "allocator-v1", not(feature = "std")))] +pub mod config; From dac17299a78dc4090928389e73f51a1a81024639 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Thu, 7 Sep 2023 18:18:55 +0800 Subject: [PATCH 02/10] improve --- .../primitives/allocator-v1/src/config.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/substrate/primitives/allocator-v1/src/config.rs b/substrate/primitives/allocator-v1/src/config.rs index 2d834aafffdb..51ba66884257 100644 --- a/substrate/primitives/allocator-v1/src/config.rs +++ b/substrate/primitives/allocator-v1/src/config.rs @@ -27,15 +27,15 @@ unsafe fn alloc(size: usize) -> *mut u8 { ALLOCATOR.alloc(core::alloc::Layout::array::(size).unwrap()) } -#[no_mangle] -unsafe fn dealloc(ptr: *mut u8, size: usize) { - ALLOCATOR.dealloc(ptr, core::alloc::Layout::array::(size).unwrap()) -} - -#[no_mangle] -unsafe fn realloc(ptr: *mut u8, size: usize, new_size: usize) -> *mut u8 { - ALLOCATOR.realloc(ptr, core::alloc::Layout::array::(size).unwrap(), new_size) -} +// #[no_mangle] +// unsafe fn dealloc(ptr: *mut u8, size: usize) { +// ALLOCATOR.dealloc(ptr, core::alloc::Layout::array::(size).unwrap()) +// } +// +// #[no_mangle] +// unsafe fn realloc(ptr: *mut u8, size: usize, new_size: usize) -> *mut u8 { +// ALLOCATOR.realloc(ptr, core::alloc::Layout::array::(size).unwrap(), new_size) +// } // TODO: maybe it's better to rename this crate to `sp-runtime-abi`. /// The dummy function represents the version of runtime ABI. @@ -44,7 +44,7 @@ fn v1() { // nop } -// TODO +// TODO: design a better error message for panic. /// A default panic handler for WASM environment. #[cfg(all(not(feature = "disable_panic_handler"), not(feature = "std")))] #[panic_handler] From f7661a6714c24417bc6e468e5b9d09638f5db9e2 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Fri, 8 Sep 2023 11:29:54 +0800 Subject: [PATCH 03/10] try to impl executor --- Cargo.lock | 1 + .../bin/node-template/runtime/src/lib.rs | 2 +- .../client/executor/wasmtime/src/host.rs | 46 +++++++----- .../executor/wasmtime/src/instance_wrapper.rs | 15 +++- .../client/executor/wasmtime/src/runtime.rs | 71 ++++++++++++++++--- substrate/primitives/allocator-v1/Cargo.toml | 7 +- .../primitives/allocator-v1/src/config.rs | 24 ++++++- 7 files changed, 133 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83590ccd2e82..88381ba971fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16693,6 +16693,7 @@ version = "7.0.0" dependencies = [ "lol_alloc", "sp-io", + "sp-std", ] [[package]] diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index e69bed704efb..61215b4cb32b 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -6,7 +6,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -extern crate sp_allocator_v1; +pub use sp_allocator_v1 as _; use pallet_grandpa::AuthorityId as GrandpaId; use sp_api::impl_runtime_apis; diff --git a/substrate/client/executor/wasmtime/src/host.rs b/substrate/client/executor/wasmtime/src/host.rs index 9bd3ca3dade5..baebf64671dd 100644 --- a/substrate/client/executor/wasmtime/src/host.rs +++ b/substrate/client/executor/wasmtime/src/host.rs @@ -19,7 +19,7 @@ //! This module defines `HostState` and `HostContext` structs which provide logic and state //! required for execution of host. -use wasmtime::Caller; +use wasmtime::{AsContextMut, Caller, Val}; use sc_allocator::{AllocationStats, FreeingBumpHeapAllocator}; use sp_wasm_interface::{Pointer, WordSize}; @@ -41,8 +41,8 @@ pub struct HostState { impl HostState { /// Constructs a new `HostState`. - pub fn new(allocator: FreeingBumpHeapAllocator) -> Self { - HostState { allocator: Some(allocator), panic_message: None } + pub fn new(allocator: Option) -> Self { + HostState { allocator, panic_message: None } } /// Takes the error message out of the host state, leaving a `None` in its place. @@ -88,23 +88,35 @@ impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> { fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result> { let memory = self.caller.data().memory(); - let mut allocator = self - .host_state_mut() - .allocator - .take() - .expect("allocator is not empty when calling a function in wasm; qed"); - - // We can not return on error early, as we need to store back allocator. - let res = allocator - .allocate(&mut MemoryWrapper(&memory, &mut self.caller), size) - .map_err(|e| e.to_string()); - - self.host_state_mut().allocator = Some(allocator); - - res + if let Some(alloc) = self.caller.data().alloc { + let params = [Val::I32(size as i32)]; + let mut results = [Val::I32(0)]; + + alloc.call(self.caller.as_context_mut(), ¶ms, &mut results); + let data_ptr = results[0].i32().unwrap(); + let data_ptr = Pointer::new( data_ptr as u32); + + Ok(data_ptr) + } else { + let mut allocator = self + .host_state_mut() + .allocator + .take() + .expect("allocator is not empty when calling a function in wasm; qed"); + + // We can not return on error early, as we need to store back allocator. + let res = allocator + .allocate(&mut MemoryWrapper(&memory, &mut self.caller), size) + .map_err(|e| e.to_string()); + + self.host_state_mut().allocator = Some(allocator); + + res + } } fn deallocate_memory(&mut self, ptr: Pointer) -> sp_wasm_interface::Result<()> { + log::info!("deallocate_memory"); let memory = self.caller.data().memory(); let mut allocator = self .host_state_mut() diff --git a/substrate/client/executor/wasmtime/src/instance_wrapper.rs b/substrate/client/executor/wasmtime/src/instance_wrapper.rs index 6d319cce509e..c9bda7450a69 100644 --- a/substrate/client/executor/wasmtime/src/instance_wrapper.rs +++ b/substrate/client/executor/wasmtime/src/instance_wrapper.rs @@ -25,9 +25,7 @@ use sc_executor_common::{ wasm_runtime::InvokeMethod, }; use sp_wasm_interface::{Pointer, Value, WordSize}; -use wasmtime::{ - AsContext, AsContextMut, Engine, Extern, Instance, InstancePre, Memory, Table, Val, -}; +use wasmtime::{AsContext, AsContextMut, Engine, Extern, Func, Instance, InstancePre, Memory, Table, Val}; /// Invoked entrypoint format. pub enum EntryPointType { @@ -82,8 +80,10 @@ impl EntryPoint { }); if let Some(message) = host_state.take_panic_message() { + // todo!("1"); Error::AbortedDueToPanic(MessageWithBacktrace { message, backtrace }) } else { + // todo!("2"); let message = trap.root_cause().to_string(); Error::AbortedDueToTrap(MessageWithBacktrace { message, backtrace }) } @@ -173,9 +173,11 @@ impl InstanceWrapper { let memory = get_linear_memory(&instance, &mut store)?; let table = get_table(&instance, &mut store); + let alloc = get_export_alloc(&instance, &mut store); store.data_mut().memory = Some(memory); store.data_mut().table = table; + store.data_mut().alloc = alloc; Ok(InstanceWrapper { instance, memory, store }) } @@ -309,6 +311,13 @@ fn get_table(instance: &Instance, ctx: &mut Store) -> Option { .and_then(Extern::into_table) } +/// Extract export `alloc` func from the given instance. +fn get_export_alloc(instance: &Instance, ctx: impl AsContextMut) -> Option { + instance + .get_export(ctx, "alloc") + .and_then(Extern::into_func) +} + /// Functions related to memory. impl InstanceWrapper { /// Returns the pointer to the first byte of the linear memory for this instance. diff --git a/substrate/client/executor/wasmtime/src/runtime.rs b/substrate/client/executor/wasmtime/src/runtime.rs index 23b069870aa3..cd12c52a282d 100644 --- a/substrate/client/executor/wasmtime/src/runtime.rs +++ b/substrate/client/executor/wasmtime/src/runtime.rs @@ -42,7 +42,7 @@ use std::{ Arc, }, }; -use wasmtime::{AsContext, Engine, Memory, Table}; +use wasmtime::{AsContext, Engine, Func, Memory, Table, Val}; #[derive(Default)] pub(crate) struct StoreData { @@ -52,6 +52,8 @@ pub(crate) struct StoreData { pub(crate) memory: Option, /// This will be set only if the runtime actually contains a table. pub(crate) table: Option
, + /// This will be set only if the runtime actually contains a table. + pub(crate) alloc: Option, } impl StoreData { @@ -190,10 +192,13 @@ impl WasmtimeInstance { ) })?; globals_snapshot.apply(&mut InstanceGlobals { instance: instance_wrapper }); - let allocator = FreeingBumpHeapAllocator::new(*heap_base); - let result = - perform_call(data, instance_wrapper, entrypoint, allocator, allocation_stats); + let result = if let Some(alloc) = instance_wrapper.store().data().alloc { + perform_call_v1(data, instance_wrapper, entrypoint, alloc) + } else { + let allocator = FreeingBumpHeapAllocator::new(*heap_base); + perform_call(data, instance_wrapper, entrypoint, allocator, allocation_stats) + }; // Signal to the OS that we are done with the linear memory and that it can be // reclaimed. @@ -203,11 +208,15 @@ impl WasmtimeInstance { }, Strategy::RecreateInstance(ref mut instance_creator) => { let mut instance_wrapper = instance_creator.instantiate()?; - let heap_base = instance_wrapper.extract_heap_base()?; let entrypoint = instance_wrapper.resolve_entrypoint(method)?; - let allocator = FreeingBumpHeapAllocator::new(heap_base); - perform_call(data, &mut instance_wrapper, entrypoint, allocator, allocation_stats) + if let Some(alloc) = instance_wrapper.store().data().alloc { + perform_call_v1(data, &mut instance_wrapper, entrypoint, alloc) + } else { + let heap_base = instance_wrapper.extract_heap_base()?; + let allocator = FreeingBumpHeapAllocator::new(heap_base); + perform_call(data, &mut instance_wrapper, entrypoint, allocator, allocation_stats) + } }, } } @@ -775,7 +784,7 @@ fn perform_call( ) -> Result> { let (data_ptr, data_len) = inject_input_data(instance_wrapper, &mut allocator, data)?; - let host_state = HostState::new(allocator); + let host_state = HostState::new(Some(allocator)); // Set the host state before calling into wasm. instance_wrapper.store_mut().data_mut().host_state = Some(host_state); @@ -796,6 +805,36 @@ fn perform_call( Ok(output) } +fn perform_call_v1( + data: &[u8], + instance_wrapper: &mut InstanceWrapper, + entrypoint: EntryPoint, + alloc: Func, + // allocation_stats: &mut Option, +) -> Result> { + let (data_ptr, data_len) = inject_input_data_v1(instance_wrapper, alloc, data)?; + + let host_state = HostState::new(None); + + // Set the host state before calling into wasm. + instance_wrapper.store_mut().data_mut().host_state = Some(host_state); + + let ret = entrypoint + .call(instance_wrapper.store_mut(), data_ptr, data_len) + .map(unpack_ptr_and_len); + + // Reset the host state + let host_state = instance_wrapper.store_mut().data_mut().host_state.take().expect( + "the host state is always set before calling into WASM so it can't be None here; qed", + ); + // *allocation_stats = Some(host_state.allocation_stats()); + + let (output_ptr, output_len) = ret?; + let output = extract_output_data(instance_wrapper, output_ptr, output_len)?; + + Ok(output) +} + fn inject_input_data( instance: &mut InstanceWrapper, allocator: &mut FreeingBumpHeapAllocator, @@ -809,6 +848,22 @@ fn inject_input_data( Ok((data_ptr, data_len)) } +fn inject_input_data_v1( + instance: &mut InstanceWrapper, + alloc: Func, + data: &[u8], +) -> Result<(Pointer, WordSize)> { + let data_len = data.len() as WordSize; + let params = [Val::I32(data_len as _ )]; + let mut results = [Val::I32(0)]; + + alloc.call(instance.store_mut(), ¶ms, &mut results).expect("alloc must success; qed"); + let data_ptr = results[0].i32().unwrap(); + let data_ptr = Pointer::new( data_ptr as u32); + util::write_memory_from(instance.store_mut(), data_ptr, data)?; + Ok((data_ptr, data_len)) +} + fn extract_output_data( instance: &InstanceWrapper, output_ptr: u32, diff --git a/substrate/primitives/allocator-v1/Cargo.toml b/substrate/primitives/allocator-v1/Cargo.toml index 75573f2b3d01..921b1013b7e4 100644 --- a/substrate/primitives/allocator-v1/Cargo.toml +++ b/substrate/primitives/allocator-v1/Cargo.toml @@ -18,15 +18,20 @@ lol_alloc = { version = "0.4", optional = true } # not used just enable feature sp-io = { path = "../io", default-features = false } +sp-std = { path = "../std", default-features = false } [features] default = ["std"] std = [ "sp-io/std", + "sp-std/std", ] +improved_panic_error_reporting = [] + allocator-v1 = [ - "lol_alloc", + "dep:lol_alloc", + "improved_panic_error_reporting", "sp-io/disable_allocator", "sp-io/disable_panic_handler", "sp-io/disable_oom", diff --git a/substrate/primitives/allocator-v1/src/config.rs b/substrate/primitives/allocator-v1/src/config.rs index 51ba66884257..633206561338 100644 --- a/substrate/primitives/allocator-v1/src/config.rs +++ b/substrate/primitives/allocator-v1/src/config.rs @@ -49,13 +49,31 @@ fn v1() { #[cfg(all(not(feature = "disable_panic_handler"), not(feature = "std")))] #[panic_handler] #[no_mangle] -pub fn panic(_info: &core::panic::PanicInfo) -> ! { - core::arch::wasm32::unreachable() +pub fn panic(info: &core::panic::PanicInfo) -> ! { + let message = sp_std::alloc::format!("{}", info); + #[cfg(feature = "improved_panic_error_reporting")] + { + sp_io::panic_handler::abort_on_panic(&message); + } + #[cfg(not(feature = "improved_panic_error_reporting"))] + { + sp_io::logging::log(LogLevel::Error, "runtime", message.as_bytes()); + core::arch::wasm32::unreachable(); + } } + /// A default OOM handler for WASM environment. #[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))] #[alloc_error_handler] pub fn oom(_layout: core::alloc::Layout) -> ! { - core::arch::wasm32::unreachable() + #[cfg(feature = "improved_panic_error_reporting")] + { + panic_handler::abort_on_panic("Runtime memory exhausted."); + } + #[cfg(not(feature = "improved_panic_error_reporting"))] + { + sp_io::logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); + core::arch::wasm32::unreachable(); + } } From 89c6a2e9b5986f9239e890dfa344d547fd808632 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Fri, 8 Sep 2023 12:14:04 +0800 Subject: [PATCH 04/10] wip --- .../client/executor/wasmtime/src/runtime.rs | 8 +++---- substrate/primitives/allocator-v1/Cargo.toml | 1 - .../primitives/allocator-v1/src/config.rs | 23 ++++++++++--------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/substrate/client/executor/wasmtime/src/runtime.rs b/substrate/client/executor/wasmtime/src/runtime.rs index cd12c52a282d..5693c87c2839 100644 --- a/substrate/client/executor/wasmtime/src/runtime.rs +++ b/substrate/client/executor/wasmtime/src/runtime.rs @@ -209,8 +209,8 @@ impl WasmtimeInstance { Strategy::RecreateInstance(ref mut instance_creator) => { let mut instance_wrapper = instance_creator.instantiate()?; let entrypoint = instance_wrapper.resolve_entrypoint(method)?; - if let Some(alloc) = instance_wrapper.store().data().alloc { + println!("RecreateInstance: alloc: {:?}", alloc); perform_call_v1(data, &mut instance_wrapper, entrypoint, alloc) } else { let heap_base = instance_wrapper.extract_heap_base()?; @@ -810,7 +810,6 @@ fn perform_call_v1( instance_wrapper: &mut InstanceWrapper, entrypoint: EntryPoint, alloc: Func, - // allocation_stats: &mut Option, ) -> Result> { let (data_ptr, data_len) = inject_input_data_v1(instance_wrapper, alloc, data)?; @@ -827,8 +826,6 @@ fn perform_call_v1( let host_state = instance_wrapper.store_mut().data_mut().host_state.take().expect( "the host state is always set before calling into WASM so it can't be None here; qed", ); - // *allocation_stats = Some(host_state.allocation_stats()); - let (output_ptr, output_len) = ret?; let output = extract_output_data(instance_wrapper, output_ptr, output_len)?; @@ -855,12 +852,13 @@ fn inject_input_data_v1( ) -> Result<(Pointer, WordSize)> { let data_len = data.len() as WordSize; let params = [Val::I32(data_len as _ )]; - let mut results = [Val::I32(0)]; + let mut results = [Val::I32(1)]; alloc.call(instance.store_mut(), ¶ms, &mut results).expect("alloc must success; qed"); let data_ptr = results[0].i32().unwrap(); let data_ptr = Pointer::new( data_ptr as u32); util::write_memory_from(instance.store_mut(), data_ptr, data)?; + println!("inject_input_data_v1 data {data:?} data_ptr: {data_ptr:?}"); Ok((data_ptr, data_len)) } diff --git a/substrate/primitives/allocator-v1/Cargo.toml b/substrate/primitives/allocator-v1/Cargo.toml index 921b1013b7e4..44db54ac1e41 100644 --- a/substrate/primitives/allocator-v1/Cargo.toml +++ b/substrate/primitives/allocator-v1/Cargo.toml @@ -31,7 +31,6 @@ improved_panic_error_reporting = [] allocator-v1 = [ "dep:lol_alloc", - "improved_panic_error_reporting", "sp-io/disable_allocator", "sp-io/disable_panic_handler", "sp-io/disable_oom", diff --git a/substrate/primitives/allocator-v1/src/config.rs b/substrate/primitives/allocator-v1/src/config.rs index 633206561338..984cc312fe10 100644 --- a/substrate/primitives/allocator-v1/src/config.rs +++ b/substrate/primitives/allocator-v1/src/config.rs @@ -24,6 +24,7 @@ pub static ALLOCATOR: AssumeSingleThreaded = #[no_mangle] unsafe fn alloc(size: usize) -> *mut u8 { + // return 1 as * mut u8; ALLOCATOR.alloc(core::alloc::Layout::array::(size).unwrap()) } @@ -50,14 +51,14 @@ fn v1() { #[panic_handler] #[no_mangle] pub fn panic(info: &core::panic::PanicInfo) -> ! { - let message = sp_std::alloc::format!("{}", info); - #[cfg(feature = "improved_panic_error_reporting")] - { - sp_io::panic_handler::abort_on_panic(&message); - } + // let message = sp_std::alloc::format!("{}", info); + // #[cfg(feature = "improved_panic_error_reporting")] + // { + // sp_io::panic_handler::abort_on_panic(&message); + // } #[cfg(not(feature = "improved_panic_error_reporting"))] { - sp_io::logging::log(LogLevel::Error, "runtime", message.as_bytes()); + // sp_io::logging::log(LogLevel::Error, "runtime", message.as_bytes()); core::arch::wasm32::unreachable(); } } @@ -67,13 +68,13 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { #[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))] #[alloc_error_handler] pub fn oom(_layout: core::alloc::Layout) -> ! { - #[cfg(feature = "improved_panic_error_reporting")] - { - panic_handler::abort_on_panic("Runtime memory exhausted."); - } + // #[cfg(feature = "improved_panic_error_reporting")] + // { + // panic_handler::abort_on_panic("Runtime memory exhausted."); + // } #[cfg(not(feature = "improved_panic_error_reporting"))] { - sp_io::logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); + // sp_io::logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); core::arch::wasm32::unreachable(); } } From 310f1eaf14b0b003f781eecc505b74f8842e0934 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Thu, 21 Sep 2023 14:59:29 +0800 Subject: [PATCH 05/10] clean up code and detect v1 --- .../common/src/runtime_blob/runtime_blob.rs | 19 ++++++++- .../client/executor/wasmtime/src/host.rs | 34 ++++++++------- .../executor/wasmtime/src/instance_wrapper.rs | 10 ++--- .../client/executor/wasmtime/src/runtime.rs | 24 ++++++----- .../primitives/allocator-v1/src/config.rs | 42 +++++++++---------- 5 files changed, 76 insertions(+), 53 deletions(-) diff --git a/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs b/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs index becf9e219b0b..074e1c4724ce 100644 --- a/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs +++ b/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs @@ -52,6 +52,14 @@ impl RuntimeBlob { Ok(Self { raw_module }) } + /// Return true if wasm contains a export function. + pub fn contain_export_func(&self, func: &str) -> bool { + self.raw_module.export_section().map(|section| { + section.entries().iter().any(|entry| entry.field() == func) + }) + .unwrap_or(false) + } + /// The number of globals defined in locally in this module. pub fn declared_globals_count(&self) -> u32 { self.raw_module @@ -160,6 +168,8 @@ impl RuntimeBlob { &mut self, heap_alloc_strategy: HeapAllocStrategy, ) -> Result<(), WasmError> { + let is_allocator_v1 = self.contain_export_func("v1"); + let memory_section = self .raw_module .memory_section_mut() @@ -168,6 +178,7 @@ impl RuntimeBlob { if memory_section.entries().is_empty() { return Err(WasmError::Other("memory section is empty".into())) } + for memory_ty in memory_section.entries_mut() { let initial = memory_ty.limits().initial(); let (min, max) = match heap_alloc_strategy { @@ -177,7 +188,13 @@ impl RuntimeBlob { }, HeapAllocStrategy::Static { extra_pages } => { let pages = initial.saturating_add(extra_pages); - (pages, Some(pages)) + // The runtime-customized allocator may rely on this init memory page, + // so this value cannot be modified at will, otherwise it will cause errors in the allocator logic. + if is_allocator_v1 { + (initial, Some(pages)) + } else { + (pages, Some(pages)) + } }, }; *memory_ty = MemoryType::new(min, max); diff --git a/substrate/client/executor/wasmtime/src/host.rs b/substrate/client/executor/wasmtime/src/host.rs index 0742a07312f2..2379fb7b6cf4 100644 --- a/substrate/client/executor/wasmtime/src/host.rs +++ b/substrate/client/executor/wasmtime/src/host.rs @@ -92,9 +92,11 @@ impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> { let params = [Val::I32(size as i32)]; let mut results = [Val::I32(0)]; - alloc.call(self.caller.as_context_mut(), ¶ms, &mut results); + alloc + .call(self.caller.as_context_mut(), ¶ms, &mut results) + .expect("alloc must success; qed"); let data_ptr = results[0].i32().unwrap(); - let data_ptr = Pointer::new( data_ptr as u32); + let data_ptr = Pointer::new(data_ptr as u32); Ok(data_ptr) } else { @@ -116,22 +118,26 @@ impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> { } fn deallocate_memory(&mut self, ptr: Pointer) -> sp_wasm_interface::Result<()> { - log::info!("deallocate_memory"); let memory = self.caller.data().memory(); - let mut allocator = self - .host_state_mut() - .allocator - .take() - .expect("allocator is not empty when calling a function in wasm; qed"); + if let Some(_alloc) = self.caller.data().alloc { + // TODO: maybe we need to support it. + unreachable!("The `deallocate_memory` never be used in allocator v1"); + } else { + let mut allocator = self + .host_state_mut() + .allocator + .take() + .expect("allocator is not empty when calling a function in wasm; qed"); - // We can not return on error early, as we need to store back allocator. - let res = allocator - .deallocate(&mut MemoryWrapper(&memory, &mut self.caller), ptr) - .map_err(|e| e.to_string()); + // We can not return on error early, as we need to store back allocator. + let res = allocator + .deallocate(&mut MemoryWrapper(&memory, &mut self.caller), ptr) + .map_err(|e| e.to_string()); - self.host_state_mut().allocator = Some(allocator); + self.host_state_mut().allocator = Some(allocator); - res + res + } } fn register_panic_error_message(&mut self, message: &str) { diff --git a/substrate/client/executor/wasmtime/src/instance_wrapper.rs b/substrate/client/executor/wasmtime/src/instance_wrapper.rs index e309631a21d4..f1053260d57d 100644 --- a/substrate/client/executor/wasmtime/src/instance_wrapper.rs +++ b/substrate/client/executor/wasmtime/src/instance_wrapper.rs @@ -25,7 +25,9 @@ use sc_executor_common::{ wasm_runtime::InvokeMethod, }; use sp_wasm_interface::{Pointer, Value, WordSize}; -use wasmtime::{AsContext, AsContextMut, Engine, Extern, Func, Instance, InstancePre, Memory, Table, Val}; +use wasmtime::{ + AsContext, AsContextMut, Engine, Extern, Func, Instance, InstancePre, Memory, Table, Val, +}; /// Invoked entrypoint format. pub enum EntryPointType { @@ -80,10 +82,8 @@ impl EntryPoint { }); if let Some(message) = host_state.take_panic_message() { - // todo!("1"); Error::AbortedDueToPanic(MessageWithBacktrace { message, backtrace }) } else { - // todo!("2"); let message = trap.root_cause().to_string(); Error::AbortedDueToTrap(MessageWithBacktrace { message, backtrace }) } @@ -303,9 +303,7 @@ fn get_table(instance: &Instance, ctx: &mut Store) -> Option
{ /// Extract export `alloc` func from the given instance. fn get_export_alloc(instance: &Instance, ctx: impl AsContextMut) -> Option { - instance - .get_export(ctx, "alloc") - .and_then(Extern::into_func) + instance.get_export(ctx, "alloc").and_then(Extern::into_func) } /// Functions related to memory. diff --git a/substrate/client/executor/wasmtime/src/runtime.rs b/substrate/client/executor/wasmtime/src/runtime.rs index e341182bf6ac..60f41e6545b5 100644 --- a/substrate/client/executor/wasmtime/src/runtime.rs +++ b/substrate/client/executor/wasmtime/src/runtime.rs @@ -127,7 +127,13 @@ impl WasmtimeInstance { } else { let heap_base = instance_wrapper.extract_heap_base()?; let allocator = FreeingBumpHeapAllocator::new(heap_base); - perform_call(data, &mut instance_wrapper, entrypoint, allocator, allocation_stats) + perform_call( + data, + &mut instance_wrapper, + entrypoint, + allocator, + allocation_stats, + ) } }, } @@ -680,10 +686,6 @@ fn perform_call_v1( .call(instance_wrapper.store_mut(), data_ptr, data_len) .map(unpack_ptr_and_len); - // Reset the host state - let host_state = instance_wrapper.store_mut().data_mut().host_state.take().expect( - "the host state is always set before calling into WASM so it can't be None here; qed", - ); let (output_ptr, output_len) = ret?; let output = extract_output_data(instance_wrapper, output_ptr, output_len)?; @@ -709,14 +711,16 @@ fn inject_input_data_v1( data: &[u8], ) -> Result<(Pointer, WordSize)> { let data_len = data.len() as WordSize; - let params = [Val::I32(data_len as _ )]; - let mut results = [Val::I32(1)]; + let params = [Val::I32(data_len as _)]; + let mut results = [Val::I32(0)]; - alloc.call(instance.store_mut(), ¶ms, &mut results).expect("alloc must success; qed"); + alloc + .call(instance.store_mut(), ¶ms, &mut results) + .expect("alloc must success; qed"); let data_ptr = results[0].i32().unwrap(); - let data_ptr = Pointer::new( data_ptr as u32); + let data_ptr = Pointer::new(data_ptr as u32); util::write_memory_from(instance.store_mut(), data_ptr, data)?; - println!("inject_input_data_v1 data {data:?} data_ptr: {data_ptr:?}"); + Ok((data_ptr, data_len)) } diff --git a/substrate/primitives/allocator-v1/src/config.rs b/substrate/primitives/allocator-v1/src/config.rs index 984cc312fe10..daae3fe95585 100644 --- a/substrate/primitives/allocator-v1/src/config.rs +++ b/substrate/primitives/allocator-v1/src/config.rs @@ -24,19 +24,18 @@ pub static ALLOCATOR: AssumeSingleThreaded = #[no_mangle] unsafe fn alloc(size: usize) -> *mut u8 { - // return 1 as * mut u8; ALLOCATOR.alloc(core::alloc::Layout::array::(size).unwrap()) } -// #[no_mangle] -// unsafe fn dealloc(ptr: *mut u8, size: usize) { -// ALLOCATOR.dealloc(ptr, core::alloc::Layout::array::(size).unwrap()) -// } -// -// #[no_mangle] -// unsafe fn realloc(ptr: *mut u8, size: usize, new_size: usize) -> *mut u8 { -// ALLOCATOR.realloc(ptr, core::alloc::Layout::array::(size).unwrap(), new_size) -// } +#[no_mangle] +unsafe fn dealloc(ptr: *mut u8, size: usize) { + ALLOCATOR.dealloc(ptr, core::alloc::Layout::array::(size).unwrap()) +} + +#[no_mangle] +unsafe fn realloc(ptr: *mut u8, size: usize, new_size: usize) -> *mut u8 { + ALLOCATOR.realloc(ptr, core::alloc::Layout::array::(size).unwrap(), new_size) +} // TODO: maybe it's better to rename this crate to `sp-runtime-abi`. /// The dummy function represents the version of runtime ABI. @@ -45,20 +44,19 @@ fn v1() { // nop } -// TODO: design a better error message for panic. /// A default panic handler for WASM environment. #[cfg(all(not(feature = "disable_panic_handler"), not(feature = "std")))] #[panic_handler] #[no_mangle] pub fn panic(info: &core::panic::PanicInfo) -> ! { - // let message = sp_std::alloc::format!("{}", info); - // #[cfg(feature = "improved_panic_error_reporting")] - // { - // sp_io::panic_handler::abort_on_panic(&message); - // } + let message = sp_std::alloc::format!("{}", info); + #[cfg(feature = "improved_panic_error_reporting")] + { + sp_io::panic_handler::abort_on_panic(&message); + } #[cfg(not(feature = "improved_panic_error_reporting"))] { - // sp_io::logging::log(LogLevel::Error, "runtime", message.as_bytes()); + sp_io::logging::log(LogLevel::Error, "runtime", message.as_bytes()); core::arch::wasm32::unreachable(); } } @@ -68,13 +66,13 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { #[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))] #[alloc_error_handler] pub fn oom(_layout: core::alloc::Layout) -> ! { - // #[cfg(feature = "improved_panic_error_reporting")] - // { - // panic_handler::abort_on_panic("Runtime memory exhausted."); - // } + #[cfg(feature = "improved_panic_error_reporting")] + { + panic_handler::abort_on_panic("Runtime memory exhausted."); + } #[cfg(not(feature = "improved_panic_error_reporting"))] { - // sp_io::logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); + sp_io::logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); core::arch::wasm32::unreachable(); } } From f65539fbb15922e37057d3c384b55abf00e55a74 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Thu, 21 Sep 2023 15:29:41 +0800 Subject: [PATCH 06/10] fix allocator imports --- substrate/primitives/allocator-v1/Cargo.toml | 5 +++-- substrate/primitives/allocator-v1/src/config.rs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/substrate/primitives/allocator-v1/Cargo.toml b/substrate/primitives/allocator-v1/Cargo.toml index 44db54ac1e41..94e3f84a9be7 100644 --- a/substrate/primitives/allocator-v1/Cargo.toml +++ b/substrate/primitives/allocator-v1/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" homepage = "https://substrate.io" repository = "https://github.com/paritytech/substrate/" description = "I/O for Substrate runtimes" -documentation = "https://docs.rs/sp-io" +documentation = "https://docs.rs/sp-allocator-v1" readme = "README.md" [package.metadata.docs.rs] @@ -16,15 +16,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] lol_alloc = { version = "0.4", optional = true } -# not used just enable feature sp-io = { path = "../io", default-features = false } sp-std = { path = "../std", default-features = false } +sp-core = { path = "../core", default-features = false } [features] default = ["std"] std = [ "sp-io/std", "sp-std/std", + "sp-core/std", ] improved_panic_error_reporting = [] diff --git a/substrate/primitives/allocator-v1/src/config.rs b/substrate/primitives/allocator-v1/src/config.rs index daae3fe95585..248d3449b0d4 100644 --- a/substrate/primitives/allocator-v1/src/config.rs +++ b/substrate/primitives/allocator-v1/src/config.rs @@ -56,7 +56,7 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { } #[cfg(not(feature = "improved_panic_error_reporting"))] { - sp_io::logging::log(LogLevel::Error, "runtime", message.as_bytes()); + sp_io::logging::log(sp_core::LogLevel::Error, "runtime", message.as_bytes()); core::arch::wasm32::unreachable(); } } @@ -72,7 +72,7 @@ pub fn oom(_layout: core::alloc::Layout) -> ! { } #[cfg(not(feature = "improved_panic_error_reporting"))] { - sp_io::logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); + sp_io::logging::log(sp_core::LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); core::arch::wasm32::unreachable(); } } From bfd4fff98c2316f0fbe15da10bcbeb45823fc1ae Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Thu, 21 Sep 2023 15:44:31 +0800 Subject: [PATCH 07/10] fmt --- .../executor/common/src/runtime_blob/runtime_blob.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs b/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs index 074e1c4724ce..d6b7c4a39742 100644 --- a/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs +++ b/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs @@ -54,9 +54,9 @@ impl RuntimeBlob { /// Return true if wasm contains a export function. pub fn contain_export_func(&self, func: &str) -> bool { - self.raw_module.export_section().map(|section| { - section.entries().iter().any(|entry| entry.field() == func) - }) + self.raw_module + .export_section() + .map(|section| section.entries().iter().any(|entry| entry.field() == func)) .unwrap_or(false) } @@ -189,7 +189,8 @@ impl RuntimeBlob { HeapAllocStrategy::Static { extra_pages } => { let pages = initial.saturating_add(extra_pages); // The runtime-customized allocator may rely on this init memory page, - // so this value cannot be modified at will, otherwise it will cause errors in the allocator logic. + // so this value cannot be modified at will, otherwise it will cause errors in + // the allocator logic. if is_allocator_v1 { (initial, Some(pages)) } else { From 4124690d8a9dddd0358bb524e80d27cd954193c8 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Thu, 21 Sep 2023 15:49:22 +0800 Subject: [PATCH 08/10] update Cargo.lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index d6f1df9955af..452cde9c8850 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16643,6 +16643,7 @@ name = "sp-allocator-v1" version = "7.0.0" dependencies = [ "lol_alloc", + "sp-core", "sp-io", "sp-std", ] From 7092efd83089496d94122902b5af4c8b66a56095 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Thu, 21 Sep 2023 19:15:31 +0800 Subject: [PATCH 09/10] fix lint --- substrate/bin/node-template/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 61215b4cb32b..88125c2ebd22 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -6,7 +6,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -pub use sp_allocator_v1 as _; +use sp_allocator_v1 as _; use pallet_grandpa::AuthorityId as GrandpaId; use sp_api::impl_runtime_apis; From 81f12afb00adbcca912383bc12570f0c38b0ce65 Mon Sep 17 00:00:00 2001 From: yjhmelody Date: Mon, 11 Dec 2023 23:37:49 +0800 Subject: [PATCH 10/10] improve docs --- Cargo.lock | 14 +------------- substrate/primitives/allocator-v1/Cargo.toml | 4 ++-- substrate/primitives/allocator-v1/README.md | 3 +++ substrate/primitives/allocator-v1/src/config.rs | 12 +++++++----- substrate/primitives/allocator-v1/src/lib.rs | 4 ++-- 5 files changed, 15 insertions(+), 22 deletions(-) create mode 100644 substrate/primitives/allocator-v1/README.md diff --git a/Cargo.lock b/Cargo.lock index c361c8eb8da7..94bd81c2e562 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7726,15 +7726,6 @@ dependencies = [ "value-bag", ] -[[package]] -name = "lol_alloc" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36aabc32b791f1a506e0bb90e0fa03e983500549d7b1f2dad45b5fc20ef45974" -dependencies = [ - "spin 0.9.8", -] - [[package]] name = "lru" version = "0.8.1" @@ -17191,7 +17182,7 @@ dependencies = [ name = "sp-allocator-v1" version = "7.0.0" dependencies = [ - "lol_alloc", + "dlmalloc", "sp-core", "sp-io", "sp-std 8.0.0", @@ -18243,9 +18234,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "spinners" diff --git a/substrate/primitives/allocator-v1/Cargo.toml b/substrate/primitives/allocator-v1/Cargo.toml index 94e3f84a9be7..a1122b0d76cc 100644 --- a/substrate/primitives/allocator-v1/Cargo.toml +++ b/substrate/primitives/allocator-v1/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -lol_alloc = { version = "0.4", optional = true } +dlmalloc = { version = "0.2.4", optional = true, features = ["global"] } sp-io = { path = "../io", default-features = false } sp-std = { path = "../std", default-features = false } @@ -31,7 +31,7 @@ std = [ improved_panic_error_reporting = [] allocator-v1 = [ - "dep:lol_alloc", + "dep:dlmalloc", "sp-io/disable_allocator", "sp-io/disable_panic_handler", "sp-io/disable_oom", diff --git a/substrate/primitives/allocator-v1/README.md b/substrate/primitives/allocator-v1/README.md new file mode 100644 index 000000000000..2e55f49069f4 --- /dev/null +++ b/substrate/primitives/allocator-v1/README.md @@ -0,0 +1,3 @@ +Spec about runtime allocator + +License: Apache-2.0 diff --git a/substrate/primitives/allocator-v1/src/config.rs b/substrate/primitives/allocator-v1/src/config.rs index 248d3449b0d4..ec028d647981 100644 --- a/substrate/primitives/allocator-v1/src/config.rs +++ b/substrate/primitives/allocator-v1/src/config.rs @@ -16,11 +16,10 @@ // limitations under the License. use core::alloc::GlobalAlloc; -use lol_alloc::{AssumeSingleThreaded, FreeListAllocator}; +use dlmalloc::GlobalDlmalloc; #[global_allocator] -pub static ALLOCATOR: AssumeSingleThreaded = - unsafe { AssumeSingleThreaded::new(FreeListAllocator::new()) }; +pub static ALLOCATOR: GlobalDlmalloc = GlobalDlmalloc; #[no_mangle] unsafe fn alloc(size: usize) -> *mut u8 { @@ -61,7 +60,6 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { } } - /// A default OOM handler for WASM environment. #[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))] #[alloc_error_handler] @@ -72,7 +70,11 @@ pub fn oom(_layout: core::alloc::Layout) -> ! { } #[cfg(not(feature = "improved_panic_error_reporting"))] { - sp_io::logging::log(sp_core::LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); + sp_io::logging::log( + sp_core::LogLevel::Error, + "runtime", + b"Runtime memory exhausted. Aborting", + ); core::arch::wasm32::unreachable(); } } diff --git a/substrate/primitives/allocator-v1/src/lib.rs b/substrate/primitives/allocator-v1/src/lib.rs index db25ff91abb6..c835a30d40f1 100644 --- a/substrate/primitives/allocator-v1/src/lib.rs +++ b/substrate/primitives/allocator-v1/src/lib.rs @@ -15,11 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # V1 spec about runtime abi +//! # Spec about runtime allocator //! //! Export the `alloc`/`dealloc`/`realloc` primitive functions inside the runtime to host. //! -//! In runtime crate, must use the following sp-io features: +//! When enable this crate, the following features will be set: //! - disable_allocator //! - disable_panic_handler //! - disable_oom