dotnet / dotnet/runtime

[browser][coreCLR] R2R: Runtime shard consumer — lazy IL shard load

Open
#130,515 2 comments 0 reactions 1 assignee Claimed by @pavelsavara View on GitHub
arch-wasm area-AssemblyLoader os-browser
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

# Runtime shard consumer: lazy IL shard load

Part of #130524.

Status: **draft / issue candidate** · Area: CoreCLR-on-WASM runtime, assembly loading · Related: #130523 (splitter/producer), #130522 (R2R over in-memory IL), #130516 (R2R-shard trigger/loader)

## Goal

The runtime-side consumer of the shard layout #130523 produces: resolve and load IL **namespace-shards on demand**, so only the shards an app actually exercises are brought in, rather than eagerly loading every shard. It uses the facade's type-forwarders plus the boot-config namespace/shard metadata, and coordinates with the R2R lazy-load path.

## Why

Splitting IL into shards (#130523) only pays off if the runtime can bring shards in lazily. This work turns the static shard layout into on-demand loading, so download and load cost track what the app uses.

## Direction

- **Ride the forwarder → assembly resolution.** When a forwarded type is first needed, the runtime resolves it to its shard assembly; the consumer supplies or fetches that shard per its boot-config asset. The namespace metadata is a secondary index for grouping and pre-fetch.
- **Coordinate with the R2R lazy path.** Shard loading aligns with the interpreter-driven, async-tolerant hot-path streaming already planned for R2R, so a shard is fetched where blocking is acceptable rather than mid-execution.
- **JSPI is explicitly out of scope.** No synchronous fault-in of a download via JSPI. The consumer targets async-tolerant load points (interpreter keeps running, pre-fetch, load at safe points) instead of blocking a synchronous type resolution on a network fetch.
- **Behavior stays identical.** An app using shards behaves the same as one with monolithic assemblies; the split is invisible except for load timing.

## Scope

**In:** on-demand shard resolution and loading driven by the facade forwarders plus boot-config metadata; coordination with the R2R lazy-load path; an async-tolerant load strategy.

**Out:** the build-time splitter (#130523); the R2R-shard fetch/instantiate (owned by #130516 — this consumer handles IL shards only); JSPI-based synchronous IL fault-in; precompilation.

## Success criteria

- An app loads only the shards it exercises (plus the facade), with identical behavior.
- Shard loads happen at async-tolerant points without requiring synchronous blocking on downloads.
- Works together with the R2R lazy-load path and with the R2R metadata reuse (#130522).

## Open questions

- Which load points are safe and async-tolerant without JSPI (pre-fetch heuristics, interpreter yield points), and how to avoid a synchronous resolve stalling on a not-yet-resident shard.
- The trigger contract shared with the R2R lazy path, so a hot method and its IL shard are brought in coherently.
- Fallback behavior if a needed shard is not yet resident at a synchronous resolution point.

> [!NOTE]
> This issue was drafted with GitHub Copilot assistance.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.