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

Added basic AddressMap support for singlepass #1870

Merged
merged 22 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7745875
Added address map instructions for traps in singlepass
syrusakbary Dec 4, 2020
55d001d
Debug frameinfos
syrusakbary Dec 4, 2020
917eadb
Improve debugging of FunctionInfo
syrusakbary Dec 4, 2020
2178f27
Added stackoverflow traps on function calls in singlepass
syrusakbary Dec 4, 2020
cc0d595
Fixed last tests in Linux
syrusakbary Dec 4, 2020
6eb897d
Revert "Debug frameinfos"
syrusakbary Dec 4, 2020
24960b7
Merge branch 'master' into singlepass-addressmap
syrusakbary Dec 4, 2020
bdb0a93
Update address_map.rs
syrusakbary Dec 4, 2020
9a5336f
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 4, 2020
34cf011
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 4, 2020
0893de0
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 4, 2020
6e38d72
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 4, 2020
785f41b
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 4, 2020
b7eb928
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 4, 2020
f119af7
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 4, 2020
263504d
Improved instruction mapping
syrusakbary Dec 8, 2020
30f622f
Merge branch 'master' of github.com:wasmerio/wasmer into singlepass-a…
syrusakbary Dec 8, 2020
b54df7e
Fixed lint issues in singlepass
syrusakbary Dec 8, 2020
f6c0d4f
Fix lint in singlepass
syrusakbary Dec 8, 2020
5a2c14a
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 8, 2020
bfbb0e1
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary Dec 8, 2020
f2356ed
Fix linting issues
syrusakbary Dec 8, 2020
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
20 changes: 20 additions & 0 deletions lib/compiler-singlepass/src/address_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use wasmer_compiler::{FunctionAddressMap, FunctionBodyData, InstructionAddressMap, SourceLoc};

pub fn get_function_address_map<'data>(
instructions: Vec<InstructionAddressMap>,
data: &FunctionBodyData<'data>,
body_len: usize,
) -> FunctionAddressMap {
// Generate source loc for a function start/end to identify boundary within module.
// It will wrap around if byte code is larger than 4 GB.
let start_srcloc = SourceLoc::new(data.module_offset as u32);
let end_srcloc = SourceLoc::new((data.module_offset + data.data.len()) as u32);

FunctionAddressMap {
instructions,
start_srcloc,
end_srcloc,
body_offset: 0,
body_len,
}
}
105 changes: 84 additions & 21 deletions lib/compiler-singlepass/src/codegen_x64.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::address_map::get_function_address_map;
use crate::{common_decl::*, config::Singlepass, emitter_x64::*, machine::Machine, x64_decl::*};
use dynasmrt::{x64::Assembler, DynamicLabel};
use smallvec::{smallvec, SmallVec};
Expand All @@ -8,8 +9,8 @@ use wasmer_compiler::wasmparser::{
};
use wasmer_compiler::{
CompiledFunction, CompiledFunctionFrameInfo, CustomSection, CustomSectionProtection,
FunctionBody, Relocation, RelocationKind, RelocationTarget, SectionBody, SectionIndex,
TrapInformation,
FunctionBody, FunctionBodyData, InstructionAddressMap, Relocation, RelocationKind,
RelocationTarget, SectionBody, SectionIndex, SourceLoc, TrapInformation,
};
use wasmer_types::{
entity::{EntityRef, PrimaryMap, SecondaryMap},
Expand Down Expand Up @@ -80,6 +81,14 @@ pub struct FuncGen<'a> {

/// A set of special labels for trapping.
special_labels: SpecialLabelSet,

/// The source location for the current operator.
src_loc: u32,

/// Map from byte offset into wasm function to range of native instructions.
///
// Important: all instructions must be ordered.
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
instructions_address_map: Vec<InstructionAddressMap>,
}

