Skip to content
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

Move function call trampolines to Artifact instead of EngineInner. #1710

Merged
merged 32 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
447de21
A mess of changes.
nlewycky Oct 2, 2020
3df1933
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 7, 2020
e05e0ef
Add a 'trampoline' field to ExportFunction.
nlewycky Oct 8, 2020
5d147f8
WIP checkpoint. Code that builds.
nlewycky Oct 8, 2020
c9ea2fa
cargo lint cleanups.
nlewycky Oct 8, 2020
a6ad7af
Move function call trampolines from engine inner to artifact in engin…
nlewycky Oct 8, 2020
a484765
Move trampolines to artifact in engine-{jit,object-file,dummy}.
nlewycky Oct 9, 2020
9793d45
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 9, 2020
37615b1
Re-enable features that were temporarily disabled for development.
nlewycky Oct 9, 2020
d696171
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 9, 2020
e6801dd
DO NOT MERGE TO MASTER.
nlewycky Oct 12, 2020
fed7541
Revert "DO NOT MERGE TO MASTER."
nlewycky Oct 12, 2020
c2646c1
Permit exported functions to be host functions.
nlewycky Oct 12, 2020
1803ce4
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 12, 2020
f28b194
Add changelog entry.
nlewycky Oct 12, 2020
df3b1f2
Simplify this loop.
nlewycky Oct 12, 2020
45e9fbd
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 12, 2020
6ede21c
Update lib/vm/src/export.rs
nlewycky Oct 13, 2020
8350c7b
Comment ends in a full stop.
nlewycky Oct 13, 2020
e94e585
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 13, 2020
18f955a
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 13, 2020
62b9c8b
Move Library from artifact to engine inner.
nlewycky Oct 13, 2020
83caef6
cargo fmt
nlewycky Oct 13, 2020
90efd53
Remove accidentally added debug code.
nlewycky Oct 13, 2020
ed630bf
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 14, 2020
c91c448
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 15, 2020
57202f7
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 16, 2020
ff15be3
Un-ignore these fixed tests.
nlewycky Oct 16, 2020
00c9310
Merge branch 'master' into feature/trampoline-in-artifact
syrusakbary Oct 19, 2020
ae5fc2a
Rename trampoline to call_trampoline, part 1.
nlewycky Oct 20, 2020
29c9cb1
Rename trampoline to call_trampoline, part 2.
nlewycky Oct 20, 2020
f55121c
Merge branch 'master' into feature/trampoline-in-artifact
nlewycky Oct 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

## **[Unreleased]**

- [#1710](https://github.com/wasmerio/wasmer/pull/1710) Memory for function call trampolines is now owned by the Artifact.
### Added

- [#1736](https://github.com/wasmerio/wasmer/pull/1736) Implement `wasm_global_type` in the Wasm C API.
Expand Down
29 changes: 19 additions & 10 deletions lib/api/src/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use wasmer_vm::{
/// A function defined in the Wasm module
#[derive(Clone, PartialEq)]
pub struct WasmFunctionDefinition {
// The trampoline to do the call
// Address of the trampoline to do the call.
pub(crate) trampoline: VMTrampoline,
}

Expand Down Expand Up @@ -95,6 +95,7 @@ impl Function {
kind: VMFunctionKind::Dynamic,
vmctx,
signature: ty.clone(),
trampoline: None,
},
}
}
Expand Down Expand Up @@ -144,6 +145,7 @@ impl Function {
kind: VMFunctionKind::Dynamic,
vmctx,
signature: ty.clone(),
trampoline: None,
},
}
}
Expand Down Expand Up @@ -185,6 +187,7 @@ impl Function {
vmctx,
signature,
kind: VMFunctionKind::Static,
trampoline: None,
},
}
}
Expand Down Expand Up @@ -238,6 +241,7 @@ impl Function {
kind: VMFunctionKind::Static,
vmctx,
signature,
trampoline: None,
},
}
}
Expand Down Expand Up @@ -351,15 +355,20 @@ impl Function {
}

