-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Additional performance improvements for module instantiation. #2842
Additional performance improvements for module instantiation. #2842
Conversation
@alexcrichton Hopefully this didn't step on the work you were in the middle of for the feedback on #2820 (🤞 that you hadn't started work on it before going on vacation). As I needed to refactor |
Subscribe to Label Actioncc @peterhuene
This issue or pull request has been labeled: "wasmtime:api"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries at all! I think it makes sense all as one go as well and I also hadn't started working on it yet :)
I left a bunch of comments below, but my main thinking is that I'm a little uncomfortable with the dynamic lifetimes of a VMSharedSignatureIndex
now. I only realized halfway through that you were careful to not store VMTrampoline
pointers globally (which makes sense), but this is definitely a radically different ownership model than what we had before where "everything lives as long as Store
".
I don't see anything wrong here but I'm hoping that we can finagle the APIs a bit and/or use registration "tokens" or something like that to better document-via-code the ownership story for shared signature indices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, @peterhuene!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm yeah you're right about the filter_map
and it not being usable. That being said it still makes me feel uncomfortable. What would you think of something like this:
trait ModuleLookup {
fn lookup_module(&self, pc: usize) -> Option<Arc<dyn StackMapLookup>>;
}
trait StackMapLookup {
fn lookup_func(&self, pc: usize) -> Option<&StackMap>;
}
The two-level indirection is kinda ugly but I think this should work. We'd store *const dyn ModuleLookup
inside of the VMContext
and looking up a stack map would be a two-level process. The Arc
returned from the first one would be Arc<CompiledModule>
under the hood.
We could even go further and do:
trait ModuleLookup {
fn lookup_module(&self, pc: usize) -> Option<Arc<dyn StackMapLookup>>;
}
trait StackMapLookup {
fn lookup_func(&self, pc: usize) -> Option<&[StackMapInformation]>;
}
which would leave the binary-search to the externref.rs
module instead of having it sort of out-of-the-place in registry.rs
That push of the latest commit broke the build in a really strange way (as if the CI wasn't building all the changes) 😕. Oh, upstream just added a new call to initialize trap handling, noticed it on a rebase (weird that GitHub is reporting no merge conflicts though as I had one on the rebase). Will fix. |
This commit moves the shared signature registry out of `Store` and into `Engine`. This helps eliminate work that was performed whenever a `Module` was instantiated into a `Store`. Now a `Module` is registered with the shared signature registry upon creation, storing the mapping from the module's signature index space to the shared index space. This also refactors the "frame info" registry into a general purpose "module registry" that is used to look up trap information, signature information, and (soon) stack map information.
This commit removes the stack map registry and instead uses the existing information from the store's module registry to lookup stack maps. A trait is now used to pass the lookup context to the runtime, implemented by `Store` to do the lookup. With this change, module registration in `Store` is now entirely limited to inserting the module into the module registry.
* Make `FunctionInfo` public and `CompiledModule::func_info` return it. * Make the `StackMapLookup` trait unsafe. * Add comments for the purpose of `EngineHostFuncs`. * Rework ownership model of shared signatures: `SignatureCollection` in conjunction with `SignatureRegistry` is now used so that the `Engine`, `Store`, and `Module` don't need to worry about unregistering shared signatures. * Implement `Func::param_arity` and `Func::result_arity` in terms of `Func::ty`. * Make looking up a trampoline with the module registry more efficient by doing a binary search on the function's starting PC value for the owning module and then looking up the trampoline with only that module. * Remove reference to the shared signatures from `GlobalRegisteredModule`.
6bb99c2
to
6ac1321
Compare
Wouldn't the two-stage lookup suffer the same problem as we're borrowing from an interior reference of a |
Oh I guess if it's |
f1bdcec
to
8ed8f61
Compare
This commit uses a two-phase lookup of stack map information from modules rather than giving back raw pointers to stack maps. First the runtime looks up information about a module from a pc value, which returns an `Arc` it keeps a reference on while completing the stack map lookup. Second it then queries the module information for the stack map from a pc value, getting a reference to the stack map (which is now safe because of the `Arc` held by the runtime).
This file hasn't been used for a while and was mistakenly not deleted.
8ed8f61
to
05b3b41
Compare
@alexcrichton all feedback should now be addressed. |
This commit adds `Module::from_parts` as an internal constructor that shared the implementation between `Module::from_binary` and module deserialization.
05b3b41
to
ef2ad63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎊
This PR contains a number of internal refactorings that help make
Store::register_module
do as little work as possible (registration is now only an insertion into aBTreeMap
).This will improve module instantiation performance for modules containing lots of functions and instructions.
The changes are:
Store
and intoEngine
. Modules now register their signatures with the registry upon creation and store the signature index -> shared index mappings internally.Config
upon engine creation as well as store the anyfunc representations of the host functions (previously kept inStore
).StoreFrameInfo
andStackMapRegistry
in favor of a unifiedModuleRegistry
per-store. The module registry can be queried based on program counter values to quickly locate the owning module.StackMapRegistry
, the runtime is now given a trait object to call back on for finding the stack map for a program counter value during GC. The lookup uses the existing data inCompiledModule
which is already optimized for the search.This PR supersedes #2820.