mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-13 00:51:20 +00:00
Swap code lazily when tiering up from singlepass to LLVM.
Does not handle long-running functions, but should work at least.
This commit is contained in:
@ -239,6 +239,7 @@ pub struct LLVMBackend {
|
||||
#[allow(dead_code)]
|
||||
buffer: Arc<Buffer>,
|
||||
msm: Option<ModuleStateMap>,
|
||||
local_func_id_to_offset: Vec<usize>,
|
||||
}
|
||||
|
||||
impl LLVMBackend {
|
||||
@ -380,6 +381,17 @@ impl LLVMBackend {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
//println!("MSM: {:?}", msm);
|
||||
|
||||
(
|
||||
@ -387,6 +399,7 @@ impl LLVMBackend {
|
||||
module,
|
||||
buffer: Arc::clone(&buffer),
|
||||
msm: Some(msm),
|
||||
local_func_id_to_offset,
|
||||
},
|
||||
LLVMCache { buffer },
|
||||
)
|
||||
@ -397,6 +410,7 @@ impl LLVMBackend {
|
||||
module,
|
||||
buffer: Arc::clone(&buffer),
|
||||
msm: None,
|
||||
local_func_id_to_offset: vec![],
|
||||
},
|
||||
LLVMCache { buffer },
|
||||
)
|
||||
@ -428,6 +442,7 @@ impl LLVMBackend {
|
||||
module,
|
||||
buffer: Arc::clone(&buffer),
|
||||
msm: None,
|
||||
local_func_id_to_offset: vec![],
|
||||
},
|
||||
LLVMCache { buffer },
|
||||
))
|
||||
@ -491,6 +506,10 @@ impl RunnableModule for LLVMBackend {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_local_function_offsets(&self) -> Option<Vec<usize>> {
|
||||
Some(self.local_func_id_to_offset.clone())
|
||||
}
|
||||
|
||||
fn get_module_state_map(&self) -> Option<ModuleStateMap> {
|
||||
self.msm.clone()
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use wasmer_runtime_core::{
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
structures::{Map, TypedIndex},
|
||||
types::{
|
||||
FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type, ImportedFuncIndex,
|
||||
FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type,
|
||||
},
|
||||
};
|
||||
use wasmparser::{BinaryReaderError, MemoryImmediate, Operator, Type as WpType};
|
||||
@ -303,7 +303,7 @@ fn resolve_memory_ptr(
|
||||
}
|
||||
|
||||
fn emit_stack_map(
|
||||
module_info: &ModuleInfo,
|
||||
_module_info: &ModuleInfo,
|
||||
intrinsics: &Intrinsics,
|
||||
builder: &Builder,
|
||||
local_function_id: usize,
|
||||
@ -311,7 +311,7 @@ fn emit_stack_map(
|
||||
kind: StackmapEntryKind,
|
||||
locals: &[PointerValue],
|
||||
state: &State,
|
||||
ctx: &mut CtxType,
|
||||
_ctx: &mut CtxType,
|
||||
opcode_offset: usize,
|
||||
) {
|
||||
let stackmap_id = target.entries.len();
|
||||
|
@ -11,8 +11,8 @@ use wasmer_runtime_core::state::{
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
use wasmer_runtime_core::{
|
||||
module::ModuleInfo,
|
||||
types::{GlobalIndex, TableIndex, LocalOrImport},
|
||||
structures::TypedIndex,
|
||||
types::{GlobalIndex, LocalOrImport, TableIndex},
|
||||
vm,
|
||||
};
|
||||
|
||||
@ -154,30 +154,48 @@ impl StackmapEntry {
|
||||
MachineValue::WasmStack(x)
|
||||
}
|
||||
ValueSemantic::Ctx => MachineValue::Vmctx,
|
||||
ValueSemantic::SignalMem => MachineValue::VmctxDeref(vec![Ctx::offset_interrupt_signal_mem() as usize, 0]),
|
||||
ValueSemantic::PointerToMemoryBase => MachineValue::VmctxDeref(vec![Ctx::offset_memory_base() as usize]),
|
||||
ValueSemantic::PointerToMemoryBound => MachineValue::VmctxDeref(vec![Ctx::offset_memory_bound() as usize]),
|
||||
ValueSemantic::MemoryBase => MachineValue::VmctxDeref(vec![Ctx::offset_memory_base() as usize, 0]),
|
||||
ValueSemantic::MemoryBound => MachineValue::VmctxDeref(vec![Ctx::offset_memory_bound() as usize, 0]),
|
||||
ValueSemantic::PointerToGlobal(idx) => MachineValue::VmctxDeref(deref_global(module_info, idx, false)),
|
||||
ValueSemantic::Global(idx) => MachineValue::VmctxDeref(deref_global(module_info, idx, true)),
|
||||
ValueSemantic::PointerToTableBase => MachineValue::VmctxDeref(deref_table_base(module_info, 0, false)),
|
||||
ValueSemantic::PointerToTableBound => MachineValue::VmctxDeref(deref_table_bound(module_info, 0, false)),
|
||||
ValueSemantic::SignalMem => {
|
||||
MachineValue::VmctxDeref(vec![Ctx::offset_interrupt_signal_mem() as usize, 0])
|
||||
}
|
||||
ValueSemantic::PointerToMemoryBase => {
|
||||
MachineValue::VmctxDeref(vec![Ctx::offset_memory_base() as usize])
|
||||
}
|
||||
ValueSemantic::PointerToMemoryBound => {
|
||||
MachineValue::VmctxDeref(vec![Ctx::offset_memory_bound() as usize])
|
||||
}
|
||||
ValueSemantic::MemoryBase => {
|
||||
MachineValue::VmctxDeref(vec![Ctx::offset_memory_base() as usize, 0])
|
||||
}
|
||||
ValueSemantic::MemoryBound => {
|
||||
MachineValue::VmctxDeref(vec![Ctx::offset_memory_bound() as usize, 0])
|
||||
}
|
||||
ValueSemantic::PointerToGlobal(idx) => {
|
||||
MachineValue::VmctxDeref(deref_global(module_info, idx, false))
|
||||
}
|
||||
ValueSemantic::Global(idx) => {
|
||||
MachineValue::VmctxDeref(deref_global(module_info, idx, true))
|
||||
}
|
||||
ValueSemantic::PointerToTableBase => {
|
||||
MachineValue::VmctxDeref(deref_table_base(module_info, 0, false))
|
||||
}
|
||||
ValueSemantic::PointerToTableBound => {
|
||||
MachineValue::VmctxDeref(deref_table_bound(module_info, 0, false))
|
||||
}
|
||||
ValueSemantic::ImportedFuncPointer(idx) => MachineValue::VmctxDeref(vec![
|
||||
Ctx::offset_imported_funcs() as usize,
|
||||
vm::ImportedFunc::size() as usize * idx + vm::ImportedFunc::offset_func() as usize,
|
||||
vm::ImportedFunc::size() as usize * idx
|
||||
+ vm::ImportedFunc::offset_func() as usize,
|
||||
0,
|
||||
]),
|
||||
ValueSemantic::ImportedFuncCtx(idx) => MachineValue::VmctxDeref(vec![
|
||||
Ctx::offset_imported_funcs() as usize,
|
||||
vm::ImportedFunc::size() as usize * idx + vm::ImportedFunc::offset_vmctx() as usize,
|
||||
0,
|
||||
]),
|
||||
ValueSemantic::DynamicSigindice(idx) => MachineValue::VmctxDeref(vec![
|
||||
Ctx::offset_signatures() as usize,
|
||||
idx * 4,
|
||||
vm::ImportedFunc::size() as usize * idx
|
||||
+ vm::ImportedFunc::offset_vmctx() as usize,
|
||||
0,
|
||||
]),
|
||||
ValueSemantic::DynamicSigindice(idx) => {
|
||||
MachineValue::VmctxDeref(vec![Ctx::offset_signatures() as usize, idx * 4, 0])
|
||||
}
|
||||
};
|
||||
match loc.ty {
|
||||
LocationType::Register => {
|
||||
@ -538,16 +556,10 @@ impl StackMap {
|
||||
|
||||
fn deref_global(info: &ModuleInfo, idx: usize, deref_into_value: bool) -> Vec<usize> {
|
||||
let mut x: Vec<usize> = match GlobalIndex::new(idx).local_or_import(info) {
|
||||
LocalOrImport::Local(idx) => vec![
|
||||
Ctx::offset_globals() as usize,
|
||||
idx.index() * 8,
|
||||
0,
|
||||
],
|
||||
LocalOrImport::Import(idx) => vec![
|
||||
Ctx::offset_imported_globals() as usize,
|
||||
idx.index() * 8,
|
||||
0,
|
||||
],
|
||||
LocalOrImport::Local(idx) => vec![Ctx::offset_globals() as usize, idx.index() * 8, 0],
|
||||
LocalOrImport::Import(idx) => {
|
||||
vec![Ctx::offset_imported_globals() as usize, idx.index() * 8, 0]
|
||||
}
|
||||
};
|
||||
if deref_into_value {
|
||||
x.push(0);
|
||||
@ -557,16 +569,10 @@ fn deref_global(info: &ModuleInfo, idx: usize, deref_into_value: bool) -> Vec<us
|
||||
|
||||
fn deref_table_base(info: &ModuleInfo, idx: usize, deref_into_value: bool) -> Vec<usize> {
|
||||
let mut x: Vec<usize> = match TableIndex::new(idx).local_or_import(info) {
|
||||
LocalOrImport::Local(idx) => vec![
|
||||
Ctx::offset_tables() as usize,
|
||||
idx.index() * 8,
|
||||
0,
|
||||
],
|
||||
LocalOrImport::Import(idx) => vec![
|
||||
Ctx::offset_imported_tables() as usize,
|
||||
idx.index() * 8,
|
||||
0,
|
||||
],
|
||||
LocalOrImport::Local(idx) => vec![Ctx::offset_tables() as usize, idx.index() * 8, 0],
|
||||
LocalOrImport::Import(idx) => {
|
||||
vec![Ctx::offset_imported_tables() as usize, idx.index() * 8, 0]
|
||||
}
|
||||
};
|
||||
if deref_into_value {
|
||||
x.push(0);
|
||||
@ -576,19 +582,13 @@ fn deref_table_base(info: &ModuleInfo, idx: usize, deref_into_value: bool) -> Ve
|
||||
|
||||
fn deref_table_bound(info: &ModuleInfo, idx: usize, deref_into_value: bool) -> Vec<usize> {
|
||||
let mut x: Vec<usize> = match TableIndex::new(idx).local_or_import(info) {
|
||||
LocalOrImport::Local(idx) => vec![
|
||||
Ctx::offset_tables() as usize,
|
||||
idx.index() * 8,
|
||||
8,
|
||||
],
|
||||
LocalOrImport::Import(idx) => vec![
|
||||
Ctx::offset_imported_tables() as usize,
|
||||
idx.index() * 8,
|
||||
8,
|
||||
],
|
||||
LocalOrImport::Local(idx) => vec![Ctx::offset_tables() as usize, idx.index() * 8, 8],
|
||||
LocalOrImport::Import(idx) => {
|
||||
vec![Ctx::offset_imported_tables() as usize, idx.index() * 8, 8]
|
||||
}
|
||||
};
|
||||
if deref_into_value {
|
||||
x.push(0);
|
||||
}
|
||||
x
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user