Skip to content

Audit object-reference threadvars for worker-exit lifetime #892

Description

@frostney

Follow-up to #885 / #891.

PR #891 fixed the worker-exit lifetime of managed threadvars (AnsiString / TArray<>) via Goccia.ThreadCleanupRegistry, but deliberately scoped out object-reference threadvars, because FPC never auto-finalizes object refs anywhere and freeing them at thread exit risks double-free / use-after-free that needs per-site analysis.

Audit the object-reference threadvars surfaced during #885 and route any genuine leakers (or document why each is already safe):

  • Goccia.Builtins.GlobalSymbolGSharedSymbolRegistry: TOrderedStringMap<...> (ref-counted; appears safe — confirm)
  • Goccia.Values.SymbolValueGSymbolRegistry: THashMap<...>
  • Goccia.ObjectModelGPublishedGetterHosts: TObjectList<...>
  • Goccia.Compiler.StatementsTList working-state threadvars
  • any others found by a fresh sweep of source/units + source/shared

Acceptance criteria

  • Each object-reference threadvar is either freed on the correct teardown path(s) or has a comment explaining why it is already safe (owned/freed elsewhere).
  • No double-free / use-after-free introduced (verify under the worker spawn→exit path).

Also in scope: manually-pinned per-thread prototype hosts (from #891 review)

Several value types keep a threadvar FPrototypeMethodHost: TGoccia<Type>Value that InitializePrototype assigns and manually GC-pins (PinObject) so the cached member definitions stay valid across realms on the thread — e.g. Goccia.Values.ArrayValue, Goccia.Values.BigIntValue, Goccia.Values.BooleanObjectValue, Goccia.Builtins.Performance (FPrototypeMethodHost), and similar. These are object-reference threadvars (not managed types), so #891 left them untouched. Per [docs/garbage-collector.md], built-in prototypes are normally pinned via realm slots and released on realm Destroy; these manual pins are a separate, per-thread mechanism.

Determine whether the manually-pinned host is reclaimed at worker GC shutdown or leaks per worker, and either move it to a realm-slot / true process singleton or unpin+nil it on thread teardown. Sweep for every FPrototypeMethodHost (and equivalent manually-pinned host threadvars).

Metadata

Metadata

Assignees

No one assigned

    Labels

    engineTGocciaEngine: language semantics, ECMAScript built-ins, parser, interpreter, bytecode VM

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions