Skip to content

fix(wasm-split): deduplicate shared residual symbols - #5738

Open
sarendipitee wants to merge 1 commit into
DioxusLabs:mainfrom
sarendipitee:wasm-split-chunk-dedupe
Open

fix(wasm-split): deduplicate shared residual symbols#5738
sarendipitee wants to merge 1 commit into
DioxusLabs:mainfrom
sarendipitee:wasm-split-chunk-dedupe

Conversation

@sarendipitee

Copy link
Copy Markdown

Fix duplicated symbols across shared wasm-split chunks

Summary

Fix shared-symbol ownership across lazy WASM split points.

The splitter now:

  • Records each non-main symbol's lazy split-point consumers.
  • Groups symbols by their exact consumer set.
  • Assigns each shared symbol one residual-chunk owner.
  • Stops residual dependency traversal at symbols owned by another residual chunk.
  • Imports foreign residual functions through the shared indirect-function table.
  • Records foreign residual chunk dependencies for function and data-symbol references.
  • Prevents foreign data bodies from being retained in dependent residual chunks.
  • Preserves main-module ownership and GC roots.
  • Emits residual chunk dependencies into generated loaders.
  • Uses invoked dependency callbacks so makeLoad awaits and instantiates dependencies before dependents.
  • Supports forward references between generated chunk declarations.
  • Caches in-flight loads and resets failed load promises for retry.

Problem

Previously, symbols reachable from multiple lazy split points could remain defined in multiple residual chunks. The resulting artifacts duplicated shared function/data bodies and did not reliably establish ownership or dependency edges.

The generated loader also needed to await residual-to-residual dependencies. Without that edge, a dependent chunk could instantiate before the chunk that provides its imported function or data state.

Implementation

Ownership and emission

packages/wasm-split/wasm-split-cli/src/lib.rs

  • Builds exact-consumer-set residual chunks.
  • Adds residual_chunk_symbols() to classify retained symbols, foreign imports, and owner dependencies.
  • Handles Node::Function and Node::DataSymbol separately.
  • Converts shared functions to imports and removes duplicate definitions before GC.
  • Keeps main-owned symbols in the main module.

Generated loader dependencies

packages/wasm-split/wasm-split-cli/src/main.rs

Residual chunk loaders now emit dependencies in the form:

() => __wasm_split_load_chunk_1();

The callback defers lookup until load time, allowing forward references to later const declarations while still invoking the dependency loader when makeLoad executes dep().

Runtime loading

packages/wasm-split/wasm-split-cli/src/__wasm_split.js

  • Awaits all declared dependencies before instantiation.
  • Caches in-flight loads to avoid duplicate concurrent instantiation.
  • Clears the cached promise after failure.
  • Rethrows failures to dependent callers.
  • Publishes instantiated exports through fusedImports.

Tests and verification

Rust

cargo test -p wasm-split-cli --lib -- --nocapture
3 passed

cargo test -p wasm-split-cli --bin wasm-split-cli -- --nocapture
1 passed

cargo check -p wasm-split-harness
passed

Coverage includes:

  • Shared Function/DataSymbol ownership.
  • Main-module exclusion.
  • Foreign residual function imports.
  • Foreign data-symbol dependency classification.
  • GC rooting behavior.
  • Residual loader dependency callback generation.
  • Forward reference from a lower-index chunk to a later chunk.

Browser

The wasm-split Playwright regression passes with all 3 tests green. It covers initial rendering, local/global WASM behavior, lazy module loading, route navigation, gzip/brotli modules, and shared-chunk requests.

3 passed

Static checks

node --check packages/playwright-tests/wasm-split.spec.js
passed

git diff --check
passed

Files changed

  • packages/wasm-split/wasm-split-cli/src/lib.rs
  • packages/wasm-split/wasm-split-cli/src/main.rs
  • packages/wasm-split/wasm-split-cli/src/__wasm_split.js
  • packages/playwright-tests/wasm-split-harness/src/main.rs
  • packages/playwright-tests/wasm-split.spec.js
  • packages/playwright-tests/playwright.config.js
  • WASM_SPLIT_SHARED_CHUNK_DUPLICATION.md

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant