-
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
Refactor wasmtime::FuncType
to hold a handle to its registered type
#7892
Conversation
Subscribe to Label Actioncc @fitzgen, @peterhuene
This issue or pull request has been labeled: "fuzzing", "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.
I'm a little wary in how the type-related stuff feels "heavyweight" with lots of Arc
, but I don't know of what else to do and we don't necessarily have a benchmark/threshold that this would or wouldn't become a problem at, so seems fine to stay the course and we can improve later if necessary.
I'm also a little worried about passing in &Engine
when reading types since that feels like it can get unwieldy/unergonomic pretty quickly. One solution would be to store Engine
in more places but then that also feeds back into the above where types become more heavyweight with more Arc
s. I don't feel I have a great sense of balance between these concerns right now.
Otherwise though I'd recommend prtest:full
for this PR. I know the C API is going to need changes, and substantive ones too. The Wasm C API header file does not pass an engine in when creating a function type, for example, so the C function type is going to need to become different than wasmtime::FuncType
pub(crate) fn from_wasm_func_type(engine: &Engine, ty: &WasmFuncType) -> FuncType { | ||
let ty = engine.signatures().register(ty); | ||
Self { ty } | ||
} |
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 seems like a method we should be ideally removing through this refactoring (or enabling removing).
The callers I see are:
ExternType::from_wasmtime
- this seems like it should not be necessary since the signature is guaranteed to aleady be registered through the module already so with a bit more plumbing we should be able to convert to a shared index in theory.ComponentItem::from
- this is I think the same as the above just with components instead of modulesFuncType::new
- this seems justified, but in the sense that this method would get inlined intoFuncType::new
It's ok to defer this to later, but wanted to note this down.
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.
The first two should still re-register the type (ie increment its ref count), even though it should already be registered, because we wouldn't want to end up in the situation where
- we load a module, registering its types
- get a registered type from the module
- drop the module, unregistering its types
- and now have a dangling function type
We could have a helper to get an already-registered type and increment its ref count, but I'm not sure how that would be any more efficient than what exists now. I guess it could at minimum assert that the type is already registered, but this isn't really giving us much I don't think.
Or maybe I am completely missing your point?
pub fn imports(&self) -> impl ExactSizeIterator<Item = ((&str, &str), ExternType)> { | ||
pub fn imports<'a>( | ||
&'a self, | ||
engine: &'a Engine, |
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.
I think this is a bit unfortunate and ideally we'd wrap this via some other means, for example storing a Component
in Handle<T>
or an Engine
in there or something like that. That being said this isn't the end of the world so I think it's reasonable to keep it around for now and see if we can figure out something better in the future.
We could make it a single
I'm happy to explore either option, or even something else, if you can think of anything. But I think it would be best to do so in a follow up PR. |
Another thing I was thinking that might make sense, but I haven't fully explored yet:
I don't think this would be a magic solution, but I think it would at least make more clear the relationship between an engine and a registry and make it so that if you need access to both things you don't need to choose between
Again, this is something for future exploration, IMO. |
FWIW, filed WebAssembly/wasm-c-api#190 so that we can eventually implement the relevant bits of the Wasm C API again. |
Yeah I think it's reasonable to explore this all in the future, I don't have any great ideas myself so it's mostly otherwise about is this semantically what we want which I believe is "yes", and then overhead/perf needs a guiding use case to help inform it. Also IMO we need to support the C API as-is while it hasn't changed, so it means that |
934d924
to
7791bd1
Compare
Rather than holding a copy of the type directly, it now holds a `RegisteredType` which internally is * A `VMSharedTypeIndex` pointing into the engine's types registry. * An `Arc` handle to the engine's type registry. * An `Arc` handle to the actual type. The last exists only to keep it so that accessing a `wasmtime::FuncType`'s parameters and results fast, avoiding any new locking on call hot paths. This is helping set the stage for further types and `TypeRegistry` refactors needed for Wasm GC.
7791bd1
to
3a74942
Compare
Rather than holding a copy of the type directly, it now holds a
RegisteredType
which internally isVMSharedTypeIndex
pointing into the engine's types registry.Arc
handle to the engine's type registry.Arc
handle to the actual type.The last exists only to keep it so that accessing a
wasmtime::FuncType
's parameters and results fast, avoiding any new locking on call hot paths.This is helping set the stage for further types and
TypeRegistry
refactors needed for Wasm GC.