You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(radls): refcount DocumentVersion to free tree-sitter C memory
Every parser.Parse allocates a *ts.Tree wrapping C-heap memory.
go-tree-sitter requires explicit Close() to release it (the
upstream README explicitly warns against finalizers due to cgo
hazards: Nodes hold references into the C tree but the Go GC
can't see them, so a finalizer-driven Close can fire while
another goroutine is walking the tree). The Phase 8b snapshot
model dropped the only call site that closed trees, so every
didChange now leaks one tree until the process exits.
Implement reference counting on DocumentVersion. The Document
holds one reference; each State.Snapshot / SnapshotByID call
bumps the count and returns to a caller who MUST call Release.
When the count reaches zero the tree is Close()d.
The acquire path uses CAS rather than plain Add so we can't
resurrect a snapshot whose tree has already been freed - the
'weak-to-strong reference upgrade' pattern. A small race window
exists between loading Document.snapshot and acquire(): the
writer can Release the old version we observed. acquire returns
false in that case and we retry; Document.snapshot has by then
been updated to point at a newer version.
Also fix the secondary leak in RadTree.Update (the standalone
checker path): the old tree was being abandoned without Close.
Now Update Closes the previous root.
The RadTree.Close becomes idempotent via sync.Once because the
underlying ts.Tree.Close is NOT idempotent (always calls
ts_tree_delete; second call double-frees). closeOnce lets
callers defer-Close confidently and also protects the
Document.Update -> Release path when Update's child tree replaces
a snapshot.
Tests: explicit refs-go-to-zero -> tree-nil verification,
late-acquire-on-released-snapshot must fail, all existing
snapshot/concurrency tests updated to Release. Race-clean under
-race across the full project.
0 commit comments