Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Fair reusing of wasm runtime instances #3011

Merged
merged 72 commits into from
Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
a1820f4
Add test from original bug report
cmichi Jun 13, 2019
adaa8dc
No longer cleanup module instance
cmichi Jun 19, 2019
ccba1ef
Replace runtime cache with synchronous clone
cmichi Jun 24, 2019
e3dba7f
Fix test
cmichi Jun 25, 2019
0feabfc
Preserve initial runtime memory and restore it on fetch
cmichi Jun 25, 2019
f69f0ef
Remove leftover comment
cmichi Jun 26, 2019
65f4616
Fix style
cmichi Jun 28, 2019
a9a9014
Improve variable naming
cmichi Jun 28, 2019
1abeb70
Replace get_into() with get()
cmichi Jun 28, 2019
91a8f82
Handle missing memory export better
cmichi Jun 28, 2019
1b76de2
Return earlier when creating runtime first time
cmichi Jun 28, 2019
1a34c15
Improve comments
cmichi Jun 28, 2019
8d926b1
fmt
pepyakin Jun 28, 2019
2802866
Fix #2967.
pepyakin Jun 28, 2019
6f16b45
Eradicate `code` from `Error::InvalidCode`
pepyakin Jun 28, 2019
457d6c6
tidy
pepyakin Jun 28, 2019
35b2deb
A state snapshot doc.
pepyakin Jul 1, 2019
60fdbf5
Store multiple runtimes by hash.
pepyakin Jul 1, 2019
6d34c0a
Merge remote-tracking branch 'origin/master' into cmichi-ensure-clean…
pepyakin Jul 1, 2019
cc1917c
Get rid of deref.
pepyakin Jul 1, 2019
537ad5f
Docs
pepyakin Jul 1, 2019
a47adda
Use Self for instantiate_module
pepyakin Jul 2, 2019
e927acb
REVERT ME
pepyakin Jul 2, 2019
f94e07c
Should be ok
pepyakin Jul 2, 2019
20933ee
Commit
pepyakin Jul 2, 2019
1def782
Remove dbg
pepyakin Jul 2, 2019
48cab4c
Use fast-memory's erase
pepyakin Jul 2, 2019
92b6e27
Clean and undo hacks.
pepyakin Jul 3, 2019
64d9dab
Introduce a dedicated error for heap_base
pepyakin Jul 3, 2019
a7ee559
Ban the start function.
pepyakin Jul 3, 2019
565be74
Clean, docs and refactor
pepyakin Jul 3, 2019
caf5a00
Merge master into ser-reuse-wasm
pepyakin Jul 4, 2019
ca1796b
Add rustflags.
pepyakin Jul 4, 2019
9a07c17
Update Cargo.lock
pepyakin Jul 4, 2019
ee06caf
Apply Basti's suggestions
pepyakin Jul 4, 2019
1ffa62e
Rename allocates_huge_stack_array
pepyakin Jul 4, 2019
4becdd8
Merge remote-tracking branch 'origin/master' into ser-reuse-wasm
pepyakin Jul 4, 2019
3d02c90
Extend TestClientBuilder with set_heap_pages
pepyakin Jul 4, 2019
49d2117
Update the test.
pepyakin Jul 4, 2019
b79b6c5
Update core/executor/src/wasm_executor.rs
pepyakin Jul 5, 2019
5b91eaf
Update core/executor/src/wasm_runtimes_cache.rs
pepyakin Jul 5, 2019
7c06950
Update core/executor/src/error.rs
pepyakin Jul 5, 2019
6077aba
Update core/executor/src/error.rs
pepyakin Jul 5, 2019
4ce3684
Fix tests.
pepyakin Jul 5, 2019
42c5950
Update cargo-lock
pepyakin Jul 8, 2019
4355dfc
Merge remote-tracking branch 'origin/master' into ser-reuse-wasm
pepyakin Jul 8, 2019
d053556
Use wasmi master
pepyakin Jul 8, 2019
a98352f
Use master wasmi
pepyakin Jul 9, 2019
bd92e71
Move tests.
pepyakin Jul 9, 2019
c7fcc4d
Use wasmi crates.io
pepyakin Jul 9, 2019
455a3a0
Merge master into ser-reuse-wasm
pepyakin Jul 9, 2019
b67e52e
Update Cargo.lock
pepyakin Jul 9, 2019
569a78b
Fix build.rs
pepyakin Jul 9, 2019
8519501
Bump runtime version
pepyakin Jul 9, 2019
751ef3e
Revert initial_heap_pages renaming
pepyakin Jul 9, 2019
c3cc2cb
Bump wasmi up to 0.5.0
pepyakin Jul 10, 2019
8b243ad
Merge 'origin/master' into ser-reuse-wasm
pepyakin Jul 10, 2019
2da6066
Bump runtime version
pepyakin Jul 10, 2019
66c7427
Merge branch 'master' into ser-reuse-wasm
pepyakin Jul 11, 2019
5845385
Merge remote-tracking branch 'origin/master' into ser-reuse-wasm
pepyakin Jul 12, 2019
1162e4e
Don't restore an instance every now and then
pepyakin Jul 12, 2019
fac2162
Merge branch 'master' into ser-reuse-wasm
Demi-Marie Jul 13, 2019
6d2d17b
Update core/executor/src/wasm_runtimes_cache.rs
pepyakin Jul 13, 2019
e5ca259
Propagate error in CacheError
pepyakin Jul 24, 2019
15dc874
Clarify the get_heap_base call in instantiation
pepyakin Jul 24, 2019
27a4602
Supply --export=__heap_base
pepyakin Jul 24, 2019
fbbc10f
Bump version.
pepyakin Jul 24, 2019
cda8690
Use combinators for segments.
pepyakin Jul 24, 2019
f04de66
Merge branch 'master' into ser-reuse-wasm
pepyakin Jul 24, 2019
8f1d73a
Fix build.rs
pepyakin Jul 24, 2019
4bb7bcf
Fix build.rs for runtime-test
pepyakin Jul 25, 2019
78046ec
Merge 'origin/master' into ser-reuse-wasm
pepyakin Jul 25, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions core/client/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ mod tests {
let mut storage = GenesisConfig::new(false,
vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()],
vec![AccountKeyring::One.into(), AccountKeyring::Two.into()],
1000
1000,
None,
).genesis_map();
let state_root = BlakeTwo256::trie_root(storage.clone().into_iter());
let block = construct_genesis_block::<Block>(state_root);
Expand Down Expand Up @@ -178,7 +179,8 @@ mod tests {
let mut storage = GenesisConfig::new(false,
vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()],
vec![AccountKeyring::One.into(), AccountKeyring::Two.into()],
1000
1000,
None,
).genesis_map();
let state_root = BlakeTwo256::trie_root(storage.clone().into_iter());
let block = construct_genesis_block::<Block>(state_root);
Expand Down Expand Up @@ -207,7 +209,8 @@ mod tests {
let mut storage = GenesisConfig::new(false,
vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()],
vec![AccountKeyring::One.into(), AccountKeyring::Two.into()],
68
68,
None,
).genesis_map();
let state_root = BlakeTwo256::trie_root(storage.clone().into_iter());
let block = construct_genesis_block::<Block>(state_root);
Expand Down
3 changes: 2 additions & 1 deletion core/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ serializer = { package = "substrate-serializer", path = "../serializer" }
state_machine = { package = "substrate-state-machine", path = "../state-machine" }
runtime_version = { package = "sr-version", path = "../sr-version" }
panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" }
wasmi = { version = "0.4.3" }
wasmi = "0.5.0"
parity-wasm = "0.31"
byteorder = "1.3"
lazy_static = "1.3"
parking_lot = "0.8.0"
Expand Down
7 changes: 5 additions & 2 deletions core/executor/runtime-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

