ReviewOS

zig-utils/zig-js

Intl.Segmenter: publish immutable formatter state

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

Parent: #475 Related benchmark/evidence: #460

Problem

Intl.Segmenter validates granularity at construction but stores it in a hidden ordinary options object. Each segment and resolvedOptions call rereads generic formatter properties even though locale/granularity never change. This formatter-level state is independent from the already-immutable per-input SegmenterInput and the mutable Segments/iterator cursors.

The existing representative_intl_segmenter_iterate_word boundary constructs each Segments input inside the scored loop and consumes every observable record field. Current zig-js and system JSC agree on checksum 360619407. Exact-parent zig-js attribution for one 100-job invocation is:

  • property-lock acquisitions: 15,705,190
  • backing allocations: 9,605,790 / 1,315,265,952 bytes
  • current backing: 109,198,405 bytes; peak: 110,397,046 bytes
  • GC cells: 4,979,258; collections: 162

Single diagnostic samples were 2.561 s in zig-js and 140.1 ms in system JSC; these are diagnostic only, not publication evidence.

Scope

  • Publish locale and granularity into an object-owned immutable formatter record after observable option reads.
  • Make segment and resolvedOptions consume that record directly and use its native slot as the Segmenter receiver brand.
  • Preserve GetOptionsObject behavior, option order/coercion, input coercion timing/count, output records, subclasses, and error ordering.
  • Account/finalize the formatter record through the bounded backing allocator; cover OOM, bounded heap, moving GC, and concurrent read safety.
  • Keep Segments input ownership and iterator cursor representation out of this change.

Acceptance

  • No hidden ordinary options bag remains on newly constructed Segmenter formatters.
  • Focused Segmenter/test262, Intl402, OOM, GC movement, concurrent read, TSan, and full unit gates pass.
  • Exact-parent comparison reports checksum equality and quantified retained changes; retain only a real improvement.
  • No ICU/system-JSC runtime dependency, global mutable cache, skipped observable hook, or repro-specific shortcut.
9 days ago

Completed on main in d77dbd2b.

Segmenter now publishes object-owned, GC-finalized immutable locale/granularity formatter state after all observable option reads. segment and resolvedOptions consume the native record directly, newly constructed formatters have no hidden ordinary options bag, and forged hidden properties no longer establish the brand. Existing Segments input ownership and mutable iterator cursor representation were deliberately left unchanged.

Exact-parent evidence at checksum 360619407:

  • 5-sample median: 2,745,043,333 -> 2,692,355,167 ns (-1.92%)
  • property locks: 15,705,190 -> 15,692,387 (-0.08%)
  • GC cells: 4,979,258 -> 4,979,257
  • bounded cost: one additional 40-byte backing allocation

Validation: Segmenter test262 79 -> 79; full Intl402 3,341 -> 3,341; focused TSan 8/8 including bounded adversarial input, moving nursery/iterator progress, shared realm, OOM, and native concurrent reads; full units 1,692 pass / 1 skip / 0 fail / 0 leak.

Sign in to comment on this issue.