Skip to content

Remove ensure_trace_info methods#13843

Open
alexcrichton wants to merge 8 commits into
bytecodealliance:mainfrom
alexcrichton:no-ensure-trace-info
Open

Remove ensure_trace_info methods#13843
alexcrichton wants to merge 8 commits into
bytecodealliance:mainfrom
alexcrichton:no-ensure-trace-info

Conversation

@alexcrichton

Copy link
Copy Markdown
Member

This commit removes all ensure_trace_info methods from all GC
collectors, the GC store, etc. The goal of this commit is to accelerate
instantiation of modules that use GC by avoiding using the read-write
lock on the TypeRegistry stored within the engine. As shown in #13822
even in read-only situations this comes with a significant performance
penalty.

The strategy taken in this commit is to take an alternative route of
handling trace information, empowered by the previous commit. Notably
trace information is now all available at Module-creation time, for
example, and need not be re-calculated for each store. The main
difficulty is then looking up this trace information at runtime when a
GC is performed. This commit implements functionality where TraceInfos
is repurposed as a cache rather than a storage table. The cache stores
where the trace information is located, and then trace information is
looked up where it lies at-rest within a Module or RegisteredType.

This means that the first time a type is traced within a store it
requires a search to determine where the trace information is located.
Right now this involves two locations:

  • If a store's gc_host_alloc_types maps contains the type index, then
    that's where the trace information is located.

  • Otherwise a module previously inserted into a store's ModuleRegistry
    must have trace information. The entire registry is searched and each
    module is consulted to determine if it has trace information for the
    type index in question.

The TraceInfos cache is intended to amortize this cost of a lookup.
This lookup is additionally mitigated in the copying collector where
this is only required for "big structs" where their tracing information
can't be stored inline in the object header itself. Overall it's
expected that for the copying collector this change has little effect on
typical GC performance itself.

Additionally overall, however, this eliminates usage of the read/write
lock in the TypeRegistry entirely during instantiation. Eliminating
this lock acquisition was the goal of this commit, and this is expected
to help improve parallel instantiation performance of GC-using modules.

Note: this is currently built on #13842

@alexcrichton alexcrichton requested a review from a team as a code owner July 7, 2026 21:16
@alexcrichton alexcrichton requested review from fitzgen and removed request for a team July 7, 2026 21:16
@alexcrichton alexcrichton force-pushed the no-ensure-trace-info branch from d8a6d13 to 1235f62 Compare July 7, 2026 21:38
@alexcrichton alexcrichton requested a review from a team as a code owner July 7, 2026 22:00
This commit is an update to the DRC collector to avoid immediately
dropping GC references in `write_gc_ref`. This is done today by
threading contextual information such as `ExternRefHostDataTable` all
the way down to `write_gc_ref` and `drop_gc_ref` hooks, but a
refactoring that I'm planning to do is going to make it significantly
more complicated to thread all necessary contextual information through
to these hooks. Specifically I'm hoping to store `TraceInfo` outside of
stores and instead inside of `Module` and `RegisteredType` to avoid the
need for per-type work done during module instantiation. Threading this
context through these hooks is effectively ergonomically a no-go.

The strategy then taken in this commit is to change the DRC allocator,
the only allocator we have that needs this information during these
barriers. The DRC allocator now defers full deallocation of GC
allocations to a later point in time where contextual information is
available (e.g. during a GC itself). This means that host-initiated
writes/drops are no longer guaranteed to actually run destructors
immediately (same as with the copying collector). Internally the DRC
heap already has a stack of references to decrement, and previously it
was only needed during a decrement operation and now it's instead
modified to persist between GC barriers through to a GC itself.
This is an attempt to move more information that's only needed for
GC-enabled Wasmtime to `gc`-feature-gated files. This moves some
methods, types, etc, from `store.rs` to `store/gc.rs`
This commit updates the `RegisteredType` and `TypeCollection`
abstractions to inherently store within them `TraceInfo` used for GC
types. This was previously calculated per-instantiation and per-store
when modules were instantiated or types were inserted into the store.
No consumers of this information currently exist, but the goal of this
commit is to enable the next commit to use it.
This commit removes all `ensure_trace_info` methods from all GC
collectors, the GC store, etc. The goal of this commit is to accelerate
instantiation of modules that use GC by avoiding using the read-write
lock on the `TypeRegistry` stored within the engine. As shown in bytecodealliance#13822
even in read-only situations this comes with a significant performance
penalty.

The strategy taken in this commit is to take an alternative route of
handling trace information, empowered by the previous commit. Notably
trace information is now all available at `Module`-creation time, for
example, and need not be re-calculated for each store. The main
difficulty is then looking up this trace information at runtime when a
GC is performed. This commit implements functionality where `TraceInfos`
is repurposed as a cache rather than a storage table. The cache stores
where the trace information is located, and then trace information is
looked up where it lies at-rest within a `Module` or `RegisteredType`.

This means that the first time a type is traced within a store it
requires a search to determine where the trace information is located.
Right now this involves two locations:

* If a store's `gc_host_alloc_types` maps contains the type index, then
  that's where the trace information is located.

* Otherwise a module previously inserted into a store's `ModuleRegistry`
  must have trace information. The entire registry is searched and each
  module is consulted to determine if it has trace information for the
  type index in question.

The `TraceInfos` cache is intended to amortize this cost of a lookup.
This lookup is additionally mitigated in the copying collector where
this is only required for "big structs" where their tracing information
can't be stored inline in the object header itself. Overall it's
expected that for the copying collector this change has little effect on
typical GC performance itself.

Additionally overall, however, this eliminates usage of the read/write
lock in the `TypeRegistry` entirely during instantiation. Eliminating
this lock acquisition was the goal of this commit, and this is expected
to help improve parallel instantiation performance of GC-using modules.
@alexcrichton alexcrichton force-pushed the no-ensure-trace-info branch from 5af0adb to aee3216 Compare July 7, 2026 22:55
@github-actions github-actions Bot added wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:ref-types Issues related to reference types and GC in Wasmtime labels Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Subscribe to Label Action

cc @fitzgen

Details This issue or pull request has been labeled: "wasmtime:api", "wasmtime:ref-types"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: wasmtime:ref-types

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:ref-types Issues related to reference types and GC in Wasmtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant