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:
Nick Fitzgerald
2022-12-14 16:26:45 -08:00
committed by GitHub
parent e03d65cca7
commit c0b587ac5f
198 changed files with 2494 additions and 4232 deletions

View File

@@ -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 {

View File

@@ -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>;