Remove dependency on the region crate (#4407)

This commit removes Wasmtime's dependency on the `region` crate. The
motivation for this came about when I was updating dependencies and saw
that `region` had a new major version at 3.0.0 as opposed to our
currently used 2.3 track. In reviewing the use cases of `region` within
Wasmtime I found two trends in particular which motivated this commit:

* Some unix-specific areas of `wasmtime_runtime` use
  `rustix::mm::mprotect` instead of `region::protect` already. This
  means that the usage of `region::protect` for changing virtual memory
  protections was already inconsistent.

* Many uses of `region::protect` were already in unix-specific regions
  which could make use of `rustix`.

Overall I opted to remove the dependency on the `region` crate to avoid
chasing its versions over time. Unix-specific changes of protections
were easily changed to `rustix::mm::mprotect`. There were two locations
where a windows/unix split is now required and I subjectively ruled
"that seems ok". Finally removing `region` also meant that the "what is
the current page size" query needed to be inlined into
`wasmtime_runtime`, which I have also subjectively ruled "that seems
fine".

Finally one final refactoring here was that the `unix.rs` and `linux.rs`
split for the pooling allocator was merged. These two files already only
differed in one function so I slapped a `cfg_if!` in there to help
reduce the duplication.
This commit is contained in:
Alex Crichton
2022-07-07 16:28:25 -05:00
committed by GitHub
parent 9c43749dfe
commit 601e8f3094
14 changed files with 134 additions and 121 deletions

View File

@@ -1,26 +1,45 @@
use anyhow::{Context, Result};
use rustix::mm::{mprotect, MprotectFlags};
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
if len == 0 {
return Ok(());
}
// By creating a new mapping at the same location, this will discard the
// mapping for the pages in the given range.
// The new mapping will be to the CoW zero page, so this effectively
// zeroes the pages.
unsafe {
rustix::mm::mmap_anonymous(
addr as _,
len,
if protect {
rustix::mm::ProtFlags::empty()
cfg_if::cfg_if! {
if #[cfg(target_os = "linux")] {
use rustix::mm::{madvise, Advice};
if protect {
mprotect(addr.cast(), len, MprotectFlags::empty())
.context("failed to protect memory pages")?;
}
// On Linux, this is enough to cause the kernel to initialize
// the pages to 0 on next access
madvise(addr as _, len, Advice::LinuxDontNeed)
.context("madvise failed to decommit: {}")?;
} else {
rustix::mm::ProtFlags::READ | rustix::mm::ProtFlags::WRITE
},
rustix::mm::MapFlags::PRIVATE | rustix::mm::MapFlags::FIXED,
)
.context("mmap failed to remap pages: {}")?;
use rustix::mm::{mmap_anonymous, ProtFlags, MapFlags};
// By creating a new mapping at the same location, this will
// discard the mapping for the pages in the given range.
// The new mapping will be to the CoW zero page, so this
// effectively zeroes the pages.
mmap_anonymous(
addr as _,
len,
if protect {
ProtFlags::empty()
} else {
ProtFlags::READ | ProtFlags::WRITE
},
MapFlags::PRIVATE | MapFlags::FIXED,
)
.context("mmap failed to remap pages: {}")?;
}
}
}
Ok(())
@@ -33,7 +52,7 @@ pub fn commit_memory_pages(addr: *mut u8, len: usize) -> Result<()> {
// Just change the protection level to READ|WRITE
unsafe {
region::protect(addr, len, region::Protection::READ_WRITE)
mprotect(addr.cast(), len, MprotectFlags::READ | MprotectFlags::WRITE)
.context("failed to make linear memory pages read/write")
}
}