Disconnects Store state fields from Compiler (#1761)
* Moves CodeMemory, VMInterrupts and SignatureRegistry from Compiler * CompiledModule holds CodeMemory and GdbJitImageRegistration * Store keeps track of its JIT code * Makes "jit_int.rs" stuff Send+Sync * Adds the threads example.
This commit is contained in:
@@ -3,27 +3,16 @@
|
||||
|
||||
use crate::vmcontext::VMSharedSignatureIndex;
|
||||
use more_asserts::assert_lt;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{hash_map, HashMap};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::RwLock;
|
||||
use wasmtime_environ::{ir, wasm::WasmFuncType};
|
||||
|
||||
/// WebAssembly requires that the caller and callee signatures in an indirect
|
||||
/// call must match. To implement this efficiently, keep a registry of all
|
||||
/// signatures, shared by all instances, so that call sites can just do an
|
||||
/// index comparison.
|
||||
#[derive(Debug)]
|
||||
pub struct SignatureRegistry {
|
||||
// This structure is stored in a `Compiler` and is intended to be shared
|
||||
// across many instances. Ideally instances can themselves be sent across
|
||||
// threads, and ideally we can compile across many threads. As a result we
|
||||
// use interior mutability here with a lock to avoid having callers to
|
||||
// externally synchronize calls to compilation.
|
||||
inner: RwLock<Inner>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct Inner {
|
||||
pub struct SignatureRegistry {
|
||||
wasm2index: HashMap<WasmFuncType, VMSharedSignatureIndex>,
|
||||
|
||||
// Maps the index to the original Wasm signature.
|
||||
@@ -34,35 +23,31 @@ struct Inner {
|
||||
}
|
||||
|
||||
impl SignatureRegistry {
|
||||
/// Create a new `SignatureRegistry`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inner: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a signature and return its unique index.
|
||||
pub fn register(&self, wasm: WasmFuncType, native: ir::Signature) -> VMSharedSignatureIndex {
|
||||
let Inner {
|
||||
wasm2index,
|
||||
index2wasm,
|
||||
index2native,
|
||||
} = &mut *self.inner.write().unwrap();
|
||||
let len = wasm2index.len();
|
||||
pub fn register(
|
||||
&mut self,
|
||||
wasm: WasmFuncType,
|
||||
native: ir::Signature,
|
||||
) -> VMSharedSignatureIndex {
|
||||
let len = self.wasm2index.len();
|
||||
|
||||
*wasm2index.entry(wasm.clone()).or_insert_with(|| {
|
||||
// Keep `signature_hash` len under 2**32 -- VMSharedSignatureIndex::new(std::u32::MAX)
|
||||
// is reserved for VMSharedSignatureIndex::default().
|
||||
assert_lt!(
|
||||
len,
|
||||
std::u32::MAX as usize,
|
||||
"Invariant check: signature_hash.len() < std::u32::MAX"
|
||||
);
|
||||
let index = VMSharedSignatureIndex::new(u32::try_from(len).unwrap());
|
||||
index2wasm.insert(index, wasm);
|
||||
index2native.insert(index, native);
|
||||
index
|
||||
})
|
||||
match self.wasm2index.entry(wasm.clone()) {
|
||||
hash_map::Entry::Occupied(entry) => *entry.get(),
|
||||
hash_map::Entry::Vacant(entry) => {
|
||||
// Keep `signature_hash` len under 2**32 -- VMSharedSignatureIndex::new(std::u32::MAX)
|
||||
// is reserved for VMSharedSignatureIndex::default().
|
||||
assert_lt!(
|
||||
len,
|
||||
std::u32::MAX as usize,
|
||||
"Invariant check: signature_hash.len() < std::u32::MAX"
|
||||
);
|
||||
let index = VMSharedSignatureIndex::new(u32::try_from(len).unwrap());
|
||||
entry.insert(index);
|
||||
self.index2wasm.insert(index, wasm);
|
||||
self.index2native.insert(index, native);
|
||||
index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Looks up a shared native signature within this registry.
|
||||
@@ -70,7 +55,7 @@ impl SignatureRegistry {
|
||||
/// Note that for this operation to be semantically correct the `idx` must
|
||||
/// have previously come from a call to `register` of this same object.
|
||||
pub fn lookup_native(&self, idx: VMSharedSignatureIndex) -> Option<ir::Signature> {
|
||||
self.inner.read().unwrap().index2native.get(&idx).cloned()
|
||||
self.index2native.get(&idx).cloned()
|
||||
}
|
||||
|
||||
/// Looks up a shared Wasm signature within this registry.
|
||||
@@ -78,6 +63,6 @@ impl SignatureRegistry {
|
||||
/// Note that for this operation to be semantically correct the `idx` must
|
||||
/// have previously come from a call to `register` of this same object.
|
||||
pub fn lookup_wasm(&self, idx: VMSharedSignatureIndex) -> Option<WasmFuncType> {
|
||||
self.inner.read().unwrap().index2wasm.get(&idx).cloned()
|
||||
self.index2wasm.get(&idx).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user