Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add guard pages to the front of linear memories #2977

Merged
merged 9 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ tracing-subscriber = "0.2.16"
wast = "36.0.0"
criterion = "0.3.4"
num_cpus = "1.13.0"
winapi = { version = "0.3.9", features = ['memoryapi'] }

[build-dependencies]
anyhow = "1.0.19"
Expand Down
5 changes: 1 addition & 4 deletions benches/thread_eager_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,7 @@ fn test_setup() -> (Engine, Module) {
memory_pages: 1,
..Default::default()
},
instance_limits: InstanceLimits {
count: pool_count,
memory_reservation_size: 1,
},
instance_limits: InstanceLimits { count: pool_count },
});
let engine = Engine::new(&config).unwrap();

Expand Down
2 changes: 2 additions & 0 deletions crates/cranelift/src/func_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
MemoryPlan {
style: MemoryStyle::Dynamic,
offset_guard_size,
pre_guard_size: _,
memory: _,
} => {
let heap_bound = func.create_global_value(ir::GlobalValueData::Load {
Expand All @@ -1276,6 +1277,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
MemoryPlan {
style: MemoryStyle::Static { bound },
offset_guard_size,
pre_guard_size: _,
memory: _,
} => (
Uimm64::new(offset_guard_size),
Expand Down
7 changes: 7 additions & 0 deletions crates/environ/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ pub struct MemoryPlan {
pub memory: Memory,
/// Our chosen implementation style.
pub style: MemoryStyle,
/// Chosen size of a guard page before the linear memory allocation.
pub pre_guard_size: u64,
/// Our chosen offset-guard size.
pub offset_guard_size: u64,
}
Expand All @@ -75,6 +77,11 @@ impl MemoryPlan {
memory,
style,
offset_guard_size,
pre_guard_size: if tunables.guard_before_linear_memory {
offset_guard_size
} else {
0
},
}
}
}
Expand Down
40 changes: 22 additions & 18 deletions crates/environ/src/tunables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,42 +32,46 @@ pub struct Tunables {

/// Whether or not to treat the static memory bound as the maximum for unbounded heaps.
pub static_memory_bound_is_maximum: bool,

/// Whether or not linear memory allocations will have a guard region at the
/// beginning of the allocation in addition to the end.
pub guard_before_linear_memory: bool,
}

impl Default for Tunables {
fn default() -> Self {
Self {
#[cfg(target_pointer_width = "32")]
/// Size in wasm pages of the bound for static memories.
static_memory_bound: 0x4000,
// 64-bit has tons of address space to static memories can have 4gb
// address space reservations liberally by default, allowing us to
// help eliminate bounds checks.
//
// Coupled with a 2 GiB address space guard it lets us translate
// wasm offsets into x86 offsets as aggressively as we can.
#[cfg(target_pointer_width = "64")]
/// Size in wasm pages of the bound for static memories.
///
/// When we allocate 4 GiB of address space, we can avoid the
/// need for explicit bounds checks.
static_memory_bound: 0x1_0000,
#[cfg(target_pointer_width = "64")]
static_memory_offset_guard_size: 0x8000_0000,

// For 32-bit we scale way down to 10MB of reserved memory. This
// impacts performance severely but allows us to have more than a
// few instances running around.
#[cfg(target_pointer_width = "32")]
static_memory_bound: (10 * (1 << 20)) / crate::WASM_PAGE_SIZE,
#[cfg(target_pointer_width = "32")]
/// Size in bytes of the offset guard for static memories.
static_memory_offset_guard_size: 0x1_0000,
#[cfg(target_pointer_width = "64")]
/// Size in bytes of the offset guard for static memories.
///
/// Allocating 2 GiB of address space lets us translate wasm
/// offsets into x86 offsets as aggressively as we can.
static_memory_offset_guard_size: 0x8000_0000,

/// Size in bytes of the offset guard for dynamic memories.
///
/// Allocate a small guard to optimize common cases but without
/// wasting too much memory.
// Size in bytes of the offset guard for dynamic memories.
//
// Allocate a small guard to optimize common cases but without
// wasting too much memory.
dynamic_memory_offset_guard_size: 0x1_0000,

generate_native_debuginfo: false,
parse_wasm_debuginfo: true,
interruptable: false,
consume_fuel: false,
static_memory_bound_is_maximum: false,
guard_before_linear_memory: true,
}
}
}
2 changes: 2 additions & 0 deletions crates/fuzzing/src/generators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct Config {
static_memory_maximum_size: Option<u32>,
static_memory_guard_size: Option<u32>,
dynamic_memory_guard_size: Option<u32>,
guard_before_linear_memory: bool,
}

impl Config {
Expand All @@ -82,6 +83,7 @@ impl Config {
.static_memory_maximum_size(self.static_memory_maximum_size.unwrap_or(0).into())
.static_memory_guard_size(self.static_memory_guard_size.unwrap_or(0).into())
.dynamic_memory_guard_size(self.dynamic_memory_guard_size.unwrap_or(0).into())
.guard_before_linear_memory(self.guard_before_linear_memory)
.cranelift_nan_canonicalization(self.canonicalize_nans)
.cranelift_opt_level(self.opt_level.to_wasmtime())
.interruptable(self.interruptable)
Expand Down
Loading