Skip to content

Commit 185f7a8

Browse files
authored
Don't use MemoryStyle in MmapMemory (bytecodealliance#9574)
This commit removes the use fo `MemoryStyle` for determining the size of the allocation of a `MmapMemory`. This should semanatically be the same as before but it's hoped that the new version is clearer to understand as it doesn't require going through the `MemoryStyle` abstraction to understand how tunables interact with linear memory. The semantics for the allocation of linear memory are: reservation = tunables.memory_reservation growth = tunables.memory_reservation_for_growth if maximum <= reservation { growth = 0 } else if minimum <= reservation { // use settings above } else { reservation = minimum + growth } This means that the initial memory allocation is always `tunables.memory_reservation` unless that's not large enough to fit the linear memory. In such a situation the other settings, such as `memory_reservation_for_growth`, kick in. The logic of clamping the maximum and/or dealing with static/dynamic are now all unnecessary and/or tracked elsewhere. For example the clamping nature of `maximum` now happens implicitly by rejecting growth when `memory_may_move` is false which should help keep that complexity localized where necessary rather than conflating multiple settings together.
1 parent f2cf2df commit 185f7a8

File tree

1 file changed

+32
-40
lines changed

1 file changed

+32
-40
lines changed

crates/wasmtime/src/runtime/vm/memory.rs

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use alloc::sync::Arc;
1313
use core::ops::Range;
1414
use core::ptr::NonNull;
1515
use core::time::Duration;
16-
use wasmtime_environ::{MemoryStyle, Trap, Tunables};
16+
use wasmtime_environ::{Trap, Tunables};
1717

1818
/// A memory allocator
1919
pub trait RuntimeMemoryCreator: Send + Sync {
@@ -227,62 +227,54 @@ impl MmapMemory {
227227
ty: &wasmtime_environ::Memory,
228228
tunables: &Tunables,
229229
minimum: usize,
230-
mut maximum: Option<usize>,
230+
maximum: Option<usize>,
231231
memory_image: Option<&Arc<MemoryImage>>,
232232
) -> Result<Self> {
233-
let style = MemoryStyle::for_memory(*ty, tunables);
234-
235233
// It's a programmer error for these two configuration values to exceed
236234
// the host available address space, so panic if such a configuration is
237235
// found (mostly an issue for hypothetical 32-bit hosts).
236+
//
237+
// Also be sure to round up to the host page size for this value.
238238
let offset_guard_bytes = usize::try_from(tunables.memory_guard_size).unwrap();
239+
let offset_guard_bytes = round_usize_up_to_host_pages(offset_guard_bytes)?;
239240
let pre_guard_bytes = if tunables.guard_before_linear_memory {
240241
offset_guard_bytes
241242
} else {
242243
0
243244
};
244245

245-
// Ensure that our guard regions are multiples of the host page size.
246-
let offset_guard_bytes = round_usize_up_to_host_pages(offset_guard_bytes)?;
247-
let pre_guard_bytes = round_usize_up_to_host_pages(pre_guard_bytes)?;
248-
249-
let (alloc_bytes, extra_to_reserve_on_growth) = match style {
250-
// Dynamic memories start with the larger of the minimum size of
251-
// memory or the configured memory reservation. This ensures that
252-
// the allocation fits the constraints in `tunables` where it must
253-
// be as large as the specified reservation.
254-
//
255-
// Then `reserve` amount is added extra to the virtual memory
256-
// allocation for memory to grow into.
257-
MemoryStyle::Dynamic { reserve } => {
258-
let minimum = round_usize_up_to_host_pages(minimum)?;
259-
let reservation = usize::try_from(tunables.memory_reservation).unwrap();
260-
let reservation = round_usize_up_to_host_pages(reservation)?;
261-
262-
(
263-
minimum.max(reservation),
264-
round_usize_up_to_host_pages(usize::try_from(reserve).unwrap())?,
265-
)
246+
// Calculate how much is going to be allocated for this linear memory in
247+
// addition to how much extra space we're reserving to grow into.
248+
//
249+
// If the minimum size of this linear memory fits within the initial
250+
// allocation (tunables.memory_reservation) then that's how many bytes
251+
// are going to be allocated. If the maximum size of linear memory
252+
// additionally fits within the entire allocation then there's no need
253+
// to reserve any extra for growth.
254+
//
255+
// If the minimum size doesn't fit within this linear memory.
256+
let mut alloc_bytes = tunables.memory_reservation;
257+
let mut extra_to_reserve_on_growth = tunables.memory_reservation_for_growth;
258+
let minimum_u64 = u64::try_from(minimum).unwrap();
259+
if minimum_u64 <= alloc_bytes {
260+
if let Ok(max) = ty.maximum_byte_size() {
261+
if max <= alloc_bytes {
262+
extra_to_reserve_on_growth = 0;
263+
}
266264
}
265+
} else {
266+
alloc_bytes = minimum_u64.saturating_add(extra_to_reserve_on_growth);
267+
}
267268

268-
// Static memories will never move in memory and consequently get
269-
// their entire allocation up-front with no extra room to grow into.
270-
// Note that the `maximum` is adjusted here to whatever the smaller
271-
// of the two is, the `maximum` given or the `bound` specified for
272-
// this memory.
273-
MemoryStyle::Static { byte_reservation } => {
274-
assert!(byte_reservation >= ty.minimum_byte_size().unwrap());
275-
let bound_bytes = usize::try_from(byte_reservation).unwrap();
276-
let bound_bytes = round_usize_up_to_host_pages(bound_bytes)?;
277-
maximum = Some(bound_bytes.min(maximum.unwrap_or(usize::MAX)));
278-
(bound_bytes, 0)
279-
}
280-
};
281-
assert!(usize_is_multiple_of_host_page_size(alloc_bytes));
269+
// Convert `alloc_bytes` and `extra_to_reserve_on_growth` to
270+
// page-aligned `usize` values.
271+
let alloc_bytes = usize::try_from(alloc_bytes).unwrap();
272+
let extra_to_reserve_on_growth = usize::try_from(extra_to_reserve_on_growth).unwrap();
273+
let alloc_bytes = round_usize_up_to_host_pages(alloc_bytes)?;
274+
let extra_to_reserve_on_growth = round_usize_up_to_host_pages(extra_to_reserve_on_growth)?;
282275

283276
let request_bytes = pre_guard_bytes
284277
.checked_add(alloc_bytes)
285-
.and_then(|i| i.checked_add(extra_to_reserve_on_growth))
286278
.and_then(|i| i.checked_add(offset_guard_bytes))
287279
.ok_or_else(|| format_err!("cannot allocate {} with guard regions", minimum))?;
288280
assert!(usize_is_multiple_of_host_page_size(request_bytes));

0 commit comments

Comments
 (0)