Skip to content

Wide-object Object.defineProperty + in are O(N) per call — quadratic init for Babel/webpack re-export modules (94× vs node) #6748

Description

@proggeramlug

Summary

Repeated Object.defineProperty and k in obj on a wide object (>32 keys) are O(N) per call — O(N²) for build loops. This is the webpack/Babel CJS re-export module shape, and it dominates large-bundle module init under perry.

Repro

const t = {};
for (let i = 0; i < 2400; i++)
  Object.defineProperty(t, "g" + i, { enumerable: true, get: () => i });
// perry: 527ms (x3.4 per size doubling — quadratic); node: 0.6ms

Real-world: a single @babel/types/lib/index.js (webpack re-export module: if (k in exports) …; Object.defineProperty(exports, k, {get}) per key) took 292ms vs node's 3ms (94×) inside the pi coding agent's jiti/dist/babel.cjs — the largest single contributor to pi's 3.3s startup under perry (measured by per-module init instrumentation).

Root cause

The define flow runs THREE linear keys_array scans per call (enforce_define_property_invariantsown_key_present, the existing-attrs check→obj_value_has_own_key, ensure_key_in_keys_array's dup check), and the in operator's own-key walk runs a fourth. The [[Set]] fast path solved this long ago with the authoritative KEYS_INDEX sidecar (append-without-scan); the define/in paths never adopted it. Bonus: the sidecar's rebuild skipped SSO inline keys (is_string() is heap-tag-only), so an authoritative miss could duplicate a short key.

Fix

PR incoming: route the define flow's presence checks and ordinary_has_property's own-key step through the sidecar (threshold-gated, same trust model as [[Set]]), maintain it from ensure_key_in_keys_array appends, and make the rebuild SSO-aware. After: 2400 defines 527→96ms (linear), @babel/types 292→113ms. Differential regression test included (byte-match vs node on dedup/attrs-retention/SSO/delete-redefine/invariant-throws/in).

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