Disable LLVM stackmap on Windows

This commit is contained in:
losfair
2019-08-21 15:23:11 -07:00
parent 6d7a91a271
commit 53ebcc355a
2 changed files with 116 additions and 112 deletions

View File

@ -226,122 +226,125 @@ impl LLVMBackend {
let buffer = Arc::new(Buffer::LlvmMemory(memory_buffer)); let buffer = Arc::new(Buffer::LlvmMemory(memory_buffer));
let raw_stackmap = unsafe { #[cfg(all(any(target_os = "linux", target_os = "macos"), target_arch = "x86_64"))]
std::slice::from_raw_parts( {
llvm_backend_get_stack_map_ptr(module), let raw_stackmap = unsafe {
llvm_backend_get_stack_map_size(module), std::slice::from_raw_parts(
) llvm_backend_get_stack_map_ptr(module),
}; llvm_backend_get_stack_map_size(module),
if raw_stackmap.len() > 0 {
let map = stackmap::StackMap::parse(raw_stackmap).unwrap();
let (code_ptr, code_size) = unsafe {
(
llvm_backend_get_code_ptr(module),
llvm_backend_get_code_size(module),
) )
}; };
let mut msm = ModuleStateMap { if raw_stackmap.len() > 0 {
local_functions: Default::default(), let map = stackmap::StackMap::parse(raw_stackmap).unwrap();
total_size: code_size,
};
let num_local_functions = let (code_ptr, code_size) = unsafe {
module_info.func_assoc.len() - module_info.imported_functions.len(); (
let mut local_func_id_to_addr: Vec<usize> = Vec::with_capacity(num_local_functions); llvm_backend_get_code_ptr(module),
llvm_backend_get_code_size(module),
// All local functions. )
for index in module_info.imported_functions.len()..module_info.func_assoc.len() { };
let name = if cfg!(target_os = "macos") { let mut msm = ModuleStateMap {
format!("_fn{}", index) local_functions: Default::default(),
} else { total_size: code_size,
format!("fn{}", index)
}; };
let c_str = CString::new(name).unwrap(); let num_local_functions =
let ptr = unsafe { get_func_symbol(module, c_str.as_ptr()) }; module_info.func_assoc.len() - module_info.imported_functions.len();
let mut local_func_id_to_addr: Vec<usize> = Vec::with_capacity(num_local_functions);
assert!(!ptr.is_null()); // All local functions.
local_func_id_to_addr.push(ptr as usize); for index in module_info.imported_functions.len()..module_info.func_assoc.len() {
} let name = if cfg!(target_os = "macos") {
format!("_fn{}", index)
} else {
format!("fn{}", index)
};
let mut addr_to_size_record: BTreeMap<usize, &StkSizeRecord> = BTreeMap::new(); let c_str = CString::new(name).unwrap();
let ptr = unsafe { get_func_symbol(module, c_str.as_ptr()) };
for record in &map.stk_size_records { assert!(!ptr.is_null());
addr_to_size_record.insert(record.function_address as usize, record); local_func_id_to_addr.push(ptr as usize);
}
let mut map_records: BTreeMap<usize, &StkMapRecord> = BTreeMap::new();
for record in &map.stk_map_records {
map_records.insert(record.patchpoint_id as usize, record);
}
for ((start_id, start_entry), (end_id, end_entry)) in stackmaps
.entries
.iter()
.enumerate()
.step_by(2)
.zip(stackmaps.entries.iter().enumerate().skip(1).step_by(2))
{
if let Some(map_record) = map_records.get(&start_id) {
assert_eq!(start_id, map_record.patchpoint_id as usize);
assert!(start_entry.is_start);
assert!(!end_entry.is_start);
let end_record = map_records.get(&end_id);
let addr = local_func_id_to_addr[start_entry.local_function_id];
let size_record = *addr_to_size_record
.get(&addr)
.expect("size_record not found");
start_entry.populate_msm(
module_info,
code_ptr as usize,
&map,
size_record,
map_record,
end_record.map(|x| (end_entry, *x)),
&mut msm,
);
} else {
// The record is optimized out.
} }
let mut addr_to_size_record: BTreeMap<usize, &StkSizeRecord> = BTreeMap::new();
for record in &map.stk_size_records {
addr_to_size_record.insert(record.function_address as usize, record);
}
let mut map_records: BTreeMap<usize, &StkMapRecord> = BTreeMap::new();
for record in &map.stk_map_records {
map_records.insert(record.patchpoint_id as usize, record);
}
for ((start_id, start_entry), (end_id, end_entry)) in stackmaps
.entries
.iter()
.enumerate()
.step_by(2)
.zip(stackmaps.entries.iter().enumerate().skip(1).step_by(2))
{
if let Some(map_record) = map_records.get(&start_id) {
assert_eq!(start_id, map_record.patchpoint_id as usize);
assert!(start_entry.is_start);
assert!(!end_entry.is_start);
let end_record = map_records.get(&end_id);
let addr = local_func_id_to_addr[start_entry.local_function_id];
let size_record = *addr_to_size_record
.get(&addr)
.expect("size_record not found");
start_entry.populate_msm(
module_info,
code_ptr as usize,
&map,
size_record,
map_record,
end_record.map(|x| (end_entry, *x)),
&mut msm,
);
} else {
// The record is optimized out.
}
}
let code_ptr = unsafe { llvm_backend_get_code_ptr(module) } as usize;
let code_len = unsafe { llvm_backend_get_code_size(module) } as usize;
let local_func_id_to_offset: Vec<usize> = local_func_id_to_addr
.iter()
.map(|&x| {
assert!(x >= code_ptr && x < code_ptr + code_len);
x - code_ptr
})
.collect();
return (
Self {
module,
buffer: Arc::clone(&buffer),
msm: Some(msm),
local_func_id_to_offset,
},
LLVMCache { buffer },
)
} }
let code_ptr = unsafe { llvm_backend_get_code_ptr(module) } as usize;
let code_len = unsafe { llvm_backend_get_code_size(module) } as usize;
let local_func_id_to_offset: Vec<usize> = local_func_id_to_addr
.iter()
.map(|&x| {
assert!(x >= code_ptr && x < code_ptr + code_len);
x - code_ptr
})
.collect();
(
Self {
module,
buffer: Arc::clone(&buffer),
msm: Some(msm),
local_func_id_to_offset,
},
LLVMCache { buffer },
)
} else {
// This module contains no functions so no stackmaps.
(
Self {
module,
buffer: Arc::clone(&buffer),
msm: None,
local_func_id_to_offset: vec![],
},
LLVMCache { buffer },
)
} }
// Stackmap is not supported on this platform, or this module contains no functions so no stackmaps.
(
Self {
module,
buffer: Arc::clone(&buffer),
msm: None,
local_func_id_to_offset: vec![],
},
LLVMCache { buffer },
)
} }
pub unsafe fn from_buffer(memory: Memory) -> Result<(Self, LLVMCache), String> { pub unsafe fn from_buffer(memory: Memory) -> Result<(Self, LLVMCache), String> {

View File

@ -3,11 +3,6 @@
use byteorder::{LittleEndian, ReadBytesExt}; use byteorder::{LittleEndian, ReadBytesExt};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::io::{self, Cursor}; use std::io::{self, Cursor};
use wasmer_runtime_core::state::{
x64::{new_machine_state, X64Register, GPR},
FunctionStateMap, MachineStateDiff, MachineValue, ModuleStateMap, OffsetInfo, RegisterIndex,
SuspendOffset, WasmAbstractValue,
};
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
module::ModuleInfo, module::ModuleInfo,
@ -87,6 +82,7 @@ pub struct MachineStateDiff {
*/ */
impl StackmapEntry { impl StackmapEntry {
#[cfg(all(any(target_os = "linux", target_os = "macos"), target_arch = "x86_64"))]
pub fn populate_msm( pub fn populate_msm(
&self, &self,
module_info: &ModuleInfo, module_info: &ModuleInfo,
@ -95,8 +91,13 @@ impl StackmapEntry {
size_record: &StkSizeRecord, size_record: &StkSizeRecord,
map_record: &StkMapRecord, map_record: &StkMapRecord,
end: Option<(&StackmapEntry, &StkMapRecord)>, end: Option<(&StackmapEntry, &StkMapRecord)>,
msm: &mut ModuleStateMap, msm: &mut wasmer_runtime_core::state::ModuleStateMap,
) { ) {
use wasmer_runtime_core::state::{
x64::{new_machine_state, X64Register, GPR},
FunctionStateMap, MachineStateDiff, MachineValue, OffsetInfo, RegisterIndex,
SuspendOffset, WasmAbstractValue,
};
let func_base_addr = (size_record.function_address as usize) let func_base_addr = (size_record.function_address as usize)
.checked_sub(code_addr) .checked_sub(code_addr)
.unwrap(); .unwrap();
@ -232,7 +233,7 @@ impl StackmapEntry {
assert!(loc.offset_or_small_constant >= 16); // (saved_rbp, return_address) assert!(loc.offset_or_small_constant >= 16); // (saved_rbp, return_address)
assert!(loc.offset_or_small_constant % 8 == 0); assert!(loc.offset_or_small_constant % 8 == 0);
prev_frame_diff.insert( prev_frame_diff.insert(
((loc.offset_or_small_constant as usize - 16) / 8), (loc.offset_or_small_constant as usize - 16) / 8,
Some(mv), Some(mv),
); );
} else { } else {