pub(crate) fn from_export(store: &Store, wasmer_export: ExportFunction) -> Self {
let vmsignature = store.engine().register_signature(&wasmer_export.signature);
let trampoline = store
.engine()
.function_call_trampoline(vmsignature)
.expect("Can't get call trampoline for the function");
Self {
store: store.clone(),
definition: FunctionDefinition::Wasm(WasmFunctionDefinition { trampoline }),
exported: wasmer_export,
if let Some(trampoline) = wasmer_export.trampoline {
Self {
store: store.clone(),
definition: FunctionDefinition::Wasm(WasmFunctionDefinition { trampoline }),
exported: wasmer_export,
}
} else {
Self {
store: store.clone(),
definition: FunctionDefinition::Host(HostFunctionDefinition {
has_env: !wasmer_export.vmctx.is_null(),
}),
exported: wasmer_export,
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions lib/api/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ where
vmctx: other.vmctx,
signature,
kind: other.arg_kind,
trampoline: None,
}
}
}
Expand All @@ -88,6 +89,7 @@ where
vmctx: other.vmctx,
signature,
kind: other.arg_kind,
trampoline: None,
},
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ impl ValFuncRef for Val {
// are converted to use the trampolines with static signatures).
kind: wasmer_vm::VMFunctionKind::Static,
vmctx: item.vmctx,
trampoline: None,
};
let f = Function::from_export(store, export);
Self::FuncRef(f)
Expand Down
14 changes: 12 additions & 2 deletions lib/engine-jit/src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ use wasmer_types::{
FunctionIndex, LocalFunctionIndex, MemoryIndex, OwnedDataInitializer, SignatureIndex,
TableIndex,
};
use wasmer_vm::{FunctionBodyPtr, MemoryStyle, ModuleInfo, TableStyle, VMSharedSignatureIndex};
use wasmer_vm::{
FunctionBodyPtr, MemoryStyle, ModuleInfo, TableStyle, VMSharedSignatureIndex, VMTrampoline,
};

