ReviewOS

zig-utils/zig-js

Perf: cache object-literal shape transitions in bytecode

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

Parent: #62 Related: #61

Problem

After explicit typed-edge ownership removed the prior GC membership bottleneck, the fresh symbolized object_churn profile attributed the largest non-GC child of vm.runChunk to init_prop / Interpreter.defineLiteralDataProp. Each fixed-name property of every fresh literal repeated accessor probing, shape-chain lookup, and transition-cache traversal even though a bytecode site normally sees the same immutable predecessor-to-child shape transition.

The pre-change profile sampled 81 stacks at the init_prop dispatch, including 44 in defineLiteralDataProp; shape.lookup, Shape.findTransitionCached, and Object.setOwnUnlocked were visible leaves.

Implemented design

  • reuse each init_prop instruction inline-cache entry for immutable predecessor-to-child literal shape transitions without enlarging bytecode;
  • retain four polymorphic entries so a compiled chunk reused across realms caches each realm shape independently;
  • use the existing seqlock protocol for coherent shared-mode publication and reads;
  • revalidate predecessor shape, slot/count, accessors, key order, attributes, and extensibility before direct append;
  • retain property_lock for concurrent marking/shared execution while allowing the isolated fresh-literal path to avoid it;
  • preserve GC barriers, inline-to-backed slot growth, numeric-key flags, method home objects, duplicate/accessor replacement, computed keys, and __proto__;
  • fall back to full CreateDataProperty on every guard miss.

Evidence

  • clean order-balanced 8e861ec2/current A/B: 810.839 ms vs 780.171 ms median, 3.8% less elapsed time;
  • fresh post-gate 100-job x 7-sample result: zig-js 842.744 ms vs JSC 122.002 ms, exact checksum 1030552128;
  • post-change profile removed defineLiteralDataProp, shape lookup, and transition traversal from the sampled leaf list;
  • full suite: 752/752 passed with 0 skipped, failed, or leaked; benchmark harness: 7/7 passed.

Acceptance criteria

  • Warm ordinary fixed-name literal sites bypass repeated shape lookup/transition traversal.
  • Duplicate names, accessors, __proto__, computed properties, and numeric keys retain ECMAScript semantics.
  • GC barriers and inline/backed slot ownership remain correct.
  • Parallel shared-realm execution consumes only coherently published cache entries.
  • Exact object_churn checksum remains 1030552128 and direct throughput materially improves.
  • Focused tests and the final batched suite pass.
9 days ago

Implemented and pushed directly to main in 0d118f23 (perf(vm): cache object literal shape transitions (#65)). The issue body now contains the final design, clean A/B, post-gate JSC comparison, profile result, and validation evidence.

Sign in to comment on this issue.