Support heaps with no offset-guard pages.
Also, say "guard-offset pages" rather than just "guard pages" to describe the region of a heap which is never accessible and which exists to support optimizations for heap accesses with offsets. And, introduce a `Uimm64` immediate type, and make all heap fields use `Uimm64` instead of `Imm64` since they really are unsigned.
This commit is contained in:
@@ -992,20 +992,20 @@ fn get_heap_addr(
|
||||
) -> (ir::Value, i32) {
|
||||
use std::cmp::min;
|
||||
|
||||
let guard_size: i64 = builder.func.heaps[heap].guard_size.into();
|
||||
debug_assert!(guard_size > 0, "Heap guard pages currently required");
|
||||
let mut adjusted_offset = u64::from(offset);
|
||||
let offset_guard_size: u64 = builder.func.heaps[heap].offset_guard_size.into();
|
||||
|
||||
// Generate `heap_addr` instructions that are friendly to CSE by checking offsets that are
|
||||
// multiples of the guard size. Add one to make sure that we check the pointer itself is in
|
||||
// bounds.
|
||||
//
|
||||
// For accesses on the outer skirts of the guard pages, we expect that we get a trap
|
||||
// even if the access goes beyond the guard pages. This is because the first byte pointed to is
|
||||
// inside the guard pages.
|
||||
let check_size = min(
|
||||
i64::from(u32::MAX),
|
||||
1 + (i64::from(offset) / guard_size) * guard_size,
|
||||
) as u32;
|
||||
// multiples of the offset-guard size. Add one to make sure that we check the pointer itself
|
||||
// is in bounds.
|
||||
if offset_guard_size != 0 {
|
||||
adjusted_offset = adjusted_offset / offset_guard_size * offset_guard_size;
|
||||
}
|
||||
|
||||
// For accesses on the outer skirts of the offset-guard pages, we expect that we get a trap
|
||||
// even if the access goes beyond the offset-guard pages. This is because the first byte
|
||||
// pointed to is inside the offset-guard pages.
|
||||
let check_size = min(u64::from(u32::MAX), 1 + adjusted_offset) as u32;
|
||||
let base = builder.ins().heap_addr(addr_ty, heap, addr32, check_size);
|
||||
|
||||
// Native load/store instructions take a signed `Offset32` immediate, so adjust the base
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//! wasm translation.
|
||||
|
||||
use cranelift_codegen::cursor::FuncCursor;
|
||||
use cranelift_codegen::ir::immediates::{Imm64, Offset32};
|
||||
use cranelift_codegen::ir::immediates::{Offset32, Uimm64};
|
||||
use cranelift_codegen::ir::types::*;
|
||||
use cranelift_codegen::ir::{self, InstBuilder};
|
||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
@@ -195,7 +195,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
func.create_heap(ir::HeapData {
|
||||
base: gv,
|
||||
min_size: 0.into(),
|
||||
guard_size: 0x8000_0000.into(),
|
||||
offset_guard_size: 0x8000_0000.into(),
|
||||
style: ir::HeapStyle::Static {
|
||||
bound: 0x1_0000_0000.into(),
|
||||
},
|
||||
@@ -221,9 +221,9 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
|
||||
func.create_table(ir::TableData {
|
||||
base_gv,
|
||||
min_size: Imm64::new(0),
|
||||
min_size: Uimm64::new(0),
|
||||
bound_gv,
|
||||
element_size: Imm64::new(i64::from(self.pointer_bytes()) * 2),
|
||||
element_size: Uimm64::from(u64::from(self.pointer_bytes()) * 2),
|
||||
index_type: I32,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user