/// A compiled wasm module, ready to be instantiated.
pub struct JITArtifact {
serializable: SerializableModule,
finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>,
finished_dynamic_function_trampolines: BoxedSlice<FunctionIndex, FunctionBodyPtr>,
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
frame_info_registration: Mutex<Option<GlobalFrameInfoRegistration>>,
Expand Down Expand Up @@ -150,7 +153,7 @@ impl JITArtifact {
) -> Result<Self, CompileError> {
let (
finished_functions,
_finished_function_call_trampolines,
finished_function_call_trampolines,
finished_dynamic_function_trampolines,
custom_sections,
) = inner_jit.allocate(
Expand Down Expand Up @@ -201,13 +204,16 @@ impl JITArtifact {
inner_jit.publish_eh_frame(eh_frame)?;

let finished_functions = finished_functions.into_boxed_slice();
let finished_function_call_trampolines =
finished_function_call_trampolines.into_boxed_slice();
let finished_dynamic_function_trampolines =
finished_dynamic_function_trampolines.into_boxed_slice();
let signatures = signatures.into_boxed_slice();

Ok(Self {
serializable,
finished_functions,
finished_function_call_trampolines,
finished_dynamic_function_trampolines,
signatures,
frame_info_registration: Mutex::new(None),
Expand Down Expand Up @@ -270,6 +276,10 @@ impl Artifact for JITArtifact {
&self.finished_functions
}

fn finished_function_call_trampolines(&self) -> &BoxedSlice<SignatureIndex, VMTrampoline> {
&self.finished_function_call_trampolines
}

// TODO: return *const instead of *mut
fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice<FunctionIndex, FunctionBodyPtr> {
&self.finished_dynamic_function_trampolines
Expand Down
40 changes: 10 additions & 30 deletions lib/engine-jit/src/engine.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! JIT compilation.

use crate::{CodeMemory, JITArtifact};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[cfg(feature = "compiler")]
use wasmer_compiler::Compiler;
Expand Down Expand Up @@ -33,7 +32,6 @@ impl JITEngine {
Self {
inner: Arc::new(Mutex::new(JITEngineInner {
compiler: Some(compiler),
function_call_trampolines: HashMap::new(),
code_memory: vec![],
signatures: SignatureRegistry::new(),
features,
Expand Down Expand Up @@ -61,7 +59,6 @@ impl JITEngine {
inner: Arc::new(Mutex::new(JITEngineInner {
#[cfg(feature = "compiler")]
compiler: None,
function_call_trampolines: HashMap::new(),
code_memory: vec![],
signatures: SignatureRegistry::new(),
features: Features::default(),
Expand Down Expand Up @@ -98,11 +95,6 @@ impl Engine for JITEngine {
compiler.signatures().lookup(sig)
}

/// Retrieves a trampoline given a signature
fn function_call_trampoline(&self, sig: VMSharedSignatureIndex) -> Option<VMTrampoline> {
self.inner().function_call_trampoline(sig)
}

/// Validates a WebAssembly module
fn validate(&self, binary: &[u8]) -> Result<(), CompileError> {
self.inner().validate(binary)
Expand Down Expand Up @@ -150,8 +142,6 @@ pub struct JITEngineInner {
/// The compiler
#[cfg(feature = "compiler")]
compiler: Option<Box<dyn Compiler + Send>>,
/// Pointers to trampoline functions used to enter particular signatures
function_call_trampolines: HashMap<VMSharedSignatureIndex, VMTrampoline>,
/// The features to compile the Wasm module with
features: Features,
/// The code memory is responsible of publishing the compiled
Expand Down Expand Up @@ -196,15 +186,15 @@ impl JITEngineInner {
#[allow(clippy::type_complexity)]
pub(crate) fn allocate(
&mut self,
module: &ModuleInfo,
_module: &ModuleInfo,
functions: &PrimaryMap<LocalFunctionIndex, FunctionBody>,
function_call_trampolines: &PrimaryMap<SignatureIndex, FunctionBody>,
dynamic_function_trampolines: &PrimaryMap<FunctionIndex, FunctionBody>,
custom_sections: &PrimaryMap<SectionIndex, CustomSection>,
) -> Result<
(
PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>,
PrimaryMap<SignatureIndex, FunctionBodyPtr>,
PrimaryMap<SignatureIndex, VMTrampoline>,
PrimaryMap<FunctionIndex, FunctionBodyPtr>,
PrimaryMap<SectionIndex, SectionBodyPtr>,
),
Expand Down Expand Up @@ -241,20 +231,15 @@ impl JITEngineInner {
.map(|slice| FunctionBodyPtr(slice as *mut [_]))
.collect::<PrimaryMap<LocalFunctionIndex, _>>();

let mut allocated_function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBodyPtr> =
let mut allocated_function_call_trampolines: PrimaryMap<SignatureIndex, VMTrampoline> =
PrimaryMap::new();
for ((sig_index, _), ptr) in function_call_trampolines.iter().zip(
allocated_functions
.drain(0..function_call_trampolines.len())
.map(|slice| FunctionBodyPtr(slice as *mut [_])),
) {
let func_type = &module.signatures[sig_index];
let index = self.signatures.register(&func_type);
allocated_function_call_trampolines.push(ptr);
let trampoline = unsafe {
std::mem::transmute::<*const VMFunctionBody, VMTrampoline>((**ptr).as_ptr())
};
self.function_call_trampolines.insert(index, trampoline);
for ptr in allocated_functions
.drain(0..function_call_trampolines.len())
.map(|slice| slice.as_ptr())
{
let trampoline =
unsafe { std::mem::transmute::<*const VMFunctionBody, VMTrampoline>(ptr) };
allocated_function_call_trampolines.push(trampoline);
}

let allocated_dynamic_function_trampolines = allocated_functions
Expand Down Expand Up @@ -309,9 +294,4 @@ impl JITEngineInner {
pub fn signatures(&self) -> &SignatureRegistry {
&self.signatures
}

/// Gets the trampoline pre-registered for a particular signature
pub fn function_call_trampoline(&self, sig: VMSharedSignatureIndex) -> Option<VMTrampoline> {
self.function_call_trampolines.get(&sig).cloned()
}
}
38 changes: 21 additions & 17 deletions lib/engine-native/src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ use wasmer_compiler::{CompileError, Features, OperatingSystem, Symbol, SymbolReg
use wasmer_compiler::{
CompileModuleInfo, FunctionBodyData, ModuleEnvironment, ModuleTranslationState,
};
use wasmer_engine::{
Artifact, DeserializeError, InstantiationError, LinkError, RuntimeError, SerializeError,
};
use wasmer_engine::{Artifact, DeserializeError, InstantiationError, SerializeError};
#[cfg(feature = "compiler")]
use wasmer_engine::{Engine, Tunables};
#[cfg(feature = "compiler")]
Expand All @@ -42,9 +40,8 @@ use wasmer_vm::{
pub struct NativeArtifact {
sharedobject_path: PathBuf,
metadata: ModuleMetadata,
#[allow(dead_code)]
library: Option<Library>,
finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>,
finished_dynamic_function_trampolines: BoxedSlice<FunctionIndex, FunctionBodyPtr>,
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
}
Expand Down Expand Up @@ -324,14 +321,17 @@ impl NativeArtifact {
sharedobject_path: PathBuf,
) -> Result<Self, CompileError> {
let finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> = PrimaryMap::new();
let finished_function_call_trampolines: PrimaryMap<SignatureIndex, VMTrampoline> =
PrimaryMap::new();
let finished_dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBodyPtr> =
PrimaryMap::new();
let signatures: PrimaryMap<SignatureIndex, VMSharedSignatureIndex> = PrimaryMap::new();
Ok(Self {
sharedobject_path,
metadata,
library: None,
finished_functions: finished_functions.into_boxed_slice(),
finished_function_call_trampolines: finished_function_call_trampolines
.into_boxed_slice(),
finished_dynamic_function_trampolines: finished_dynamic_function_trampolines
.into_boxed_slice(),
signatures: signatures.into_boxed_slice(),
Expand Down Expand Up @@ -367,14 +367,17 @@ impl NativeArtifact {
}
}

// Retrieve function call trampolines (for all signatures in the module)
for (sig_index, func_type) in metadata.compile_info.module.signatures.iter() {
// Retrieve function call trampolines
let mut finished_function_call_trampolines: PrimaryMap<SignatureIndex, VMTrampoline> =
PrimaryMap::with_capacity(metadata.compile_info.module.signatures.len());
for sig_index in metadata.compile_info.module.signatures.keys() {
let function_name = metadata.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
unsafe {
let trampoline: LibrarySymbol<VMTrampoline> = lib
.get(function_name.as_bytes())
.map_err(to_compile_error)?;
engine_inner.add_trampoline(&func_type, *trampoline);
let raw = *trampoline.into_raw();
finished_function_call_trampolines.push(raw);
}
}

Expand Down Expand Up @@ -418,21 +421,23 @@ impl NativeArtifact {

// Compute indices into the shared signature table.
let signatures = {
let signature_registry = engine_inner.signatures();
metadata
.compile_info
.module
.signatures
.values()
.map(|sig| signature_registry.register(sig))
.map(|sig| engine_inner.signatures().register(sig))
.collect::<PrimaryMap<_, _>>()
};

engine_inner.add_library(lib);

Ok(Self {
sharedobject_path,
metadata,
library: Some(lib),
finished_functions: finished_functions.into_boxed_slice(),
finished_function_call_trampolines: finished_function_call_trampolines
.into_boxed_slice(),
finished_dynamic_function_trampolines: finished_dynamic_function_trampolines
.into_boxed_slice(),
signatures: signatures.into_boxed_slice(),
Expand Down Expand Up @@ -571,6 +576,10 @@ impl Artifact for NativeArtifact {
&self.finished_functions
}

fn finished_function_call_trampolines(&self) -> &BoxedSlice<SignatureIndex, VMTrampoline> {
&self.finished_function_call_trampolines
}

fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice<FunctionIndex, FunctionBodyPtr> {
&self.finished_dynamic_function_trampolines
}
Expand All @@ -580,11 +589,6 @@ impl Artifact for NativeArtifact {
}

fn preinstantiate(&self) -> Result<(), InstantiationError> {
if self.library.is_none() {
return Err(InstantiationError::Link(LinkError::Trap(
RuntimeError::new("Cross compiled artifacts can't be instantiated."),
)));
}
Ok(())
}

Expand Down
Loading