Trap registry

This commit is contained in:
Artur Jamro
2019-09-19 17:20:46 -07:00
committed by Dan Gohman
parent d1706117e5
commit fa9175f9e5
12 changed files with 248 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
use crate::address_map::{ModuleAddressMap, ValueLabelsRanges};
use crate::compilation::{Compilation, Relocations};
use crate::compilation::{Compilation, Relocations, Traps};
use crate::module::Module;
use crate::module_environ::FunctionBodyData;
use core::hash::Hasher;
@@ -64,6 +64,7 @@ pub struct ModuleCacheData {
address_transforms: ModuleAddressMap,
value_ranges: ValueLabelsRanges,
stack_slots: PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
traps: Traps,
}
type ModuleCacheDataTupleType = (
@@ -72,6 +73,7 @@ type ModuleCacheDataTupleType = (
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
Traps,
);
struct Sha256Hasher(Sha256);
@@ -231,6 +233,7 @@ impl ModuleCacheData {
address_transforms: data.2,
value_ranges: data.3,
stack_slots: data.4,
traps: data.5,
}
}
@@ -241,6 +244,7 @@ impl ModuleCacheData {
self.address_transforms,
self.value_ranges,
self.stack_slots,
self.traps,
)
}
}

View File

@@ -1,7 +1,7 @@
use super::config::tests::test_prolog;
use super::*;
use crate::address_map::{FunctionAddressMap, InstructionAddressMap};
use crate::compilation::{CodeAndJTOffsets, Relocation, RelocationTarget};
use crate::compilation::{CodeAndJTOffsets, Relocation, RelocationTarget, TrapInformation};
use crate::module::{MemoryPlan, MemoryStyle, Module};
use cranelift_codegen::{binemit, ir, isa, settings, ValueLocRange};
use cranelift_entity::EntityRef;
@@ -330,11 +330,24 @@ fn new_module_cache_data(rng: &mut impl Rng) -> ModuleCacheData {
})
.collect();
let traps = (0..rng.gen_range(0, 0xd))
.map(|i| {
((i..i + rng.gen_range(0, 4))
.map(|_| TrapInformation {
code_offset: rng.gen(),
source_loc: ir::SourceLoc::new(rng.gen()),
trap_code: ir::TrapCode::StackOverflow,
})
.collect())
})
.collect();
ModuleCacheData::from_tuple((
Compilation::new(funcs),
relocs,
trans,
value_ranges,
stack_slots,
traps,
))
}

View File

@@ -129,6 +129,20 @@ pub enum RelocationTarget {
/// Relocations to apply to function bodies.
pub type Relocations = PrimaryMap<DefinedFuncIndex, Vec<Relocation>>;
/// Information about trap.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct TrapInformation {
/// The offset of the trapping instruction in native code. It is relative to the beginning of the function.
pub code_offset: binemit::CodeOffset,
/// Location of trapping instruction in WebAssembly binary module.
pub source_loc: ir::SourceLoc,
/// Code of the trap.
pub trap_code: ir::TrapCode,
}
/// Information about traps associated with the functions where the traps are placed.
pub type Traps = PrimaryMap<DefinedFuncIndex, Vec<TrapInformation>>;
/// An error while compiling WebAssembly to machine code.
#[derive(Fail, Debug)]
pub enum CompileError {
@@ -156,6 +170,7 @@ pub trait Compiler {
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
Traps,
),
CompileError,
>;

View File

@@ -6,6 +6,7 @@ use crate::address_map::{
use crate::cache::{ModuleCacheData, ModuleCacheEntry};
use crate::compilation::{
CodeAndJTOffsets, Compilation, CompileError, Relocation, RelocationTarget, Relocations,
TrapInformation, Traps,
};
use crate::func_environ::{
get_func_name, get_imported_memory32_grow_name, get_imported_memory32_size_name,
@@ -103,6 +104,31 @@ impl RelocSink {
}
}
struct TrapSink {
pub traps: Vec<TrapInformation>,
}
impl TrapSink {
fn new() -> Self {
Self { traps: Vec::new() }
}
}
impl binemit::TrapSink for TrapSink {
fn trap(
&mut self,
code_offset: binemit::CodeOffset,
source_loc: ir::SourceLoc,
trap_code: ir::TrapCode,
) {
self.traps.push(TrapInformation {
code_offset,
source_loc,
trap_code,
});
}
}
fn get_function_address_map<'data>(
context: &Context,
data: &FunctionBodyData<'data>,
@@ -161,6 +187,7 @@ impl crate::compilation::Compiler for Cranelift {
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
Traps,
),
CompileError,
> {
@@ -180,6 +207,7 @@ impl crate::compilation::Compiler for Cranelift {
let mut address_transforms = PrimaryMap::with_capacity(function_body_inputs.len());
let mut value_ranges = PrimaryMap::with_capacity(function_body_inputs.len());
let mut stack_slots = PrimaryMap::with_capacity(function_body_inputs.len());
let mut traps = PrimaryMap::with_capacity(function_body_inputs.len());
function_body_inputs
.into_iter()
@@ -207,7 +235,7 @@ impl crate::compilation::Compiler for Cranelift {
let mut code_buf: Vec<u8> = Vec::new();
let mut reloc_sink = RelocSink::new(func_index);
let mut trap_sink = binemit::NullTrapSink {};
let mut trap_sink = TrapSink::new();
let mut stackmap_sink = binemit::NullStackmapSink {};
context
.compile_and_emit(
@@ -247,12 +275,21 @@ impl crate::compilation::Compiler for Cranelift {
address_transform,
ranges,
stack_slots,
trap_sink.traps,
))
})
.collect::<Result<Vec<_>, CompileError>>()?
.into_iter()
.for_each(
|(function, func_jt_offsets, relocs, address_transform, ranges, sss)| {
|(
function,
func_jt_offsets,
relocs,
address_transform,
ranges,
sss,
function_traps,
)| {
functions.push(CodeAndJTOffsets {
body: function,
jt_offsets: func_jt_offsets,
@@ -263,6 +300,7 @@ impl crate::compilation::Compiler for Cranelift {
}
value_ranges.push(ranges.unwrap_or(std::collections::HashMap::new()));
stack_slots.push(sss);
traps.push(function_traps);
},
);
@@ -274,6 +312,7 @@ impl crate::compilation::Compiler for Cranelift {
address_transforms,
value_ranges,
stack_slots,
traps,
));
cache_entry.update_data(&data);
data

View File

@@ -57,6 +57,7 @@ pub use crate::address_map::{
pub use crate::cache::{create_new_config as cache_create_new_config, init as cache_init};
pub use crate::compilation::{
Compilation, CompileError, Compiler, Relocation, RelocationTarget, Relocations,
TrapInformation, Traps,
};
pub use crate::cranelift::Cranelift;
pub use crate::func_environ::BuiltinFunctionIndex;