Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 66c577c4c2d0b9b3cc2d706ba9311240413a5e0b
      
https://github.com/WebKit/WebKit/commit/66c577c4c2d0b9b3cc2d706ba9311240413a5e0b
  Author: Sosuke Suzuki <[email protected]>
  Date:   2026-04-30 (Thu, 30 Apr 2026)

  Changed paths:
    A JSTests/modules/namespace-single-walk.js
    A JSTests/modules/namespace-single-walk/conflict-only.js
    A JSTests/modules/namespace-single-walk/cycle-a.js
    A JSTests/modules/namespace-single-walk/cycle-b.js
    A JSTests/modules/namespace-single-walk/leaf-a.js
    A JSTests/modules/namespace-single-walk/leaf-b.js
    A JSTests/modules/namespace-single-walk/mid-left.js
    A JSTests/modules/namespace-single-walk/mid-right.js
    A JSTests/modules/namespace-single-walk/root.js
    M Source/JavaScriptCore/runtime/AbstractModuleRecord.cpp
    M Source/JavaScriptCore/runtime/AbstractModuleRecord.h

  Log Message:
  -----------
  [JSC] Walk star-export graph once when building a module namespace
https://bugs.webkit.org/show_bug.cgi?id=313549

Reviewed by Yusuke Suzuki.

GetModuleNamespace [1] currently runs GetExportedNames followed by a
ResolveExport call per name. resolveExportImpl walks the star-export
graph independently for each name, so building a namespace for a deep
barrel module costs O(names * star-edges).

Walk the graph once instead, recording each name's unique Local /
Namespace binding. A name with exactly one such binding across the whole
star-reachable graph is provably Resolved regardless of resolveSet [2]
(resolveSet only turns paths into null, and merge(Resolved, null) =
Resolved). Names with an Indirect entry, or with two or more distinct
bindings, fall back to resolveExport(). The root module's own export
entries shadow star-reachable bindings (ResolveExport returns at step
4-6 before consulting star), so a star-side conflict for a name the root
already provides never goes to the slow path.

Add Resolution::isSameBinding() and reuse it in mergeToCurrentTop.

In a local microbenchmark importing a barrel of 9000 exported names
through ~1500 star edges, namespace creation drops from 331 ms to 19 ms
(~17x). For modules without `export *` the walk visits only the root, so
behavior and cost are unchanged.

[1]: https://tc39.es/ecma262/#sec-getmodulenamespace
[2]: https://tc39.es/ecma262/#sec-resolveexport

Tests: JSTests/modules/namespace-single-walk.js
       JSTests/modules/namespace-single-walk/conflict-only.js
       JSTests/modules/namespace-single-walk/cycle-a.js
       JSTests/modules/namespace-single-walk/cycle-b.js
       JSTests/modules/namespace-single-walk/leaf-a.js
       JSTests/modules/namespace-single-walk/leaf-b.js
       JSTests/modules/namespace-single-walk/mid-left.js
       JSTests/modules/namespace-single-walk/mid-right.js
       JSTests/modules/namespace-single-walk/root.js

* JSTests/modules/namespace-single-walk.js: Added.
* JSTests/modules/namespace-single-walk/conflict-only.js: Added.
* JSTests/modules/namespace-single-walk/cycle-a.js: Added.
* JSTests/modules/namespace-single-walk/cycle-b.js: Added.
* JSTests/modules/namespace-single-walk/leaf-a.js: Added.
* JSTests/modules/namespace-single-walk/leaf-b.js: Added.
* JSTests/modules/namespace-single-walk/mid-left.js: Added.
* JSTests/modules/namespace-single-walk/mid-right.js: Added.
* JSTests/modules/namespace-single-walk/root.js: Added.
* Source/JavaScriptCore/runtime/AbstractModuleRecord.cpp:
(JSC::AbstractModuleRecord::resolveExportImpl):
(JSC::AbstractModuleRecord::getModuleNamespace):
(JSC::getExportedNames): Deleted.
* Source/JavaScriptCore/runtime/AbstractModuleRecord.h:
(JSC::AbstractModuleRecord::Resolution::isSameBinding const):

Canonical link: https://commits.webkit.org/312370@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to