ReviewOS

zig-utils/zig-js

Perf(object): publish initialized data descriptors atomically

#663
Closed chris opened this 9 days ago ·
9 days ago

Parents: #479, #532 Related: #662, #493

Problem

Fresh function and built-in initialization repeatedly publishes a data property with assignment-default attributes, releases property_lock, reacquires it, and then installs the final descriptor. The post-#662 cold Context profile retains Object.setOwnUnlocked, Object.setAttrUnlocked, installNativeProps, and setNativeWithData leaves along this exact path. Besides duplicate uncontended synchronization, a published object can transiently expose the wrong descriptor if initialization ever crosses a sharing boundary.

Scope

  • Add one Object primitive that publishes a data value and its final attributes under one property_lock critical section.
  • Prepare attribute metadata before release-publishing the Shape and restore the exact prior metadata on OOM.
  • Preserve insertion order, existing low-level accessor/data coexistence, GC barriers, Shape convergence, backing ownership, and existing-data replacement semantics.
  • Migrate function name/length, native method/static installation, constructor prototype, and other provably equivalent fresh data-descriptor initialization sites.
  • Retain ordinary assignment and Object.defineProperty semantics unchanged.
  • Measure the frozen #661 cold no-evaluation Context boundary against the exact first parent, with a warm representative Shape-transition control.

No-workaround rules

  • No lock disabling, freshness guesses at shared call sites, default-attribute publication followed by repair, ignored OOM state, predictable hashing, benchmark-only fast path, pooling, or hidden warmup.
  • No stacks, queues, jobs, Promise, microtask, Worker-lifecycle, or Map/Set iterator changes.

Acceptance

  • Unit tests prove final descriptor identity, existing-data replacement, accessor/data coexistence, insertion order, one-lock publication, and exact OOM rollback.
  • A no-GIL publication witness observes only absent or the complete final descriptor, never assignment-default attributes.
  • Function and built-in descriptor Test262 surfaces have exact nonzero before -> after accounting with zero flips.
  • Focused tests, full units, applicable TSan/threadfuzz, and docs/benchmark CI pass.
  • Exact-parent cold lifecycle evidence identifies the affected phase/RSS/finalizers; the warm Shape control does not regress materially.
9 days ago

Implementation pushed in 1605a118.

Object.setOwnWithAttr now installs attribute metadata before the Shape release store and restores the exact previous attribute entry if later Shape/slot preparation fails. The tracked setter returns prior metadata from its existing hash lookup, avoiding a second successful-path probe. Function name/length, native methods, intrinsic constructors/prototypes, error prototypes, realm globals, dynamic Function names, and raw JSON initialization use the one-lock transaction. Ordinary assignment, DefineOwnProperty, and accessor conversion are unchanged.

Correctness evidence:

  • standalone Object/Shape: 84/84
  • focused production: 3/3; focused TSan: 3/3, zero leaks
  • focused frontend: 12/12
  • final full suite: 1,753 passed / 1 platform skip / 0 failed / 0 leaked across 8 shards
  • exact parent cb0200bc -> candidate Test262: Function 509, Object 3,411, JSON 165, function expressions 264, function statements 451; 4,800 -> 4,800, byte-identical transcripts, zero failures/flips

A three-pair diagnostic preserved checksum, all 2,529,000 cell finalizers per invocation, and neutral RSS while candidate create time/cycles were lower. It is not publication evidence. Remote CI, threadfuzz, and formal quiet-host cold/warm artifacts remain pending.

9 days ago

A later descendant matrix that still contains 1605a11 completed enough relevant gates to add evidence without closing the comprehensive box: CI run 32485314750 passed all four ordinary unit shards, focused-engine-tests, Test262 parallel, docs, dependency audit, threadfuzz amplified/broad/verify, ReleaseSafe threadfuzz, TSan threadfuzz lifecycle, and TSan watchdog cleanup.

The run was superseded/cancelled and is not globally green. Its three observed failures are outside initialized-descriptor publication: the known #643 Map iterator TSan race, cve/mc-lock-stop-vs-park.js (expected 400, got 401), and semantics/oom-one-thread.js (heap-cap OOM). I am leaving the comprehensive TSan/threadfuzz/CI box open, as well as formal cold/warm evidence; no failing thread/lifecycle surface was changed.

9 days ago

Same unblock path as #662: #643 fixed in 04d46c59 removes the TSan race; the remaining `mc-lock-stop-vs-park`/`oom-one-thread` corpus failures are tracked in #722. Cold/warm evidence collection remains pending a quiet reference-host window.

9 days ago

Exact evidence preparation is complete without promoting battery diagnostics. Frozen parent cb0200bc and candidate 1605a118 comparison runners were rebuilt with Zig 0.17.0-dev.1441; SHA-256 identities are 24d5eaeb1e9df9165b44551f5d8950b900e679a3b04b5e829e7eb9983356f2fe and 03557939a8577ca816179c58834f95f8f29eab1374421ca2fcbda5ed30e89ff1. Embedded comparison/representative sources are byte-identical (7a1a5bef… / 94d9463c…). Both revisions return checksum 0 and exactly 20,232 finalized cells for an eight-context no-evaluation contract; the warm Shape-fanout control returns checksum 2 for one job. Retained seven-pair cold/warm collection remains queued until AC power and a competitor-free window; no timing from these probes is retained.

9 days ago

Comprehensive integration is now green in main CI run 32923883777: 53 required jobs passed, the one nightly-only job was skipped as configured, and 0 jobs failed or were cancelled. This closes the focused/full unit, Test262, TSan/threadfuzz, docs, and benchmark integration box for the landed #663 implementation. Exact-parent cold lifecycle and warm Shape-control evidence remains open; the current host is AC/nominal but has an unrelated unit process and system indexing load, so no timing sample is being started or retained.

9 days ago

Completed and published the remaining exact-parent cold lifecycle and warmed Shape-control evidence.

The seven-pair quiet-reference comparison is the exact cb0200bc parent → 1605a118 candidate boundary.

Cold 1,000-Context create/no-evaluation/exact-destroy row:

  • wall: 1.0096x
  • scoped create phase: 1.0031x
  • destroy phase: 1.0188x
  • retired instructions: 1.0039x
  • cycles: 1.0022x
  • process energy: 0.9977x
  • peak / retained RSS: 1.0091x / 1.0122x
  • finalizers: exactly 2,529,000 cells per invocation on both sides, with the complete finalizer object identical across all samples

Warm 100,000-transition Shape-fanout control:

  • wall: 0.9769x
  • retired instructions: 1.0088x
  • cycles: 0.9930x
  • process energy: 0.9991x
  • peak RSS: 1.0027x
  • checksum: exact (5,000,150,000)

Both rows pass the frozen 10% material-regression threshold; all required series are stable, thermals are nominal, and no samples were discarded. The docs state this as bounded-cost evidence for the atomic publication hardening, not as a broader throughput claim. Both schema-v3 artifacts, all 316 documentation links, the 50-page BunPress build, and git diff --check pass. The publication commit is verified at origin/main and closes #663.

Sign in to comment on this issue.