logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·01.11.26
← Back to news

GC and Exceptions in Wasmtime

Original article
bytecodealliance.org|143 points|25 comments|by phickey|Jul 20, 2026

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

FeatureOld Approach (Embedded GC)New Approach (Wasm GC Proposal)
Binary SizeBloated due to embedded GC logicLean; leverages runtime GC
IntrospectionNo stack maps or stack walkingNative runtime support for roots
ManagementManual/Custom memory handlingRuntime handles lifetimes & deallocation
CompatibilityDifficult for high-level languagesOptimized 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 $node →\rightarrow→ Create a new instance.
  • struct.get $node $key →\rightarrow→ Access a field.
  • struct.set $node $left →\rightarrow→ Modify 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:

  1. Every single call site had to check the return status.
  2. Branching logic was added to every call.
  3. Result=Increased binary bloat+Runtime overhead\text{Result} = \text{Increased binary bloat} + \text{Runtime overhead}Result=Increased binary bloat+Runtime overhead.

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: Reference=Index32bit→Linear Memory Offset\text{Reference} = \text{Index}_{32bit} \rightarrow \text{Linear Memory Offset}Reference=Index32bit​→Linear Memory Offset

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 ≈5μs\approx 5\mu s≈5μs.
    • 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."

GC Architecture Concept


🧪 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."