Make FunctionBodyPtr a thin pointer.

This requires keeping the length around and passing it around in a few places that need it.
This commit is contained in:
Nick Lewycky
2020-11-02 12:56:54 -08:00
parent 0ca87b8a83
commit 22187a8dc4
8 changed files with 51 additions and 69 deletions

View File

@@ -32,6 +32,7 @@ pub struct JITArtifact {
finished_dynamic_function_trampolines: BoxedSlice<FunctionIndex, FunctionBodyPtr>,
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
frame_info_registration: Mutex<Option<GlobalFrameInfoRegistration>>,
finished_function_lengths: BoxedSlice<LocalFunctionIndex, usize>,
}
impl JITArtifact {
@@ -203,7 +204,16 @@ impl JITArtifact {
inner_jit.publish_eh_frame(eh_frame)?;
let finished_functions = finished_functions.into_boxed_slice();
let finished_function_lengths = finished_functions
.values()
.map(|(_, len)| *len)
.collect::<PrimaryMap<LocalFunctionIndex, usize>>()
.into_boxed_slice();
let finished_functions = finished_functions
.values()
.map(|(ptr, _)| *ptr)
.collect::<PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>>()
.into_boxed_slice();
let finished_function_call_trampolines =
finished_function_call_trampolines.into_boxed_slice();
let finished_dynamic_function_trampolines =
@@ -217,6 +227,7 @@ impl JITArtifact {
finished_dynamic_function_trampolines,
signatures,
frame_info_registration: Mutex::new(None),
finished_function_lengths,
})
}
@@ -247,11 +258,18 @@ impl Artifact for JITArtifact {
return;
}
let finished_function_extents = self
.finished_functions
.values()
.copied()
.zip(self.finished_function_lengths.values().copied())
.collect::<PrimaryMap<LocalFunctionIndex, _>>()
.into_boxed_slice();
let frame_infos = &self.serializable.compilation.function_frame_info;
let finished_functions = &self.finished_functions;
*info = register_frame_info(
self.serializable.compile_info.module.clone(),
finished_functions,
&finished_function_extents,
frame_infos.clone(),
);
}

View File

@@ -193,7 +193,7 @@ impl JITEngineInner {
custom_sections: &PrimaryMap<SectionIndex, CustomSection>,
) -> Result<
(
PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>,
PrimaryMap<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
PrimaryMap<SignatureIndex, VMTrampoline>,
PrimaryMap<FunctionIndex, FunctionBodyPtr>,
PrimaryMap<SectionIndex, SectionBodyPtr>,
@@ -228,7 +228,7 @@ impl JITEngineInner {
let allocated_functions_result = allocated_functions
.drain(0..functions.len())
.map(|slice| FunctionBodyPtr(slice as *mut [_]))
.map(|slice| (FunctionBodyPtr(slice.as_ptr()), slice.len()))
.collect::<PrimaryMap<LocalFunctionIndex, _>>();
let mut allocated_function_call_trampolines: PrimaryMap<SignatureIndex, VMTrampoline> =
@@ -244,7 +244,7 @@ impl JITEngineInner {
let allocated_dynamic_function_trampolines = allocated_functions
.drain(..)
.map(|slice| FunctionBodyPtr(slice as *mut [_]))
.map(|slice| FunctionBodyPtr(slice.as_ptr()))
.collect::<PrimaryMap<FunctionIndex, _>>();
let mut exec_iter = allocated_executable_sections.iter();

View File

@@ -8,20 +8,17 @@ use wasmer_compiler::{
use wasmer_types::entity::{EntityRef, PrimaryMap};
use wasmer_types::LocalFunctionIndex;
use wasmer_vm::ModuleInfo;
use wasmer_vm::{FunctionBodyPtr, SectionBodyPtr, VMFunctionBody};
use wasmer_vm::{FunctionBodyPtr, SectionBodyPtr};
fn apply_relocation(
body: usize,
r: &Relocation,
allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>,
allocated_functions: &PrimaryMap<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
) {
let target_func_address: usize = match r.reloc_target {
RelocationTarget::LocalFunc(index) => {
let fatptr: *const [VMFunctionBody] = allocated_functions[index].0;
fatptr as *const VMFunctionBody as usize
}
RelocationTarget::LocalFunc(index) => *allocated_functions[index].0 as usize,
RelocationTarget::LibCall(libcall) => libcall.function_pointer(),
RelocationTarget::CustomSection(custom_section) => {
*allocated_sections[custom_section] as usize
@@ -31,8 +28,7 @@ fn apply_relocation(
.get(func_index)
.and_then(|ofs| ofs.get(JumpTable::new(jt.index())))
.expect("func jump table");
let fatptr: *const [VMFunctionBody] = allocated_functions[func_index].0;
fatptr as *const VMFunctionBody as usize + offset as usize
*allocated_functions[func_index].0 as usize + offset as usize
}
};
@@ -69,7 +65,7 @@ fn apply_relocation(
/// required relocations and jump tables.
pub fn link_module(
_module: &ModuleInfo,
allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>,
allocated_functions: &PrimaryMap<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
function_relocations: Relocations,
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
@@ -82,8 +78,7 @@ pub fn link_module(
}
}
for (i, function_relocs) in function_relocations.iter() {
let fatptr: *const [VMFunctionBody] = allocated_functions[i].0;
let body = fatptr as *const VMFunctionBody as usize;
let body = *allocated_functions[i].0 as usize;
for r in function_relocs {
apply_relocation(body, r, allocated_functions, jt_offsets, allocated_sections);
}

View File

@@ -347,7 +347,7 @@ impl NativeArtifact {
) -> Result<Self, CompileError> {
let mut finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> =
PrimaryMap::new();
for (function_local_index, function_len) in metadata.function_body_lengths.iter() {
for (function_local_index, _function_len) in metadata.function_body_lengths.iter() {
let function_name =
metadata.symbol_to_name(Symbol::LocalFunction(function_local_index));
unsafe {
@@ -356,14 +356,9 @@ impl NativeArtifact {
let func: LibrarySymbol<unsafe extern "C" fn()> = lib
.get(function_name.as_bytes())
.map_err(to_compile_error)?;
let raw = *func.into_raw();
// The function pointer is a fat pointer, however this information
// is only used when retrieving the trap information which is not yet
// implemented in this engine.
let func_pointer =
std::slice::from_raw_parts(raw as *const (), *function_len as usize);
let func_pointer = func_pointer as *const [()] as *mut [VMFunctionBody];
finished_functions.push(FunctionBodyPtr(func_pointer));
finished_functions.push(FunctionBodyPtr(
func.into_raw().into_raw() as *const VMFunctionBody
));
}
}
@@ -397,11 +392,9 @@ impl NativeArtifact {
let trampoline: LibrarySymbol<unsafe extern "C" fn()> = lib
.get(function_name.as_bytes())
.map_err(to_compile_error)?;
let raw = *trampoline.into_raw();
let trampoline_pointer = std::slice::from_raw_parts(raw as *const (), 0);
let trampoline_pointer =
trampoline_pointer as *const [()] as *mut [VMFunctionBody];
finished_dynamic_function_trampolines.push(FunctionBodyPtr(trampoline_pointer));
finished_dynamic_function_trampolines.push(FunctionBodyPtr(
trampoline.into_raw().into_raw() as *const VMFunctionBody,
));
}
}

View File

@@ -306,12 +306,6 @@ impl ObjectFileArtifact {
let num_finished_functions = usize::from_ne_bytes(byte_buffer);
let mut finished_functions = PrimaryMap::new();
#[repr(C)]
struct SlicePtr {
ptr: usize,
len: usize,
}
let engine_inner = engine.inner();
let signature_registry = engine_inner.signatures();
let mut sig_map: BTreeMap<SignatureIndex, VMSharedSignatureIndex> = BTreeMap::new();
@@ -323,14 +317,12 @@ impl ObjectFileArtifact {
let vm_shared_idx = signature_registry.register(&func_type);
sig_map.insert(sig_idx, vm_shared_idx);
let mut sp = SlicePtr { ptr: 0, len: 0 };
byte_buffer[0..WORD_SIZE]
.clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]);
sp.ptr = usize::from_ne_bytes(byte_buffer);
cur_offset += WORD_SIZE;
// TODO: we can read back the length here if we serialize it. This will improve debug output.
let fp = FunctionBodyPtr(mem::transmute(sp));
let fp = FunctionBodyPtr(byte_buffer.as_ptr() as _);
finished_functions.push(fp);
}
@@ -364,14 +356,12 @@ impl ObjectFileArtifact {
cur_offset += WORD_SIZE;
let num_dynamic_trampoline_functions = usize::from_ne_bytes(byte_buffer);
for _i in 0..num_dynamic_trampoline_functions {
let mut sp = SlicePtr { ptr: 0, len: 0 };
byte_buffer[0..WORD_SIZE]
.clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]);
sp.ptr = usize::from_ne_bytes(byte_buffer);
cur_offset += WORD_SIZE;
// TODO: we can read back the length here if we serialize it. This will improve debug output.
let fp = FunctionBodyPtr(mem::transmute(sp));
let fp = FunctionBodyPtr(byte_buffer.as_ptr() as _);
finished_dynamic_function_trampolines.push(fp);
}

View File

@@ -227,18 +227,15 @@ impl Drop for GlobalFrameInfoRegistration {
/// dropped, will be used to unregister all name information from this map.
pub fn register(
module: Arc<ModuleInfo>,
finished_functions: &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
finished_functions: &BoxedSlice<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
frame_infos: PrimaryMap<LocalFunctionIndex, SerializableFunctionFrameInfo>,
) -> Option<GlobalFrameInfoRegistration> {
let mut min = usize::max_value();
let mut max = 0;
let mut functions = BTreeMap::new();
for (i, allocated) in finished_functions.iter() {
let (start, end) = unsafe {
let ptr = (***allocated).as_ptr();
let len = (***allocated).len();
(ptr as usize, ptr as usize + len)
};
for (i, (start, len)) in finished_functions.iter() {
let start = **start as usize;
let end = start + len;
min = cmp::min(min, start);
max = cmp::max(max, end);
let func = FunctionInfo {

View File

@@ -58,13 +58,13 @@ pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets};
/// Version number of this crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
/// A safe wrapper around `VMFunctionBody`
/// A safe wrapper around `VMFunctionBody`.
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct FunctionBodyPtr(pub *const [VMFunctionBody]);
pub struct FunctionBodyPtr(pub *const VMFunctionBody);
impl std::ops::Deref for FunctionBodyPtr {
type Target = *const [VMFunctionBody];
type Target = *const VMFunctionBody;
fn deref(&self) -> &Self::Target {
&self.0

View File

@@ -15,7 +15,7 @@ use wasmer_types::{
TableIndex,
};
use wasmer_vm::{
FunctionBodyPtr, MemoryStyle, ModuleInfo, TableStyle, VMContext, VMFunctionBody,
FunctionBodyPtr, MemoryStyle, ModuleInfo, TableStyle, VMContext,
VMSharedSignatureIndex, VMTrampoline,
};
@@ -135,11 +135,7 @@ impl DummyArtifact {
// We prepare the pointers for the finished functions.
let finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> = (0
..num_local_functions)
.map(|_| unsafe {
let func_pointer = std::slice::from_raw_parts(dummy_function as *const (), 0);
let func_pointer = std::mem::transmute::<_, *mut [VMFunctionBody]>(func_pointer);
FunctionBodyPtr(func_pointer)
})
.map(|_| FunctionBodyPtr(dummy_function as _))
.collect::<PrimaryMap<_, _>>();
// We prepare the pointers for the finished function call trampolines.
@@ -151,14 +147,7 @@ impl DummyArtifact {
// We prepare the pointers for the finished dynamic function trampolines.
let finished_dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBodyPtr> = (0
..metadata.module.num_imported_functions)
.map(|_| {
FunctionBodyPtr(unsafe {
std::mem::transmute::<_, *mut [VMFunctionBody]>((
dummy_function as *const (),
0,
))
})
})
.map(|_| FunctionBodyPtr(dummy_function as _))
.collect::<PrimaryMap<_, _>>();
// Compute indices into the shared signature table.