From ff45aea0ead9f76e2e0387b579ff0bdc71a1af74 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 15 Dec 2018 10:30:53 -0800 Subject: [PATCH] [WIP] Improved memory handling (#56) * Improved memory handling * Fix memory accessibility * Fix formatting --- src/common/mmap/unix.rs | 1 - src/common/mmap/windows.rs | 4 ++-- src/webassembly/instance.rs | 2 +- src/webassembly/memory.rs | 19 +++++++++---------- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/common/mmap/unix.rs b/src/common/mmap/unix.rs index cc60063f4..64071f6f0 100644 --- a/src/common/mmap/unix.rs +++ b/src/common/mmap/unix.rs @@ -43,7 +43,6 @@ impl Mmap { libc::mmap( ptr::null_mut(), alloc_size, - // libc::PROT_READ | libc::PROT_WRITE, libc::PROT_NONE, libc::MAP_PRIVATE | libc::MAP_ANON, -1, diff --git a/src/common/mmap/windows.rs b/src/common/mmap/windows.rs index 6e692398d..52fe80be6 100644 --- a/src/common/mmap/windows.rs +++ b/src/common/mmap/windows.rs @@ -7,7 +7,7 @@ use std::ptr; use std::slice; use std::string::String; use winapi::um::memoryapi::{VirtualAlloc, VirtualFree}; -use winapi::um::winnt::{MEM_COMMIT, MEM_RELEASE, MEM_RESERVE, PAGE_READWRITE}; +use winapi::um::winnt::{MEM_COMMIT, MEM_RELEASE, MEM_RESERVE, PAGE_NOACCESS}; use super::common::round_up_to_page_size; @@ -39,7 +39,7 @@ impl Mmap { ptr::null_mut(), size, MEM_COMMIT | MEM_RESERVE, - PAGE_READWRITE, + PAGE_NOACCESS, ) }; if !ptr.is_null() { diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index a731b1804..fdcdeefd7 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -509,7 +509,7 @@ impl Instance { let mem = &mut memories[init.memory_index.index()]; let end_of_init = offset + init.data.len(); if end_of_init > mem.current_size() { - let grow_pages = (end_of_init / LinearMemory::WASM_PAGE_SIZE) + 1; + let grow_pages = (end_of_init / LinearMemory::PAGE_SIZE as usize) + 1; mem.grow(grow_pages as u32) .expect("failed to grow memory for data initializers"); } diff --git a/src/webassembly/memory.rs b/src/webassembly/memory.rs index 0c755bf34..cc69a66f2 100644 --- a/src/webassembly/memory.rs +++ b/src/webassembly/memory.rs @@ -35,7 +35,6 @@ pub struct LinearMemory { impl LinearMemory { pub const PAGE_SIZE: u32 = 65536; pub const MAX_PAGES: u32 = 65536; - pub const WASM_PAGE_SIZE: usize = 1 << 16; // 64 KiB pub const DEFAULT_HEAP_SIZE: usize = 1 << 32; // 4 GiB pub const DEFAULT_GUARD_SIZE: usize = 1 << 31; // 2 GiB pub const DEFAULT_SIZE: usize = Self::DEFAULT_HEAP_SIZE + Self::DEFAULT_GUARD_SIZE; // 6 GiB @@ -51,18 +50,17 @@ impl LinearMemory { initial, maximum ); - let offset_guard_size = LinearMemory::DEFAULT_SIZE as usize; - let mut mmap = Mmap::with_size(offset_guard_size).expect("Can't create mmap"); + let mut mmap = Mmap::with_size(Self::DEFAULT_SIZE).expect("Can't create mmap"); let base = mmap.as_mut_ptr(); + // map initial pages as readwrite since the inital mmap is mapped as not accessible. if initial != 0 { unsafe { region::protect( - base as _, + base, initial as usize * Self::PAGE_SIZE as usize, - region::Protection::Read | region::Protection::Write, - // region::Protection::None, + region::Protection::ReadWrite, ) } .expect("unable to make memory inaccessible"); @@ -82,7 +80,7 @@ impl LinearMemory { Self { mmap, current: initial, - offset_guard_size, + offset_guard_size: LinearMemory::DEFAULT_GUARD_SIZE, maximum, } } @@ -137,15 +135,16 @@ impl LinearMemory { let prev_bytes = (prev_pages * Self::PAGE_SIZE) as usize; let new_bytes = (new_pages * Self::PAGE_SIZE) as usize; + // if new_bytes > self.mmap.len() - self.offset_guard_size { unsafe { region::protect( - self.mmap.as_mut_ptr().add(prev_bytes) as _, + self.mmap.as_ptr().add(prev_bytes) as _, new_bytes - prev_bytes, - region::Protection::Read | region::Protection::Write, - // region::Protection::None, + region::Protection::ReadWrite, ) } .expect("unable to make memory inaccessible"); + // }; // if new_bytes > self.mmap.len() - self.offset_guard_size { // // If we have no maximum, this is a "dynamic" heap, and it's allowed to move. // assert!(self.maximum.is_none());