ReviewOS

zig-utils/zig-js

JSON.stringify: append ordinary string runs in bulk

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

Parents: #473, #493 Related: #460, #461, #516, #518, #519, #556, #558

Problem

writeJsonString appends every ordinary byte separately. Large already-safe strings therefore execute one grow/capacity check and list-length mutation per byte even though their output is a contiguous copy. Property names and string values both take this path, so attacker-controlled string width can turn serialization into avoidable dispatch and allocator bookkeeping.

Scope

  • Land benchmark-first rows for large plain ASCII strings at multiple widths, valid multibyte Unicode, sparse mixed escapes including quotes/backslashes/control bytes, lone-surrogate WTF-8, and a short-string control.
  • Scan once for JSON escape boundaries and append maximal ordinary byte runs in bulk.
  • Preserve exact escaping, lowercase hexadecimal spelling, WTF-8 lone-surrogate behavior, property-name/value output, and all replacer/toJSON/property-order semantics.
  • Keep temporary/output ownership and OOM propagation exact; do not introduce persistent caches or alternate string representations.

No-workaround rules

  • No input recognition, output precomputation, skipped escaping validation, ASCII-only shortcut, replacement of lone surrogates, changed JSON spelling, system JSON library, or hidden lower input cap.
  • Do not touch stacks, queues, jobs, Promise/microtask, or Worker lifecycle code.

Acceptance

  • Benchmark source, widths, escape distribution, Unicode/WTF-8 controls, checksums, jobs, warmup, and timed boundary land before the runtime change.
  • Ordinary byte runs are appended in bulk with O(n) scanning and bounded transient storage; no-escape strings do not perform per-byte output appends.
  • Quotes, reverse solidus, named controls, other U+0000–U+001F controls, valid Unicode, lone high/low surrogates, property keys, and string values preserve exact output.
  • Focused OOM, deep/wide, precise-GC, TSan, forced execution modes where eligible, JSON.stringify test262, and full units pass without regressions.
  • Seven-pair exact-parent evidence publishes wall, CPU, peak RSS, instructions/cycles/energy availability, thermal state, and dispersion with no discarded samples; the short-string control has no regression.

Security boundary

String width, escape density, byte distribution, surrogate shape, callback behavior, and allocation pressure are attacker-controlled. The optimization reduces ordinary-output work without weakening JSON escaping or turning partial allocation failure into observable partial output.

Resolution

9 days ago

The prerequisite output-path change in #558 is complete via 3ec9847f, with exact-parent evidence in 61652299. #557 can now optimize ordinary string runs against one authoritative temporary output buffer without reintroducing ancestor copies; the shallow control remains neutral and Test262 JSON.stringify is 66/66.

9 days ago

Benchmark foundation 98972688 is now on main before the runtime change. It freezes plain 4K/16K/64K rows plus valid multibyte Unicode, sparse mixed escaping, separated lone high/low surrogates, and a short-string control. Inputs and exact fixed-size probes are built before ten warmups; all seven one-job checksums and the complete benchmark validation family pass. Parent diagnostics are recorded in the commit body. Runtime work will compare directly against this commit.

9 days ago

Runtime a7da43f4 is now on main: safe bytes are scanned once and maximal ordinary runs are appended in bulk, with exact fallback only for quotes, reverse solidus, controls, and WTF-8 surrogates. Exact key/value spelling, 64K width, precise-GC/compaction, forced-tier, TSan, and failure-atomic 8 MiB OOM witnesses pass. Full units are 1,633 passed plus 1 expected skip; ReleaseFast Test262 JSON.stringify remains 66/66; all seven frozen benchmark checksums remain unchanged. Seven-pair exact-parent evidence against 98972688 is next.

9 days ago

Completed by benchmark-first 98972688, runtime a7da43f4, and evidence 6dbe188f.

The runtime now scans each string once and bulk-appends maximal ordinary byte runs. It breaks only for quotes, reverse solidus, U+0000–U+001F controls, or exact WTF-8 surrogate encodings. Exact key/value spelling, lowercase hexadecimal escapes, valid multibyte Unicode, OOM teardown, and callback/property semantics remain intact.

Exact-parent retired-instruction ratios:

  • plain 4K / 16K / 64K: 0.9619x / 0.9560x / 0.9565x
  • valid multibyte Unicode: 0.9706x
  • 64K ordinary bytes with sparse mixed escapes: 0.9575x
  • lone-surrogate control: 1.0102x, peak RSS 1.0028x

The dated overview records all 98 order-balanced fresh processes, battery power, nominal thermal state, no discards, complete dispersion, and diagnostic wall caveats.

Validation: Test262 JSON.stringify 66/66; focused Debug and TSan 12/12; full units 1,633 passed plus 1 expected skip with 0 failures/leaks; wide, precise-GC/compaction, forced-tier, and bounded-OOM witnesses; seven schema validations; benchmark validation family; 267-file docs link gate.

Sign in to comment on this issue.