-
Notifications
You must be signed in to change notification settings - Fork 824
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
+107
−21
Merged
Changes from 8 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 55d001d
Debug frameinfos
syrusakbary 917eadb
Improve debugging of FunctionInfo
syrusakbary 2178f27
Added stackoverflow traps on function calls in singlepass
syrusakbary cc0d595
Fixed last tests in Linux
syrusakbary 6eb897d
Revert "Debug frameinfos"
syrusakbary 24960b7
Merge branch 'master' into singlepass-addressmap
syrusakbary bdb0a93
Update address_map.rs
syrusakbary 9a5336f
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary 34cf011
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary 0893de0
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary 6e38d72
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary 785f41b
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary b7eb928
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary f119af7
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary 263504d
Improved instruction mapping
syrusakbary 30f622f
Merge branch 'master' of github.com:wasmerio/wasmer into singlepass-a…
syrusakbary b54df7e
Fixed lint issues in singlepass
syrusakbary f6c0d4f
Fix lint in singlepass
syrusakbary 5a2c14a
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary bfbb0e1
Update lib/compiler-singlepass/src/codegen_x64.rs
syrusakbary f2356ed
Fix linting issues
syrusakbary File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 artificial srcloc for 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, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}; | ||
|
@@ -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}, | ||
|
@@ -80,6 +81,12 @@ pub struct FuncGen<'a> { | |
|
||
/// A set of special labels for trapping. | ||
special_labels: SpecialLabelSet, | ||
|
||
/// The source location for the current operator | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
src_loc: u32, | ||
|
||
/// All the InstructionAddressMap | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
instructions_address_map: Vec<InstructionAddressMap>, | ||
} | ||
|
||
struct SpecialLabelSet { | ||
|
@@ -251,6 +258,11 @@ struct I2O1 { | |
} | ||
|
||
impl<'a> FuncGen<'a> { | ||
/// Set the source location of the Wasm to the given offset | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
|
@@ -306,13 +318,23 @@ impl<'a> FuncGen<'a> { | |
for i in begin..end { | ||
self.trap_table.offset_to_code.insert(i, code); | ||
} | ||
self.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: begin, | ||
code_len: end - begin, | ||
}); | ||
nlewycky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
} | ||
|
||
/// Canonicalizes the floating point value at `input` into `output`. | ||
|
@@ -379,16 +401,28 @@ 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.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
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_trappable(); | ||
let offset = self.assembler.get_offset().0; | ||
self.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a problem (see earlier comment about DIV lengths). |
||
}); | ||
self.trap_table | ||
.offset_to_code | ||
.insert(self.assembler.get_offset().0, TrapCode::IntegerOverflow); | ||
.insert(offset, TrapCode::IntegerOverflow); | ||
op(&mut self.assembler, sz, loc); | ||
} | ||
} | ||
|
@@ -1473,16 +1507,28 @@ impl<'a> FuncGen<'a> { | |
); | ||
|
||
self.assembler.emit_label(trap_overflow); | ||
let offset = self.assembler.get_offset().0; | ||
self.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
self.trap_table | ||
.offset_to_code | ||
.insert(self.assembler.get_offset().0, TrapCode::IntegerOverflow); | ||
.insert(offset, TrapCode::IntegerOverflow); | ||
self.assembler.emit_ud2(); | ||
|
||
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.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
self.trap_table | ||
.offset_to_code | ||
.insert(offset, TrapCode::BadConversionToInteger); | ||
self.assembler.emit_ud2(); | ||
|
||
self.assembler.emit_label(end); | ||
|
@@ -1622,16 +1668,27 @@ impl<'a> FuncGen<'a> { | |
); | ||
|
||
self.assembler.emit_label(trap_overflow); | ||
let offset = self.assembler.get_offset().0; | ||
self.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
self.trap_table | ||
.offset_to_code | ||
.insert(self.assembler.get_offset().0, TrapCode::IntegerOverflow); | ||
.insert(offset, TrapCode::IntegerOverflow); | ||
self.assembler.emit_ud2(); | ||
|
||
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.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
self.trap_table | ||
.offset_to_code | ||
.insert(offset, TrapCode::BadConversionToInteger); | ||
self.assembler.emit_ud2(); | ||
|
||
self.assembler.emit_label(end); | ||
|
@@ -1754,6 +1811,17 @@ 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
|
||
self.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: 0, | ||
code_len: self.assembler.get_offset().0, | ||
}); | ||
self.trap_table | ||
.offset_to_code | ||
.insert(0, TrapCode::StackOverflow); | ||
|
||
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(), | ||
|
@@ -1819,6 +1887,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) | ||
|
@@ -5165,6 +5235,15 @@ impl<'a> FuncGen<'a> { | |
|
||
self.emit_call_sysv( | ||
|this| { | ||
let offset = this.assembler.get_offset().0; | ||
this.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(this.src_loc), | ||
code_offset: offset, | ||
code_len: 3, | ||
}); | ||
this.trap_table | ||
.offset_to_code | ||
.insert(offset, TrapCode::StackOverflow); | ||
this.assembler.emit_call_location(Location::GPR(GPR::RAX)); | ||
}, | ||
params.iter().copied(), | ||
|
@@ -5358,6 +5437,15 @@ impl<'a> FuncGen<'a> { | |
), | ||
); | ||
} else { | ||
let offset = this.assembler.get_offset().0; | ||
this.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(this.src_loc), | ||
code_offset: offset, | ||
code_len: 3, | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
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, | ||
|
@@ -6128,10 +6216,15 @@ 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.instructions_address_map.push(InstructionAddressMap { | ||
srcloc: SourceLoc::new(self.src_loc), | ||
code_offset: offset, | ||
code_len: 2, // TODO: Check this length | ||
syrusakbary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
self.trap_table | ||
.offset_to_code | ||
.insert(offset, TrapCode::UnreachableCodeReached); | ||
self.assembler.emit_ud2(); | ||
self.unreachable_depth = 1; | ||
} | ||
|
@@ -8125,7 +8218,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); | ||
|
@@ -8153,6 +8246,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(), | ||
|
@@ -8170,7 +8268,7 @@ impl<'a> FuncGen<'a> { | |
trap_code: code, | ||
}) | ||
.collect(), | ||
..Default::default() | ||
address_map, | ||
}, | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you reword this comment? This comment turns up cranelift source code if you search for "Generate artificial srcloc for" which is unfortunate, given that the rest of the function doesn't match anything in cranelift.