| aef5eeb5 | 12-Aug-2025 |
Alex Crichton <[email protected]> |
Refactor internals of table initialization and management (#11416)
* Refactor const-eval to use `Val`, not `ValRaw`
This commit refactors the evaluation of constant expressions during instantiation
Refactor internals of table initialization and management (#11416)
* Refactor const-eval to use `Val`, not `ValRaw`
This commit refactors the evaluation of constant expressions during instantiation for example to use `Val` instead of `ValRaw`. Previously the usage of `ValRaw` meant that wasm was disallowed from performing a GC during const evaluation, but currently constant expressions can indeed perform a GC. The goal of this commit is to lift this limitation. This is expected to be a minor slowdown for modules that hit this path, but most modules shouldn't hit this in a hot loop since LLVM doesn't generate modules that use this branch of const eval.
The usage of `Val` brings a number of benefits and refactorings associated with it:
* Const-evaluation is generally safer than before since everything is higher-level. * GC types in const-eval were almost already using `Val` meaning that there's actually fewer conversions now. * Instantiation code was refactored to use `wasmtime::*`-API types instead of low-level VM types. This deduplicates a good deal and lifts complexity out of the raw VM bits.
Another issue that this commit fixes is to change how table initialization is modeled internally in `vm::Instance::table_init_segment`. Previously this was done by removing the tables from an instance to get a split borrow into the store and the table. This is not valid though because if, during initialization, a GC is performed then the table is not present to find roots through the table. This function is refactored to scope borrows to within a loop instead of over a loop via various refactorings and such and usage of higher level APIs. This is again, like above, expected to pessimize performance but this is also not known to be a hot path for modules at this time.
* Remove the `TableElement` type
This commit is a refactoring of how tables work within Wasmtime to avoid funneling table elements through a `TableElement` enum internally. Instead methods are "exploded" to `grow_{gc_ref,func,cont}` which means, for example, funcrefs don't need a GcStore. The main motivation for this change was to avoid the idiom where `TableElement` represents a cloned, but unrooted, GC reference.
Prior to this commit there were a number of subtle bugs in the table code for Wasmtime where write barriers were forgotten on `table.init`, `table.set` (via the embedder API), and `table.grow`. While `table.fill` correctly handled the GC references it was awkward to get everything else working consistently so I opted to remove `TableElement` entirely to make it more clear that `&VMGcRef` is ubiquitously used meaning that the write barriers, for example, are the same as other parts of the Wasmtime codebase.
This has a few extra tests for "make sure this doesn't leak" to ensure that GC works correctly with new barriers in place.
* Fix some lints and warnings
* Fix wmemcheck build
* Review comments
* Optimize const eval and global initialization
* Fix compile
* Fix lints
show more ...
|