GC and Exceptions in Wasmtime
GC and Exceptions in Wasmtime
By Nick Fitzgerald | Bytecode Alliance | July 20, 2026
The latest release of Wasmtime 47 marks a significant milestone: both the Wasm GC and Exceptions proposals are now experimental enabled by default! 🚀
Our objective is to broaden the ecosystem of languages that can target WebAssembly and the diverse environments where Wasmtime is deployed. Achieving this required extensive architectural shifts within Wasmtime and represents the fruit of several years of dedicated engineering.
What is Wasmtime? Wasmtime is a WebAssembly runtime engineered to be fast, safe, and portable. Its maintainers are deeply invested in open standards and contribute actively to the ongoing standardization of Wasm.
🌐 Wasm GC (Garbage Collection)
In the early days of WebAssembly, languages utilizing an "objects-and-references" model (rather than raw pointers) were forced to bundle their own garbage collectors directly into the .wasm binary.
The Problem vs. The Solution
| Feature | Old Approach (Embedded GC) | New Approach (Wasm GC Proposal) |
|---|---|---|
| Binary Size | Bloated due to embedded GC logic | Lean; leverages runtime GC |
| Introspection | No stack maps or stack walking | Native runtime support for roots |
| Management | Manual/Custom memory handling | Runtime handles lifetimes & deallocation |
| Compatibility | Difficult for high-level languages | Optimized for high-level languages |
By extending the Wasm language, programs can now define their own subtyping relationships, array types, and structs. This removes the burden of manual memory management from the toolchain.
Example: Binary Tree Node
A Wasm program can now define a recursive node type for a binary tree as follows:
(rec
(type $node
(struct
(field $key (mut f64))
(field $left (mut (ref null $node)))
(field $right (mut (ref null $node)))
(field $value (mut (ref null $payload)))
)
)
)
To interact with these types, the runtime provides specific instructions:
struct.new $nodeCreate a new instance.struct.get $node $keyAccess a field.struct.set $node $leftModify a field.
⚡ Wasm Exceptions
Similar to the GC proposal, the Exceptions proposal aims to make Wasm a first-class target for languages that rely on exception handling.
The "Old Way" (Inefficient): Toolchains had to implement bespoke calling conventions. Instead of just returning a value, functions returned a status indicating if the call was a normal return or an exception. This meant:
- Every single call site had to check the return status.
- Branching logic was added to every call.
- .
The "New Way" (Efficient):
The proposal introduces native throw and try / catch constructs. This allows the runtime to use a classic unwinding approach, which ensures that the "happy path" (normal returns) incurs zero overhead.
🛠️ Wasmtime’s GC Implementation
Wasmtime utilizes a Cheney-style semi-space copying collector.
How it Works
The GC heap is split into two equal regions: the Active space and the Idle space.
- Allocation: Performed via a simple bump pointer in the active space.
- Barriers: No read or write barriers are required.
- Memory Model: To ensure sandboxing, Wasmtime re-uses linear memories to implement the GC heap.
The 32-bit Reference
A reference to a GC object is not a raw native pointer. Instead, it is a 32-bit index into the underlying linear memory:
Why use Linear Memory for the GC Heap?
- Safety: Provides defense-in-depth. Even if a collector bug corrupts the GC heap, the program cannot escape the sandbox to touch host memory.
- Speed:
- Uses virtual-memory guard pages to skip explicit bounds checks.
- Integrates with the pooling instance allocator to maintain instantiation times of .
- On 64-bit systems, 32-bit references are more cache-efficient than 64-bit pointers.
- Portability: Since linear memory is already portable across various platforms (including bare metal), the GC heap inherits this portability "for free."
🧪 Quality Assurance & Performance
To ensure the collector is robust, Wasmtime expanded its fuzzing suite:
- General Fuzzer: Capable of generating nearly any GC-using Wasm program.
- Graph Fuzzer: Specifically targets complex object graphs, type references, and subtyping.
- Corruption Fuzzer: Designed to catch heap corruption caused by compiler misoptimizations or collector bugs.
A Note on Performance
It is important to manage expectations regarding speed:
"We have prioritized the correctness of the collector over its raw performance. Unlike the collectors in V8 or SpiderMonkey, which have benefited from decades of tuning, our implementation is brand new."