Skip to content

Add garbage collection for WASM linear memory (#51)#202

Merged
aallan merged 3 commits into
mainfrom
feature/gc-wasm
Mar 4, 2026
Merged

Add garbage collection for WASM linear memory (#51)#202
aallan merged 3 commits into
mainfrom
feature/gc-wasm

Conversation

@aallan

@aallan aallan commented Mar 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Implements conservative mark-sweep garbage collection entirely in WASM (no host-side GC logic), closing the last open C8e item (Garbage collection for WASM linear memory #51)
  • Every heap allocation gets a 4-byte header (mark bit + size). The GC uses a shadow stack for root tracking, an iterative mark worklist with conservative pointer scanning, and a free-list sweep phase
  • Programs that allocate heavily (e.g., building and discarding linked lists in a loop) now survive beyond the initial 64 KiB page through automatic memory reclamation and memory.grow fallback
  • Zero GC overhead for pure programs that perform no allocation

Changes

Core GC implementation:

  • vera/codegen/assembly.py — GC globals, rewritten $alloc (header + free-list + GC trigger), $gc_collect (clear/mark/sweep)
  • vera/codegen/functions.py — GC prologue/epilogue in _compile_fn (save/restore $gc_sp, push pointer params/returns)
  • vera/codegen/closures.py — Same prologue/epilogue for lifted closure functions
  • vera/wasm/helpers.pygc_shadow_push() helper (7 WAT instructions)
  • vera/wasm/data.py — Shadow stack push after constructor/array allocations
  • vera/wasm/closures.py — Shadow stack push after closure allocation + needs_alloc flag
  • vera/wasm/calls.py — Fix to_string/strip interior pointers; shadow stack pushes in string operations

Tests:

  • 11 new GC tests in TestGarbageCollection class (WAT-level + behavioral)
  • Updated heap offset tests and verification tier counts for new example

Example:

  • examples/gc_pressure.vera — builds and discards 100-element linked lists 30 times

Documentation:

  • Updated memory layout diagram and allocator description in spec/12-runtime.md
  • Replaced "No Garbage Collection" section with full GC specification
  • Removed GC limitation from all limitation tables
  • Version bump to 0.0.65

Test plan

  • All 1418 tests pass (pytest tests/ -q)
  • Type checking clean (mypy vera/)
  • All 16 examples pass (python scripts/check_examples.py)
  • Version sync verified (python scripts/check_version_sync.py)
  • README code blocks parse (python scripts/check_readme_examples.py)
  • SKILL.md code blocks parse (python scripts/check_skill_examples.py)
  • vera run examples/gc_pressure.vera returns 151500

Closes #51

🤖 Generated with Claude Code

…#51)

Implement a conservative mark-sweep GC entirely in WASM (no host-side logic).
Programs that allocate heavily now survive beyond the initial 64 KiB page
through automatic memory reclamation and memory.grow fallback.

Key changes:
- Object headers: 4-byte header (mark bit + payload size) prepended by $alloc
- Shadow stack: explicit root tracking in linear memory (4096 bytes)
- Mark worklist: iterative marking with conservative pointer scanning (4096 bytes)
- $gc_collect: clear marks, mark from shadow stack roots, sweep to free list
- $alloc: free-list first-fit before bump allocation, GC trigger on OOM
- Function prologue/epilogue: save/restore $gc_sp, push pointer params/returns
- Lifted closure functions: same GC instrumentation as regular functions
- to_string/strip: allocate exact-size result buffers (no interior pointers)

Co-Authored-By: Claude <noreply@anthropic.invalid>
aallan and others added 2 commits March 4, 2026 19:56
Document GC architecture in vera/README.md: memory layout, allocator,
collector phases, shadow stack, and zero-overhead guarantee. Update
module line counts to reflect GC implementation growth.

Co-Authored-By: Claude <noreply@anthropic.invalid>
Collapse C8 into a <details> block (matching C6/C6.5/C7 pattern),
update roadmap table with version range v0.0.40-v0.0.65, mark C8.5
as "In progress" and make it the active "Working on" section.

Co-Authored-By: Claude <noreply@anthropic.invalid>
@aallan aallan merged commit 4f4d846 into main Mar 4, 2026
10 checks passed
@aallan aallan deleted the feature/gc-wasm branch March 4, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Garbage collection for WASM linear memory

1 participant