Skip to content

Shape descriptors cost 32 MB for 85,288 entries; V8 does the same job in 3.58 MB for 39,703 maps — ~9x per-descriptor overhead #9706

Description

@proggeramlug

From the validated heap census of claude-code (PERRY_GC_CENSUS, fork/feat/gc-census). Largest single side table, and the largest addressable memory lever now that the regex leak (#9678) is fixed.

perry node (same bundle)
shape/map count 85,288 descriptors 39,703 V8 Maps
bytes 32.0 MB 3.58 MB
per entry ~394 B ~94 B

Two independent factors: 2.1× more descriptors and ~4× more bytes each.

Worth establishing before optimising

  1. Why 2.1× more shapes than V8 for identical JS? Transition-tree sharing, or shapes minted per-site that V8 unifies? If cc creates 85k distinct object layouts, either the transition chains aren't being shared or something (per-call-site specialisation? the KEYS_INDEX sidecar from perf(object): O(1) own-key answers for wide-object defineProperty and in (#6748) #6749?) is minting duplicates. Halving the count is worth ~16 MB before touching the layout.
  2. What is in a 394-byte descriptor? ShapeDescriptor is copied by value at 63 call sites (see the shape_descriptor_field_by_id note in the campaign's prior work), so its size is already known to matter for speed. An inline key array, a sidecar pointer, and per-field metadata are the likely bulk — a census of the struct itself would say.

Ceiling

Even reaching 2× V8's per-entry cost with the current count is ~16 MB; matching count and density approaches node's 3.6 MB. Realistic target ~8–12 MB, i.e. a 20–24 MB win — the single biggest remaining item.

Verification

PERRY_GC_CENSUS=<path> reports side_tables.shapes directly; node's comparison comes from --heapsnapshot-signal=SIGUSR2 ("object shape" bucket). Both were measured this way. Any change must hold the shape-dependent fast paths green (the IC/transition tests) — a smaller descriptor that loses a field the fast path reads would trade memory for a deopt cliff.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions