mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 06:08:29 +00:00
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:
@@ -32,6 +32,7 @@ pub struct JITArtifact {
|
|||||||
finished_dynamic_function_trampolines: BoxedSlice<FunctionIndex, FunctionBodyPtr>,
|
finished_dynamic_function_trampolines: BoxedSlice<FunctionIndex, FunctionBodyPtr>,
|
||||||
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
|
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
|
||||||
frame_info_registration: Mutex<Option<GlobalFrameInfoRegistration>>,
|
frame_info_registration: Mutex<Option<GlobalFrameInfoRegistration>>,
|
||||||
|
finished_function_lengths: BoxedSlice<LocalFunctionIndex, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JITArtifact {
|
impl JITArtifact {
|
||||||
@@ -203,7 +204,16 @@ impl JITArtifact {
|
|||||||
|
|
||||||
inner_jit.publish_eh_frame(eh_frame)?;
|
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 =
|
let finished_function_call_trampolines =
|
||||||
finished_function_call_trampolines.into_boxed_slice();
|
finished_function_call_trampolines.into_boxed_slice();
|
||||||
let finished_dynamic_function_trampolines =
|
let finished_dynamic_function_trampolines =
|
||||||
@@ -217,6 +227,7 @@ impl JITArtifact {
|
|||||||
finished_dynamic_function_trampolines,
|
finished_dynamic_function_trampolines,
|
||||||
signatures,
|
signatures,
|
||||||
frame_info_registration: Mutex::new(None),
|
frame_info_registration: Mutex::new(None),
|
||||||
|
finished_function_lengths,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,11 +258,18 @@ impl Artifact for JITArtifact {
|
|||||||
return;
|
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 frame_infos = &self.serializable.compilation.function_frame_info;
|
||||||
let finished_functions = &self.finished_functions;
|
|
||||||
*info = register_frame_info(
|
*info = register_frame_info(
|
||||||
self.serializable.compile_info.module.clone(),
|
self.serializable.compile_info.module.clone(),
|
||||||
finished_functions,
|
&finished_function_extents,
|
||||||
frame_infos.clone(),
|
frame_infos.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ impl JITEngineInner {
|
|||||||
custom_sections: &PrimaryMap<SectionIndex, CustomSection>,
|
custom_sections: &PrimaryMap<SectionIndex, CustomSection>,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>,
|
PrimaryMap<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
|
||||||
PrimaryMap<SignatureIndex, VMTrampoline>,
|
PrimaryMap<SignatureIndex, VMTrampoline>,
|
||||||
PrimaryMap<FunctionIndex, FunctionBodyPtr>,
|
PrimaryMap<FunctionIndex, FunctionBodyPtr>,
|
||||||
PrimaryMap<SectionIndex, SectionBodyPtr>,
|
PrimaryMap<SectionIndex, SectionBodyPtr>,
|
||||||
@@ -228,7 +228,7 @@ impl JITEngineInner {
|
|||||||
|
|
||||||
let allocated_functions_result = allocated_functions
|
let allocated_functions_result = allocated_functions
|
||||||
.drain(0..functions.len())
|
.drain(0..functions.len())
|
||||||
.map(|slice| FunctionBodyPtr(slice as *mut [_]))
|
.map(|slice| (FunctionBodyPtr(slice.as_ptr()), slice.len()))
|
||||||
.collect::<PrimaryMap<LocalFunctionIndex, _>>();
|
.collect::<PrimaryMap<LocalFunctionIndex, _>>();
|
||||||
|
|
||||||
let mut allocated_function_call_trampolines: PrimaryMap<SignatureIndex, VMTrampoline> =
|
let mut allocated_function_call_trampolines: PrimaryMap<SignatureIndex, VMTrampoline> =
|
||||||
@@ -244,7 +244,7 @@ impl JITEngineInner {
|
|||||||
|
|
||||||
let allocated_dynamic_function_trampolines = allocated_functions
|
let allocated_dynamic_function_trampolines = allocated_functions
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.map(|slice| FunctionBodyPtr(slice as *mut [_]))
|
.map(|slice| FunctionBodyPtr(slice.as_ptr()))
|
||||||
.collect::<PrimaryMap<FunctionIndex, _>>();
|
.collect::<PrimaryMap<FunctionIndex, _>>();
|
||||||
|
|
||||||
let mut exec_iter = allocated_executable_sections.iter();
|
let mut exec_iter = allocated_executable_sections.iter();
|
||||||
|
|||||||
@@ -8,20 +8,17 @@ use wasmer_compiler::{
|
|||||||
use wasmer_types::entity::{EntityRef, PrimaryMap};
|
use wasmer_types::entity::{EntityRef, PrimaryMap};
|
||||||
use wasmer_types::LocalFunctionIndex;
|
use wasmer_types::LocalFunctionIndex;
|
||||||
use wasmer_vm::ModuleInfo;
|
use wasmer_vm::ModuleInfo;
|
||||||
use wasmer_vm::{FunctionBodyPtr, SectionBodyPtr, VMFunctionBody};
|
use wasmer_vm::{FunctionBodyPtr, SectionBodyPtr};
|
||||||
|
|
||||||
fn apply_relocation(
|
fn apply_relocation(
|
||||||
body: usize,
|
body: usize,
|
||||||
r: &Relocation,
|
r: &Relocation,
|
||||||
allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>,
|
allocated_functions: &PrimaryMap<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
|
||||||
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
|
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
|
||||||
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
|
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
|
||||||
) {
|
) {
|
||||||
let target_func_address: usize = match r.reloc_target {
|
let target_func_address: usize = match r.reloc_target {
|
||||||
RelocationTarget::LocalFunc(index) => {
|
RelocationTarget::LocalFunc(index) => *allocated_functions[index].0 as usize,
|
||||||
let fatptr: *const [VMFunctionBody] = allocated_functions[index].0;
|
|
||||||
fatptr as *const VMFunctionBody as usize
|
|
||||||
}
|
|
||||||
RelocationTarget::LibCall(libcall) => libcall.function_pointer(),
|
RelocationTarget::LibCall(libcall) => libcall.function_pointer(),
|
||||||
RelocationTarget::CustomSection(custom_section) => {
|
RelocationTarget::CustomSection(custom_section) => {
|
||||||
*allocated_sections[custom_section] as usize
|
*allocated_sections[custom_section] as usize
|
||||||
@@ -31,8 +28,7 @@ fn apply_relocation(
|
|||||||
.get(func_index)
|
.get(func_index)
|
||||||
.and_then(|ofs| ofs.get(JumpTable::new(jt.index())))
|
.and_then(|ofs| ofs.get(JumpTable::new(jt.index())))
|
||||||
.expect("func jump table");
|
.expect("func jump table");
|
||||||
let fatptr: *const [VMFunctionBody] = allocated_functions[func_index].0;
|
*allocated_functions[func_index].0 as usize + offset as usize
|
||||||
fatptr as *const VMFunctionBody as usize + offset as usize
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +65,7 @@ fn apply_relocation(
|
|||||||
/// required relocations and jump tables.
|
/// required relocations and jump tables.
|
||||||
pub fn link_module(
|
pub fn link_module(
|
||||||
_module: &ModuleInfo,
|
_module: &ModuleInfo,
|
||||||
allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>,
|
allocated_functions: &PrimaryMap<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
|
||||||
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
|
jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
|
||||||
function_relocations: Relocations,
|
function_relocations: Relocations,
|
||||||
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
|
allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
|
||||||
@@ -82,8 +78,7 @@ pub fn link_module(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i, function_relocs) in function_relocations.iter() {
|
for (i, function_relocs) in function_relocations.iter() {
|
||||||
let fatptr: *const [VMFunctionBody] = allocated_functions[i].0;
|
let body = *allocated_functions[i].0 as usize;
|
||||||
let body = fatptr as *const VMFunctionBody as usize;
|
|
||||||
for r in function_relocs {
|
for r in function_relocs {
|
||||||
apply_relocation(body, r, allocated_functions, jt_offsets, allocated_sections);
|
apply_relocation(body, r, allocated_functions, jt_offsets, allocated_sections);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ impl NativeArtifact {
|
|||||||
) -> Result<Self, CompileError> {
|
) -> Result<Self, CompileError> {
|
||||||
let mut finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> =
|
let mut finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> =
|
||||||
PrimaryMap::new();
|
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 =
|
let function_name =
|
||||||
metadata.symbol_to_name(Symbol::LocalFunction(function_local_index));
|
metadata.symbol_to_name(Symbol::LocalFunction(function_local_index));
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -356,14 +356,9 @@ impl NativeArtifact {
|
|||||||
let func: LibrarySymbol<unsafe extern "C" fn()> = lib
|
let func: LibrarySymbol<unsafe extern "C" fn()> = lib
|
||||||
.get(function_name.as_bytes())
|
.get(function_name.as_bytes())
|
||||||
.map_err(to_compile_error)?;
|
.map_err(to_compile_error)?;
|
||||||
let raw = *func.into_raw();
|
finished_functions.push(FunctionBodyPtr(
|
||||||
// The function pointer is a fat pointer, however this information
|
func.into_raw().into_raw() as *const VMFunctionBody
|
||||||
// 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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,11 +392,9 @@ impl NativeArtifact {
|
|||||||
let trampoline: LibrarySymbol<unsafe extern "C" fn()> = lib
|
let trampoline: LibrarySymbol<unsafe extern "C" fn()> = lib
|
||||||
.get(function_name.as_bytes())
|
.get(function_name.as_bytes())
|
||||||
.map_err(to_compile_error)?;
|
.map_err(to_compile_error)?;
|
||||||
let raw = *trampoline.into_raw();
|
finished_dynamic_function_trampolines.push(FunctionBodyPtr(
|
||||||
let trampoline_pointer = std::slice::from_raw_parts(raw as *const (), 0);
|
trampoline.into_raw().into_raw() as *const VMFunctionBody,
|
||||||
let trampoline_pointer =
|
));
|
||||||
trampoline_pointer as *const [()] as *mut [VMFunctionBody];
|
|
||||||
finished_dynamic_function_trampolines.push(FunctionBodyPtr(trampoline_pointer));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -306,12 +306,6 @@ impl ObjectFileArtifact {
|
|||||||
let num_finished_functions = usize::from_ne_bytes(byte_buffer);
|
let num_finished_functions = usize::from_ne_bytes(byte_buffer);
|
||||||
let mut finished_functions = PrimaryMap::new();
|
let mut finished_functions = PrimaryMap::new();
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct SlicePtr {
|
|
||||||
ptr: usize,
|
|
||||||
len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
let engine_inner = engine.inner();
|
let engine_inner = engine.inner();
|
||||||
let signature_registry = engine_inner.signatures();
|
let signature_registry = engine_inner.signatures();
|
||||||
let mut sig_map: BTreeMap<SignatureIndex, VMSharedSignatureIndex> = BTreeMap::new();
|
let mut sig_map: BTreeMap<SignatureIndex, VMSharedSignatureIndex> = BTreeMap::new();
|
||||||
@@ -323,14 +317,12 @@ impl ObjectFileArtifact {
|
|||||||
let vm_shared_idx = signature_registry.register(&func_type);
|
let vm_shared_idx = signature_registry.register(&func_type);
|
||||||
sig_map.insert(sig_idx, vm_shared_idx);
|
sig_map.insert(sig_idx, vm_shared_idx);
|
||||||
|
|
||||||
let mut sp = SlicePtr { ptr: 0, len: 0 };
|
|
||||||
byte_buffer[0..WORD_SIZE]
|
byte_buffer[0..WORD_SIZE]
|
||||||
.clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]);
|
.clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]);
|
||||||
sp.ptr = usize::from_ne_bytes(byte_buffer);
|
|
||||||
cur_offset += WORD_SIZE;
|
cur_offset += WORD_SIZE;
|
||||||
// TODO: we can read back the length here if we serialize it. This will improve debug output.
|
// 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);
|
finished_functions.push(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,14 +356,12 @@ impl ObjectFileArtifact {
|
|||||||
cur_offset += WORD_SIZE;
|
cur_offset += WORD_SIZE;
|
||||||
let num_dynamic_trampoline_functions = usize::from_ne_bytes(byte_buffer);
|
let num_dynamic_trampoline_functions = usize::from_ne_bytes(byte_buffer);
|
||||||
for _i in 0..num_dynamic_trampoline_functions {
|
for _i in 0..num_dynamic_trampoline_functions {
|
||||||
let mut sp = SlicePtr { ptr: 0, len: 0 };
|
|
||||||
byte_buffer[0..WORD_SIZE]
|
byte_buffer[0..WORD_SIZE]
|
||||||
.clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]);
|
.clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]);
|
||||||
sp.ptr = usize::from_ne_bytes(byte_buffer);
|
|
||||||
cur_offset += WORD_SIZE;
|
cur_offset += WORD_SIZE;
|
||||||
|
|
||||||
// TODO: we can read back the length here if we serialize it. This will improve debug output.
|
// 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);
|
finished_dynamic_function_trampolines.push(fp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,18 +227,15 @@ impl Drop for GlobalFrameInfoRegistration {
|
|||||||
/// dropped, will be used to unregister all name information from this map.
|
/// dropped, will be used to unregister all name information from this map.
|
||||||
pub fn register(
|
pub fn register(
|
||||||
module: Arc<ModuleInfo>,
|
module: Arc<ModuleInfo>,
|
||||||
finished_functions: &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
|
finished_functions: &BoxedSlice<LocalFunctionIndex, (FunctionBodyPtr, usize)>,
|
||||||
frame_infos: PrimaryMap<LocalFunctionIndex, SerializableFunctionFrameInfo>,
|
frame_infos: PrimaryMap<LocalFunctionIndex, SerializableFunctionFrameInfo>,
|
||||||
) -> Option<GlobalFrameInfoRegistration> {
|
) -> Option<GlobalFrameInfoRegistration> {
|
||||||
let mut min = usize::max_value();
|
let mut min = usize::max_value();
|
||||||
let mut max = 0;
|
let mut max = 0;
|
||||||
let mut functions = BTreeMap::new();
|
let mut functions = BTreeMap::new();
|
||||||
for (i, allocated) in finished_functions.iter() {
|
for (i, (start, len)) in finished_functions.iter() {
|
||||||
let (start, end) = unsafe {
|
let start = **start as usize;
|
||||||
let ptr = (***allocated).as_ptr();
|
let end = start + len;
|
||||||
let len = (***allocated).len();
|
|
||||||
(ptr as usize, ptr as usize + len)
|
|
||||||
};
|
|
||||||
min = cmp::min(min, start);
|
min = cmp::min(min, start);
|
||||||
max = cmp::max(max, end);
|
max = cmp::max(max, end);
|
||||||
let func = FunctionInfo {
|
let func = FunctionInfo {
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets};
|
|||||||
/// Version number of this crate.
|
/// Version number of this crate.
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
/// A safe wrapper around `VMFunctionBody`
|
/// A safe wrapper around `VMFunctionBody`.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct FunctionBodyPtr(pub *const [VMFunctionBody]);
|
pub struct FunctionBodyPtr(pub *const VMFunctionBody);
|
||||||
|
|
||||||
impl std::ops::Deref for FunctionBodyPtr {
|
impl std::ops::Deref for FunctionBodyPtr {
|
||||||
type Target = *const [VMFunctionBody];
|
type Target = *const VMFunctionBody;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0
|
&self.0
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use wasmer_types::{
|
|||||||
TableIndex,
|
TableIndex,
|
||||||
};
|
};
|
||||||
use wasmer_vm::{
|
use wasmer_vm::{
|
||||||
FunctionBodyPtr, MemoryStyle, ModuleInfo, TableStyle, VMContext, VMFunctionBody,
|
FunctionBodyPtr, MemoryStyle, ModuleInfo, TableStyle, VMContext,
|
||||||
VMSharedSignatureIndex, VMTrampoline,
|
VMSharedSignatureIndex, VMTrampoline,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -135,11 +135,7 @@ impl DummyArtifact {
|
|||||||
// We prepare the pointers for the finished functions.
|
// We prepare the pointers for the finished functions.
|
||||||
let finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> = (0
|
let finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> = (0
|
||||||
..num_local_functions)
|
..num_local_functions)
|
||||||
.map(|_| unsafe {
|
.map(|_| FunctionBodyPtr(dummy_function as _))
|
||||||
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)
|
|
||||||
})
|
|
||||||
.collect::<PrimaryMap<_, _>>();
|
.collect::<PrimaryMap<_, _>>();
|
||||||
|
|
||||||
// We prepare the pointers for the finished function call trampolines.
|
// 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.
|
// We prepare the pointers for the finished dynamic function trampolines.
|
||||||
let finished_dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBodyPtr> = (0
|
let finished_dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBodyPtr> = (0
|
||||||
..metadata.module.num_imported_functions)
|
..metadata.module.num_imported_functions)
|
||||||
.map(|_| {
|
.map(|_| FunctionBodyPtr(dummy_function as _))
|
||||||
FunctionBodyPtr(unsafe {
|
|
||||||
std::mem::transmute::<_, *mut [VMFunctionBody]>((
|
|
||||||
dummy_function as *const (),
|
|
||||||
0,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<PrimaryMap<_, _>>();
|
.collect::<PrimaryMap<_, _>>();
|
||||||
|
|
||||||
// Compute indices into the shared signature table.
|
// Compute indices into the shared signature table.
|
||||||
|
|||||||
Reference in New Issue
Block a user