From ca5daec14fee4a3abe98c1b9e5ccd47c76c6ac7c Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Mon, 7 Feb 2022 10:14:52 +0100 Subject: [PATCH] More efficient WASM instance memory decommit on macos (#10801) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * More efficient WASM instance memory decommit on macos * Apply suggestions from code review Co-authored-by: Alexander Theißen * Updated error message Co-authored-by: Alexander Theißen --- .../executor/wasmtime/src/instance_wrapper.rs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/substrate/client/executor/wasmtime/src/instance_wrapper.rs b/substrate/client/executor/wasmtime/src/instance_wrapper.rs index af21a8080c..e27de7817b 100644 --- a/substrate/client/executor/wasmtime/src/instance_wrapper.rs +++ b/substrate/client/executor/wasmtime/src/instance_wrapper.rs @@ -361,6 +361,33 @@ impl InstanceWrapper { return; } } + } else if #[cfg(target_os = "macos")] { + use std::sync::Once; + + unsafe { + let ptr = self.memory.data_ptr(&self.store); + let len = self.memory.data_size(&self.store); + + // On MacOS we can simply overwrite memory mapping. + if libc::mmap( + ptr as _, + len, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_FIXED | libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ) == libc::MAP_FAILED { + static LOGGED: Once = Once::new(); + LOGGED.call_once(|| { + log::warn!( + "Failed to decommit WASM instance memory through mmap: {}", + std::io::Error::last_os_error(), + ); + }); + } else { + return; + } + } } } @@ -377,3 +404,15 @@ impl InstanceWrapper { &mut self.store } } + +#[test] +fn decommit_works() { + let engine = wasmtime::Engine::default(); + let code = wat::parse_str("(module (memory (export \"memory\") 1 4))").unwrap(); + let module = Module::new(&engine, code).unwrap(); + let mut wrapper = InstanceWrapper::new::<()>(&module, 2, true, None).unwrap(); + unsafe { *wrapper.memory.data_ptr(&wrapper.store) = 42 }; + assert_eq!(unsafe { *wrapper.memory.data_ptr(&wrapper.store) }, 42); + wrapper.decommit(); + assert_eq!(unsafe { *wrapper.memory.data_ptr(&wrapper.store) }, 0); +}