use wasm_builder_runner::{build_current_project, WasmBuilderSource};
use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource};

fn main() {
build_current_project(
build_current_project_with_rustflags(
"wasm_binary.rs",
WasmBuilderSource::CratesOrPath {
path: "../../utils/wasm-builder",
version: "1.0.4",
},
// This instructs LLD to export __heap_base as a global variable, which is used by the
// external memory allocator.
"-Clink-arg=--export=__heap_base",
);
}
54 changes: 17 additions & 37 deletions core/executor/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,13 @@ impl FreeingBumpHeapAllocator {
///
/// # Arguments
///
/// * `ptr_offset` - The pointers returned by `allocate()` start from this
/// offset on. The pointer offset needs to be aligned to a multiple of 8,
/// hence a padding might be added to align `ptr_offset` properly.
///
/// * `heap_size` - The size available to this heap instance (in bytes) for
/// allocating memory.
///
/// * `heap` - A `MemoryRef` to the available `MemoryInstance` which is
/// used as the heap.
///
pub fn new(mem: MemoryRef) -> Self {
/// - `mem` - reference to the linear memory instance on which this allocator operates.
/// - `heap_base` - the offset from the beginning of the linear memory where the heap starts.
pub fn new(mem: MemoryRef, heap_base: u32) -> Self {
let current_size: Bytes = mem.current_size().into();
let current_size = current_size.0 as u32;
let used_size = mem.used_size().0 as u32;

let mut ptr_offset = used_size;
let mut ptr_offset = heap_base;
let padding = ptr_offset % ALIGNMENT;
if padding != 0 {
ptr_offset += ALIGNMENT - padding;
Expand Down Expand Up @@ -195,16 +186,11 @@ mod tests {

const PAGE_SIZE: u32 = 65536;

fn set_offset(mem: MemoryRef, offset: usize) {
let offset: Vec<u8> = vec![255; offset];
mem.set(0, &offset).unwrap();
}

#[test]
fn should_allocate_properly() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 0);

// when
let ptr = heap.allocate(1).unwrap();
Expand All @@ -217,8 +203,7 @@ mod tests {
fn should_always_align_pointers_to_multiples_of_8() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
set_offset(mem.clone(), 13);
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 13);

// when
let ptr = heap.allocate(1).unwrap();
Expand All @@ -233,7 +218,7 @@ mod tests {
fn should_increment_pointers_properly() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 0);

// when
let ptr1 = heap.allocate(1).unwrap();
Expand All @@ -256,7 +241,7 @@ mod tests {
fn should_free_properly() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 0);
let ptr1 = heap.allocate(1).unwrap();
// the prefix of 8 bytes is prepended to the pointer
assert_eq!(ptr1, 8);
Expand All @@ -278,9 +263,8 @@ mod tests {
fn should_deallocate_and_reallocate_properly() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
set_offset(mem.clone(), 13);
let padded_offset = 16;
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 13);

let ptr1 = heap.allocate(1).unwrap();
// the prefix of 8 bytes is prepended to the pointer
Expand All @@ -306,7 +290,7 @@ mod tests {
fn should_build_linked_list_of_free_areas_properly() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 0);

let ptr1 = heap.allocate(8).unwrap();
let ptr2 = heap.allocate(8).unwrap();
Expand All @@ -333,8 +317,7 @@ mod tests {
fn should_not_allocate_if_too_large() {
// given
let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap();
set_offset(mem.clone(), 13);
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 13);

// when
let ptr = heap.allocate(PAGE_SIZE - 13);
Expand All @@ -353,7 +336,7 @@ mod tests {
fn should_not_allocate_if_full() {
// given
let mem = MemoryInstance::alloc(Pages(1), Some(Pages(1))).unwrap();
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 0);
let ptr1 = heap.allocate((PAGE_SIZE / 2) - 8).unwrap();
assert_eq!(ptr1, 8);

Expand All @@ -376,7 +359,7 @@ mod tests {
// given
let pages_needed = (MAX_POSSIBLE_ALLOCATION as usize / PAGE_SIZE as usize) + 1;
let mem = MemoryInstance::alloc(Pages(pages_needed), Some(Pages(pages_needed))).unwrap();
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 0);

// when
let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION).unwrap();
Expand All @@ -389,7 +372,7 @@ mod tests {
fn should_not_allocate_if_requested_size_too_large() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 0);

// when
let ptr = heap.allocate(MAX_POSSIBLE_ALLOCATION + 1);
Expand All @@ -408,8 +391,7 @@ mod tests {
fn should_include_prefixes_in_total_heap_size() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
set_offset(mem.clone(), 1);
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 1);

// when
// an item size of 16 must be used then
Expand All @@ -423,8 +405,7 @@ mod tests {
fn should_calculate_total_heap_size_to_zero() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
set_offset(mem.clone(), 13);
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 13);

// when
let ptr = heap.allocate(42).unwrap();
Expand All @@ -439,8 +420,7 @@ mod tests {
fn should_calculate_total_size_of_zero() {
// given
let mem = MemoryInstance::alloc(Pages(1), None).unwrap();
set_offset(mem.clone(), 19);
let mut heap = FreeingBumpHeapAllocator::new(mem);
let mut heap = FreeingBumpHeapAllocator::new(mem, 19);

// when
for _ in 1..10 {
Expand Down
11 changes: 9 additions & 2 deletions core/executor/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ pub enum Error {
#[display(fmt="Method not found: '{}'", _0)]
MethodNotFound(String),
/// Code is invalid (expected single byte)
#[display(fmt="Invalid Code: {:?}", _0)]
InvalidCode(Vec<u8>),
#[display(fmt="Invalid Code")]
InvalidCode,
/// Could not get runtime version.
#[display(fmt="On-chain runtime does not specify version")]
VersionInvalid,
Expand All @@ -58,6 +58,13 @@ pub enum Error {
/// Invalid memory reference.
#[display(fmt="Invalid memory reference")]
InvalidMemoryReference,
/// The runtime must provide a global named `__heap_base` of type i32 for specifying where the
/// allocator is allowed to place its data.
#[display(fmt="The runtime doesn't provide a global named `__heap_base`")]
HeapBaseNotFoundOrInvalid,
/// The runtime WebAssembly module is not allowed to have the `start` function.
#[display(fmt="The runtime has the `start` function")]
RuntimeHasStartFn,
/// Some other error occurred
Other(&'static str),
/// Some error occurred in the allocator
Expand Down
2 changes: 2 additions & 0 deletions core/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ mod wasm_executor;
mod native_executor;
mod sandbox;
mod allocator;
mod wasm_runtimes_cache;

pub mod error;
pub use wasmi;
pub use wasm_executor::WasmExecutor;
pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch};
pub use wasm_runtimes_cache::RuntimesCache;
pub use state_machine::Externalities;
pub use runtime_version::{RuntimeVersion, NativeVersion};
pub use parity_codec::Codec;
Expand Down
Loading