struct SpecialLabelSet {
Expand Down Expand Up @@ -251,6 +260,11 @@ struct I2O1 {
}

impl<'a> FuncGen<'a> {
/// Set the source location of the Wasm to the given offset.
pub fn set_srcloc(&mut self, offset: u32) {
self.src_loc = offset;
}

fn get_location_released(&mut self, loc: Location) -> Location {
self.machine.release_locations(&mut self.assembler, &[loc]);
loc
Expand Down Expand Up @@ -300,19 +314,21 @@ impl<'a> FuncGen<'a> {
code: TrapCode,
f: F,
) -> R {
let begin = self.assembler.get_offset().0;
let offset = self.assembler.get_offset().0;
let ret = f(self);
let end = self.assembler.get_offset().0;
for i in begin..end {
self.trap_table.offset_to_code.insert(i, code);
}
self.mark_instruction_address_end(offset);
ret
}

/// Marks one address as trappable with trap code `code`.
fn mark_address_with_trap_code(&mut self, code: TrapCode) {
let offset = self.assembler.get_offset().0;
self.trap_table.offset_to_code.insert(offset, code);
self.mark_instruction_address_end(offset);
}

/// Canonicalizes the floating point value at `input` into `output`.
Expand Down Expand Up @@ -379,17 +395,21 @@ impl<'a> FuncGen<'a> {
Location::Imm64(_) | Location::Imm32(_) => {
self.assembler.emit_mov(sz, loc, Location::GPR(GPR::RCX)); // must not be used during div (rax, rdx)
self.mark_trappable();
let offset = self.assembler.get_offset().0;
self.trap_table
.offset_to_code
.insert(self.assembler.get_offset().0, TrapCode::IntegerOverflow);
.insert(offset, TrapCode::IntegerOverflow);
op(&mut self.assembler, sz, Location::GPR(GPR::RCX));
self.mark_instruction_address_end(offset);
}
_ => {
self.mark_trappable();
let offset = self.assembler.get_offset().0;
self.trap_table
.offset_to_code
.insert(self.assembler.get_offset().0, TrapCode::IntegerOverflow);
.insert(offset, TrapCode::IntegerOverflow);
op(&mut self.assembler, sz, loc);
self.mark_instruction_address_end(offset);
}
}
}
Expand Down Expand Up @@ -1473,17 +1493,21 @@ impl<'a> FuncGen<'a> {
);

self.assembler.emit_label(trap_overflow);
let offset = self.assembler.get_offset().0;
self.trap_table
.offset_to_code
.insert(self.assembler.get_offset().0, TrapCode::IntegerOverflow);
.insert(offset, TrapCode::IntegerOverflow);
self.assembler.emit_ud2();
self.mark_instruction_address_end();

self.assembler.emit_label(trap_badconv);
self.trap_table.offset_to_code.insert(
self.assembler.get_offset().0,
TrapCode::BadConversionToInteger,
);

let offset = self.assembler.get_offset().0;
self.trap_table
.offset_to_code
.insert(offset, TrapCode::BadConversionToInteger);
self.assembler.emit_ud2();
self.mark_instruction_address_end();

self.assembler.emit_label(end);
}
Expand Down Expand Up @@ -1622,17 +1646,20 @@ impl<'a> FuncGen<'a> {
);

self.assembler.emit_label(trap_overflow);
let offset = self.assembler.get_offset().0;
self.trap_table
.offset_to_code
.insert(self.assembler.get_offset().0, TrapCode::IntegerOverflow);
.insert(offset, TrapCode::IntegerOverflow);
self.assembler.emit_ud2();
self.mark_instruction_address_end(offset);

self.assembler.emit_label(trap_badconv);
self.trap_table.offset_to_code.insert(
self.assembler.get_offset().0,
TrapCode::BadConversionToInteger,
);
let offset = self.assembler.get_offset().0;
self.trap_table
.offset_to_code
.insert(offset, TrapCode::BadConversionToInteger);
self.assembler.emit_ud2();
self.mark_instruction_address_end(offset);

self.assembler.emit_label(end);
}
Expand Down Expand Up @@ -1754,6 +1781,14 @@ impl<'a> FuncGen<'a> {

// TODO: Full preemption by explicit signal checking

// We insert set StackOverflow as the default trap that can happen
// anywhere in the function prologue for sake of simplicity.
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
let offset = 0;
self.trap_table
.offset_to_code
.insert(offset, TrapCode::StackOverflow);
self.mark_instruction_address_end(offset);

if self.machine.state.wasm_inst_offset != std::usize::MAX {
return Err(CodegenError {
message: "emit_head: wasm_inst_offset not std::usize::MAX".to_string(),
Expand All @@ -1762,6 +1797,16 @@ impl<'a> FuncGen<'a> {
Ok(())
}

/// Pushes the instruction to the address map, calculating the offset from a
/// provided beginning address.
fn mark_instruction_address_end(&mut self, begin: u32) {
self.instructions_address_map.push(InstructionAddressMap {
srcloc: SourceLoc::new(self.src_loc),
code_offset: begin,
code_len: self.assembler.get_offset().0 - begin,
});
}

pub fn new(
module: &'a ModuleInfo,
config: &'a Singlepass,
Expand Down Expand Up @@ -1819,6 +1864,8 @@ impl<'a> FuncGen<'a> {
trap_table: TrapTable::default(),
relocations: vec![],
special_labels,
src_loc: 0,
instructions_address_map: vec![],
};
fg.emit_head()?;
Ok(fg)
Expand Down Expand Up @@ -5165,7 +5212,12 @@ impl<'a> FuncGen<'a> {

self.emit_call_sysv(
|this| {
let offset = self.assembler.get_offset().0;
this.trap_table
.offset_to_code
.insert(offset, TrapCode::StackOverflow);
this.assembler.emit_call_location(Location::GPR(GPR::RAX));
self.mark_instruction_address_end();
},
params.iter().copied(),
)?;
Expand Down Expand Up @@ -5358,10 +5410,15 @@ impl<'a> FuncGen<'a> {
),
);
} else {
let offset = self.assembler.get_offset().0;
this.trap_table
.offset_to_code
.insert(offset, TrapCode::StackOverflow);
this.assembler.emit_call_location(Location::Memory(
GPR::RAX,
vmcaller_checked_anyfunc_func_ptr as i32,
));
self.mark_instruction_address_end(offset);
}
},
params.iter().copied(),
Expand Down Expand Up @@ -6128,11 +6185,12 @@ impl<'a> FuncGen<'a> {
}
Operator::Unreachable => {
self.mark_trappable();
self.trap_table.offset_to_code.insert(
self.assembler.get_offset().0,
TrapCode::UnreachableCodeReached,
);
let offset = self.assembler.get_offset().0;
self.trap_table
.offset_to_code
.insert(offset, TrapCode::UnreachableCodeReached);
self.assembler.emit_ud2();
self.mark_instruction_address_end(offset);
self.unreachable_depth = 1;
}
Operator::Return => {
Expand Down Expand Up @@ -8125,7 +8183,7 @@ impl<'a> FuncGen<'a> {
Ok(())
}

pub fn finalize(mut self) -> CompiledFunction {
pub fn finalize(mut self, data: &FunctionBodyData) -> CompiledFunction {
// Generate actual code for special labels.
self.assembler
.emit_label(self.special_labels.integer_division_by_zero);
Expand Down Expand Up @@ -8153,6 +8211,11 @@ impl<'a> FuncGen<'a> {

// Notify the assembler backend to generate necessary code at end of function.
self.assembler.finalize_function();

let body_len = self.assembler.get_offset().0;
let instructions_address_map = self.instructions_address_map;
let address_map = get_function_address_map(instructions_address_map, data, body_len);

CompiledFunction {
body: FunctionBody {
body: self.assembler.finalize().unwrap().to_vec(),
Expand All @@ -8170,7 +8233,7 @@ impl<'a> FuncGen<'a> {
trap_code: code,
})
.collect(),
..Default::default()
address_map,
},
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/compiler-singlepass/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,12 @@ impl Compiler for SinglepassCompiler {
.map_err(to_compile_error)?;

while generator.has_control_frames() {
generator.set_srcloc(reader.original_position() as u32);
let op = reader.read_operator().map_err(to_compile_error)?;
generator.feed_operator(op).map_err(to_compile_error)?;
}

Ok(generator.finalize())
Ok(generator.finalize(&input))
})
.collect::<Result<Vec<CompiledFunction>, CompileError>>()?
.into_iter()
Expand Down
1 change: 1 addition & 0 deletions lib/compiler-singlepass/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! Compared to Cranelift and LLVM, Singlepass compiles much faster but has worse
//! runtime performance.

mod address_map;
mod codegen_x64;
mod common_decl;
mod compiler;
Expand Down
1 change: 1 addition & 0 deletions lib/engine/src/trap/frame_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ impl ModuleInfoFrameInfo {
}
}

#[derive(Debug)]
struct FunctionInfo {
start: usize,
local_index: LocalFunctionIndex,
Expand Down