Remove heaps from core Cranelift, push them into cranelift-wasm (#5386)
* cranelift-wasm: translate Wasm loads into lower-level CLIF operations
Rather than using `heap_{load,store,addr}`.
* cranelift: Remove the `heap_{addr,load,store}` instructions
These are now legalized in the `cranelift-wasm` frontend.
* cranelift: Remove the `ir::Heap` entity from CLIF
* Port basic memory operation tests to .wat filetests
* Remove test for verifying CLIF heaps
* Remove `heap_addr` from replace_branching_instructions_and_cfg_predecessors.clif test
* Remove `heap_addr` from readonly.clif test
* Remove `heap_addr` from `table_addr.clif` test
* Remove `heap_addr` from the simd-fvpromote_low.clif test
* Remove `heap_addr` from simd-fvdemote.clif test
* Remove `heap_addr` from the load-op-store.clif test
* Remove the CLIF heap runtest
* Remove `heap_addr` from the global_value.clif test
* Remove `heap_addr` from fpromote.clif runtests
* Remove `heap_addr` from fdemote.clif runtests
* Remove `heap_addr` from memory.clif parser test
* Remove `heap_addr` from reject_load_readonly.clif test
* Remove `heap_addr` from reject_load_notrap.clif test
* Remove `heap_addr` from load_readonly_notrap.clif test
* Remove `static-heap-without-guard-pages.clif` test
Will be subsumed when we port `make-heap-load-store-tests.sh` to generating
`.wat` tests.
* Remove `static-heap-with-guard-pages.clif` test
Will be subsumed when we port `make-heap-load-store-tests.sh` over to `.wat`
tests.
* Remove more heap tests
These will be subsumed by porting `make-heap-load-store-tests.sh` over to `.wat`
tests.
* Remove `heap_addr` from `simple-alias.clif` test
* Remove `heap_addr` from partial-redundancy.clif test
* Remove `heap_addr` from multiple-blocks.clif test
* Remove `heap_addr` from fence.clif test
* Remove `heap_addr` from extends.clif test
* Remove runtests that rely on heaps
Heaps are not a thing in CLIF or the interpreter anymore
* Add generated load/store `.wat` tests
* Enable memory-related wasm features in `.wat` tests
* Remove CLIF heap from fcmp-mem-bug.clif test
* Add a mode for compiling `.wat` all the way to assembly in filetests
* Also generate WAT to assembly tests in `make-load-store-tests.sh`
* cargo fmt
* Reinstate `f{de,pro}mote.clif` tests without the heap bits
* Remove undefined doc link
* Remove outdated SVG and dot file from docs
* Add docs about `None` returns for base address computation helpers
* Factor out `env.heap_access_spectre_mitigation()` to a local
* Expand docs for `FuncEnvironment::heaps` trait method
* Restore f{de,pro}mote+load clif runtests with stack memory
This commit is contained in:
@@ -10,8 +10,8 @@ use crate::func_translator::FuncTranslator;
|
||||
use crate::state::FuncTranslationState;
|
||||
use crate::WasmType;
|
||||
use crate::{
|
||||
DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex,
|
||||
Table, TableIndex, TypeIndex, WasmFuncType, WasmResult,
|
||||
DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Heap, HeapData,
|
||||
HeapStyle, Memory, MemoryIndex, Table, TableIndex, TypeIndex, WasmFuncType, WasmResult,
|
||||
};
|
||||
use core::convert::TryFrom;
|
||||
use cranelift_codegen::cursor::FuncCursor;
|
||||
@@ -212,6 +212,9 @@ pub struct DummyFuncEnvironment<'dummy_environment> {
|
||||
|
||||
/// Expected reachability data (before/after for each op) to assert. This is used for testing.
|
||||
expected_reachability: Option<ExpectedReachability>,
|
||||
|
||||
/// Heaps we have created to implement Wasm linear memories.
|
||||
pub heaps: PrimaryMap<Heap, HeapData>,
|
||||
}
|
||||
|
||||
impl<'dummy_environment> DummyFuncEnvironment<'dummy_environment> {
|
||||
@@ -223,6 +226,7 @@ impl<'dummy_environment> DummyFuncEnvironment<'dummy_environment> {
|
||||
Self {
|
||||
mod_info,
|
||||
expected_reachability,
|
||||
heaps: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +254,10 @@ impl<'dummy_environment> TargetEnvironment for DummyFuncEnvironment<'dummy_envir
|
||||
fn target_config(&self) -> TargetFrontendConfig {
|
||||
self.mod_info.config
|
||||
}
|
||||
|
||||
fn heap_access_spectre_mitigation(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environment> {
|
||||
@@ -275,7 +283,11 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
})
|
||||
}
|
||||
|
||||
fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> WasmResult<ir::Heap> {
|
||||
fn heaps(&self) -> &PrimaryMap<Heap, HeapData> {
|
||||
&self.heaps
|
||||
}
|
||||
|
||||
fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> WasmResult<Heap> {
|
||||
// Create a static heap whose base address is stored at `vmctx+0`.
|
||||
let addr = func.create_global_value(ir::GlobalValueData::VMContext);
|
||||
let gv = func.create_global_value(ir::GlobalValueData::Load {
|
||||
@@ -285,12 +297,12 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
readonly: true,
|
||||
});
|
||||
|
||||
Ok(func.create_heap(ir::HeapData {
|
||||
Ok(self.heaps.push(HeapData {
|
||||
base: gv,
|
||||
min_size: 0.into(),
|
||||
offset_guard_size: 0x8000_0000.into(),
|
||||
style: ir::HeapStyle::Static {
|
||||
bound: 0x1_0000_0000.into(),
|
||||
min_size: 0,
|
||||
offset_guard_size: 0x8000_0000,
|
||||
style: HeapStyle::Static {
|
||||
bound: 0x1_0000_0000,
|
||||
},
|
||||
index_type: I32,
|
||||
}))
|
||||
@@ -455,7 +467,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
&mut self,
|
||||
mut pos: FuncCursor,
|
||||
_index: MemoryIndex,
|
||||
_heap: ir::Heap,
|
||||
_heap: Heap,
|
||||
_val: ir::Value,
|
||||
) -> WasmResult<ir::Value> {
|
||||
Ok(pos.ins().iconst(I32, -1))
|
||||
@@ -465,7 +477,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
&mut self,
|
||||
mut pos: FuncCursor,
|
||||
_index: MemoryIndex,
|
||||
_heap: ir::Heap,
|
||||
_heap: Heap,
|
||||
) -> WasmResult<ir::Value> {
|
||||
Ok(pos.ins().iconst(I32, -1))
|
||||
}
|
||||
@@ -474,9 +486,9 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
&mut self,
|
||||
_pos: FuncCursor,
|
||||
_src_index: MemoryIndex,
|
||||
_src_heap: ir::Heap,
|
||||
_src_heap: Heap,
|
||||
_dst_index: MemoryIndex,
|
||||
_dst_heap: ir::Heap,
|
||||
_dst_heap: Heap,
|
||||
_dst: ir::Value,
|
||||
_src: ir::Value,
|
||||
_len: ir::Value,
|
||||
@@ -488,7 +500,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
&mut self,
|
||||
_pos: FuncCursor,
|
||||
_index: MemoryIndex,
|
||||
_heap: ir::Heap,
|
||||
_heap: Heap,
|
||||
_dst: ir::Value,
|
||||
_val: ir::Value,
|
||||
_len: ir::Value,
|
||||
@@ -500,7 +512,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
&mut self,
|
||||
_pos: FuncCursor,
|
||||
_index: MemoryIndex,
|
||||
_heap: ir::Heap,
|
||||
_heap: Heap,
|
||||
_seg_index: u32,
|
||||
_dst: ir::Value,
|
||||
_src: ir::Value,
|
||||
@@ -625,7 +637,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
&mut self,
|
||||
mut pos: FuncCursor,
|
||||
_index: MemoryIndex,
|
||||
_heap: ir::Heap,
|
||||
_heap: Heap,
|
||||
_addr: ir::Value,
|
||||
_expected: ir::Value,
|
||||
_timeout: ir::Value,
|
||||
@@ -637,7 +649,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
|
||||
&mut self,
|
||||
mut pos: FuncCursor,
|
||||
_index: MemoryIndex,
|
||||
_heap: ir::Heap,
|
||||
_heap: Heap,
|
||||
_addr: ir::Value,
|
||||
_count: ir::Value,
|
||||
) -> WasmResult<ir::Value> {
|
||||
@@ -653,6 +665,10 @@ impl TargetEnvironment for DummyEnvironment {
|
||||
fn target_config(&self) -> TargetFrontendConfig {
|
||||
self.info.config
|
||||
}
|
||||
|
||||
fn heap_access_spectre_mitigation(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
|
||||
|
||||
@@ -8,14 +8,16 @@
|
||||
|
||||
use crate::state::FuncTranslationState;
|
||||
use crate::{
|
||||
DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex,
|
||||
Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmFuncType, WasmResult, WasmType,
|
||||
DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Heap, HeapData, Memory, MemoryIndex,
|
||||
SignatureIndex, Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmFuncType,
|
||||
WasmResult, WasmType,
|
||||
};
|
||||
use core::convert::From;
|
||||
use cranelift_codegen::cursor::FuncCursor;
|
||||
use cranelift_codegen::ir::immediates::Offset32;
|
||||
use cranelift_codegen::ir::{self, InstBuilder};
|
||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use cranelift_frontend::FunctionBuilder;
|
||||
use std::boxed::Box;
|
||||
use std::string::ToString;
|
||||
@@ -46,6 +48,9 @@ pub trait TargetEnvironment {
|
||||
/// Get the information needed to produce Cranelift IR for the given target.
|
||||
fn target_config(&self) -> TargetFrontendConfig;
|
||||
|
||||
/// Whether to enable Spectre mitigations for heap accesses.
|
||||
fn heap_access_spectre_mitigation(&self) -> bool;
|
||||
|
||||
/// Get the Cranelift integer type to use for native pointers.
|
||||
///
|
||||
/// This returns `I64` for 64-bit architectures and `I32` for 32-bit architectures.
|
||||
@@ -112,11 +117,20 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
index: GlobalIndex,
|
||||
) -> WasmResult<GlobalVariable>;
|
||||
|
||||
/// Get the heaps for this function environment.
|
||||
///
|
||||
/// The returned map should provide heap format details (encoded in
|
||||
/// `HeapData`) for each `Heap` that was previously returned by
|
||||
/// `make_heap()`. The translator will first call make_heap for each Wasm
|
||||
/// memory, and then later when translating code, will invoke `heaps()` to
|
||||
/// learn how to access the environment's implementation of each memory.
|
||||
fn heaps(&self) -> &PrimaryMap<Heap, HeapData>;
|
||||
|
||||
/// Set up the necessary preamble definitions in `func` to access the linear memory identified
|
||||
/// by `index`.
|
||||
///
|
||||
/// The index space covers both imported and locally declared memories.
|
||||
fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult<ir::Heap>;
|
||||
fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult<Heap>;
|
||||
|
||||
/// Set up the necessary preamble definitions in `func` to access the table identified
|
||||
/// by `index`.
|
||||
@@ -206,7 +220,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
&mut self,
|
||||
pos: FuncCursor,
|
||||
index: MemoryIndex,
|
||||
heap: ir::Heap,
|
||||
heap: Heap,
|
||||
val: ir::Value,
|
||||
) -> WasmResult<ir::Value>;
|
||||
|
||||
@@ -220,7 +234,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
&mut self,
|
||||
pos: FuncCursor,
|
||||
index: MemoryIndex,
|
||||
heap: ir::Heap,
|
||||
heap: Heap,
|
||||
) -> WasmResult<ir::Value>;
|
||||
|
||||
/// Translate a `memory.copy` WebAssembly instruction.
|
||||
@@ -231,9 +245,9 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
&mut self,
|
||||
pos: FuncCursor,
|
||||
src_index: MemoryIndex,
|
||||
src_heap: ir::Heap,
|
||||
src_heap: Heap,
|
||||
dst_index: MemoryIndex,
|
||||
dst_heap: ir::Heap,
|
||||
dst_heap: Heap,
|
||||
dst: ir::Value,
|
||||
src: ir::Value,
|
||||
len: ir::Value,
|
||||
@@ -247,7 +261,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
&mut self,
|
||||
pos: FuncCursor,
|
||||
index: MemoryIndex,
|
||||
heap: ir::Heap,
|
||||
heap: Heap,
|
||||
dst: ir::Value,
|
||||
val: ir::Value,
|
||||
len: ir::Value,
|
||||
@@ -263,7 +277,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
&mut self,
|
||||
pos: FuncCursor,
|
||||
index: MemoryIndex,
|
||||
heap: ir::Heap,
|
||||
heap: Heap,
|
||||
seg_index: u32,
|
||||
dst: ir::Value,
|
||||
src: ir::Value,
|
||||
@@ -420,7 +434,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
&mut self,
|
||||
pos: FuncCursor,
|
||||
index: MemoryIndex,
|
||||
heap: ir::Heap,
|
||||
heap: Heap,
|
||||
addr: ir::Value,
|
||||
expected: ir::Value,
|
||||
timeout: ir::Value,
|
||||
@@ -440,7 +454,7 @@ pub trait FuncEnvironment: TargetEnvironment {
|
||||
&mut self,
|
||||
pos: FuncCursor,
|
||||
index: MemoryIndex,
|
||||
heap: ir::Heap,
|
||||
heap: Heap,
|
||||
addr: ir::Value,
|
||||
count: ir::Value,
|
||||
) -> WasmResult<ir::Value>;
|
||||
|
||||
Reference in New Issue
Block a user