One-hop tracked storage and known-tag references - #21546
One-hop tracked storage and known-tag references#21546NullVoxPopuli-ai-agent wants to merge 1 commit into
Conversation
trackedData keeps value and tag in a single cell per (field, instance): a tracked read is one WeakMap hop + consumeTag and a write is one hop + DIRTY_TAG, replacing three map hops each way (central TRACKED_TAGS WeakMap -> per-object Map, plus the separate values WeakMap). The cell registers its tag into the central registry at creation, so notifyPropertyChange and computed-property chains observe the identical tag object the field itself consumes and dirties. On top of that, a child reference locks onto its property's canonical tag when its first framed compute consumed EXACTLY that tag: a single tag rules out branching getters (their consumed sets vary per run), and identity with the registry's cell tag proves a plain tracked-field read on a parent that cannot change (a mutable parent's tag would have been in the frame too). Locked references recompute with no frame push, no tag collection, and no combine -- the getter's own consumeTag lands in the ambient frame, which is exactly what the framed path's trailing consume achieved. Anything unproven stays on the framed path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Isolated same-batch measurement (today's
The sync one-shot improvement is real but tiny in absolute terms, and it's paid for with a genuine regression where ember is weakest. Likely mechanism: On the spike branch these changes measured differently (its scheduler coalesces to far fewer flushes, hiding per-flush ref costs), which is exactly why the isolated-on-main standard exists. The one-hop tracked-cell storage might survive on its own without the reference-locking half — if it's wanted, it should return as a separate PR with its own isolated numbers. 🤖 Generated with Claude Code |
Extracted from the #21520 spike; independent of the other extraction PRs. Full suite green locally: 9443 tests, 0 failures — including the
notifyPropertyChangeand computed-property interop this touches most directly.One-hop tracked storage:
trackedDatakeeps value and tag in a single cell per (field, instance) — a tracked read is one WeakMap hop +consumeTag, a write is one hop +DIRTY_TAG, replacing three map hops each way (centralTRACKED_TAGSWeakMap → per-object Map, plus the separate values WeakMap). The cell registers its tag into the central registry at creation (registerTagFor), sonotifyPropertyChange, computed chains, and anything else resolving tags viatagFor/dirtyTagForobserves the identical tag object the field consumes and dirties — interop is preserved by tag identity, not by parallel bookkeeping.Known-tag references: a child reference locks onto its property's canonical tag when its first framed compute consumed exactly that tag. A single consumed tag rules out branching getters (their consumed sets vary run to run); identity with the registry's cell tag proves the read was the plain tracked-field getter on a parent that cannot change (a mutable parent's tag would have been in the frame too — constants are dropped from frames). Locked references recompute with no frame push, no tag collection, and no
combine(); the getter's ownconsumeTaglands in the ambient frame, which is exactly what the framed path's trailing consume achieved. Anything unproven stays on the framed path forever.Honest impact framing: neutral on the spike's benchmark suite (its apps are worker-POJO- and helper-bound); the win scales with tracked-getter density and template property reads — the common shape of real apps — and it removes per-read allocation and map traffic unconditionally.
Related: #21520 (spike), #21543 (pools), #21544/#21545 (update-path stack).
🤖 Generated with Claude Code