ReviewOS

zig-utils/zig-js

JSON.stringify: specialize live dense array element reads

#1004
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Problem

After #1003, SerializeJSONArray no longer allocates decimal index spellings, but each present packed element still enters the full string-keyed Interpreter.getProperty path. The frozen 2,200 x 90 representative rows perform 594,000 such reads. The index is already available as usize, yet generic lookup reparses it, probes indexed descriptor state, and enters prototype/generic property scaffolding before returning a present dense own value.

Change boundary

Add a narrow SerializeJSONProperty fast path for a direct ordinary Array whose current index has no own accessor and has a present dense element. Read the live value for every index immediately before toJSON/replacer processing. Any proxy, arguments mapping, accessor, hole, sparse named property, inherited property, exotic hook, or representation change must fall back to ordinary Get. Preserve shared-realm lock discipline and never hold an object lock across user code.

This issue does not authorize snapshotting element values: earlier toJSON/replacer callbacks can mutate later indices and those mutations must remain visible.

Completion

Add mutation, accessor, sparse/inherited, proxy, and arguments witnesses. Retain JSON Test262 and required VM/tree agreement; rerun OOM/deep/cycle/GC plus TSan/no-GIL gates. Compare seven exact-parent alternating pairs on both frozen JSON rows, the array-heavy shallow-4096 row, and the object-only depth-4096 control with exact checksums. Land only on a measured non-regression.

Parent: #473. Follows #1003.

9 days ago

Landed on main as 27487356. The fast path reads each current dense element immediately before its callbacks, takes the indexed transaction in shared realms, and releases all locks before user code. Proxies, arguments, accessors, holes, sparse named entries, inherited values, and representation changes retain ordinary Get. Seven exact-parent alternating pairs with exact checksums: representative_json 0.9740x retired instructions / 0.9672x CPU, variant 0.9759x / 0.9746x, and array-heavy shallow-4096 0.8940x / 0.8556x. Object-only depth-4096 stayed neutral at 1.0016x / 0.9959x. Gates: focused witness 1/1, JSON stringify semantic/OOM/deep/GC 14/14, TSan/no-GIL 2/2, JSON Test262 165/165, required VM/tree agreement 165/165.

Sign in to comment on this issue.